@sellable/mcp 0.1.450 → 0.1.452

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.
@@ -6,7 +6,7 @@ async function postSetupEvergreenCampaigns(body) {
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. 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. 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=xhigh 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.5` into `-m` and always pass `-c model_reasoning_effort=xhigh`; a child worker that reports GPT 5.5 with high reasoning 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.",
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. 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. 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 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, prefer `codex_app.list_projects` then `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=xhigh exec --skip-git-repo-check -m <worker-model> -C <repo> -o <worker-final-file> -`; 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.5` into `-m` and always pass `-c model_reasoning_effort=xhigh`; a child worker that reports GPT 5.5 with high reasoning 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. 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: {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sellable/mcp",
3
- "version": "0.1.450",
3
+ "version": "0.1.452",
4
4
  "type": "module",
5
5
  "description": "Sellable MCP server for Claude Code and Codex campaign workflows",
6
6
  "main": "dist/index.js",
@@ -446,22 +446,60 @@ Tokenized shape:
446
446
 
447
447
  Hey there
448
448
 
449
- Thanks for the support on my post about {{post_topic_line}}
449
+ Saw you pop up on my post about {{post_topic_line}}
450
+
451
+ This one
452
+ {{post_url}}
453
+
454
+ Looks like you lead {{plain_buyer_function}} at {{company_name}}, right?
455
+
456
+ {{custom_closed_question}}
450
457
  ```
451
458
 
452
459
  Transfer rules:
453
460
 
454
461
  - Do not hardcode a post topic. Fill `{{post_topic_line}}` from the actual
455
- selected sender-authored post or use a safer source-specific phrase.
456
- - Do not add a relevance question, CTA, product line, or extra paragraph after
457
- the thank-you line. The reply-rate lesson is the casual warm acknowledgment,
458
- not a cold pitch appended to it.
462
+ selected sender-authored post or use a safer source-specific phrase. The best
463
+ lines sound like Justin's CXConnect example: a specific topic in normal human
464
+ words plus a light aside after a hyphen.
465
+ - Include the engaged post URL on its own line after `This one` when row/source
466
+ data has it. The link reminds the prospect why the message is relevant and
467
+ keeps this clearly in the Post Engagers motion instead of feeling like generic
468
+ Signal Discovery.
469
+ - Fill `{{plain_buyer_function}}` with an easy-to-understand buyer function or
470
+ category, such as `customer success`, `CX operations`, `founder-led sales`,
471
+ `sales`, `growth`, or `LinkedIn outbound`. Do not turn this line into a
472
+ feature list or internal workflow description.
473
+ - Fill `{{custom_closed_question}}` from the post topic, buyer function, company
474
+ context, and the current offer category. The question should be easy to answer,
475
+ closed-ended, and specific to that prospect. Do not reuse the same generic
476
+ question across every row.
477
+ - Good `{{custom_closed_question}}` examples:
478
+ - `Are you guys trying to make LinkedIn outbound a real founder-led channel, or is it still mostly ad hoc?`
479
+ - `Are you using LinkedIn to reach sales leaders directly, or is most pipeline still coming from intros and email?`
480
+ - `Are you actively testing outbound for growth teams right now, or is LinkedIn still more of a founder-network channel?`
481
+ - `Are you trying to turn customer feedback into account-risk signals, or is that still mostly manual check-ins?`
482
+ - `Are you looking at support conversations as a source of churn risk, or does that still mostly live in tickets and surveys?`
483
+ - `Are you building a repeatable sales motion yet, or is most of it still founder-led experimentation?`
484
+ - `Are you treating LinkedIn as a sales channel this year, or mostly as brand and founder content?`
485
+ - Bad `{{custom_closed_question}}` examples:
486
+ - `Are you trying to avoid manual research + follow-up process?`
487
+ - `Are you interested in seeing Sellable?`
488
+ - `Open to seeing how this would work?`
489
+ - `Do you need more leads, filters, messages, and sequence setup?`
490
+ - The product/category wording in the question should be plain and immediately
491
+ legible, for example `LinkedIn outbound`, `customer success`, `CX operations`,
492
+ `support`, or `post-sales`. Avoid feature-heavy phrasing such as `manual
493
+ research + follow-up process`, `lead filters`, `workflow`, `sequence setup`,
494
+ or internal mechanism language.
495
+ - Do not add a meeting ask, product pitch, proof block, or extra paragraph after
496
+ the custom closed question. The reply-rate lesson is the casual warm
497
+ acknowledgment, concrete post reminder, and low-friction custom question, not a
498
+ cold pitch appended to it.
459
499
  - Do not use "showing some love"; it reads too casual for executive/VP/director
460
500
  contacts.
461
- - Keep the thank-you line. The point of this motion is acknowledging real
462
- sender-owned support without appending a cold relevance question. Do not
463
- flatten it back to "saw you pop up" unless the sender specifically asks for
464
- that wording.
501
+ - Keep the post-engager acknowledgment. The point of this motion is acknowledging
502
+ real sender-owned support without pretending this is generic cold outreach.
465
503
  - Do not copy this shape into shared lanes, third-party thread sources, or cold
466
504
  fallback campaigns.
467
505
  - Do not pitch, ask for a meeting, or mention internal product vocabulary in
@@ -387,13 +387,10 @@ before completion.
387
387
  Short form: Workers must preserve parent postEngagerSenderIds even for shared lanes.
388
388
  Short form: Never run a shared-lane worker-local plan with `postEngagerSenderIds:[]` unless the parent `postEngagerSenderIds` is exactly `[]`.
389
389
 
390
- Worker fan-out must use visible or durable execution. In local Codex, the
391
- default and preferred runtime is `workerDispatch.preferredRuntime:
392
- "visible-codex-app-thread"`. The parent must attempt a visible Codex app thread
393
- first with the actual Codex app thread tools: if `codex_app.create_thread` is
394
- not already visible, use tool discovery for the Codex app thread tools; then
395
- call `codex_app.list_projects`, select the current repo project, and call
396
- `codex_app.create_thread` with `target:{type:"project", projectId,
390
+ Worker fan-out must use visible or durable execution. Preferred in local Codex
391
+ is a visible Codex thread created with the actual Codex app thread tools:
392
+ first call `codex_app.list_projects`, select the current repo project, then
393
+ call `codex_app.create_thread` with `target:{type:"project", projectId,
397
394
  environment:{type:"local"}}`. Do not create a worktree target for evergreen
398
395
  UAT or lane execution. The parent must record the returned thread id, pass
399
396
  exactly one lane packet into that thread, and require the worker to write the
@@ -407,10 +404,9 @@ worker exits, and contain the current `planRevision`, `actionId`, `laneKey`,
407
404
  `receiptArtifactPath`, and `durableReceiptWritten:true`. If a receipt predates
408
405
  the current run, uses an old path without `receiptRunId`, or was not freshly
409
406
  written by the current worker, stop with `blocked: stale_receipt_artifact`
410
- before parent verify or completion. A streaming worker or branch worker is a
411
- fallback only when app thread tools are unavailable; the receipt must include
412
- `preferredRuntimeAttempt` for `visible-codex-app-thread` and a non-empty
413
- `fallbackReason`, or backend verify rejects it.
407
+ before parent verify or completion. A streaming worker or branch worker is
408
+ acceptable only when it writes a fresh durable per-lane receipt artifact as it
409
+ works.
414
410
  When visible Codex app thread tools are unavailable but local Codex CLI is
415
411
  available, the accepted durable streaming-worker command shape is:
416
412
  `codex -a never -s danger-full-access -c model_reasoning_effort=xhigh exec --skip-git-repo-check -m <worker-model> -C <repo> -o <worker-final-file> -`.
@@ -720,11 +716,7 @@ not a parent-thread summary. The receipt must include:
720
716
  `workflowAssetPath:"create-campaign-v2/core/flow.v2.json"`,
721
717
  `workflowAssetLoaded:true`, the real `workerRuntime`, a visible
722
718
  `workerThreadId` or durable `receiptArtifactPath`, `durableReceiptWritten:true`
723
- when using a receipt file, and `notAdHoc:true`. If `workerRuntime` is
724
- `streaming-worker-with-durable-receipt` or
725
- `branch-worker-with-durable-receipt`, also include
726
- `preferredRuntimeAttempt` proving the parent attempted
727
- `visible-codex-app-thread` first and a non-empty `fallbackReason`.
719
+ when using a receipt file, and `notAdHoc:true`.
728
720
  - `researchSenderReceipt`: `research-sender` prompt load proof,
729
721
  `complete_sender_research` result, sender LinkedIn identity basis, and the
730
722
  notes/proof counts used before the net-new `create_campaign` call. It must
@@ -919,7 +911,7 @@ verification unless the same object also appears inside
919
911
  "workflowPromptLoadedToHasMoreFalse": true,
920
912
  "workflowAssetPath": "create-campaign-v2/core/flow.v2.json",
921
913
  "workflowAssetLoaded": true,
922
- "workerRuntime": "visible-codex-app-thread",
914
+ "workerRuntime": "separate-codex-thread",
923
915
  "workerThreadId": "<visible local Codex thread id>",
924
916
  "receiptArtifactPath": "<receiptArtifactPath from workerDispatch.receiptArtifactHint>",
925
917
  "durableReceiptWritten": true,
@@ -1338,21 +1330,35 @@ Message, and verify current-revision sample messages before final completion.
1338
1330
  Short form: Shared lanes must reject internal workflow vocabulary.
1339
1331
  Short form: revise or rerun the packaged create-campaign/generate-messages path.
1340
1332
  - **Post Engagers** first-message style: short, casual, references the
1341
- sender-authored post they engaged with, and stops after the thank-you
1342
- line. Use **no internal vocabulary, no pitch, no meeting ask, no product
1343
- line, and no relevance question** in message one:
1333
+ sender-authored post they engaged with, includes the post URL as a concrete
1334
+ reminder, uses an easy buyer-function/category line, and ends with one
1335
+ row-custom closed question. Use **no internal vocabulary, no meeting ask,
1336
+ no proof block, no feature-stack category, and no generic static question**
1337
+ in message one:
1344
1338
 
1345
1339
  ```
1346
1340
  {{first_name}}
1347
1341
 
1348
1342
  Hey there
1349
1343
 
1350
- Thank you for the support on my post about {{post_topic_line}}
1344
+ Saw you pop up on my post about {{post_topic_line}}
1345
+
1346
+ This one
1347
+ {{post_url}}
1348
+
1349
+ Looks like you lead {{plain_buyer_function}} at {{company_name}}, right?
1350
+
1351
+ {{custom_closed_question}}
1351
1352
  ```
1352
1353
 
1353
- Do not add any paragraph after the thank-you line. In particular, do not
1354
- append `curious, are you trying...`, `open to...`, `worth seeing...`, or
1355
- Sellable/product copy to a Post Engagers first message.
1354
+ `{{custom_closed_question}}` must be specific to the post topic, buyer
1355
+ function, company context, and current offer category. The category should
1356
+ be easy to understand, for example `LinkedIn outbound`, `customer success`,
1357
+ `CX operations`, `support`, `sales`, or `growth`; do not use feature-heavy
1358
+ phrasing like `manual research + follow-up process`, `lead filters`, or
1359
+ `sequence setup`. Do not add any paragraph after the custom closed question.
1360
+ In particular, do not append `open to...`, `worth seeing...`, a meeting ask,
1361
+ proof block, or Sellable/product copy to a Post Engagers first message.
1356
1362
 
1357
1363
  - **Shared Signal Discovery** first-message style: short, casual, starts
1358
1364
  from the real public business theme or buyer problem supported by the row.
@@ -227,17 +227,24 @@ when those shared lanes were sourced from engagement-like signals. Shared lanes
227
227
  must choose a signal-led, event-led, job-post-led, or proof-led motion from the
228
228
  current brief and row evidence instead of inheriting a preset first-message
229
229
  template.
230
- Post-engager first messages should thank the prospect for the support on the
231
- sender-owned post and then stop. Do not add a relevance question, CTA, product
232
- line, meeting ask, or extra paragraph after the thank-you opener unless the
233
- operator explicitly asks for a longer first message. Prefer the gold shape
234
- `Thanks for the support on my post about {{post_topic_line}}` over
235
- surveillance-flavored wording like `saw you pop up`, unless the sender explicitly
236
- asks for that older wording.
230
+ Post-engager first messages should follow the CXConnect warm shape: acknowledge
231
+ the sender-owned post engagement, include the engaged post URL after a `This one`
232
+ line when row/source data has it, add a plain buyer-function/category check, and
233
+ ask one custom closed question. The question must be specific to the post topic,
234
+ buyer function, company context, and current offer category; do not reuse one
235
+ generic feature-stack question across every row. Product/category wording should
236
+ be immediately legible, such as `LinkedIn outbound`, `customer success`, `CX
237
+ operations`, `support`, `sales`, `growth`, or `post-sales`, not internal
238
+ workflow/mechanism language like `manual research + follow-up process`, `lead
239
+ filters`, or `sequence setup`. Do not add a meeting ask, product pitch, proof
240
+ block, or extra paragraph after the custom closed question unless the operator
241
+ explicitly asks for a longer first message.
237
242
  Short form: use the CXConnect Post-Engager Warm Reply-Rate Pattern only when the source is sender-owned Post Engagers.
238
243
  Short form: Never use that warm post-engager pattern for Shared Signal Discovery or Shared Cold Fallback.
239
- Short form: Post-engager warm first messages stop after the thank-you line.
240
- Short form: Do not add `curious`, `open to`, `trying to`, product copy, or a CTA after the post-engager thank-you line.
244
+ Short form: Post-engager warm first messages use `This one` plus the post URL when available.
245
+ Short form: Post-engager warm first messages need a row-custom closed question.
246
+ Short form: Use plain category words, not feature-stack wording.
247
+ Short form: Do not add `open to`, `worth seeing`, product copy, proof blocks, or a meeting CTA after the custom closed question.
241
248
 
242
249
  ### Shared Cold Fallback quality bar
243
250