Send As
Govern a message, campaign, or notification sent on behalf of a principal.
The default send runner performs one delivery through a compatible normalized
connector and closes only after independent provider readback. plan is the
explicit no-effect runner. apply consumes an existing
runx.send_as.plan.v1 packet without planning again, and verify consumes the
provider mutation result without sending again. Provider-specific skills can
compose these phase runners while retaining the same authority model.
What this skill does
send-as binds the principal, provider, channel, recipients or audience,
content digest, consent basis, preflight checks, and approval gate. The caller
selects only a compatible provider and bounded target; it does not author
provider operations, result fields, payload plumbing, or retry keys. Runx
derives a canonical message.send request from the approved plan, binds its
idempotency key to a native digest, applies it under one approval, and verifies
the stable identity with message.read. It refuses to treat a draft, preview,
mutation acknowledgement, or test message as live delivery. A live send is
final only after provider readback and the Runx receipt seal.
Use plan when only an authorization packet is wanted. A sealed plan receipt
means only that the plan was sealed. A completed default result emits
runx.send_as.result.v1; its sent status is unavailable unless mutation and
readback both succeed.
When to use this skill
- An agent needs to send or schedule one bounded message on behalf of a user,
team, brand, account, or service through a compatible connector.
- An operator explicitly wants a plan and selects
plan.
- A provider-specific skill needs a shared authority model before it can call a
send API or MCP tool.
- The workflow must prove the intended audience, content, consent basis, and
approval decision before delivery.
- A review needs to distinguish draft, test, scheduled, approved, sent, denied,
and failed states.
When not to use this skill
- To write copy only. Use a drafting or brand-voice skill unless delivery is in
scope.
- To claim delivery from a
send_plan; only send_result with provider
readback is terminal evidence.
- To import contacts, enrich leads, verify domains, or configure billing as the
main objective.
- To send without a named principal and audience.
- To hide provider credentials, raw contact lists, or customer data in the
agent-visible output.
- To bypass unsubscribe, consent, suppression, warmup, preflight, legal, or
human approval gates.
Procedure
- Identify the principal being represented and the provider account or surface.
- Classify the send:
transactional, campaign, flow_step, support_reply,
outreach, status, or internal.
- Bind channel and audience. Audience must be a named recipient, list, segment,
support thread, channel, or scoped all-contacts decision; never an implicit
broad default.
- Bind content by digest or stable draft reference. Do not approve mutable
content by prose summary alone.
- Check consent, unsubscribe, suppression, compliance, preflight, and provider
readiness. Missing evidence becomes a blocker.
- Decide the gate:
- drafts, previews, and test sends may proceed without live-delivery
approval when provider policy permits them;
- customer, public, audience, or live sends require explicit approval;
- billing/account mutation is outside this skill and needs its own gate.
- Produce the smallest provider-neutral
send_plan that execution can consume
without widening authority.
- For the default runner, require only a compatible connector provider and
bounded target. Runx derives the normalized operations, payload, expected
stable identity, result fields, and digest-bound idempotency key. Missing
connector authority blocks before mutation.
- Apply once, then verify using the mutation result. The provider-observed
mutation idempotency key must match the runtime-bound send key; the
independent read operation has its own operation identity. Never re-plan or
resend during
verify.
- Return
needs_input for missing principal, audience, content digest,
consent basis, or provider readiness; return refused for gate bypass.
Edge cases and stop conditions
- No principal: return
needs_input; the agent cannot speak as an unnamed
actor.
- No audience: return
needs_input; do not default to all contacts or a
whole channel.
- All contacts or broad audience: require explicit reconfirmation and a
stricter preflight block.
- Mutable content: return
needs_input until content is digest-bound.
- Missing consent or unsubscribe path: block live delivery.
- Preflight failure: block provider send and preserve blocker evidence.
- Approval denied or absent: do not deliver.
- No compatible connector operation: return one actionable blocker; do not
downgrade the default invocation to a plan or simulation.
- Ambiguous mutation outcome: resume with the same idempotency key; never
create a new key to escape uncertainty.
- Raw credentials or contact dumps: redact; if redaction would remove the
evidence needed to decide, return
needs_input.
Output schema
send_plan:
decision: ready | needs_input | denied | refused
action_family: send-as
principal:
type: user | team | account | service
ref: string
provider:
name: string
account_ref: string
runtime_path: string
send_class: transactional | campaign | flow_step | support_reply | outreach | status | internal
channel: email | sms | chat | push | webhook | other
audience:
type: recipient | list | segment | thread | channel | all_contacts
ref: string
requires_reconfirmation: boolean
content:
draft_ref: string
digest: string
subject_or_title: string
gates:
preflight_required: boolean
human_approval_required: boolean
approval_ref: string
blockers: array
provider_actions: array
evidence_refs: array
success_checkpoint:
milestone: string
description: string
Successful default execution additionally emits:
send_result:
schema: runx.send_as.result.v1
status: sent | failed
outcome: completed | failed
provider: string
target: string
operation: string
content_digest: string
operation_id: string
readback_ref: string
idempotency_key: string
evidence:
mutation_readback_ref: string
verification_readback_ref: string
errors: array
Worked example
Input: "Schedule the June newsletter to the subscribers list" with a campaign
draft digest, verified sender, named list, and provider account snapshot.
Output: decision: ready; send_class: campaign; audience is the named
subscribers list; content is digest-bound; preflight and human approval are
required; the provider actions are compose/review/test, then gated schedule.
No live send is authorized until the approval gate is satisfied.
Inputs
objective (required): bounded send or delivery objective.
principal (required): who the message is sent as.
provider_context (optional): provider/account readiness, connector, or MCP
status.
audience (optional): recipient, list, segment, thread, channel, or audience
brief.
content_ref (optional): digest, draft id, template id, campaign id, or
stable content reference.
consent_basis (optional): why the recipient/audience may receive this.
operator_context (optional): approval posture, legal constraints, or extra
guardrails.
connector (required for send, apply, and verify): provider name and
bounded account, workspace, channel, campaign, or equivalent target. It
contains no credentials or caller-authored operation grammar.
1---2name: send-as3description: Send one digest-bound provider-neutral message or campaign action through a compatible connector, with an explicit plan runner and approval plus readback at the live-delivery boundary.4---56# Send As78Govern a message, campaign, or notification sent on behalf of a principal.910The default `send` runner performs one delivery through a compatible normalized11connector and closes only after independent provider readback. `plan` is the12explicit no-effect runner. `apply` consumes an existing13`runx.send_as.plan.v1` packet without planning again, and `verify` consumes the14provider mutation result without sending again. Provider-specific skills can15compose these phase runners while retaining the same authority model.1617## What this skill does1819`send-as` binds the principal, provider, channel, recipients or audience,20content digest, consent basis, preflight checks, and approval gate. The caller21selects only a compatible provider and bounded target; it does not author22provider operations, result fields, payload plumbing, or retry keys. Runx23derives a canonical `message.send` request from the approved plan, binds its24idempotency key to a native digest, applies it under one approval, and verifies25the stable identity with `message.read`. It refuses to treat a draft, preview,26mutation acknowledgement, or test message as live delivery. A live send is27final only after provider readback and the Runx receipt seal.2829Use `plan` when only an authorization packet is wanted. A sealed plan receipt30means only that the plan was sealed. A completed default result emits31`runx.send_as.result.v1`; its `sent` status is unavailable unless mutation and32readback both succeed.3334## When to use this skill3536- An agent needs to send or schedule one bounded message on behalf of a user,37 team, brand, account, or service through a compatible connector.38- An operator explicitly wants a plan and selects `plan`.39- A provider-specific skill needs a shared authority model before it can call a40 send API or MCP tool.41- The workflow must prove the intended audience, content, consent basis, and42 approval decision before delivery.43- A review needs to distinguish draft, test, scheduled, approved, sent, denied,44 and failed states.4546## When not to use this skill4748- To write copy only. Use a drafting or brand-voice skill unless delivery is in49 scope.50- To claim delivery from a `send_plan`; only `send_result` with provider51 readback is terminal evidence.52- To import contacts, enrich leads, verify domains, or configure billing as the53 main objective.54- To send without a named principal and audience.55- To hide provider credentials, raw contact lists, or customer data in the56 agent-visible output.57- To bypass unsubscribe, consent, suppression, warmup, preflight, legal, or58 human approval gates.5960## Procedure61621. Identify the principal being represented and the provider account or surface.632. Classify the send: `transactional`, `campaign`, `flow_step`, `support_reply`,64 `outreach`, `status`, or `internal`.653. Bind channel and audience. Audience must be a named recipient, list, segment,66 support thread, channel, or scoped all-contacts decision; never an implicit67 broad default.684. Bind content by digest or stable draft reference. Do not approve mutable69 content by prose summary alone.705. Check consent, unsubscribe, suppression, compliance, preflight, and provider71 readiness. Missing evidence becomes a blocker.726. Decide the gate:73 - drafts, previews, and test sends may proceed without live-delivery74 approval when provider policy permits them;75 - customer, public, audience, or live sends require explicit approval;76 - billing/account mutation is outside this skill and needs its own gate.777. Produce the smallest provider-neutral `send_plan` that execution can consume78 without widening authority.798. For the default runner, require only a compatible connector provider and80 bounded target. Runx derives the normalized operations, payload, expected81 stable identity, result fields, and digest-bound idempotency key. Missing82 connector authority blocks before mutation.839. Apply once, then verify using the mutation result. The provider-observed84 mutation idempotency key must match the runtime-bound send key; the85 independent read operation has its own operation identity. Never re-plan or86 resend during `verify`.8710. Return `needs_input` for missing principal, audience, content digest,88 consent basis, or provider readiness; return `refused` for gate bypass.8990## Edge cases and stop conditions9192- **No principal:** return `needs_input`; the agent cannot speak as an unnamed93 actor.94- **No audience:** return `needs_input`; do not default to all contacts or a95 whole channel.96- **All contacts or broad audience:** require explicit reconfirmation and a97 stricter preflight block.98- **Mutable content:** return `needs_input` until content is digest-bound.99- **Missing consent or unsubscribe path:** block live delivery.100- **Preflight failure:** block provider send and preserve blocker evidence.101- **Approval denied or absent:** do not deliver.102- **No compatible connector operation:** return one actionable blocker; do not103 downgrade the default invocation to a plan or simulation.104- **Ambiguous mutation outcome:** resume with the same idempotency key; never105 create a new key to escape uncertainty.106- **Raw credentials or contact dumps:** redact; if redaction would remove the107 evidence needed to decide, return `needs_input`.108109## Output schema110111```yaml112send_plan:113 decision: ready | needs_input | denied | refused114 action_family: send-as115 principal:116 type: user | team | account | service117 ref: string118 provider:119 name: string120 account_ref: string121 runtime_path: string122 send_class: transactional | campaign | flow_step | support_reply | outreach | status | internal123 channel: email | sms | chat | push | webhook | other124 audience:125 type: recipient | list | segment | thread | channel | all_contacts126 ref: string127 requires_reconfirmation: boolean128 content:129 draft_ref: string130 digest: string131 subject_or_title: string132 gates:133 preflight_required: boolean134 human_approval_required: boolean135 approval_ref: string136 blockers: array137 provider_actions: array138 evidence_refs: array139 success_checkpoint:140 milestone: string141 description: string142```143144Successful default execution additionally emits:145146```yaml147send_result:148 schema: runx.send_as.result.v1149 status: sent | failed150 outcome: completed | failed151 provider: string152 target: string153 operation: string154 content_digest: string155 operation_id: string156 readback_ref: string157 idempotency_key: string158 evidence:159 mutation_readback_ref: string160 verification_readback_ref: string161 errors: array162```163164## Worked example165166Input: "Schedule the June newsletter to the subscribers list" with a campaign167draft digest, verified sender, named list, and provider account snapshot.168169Output: `decision: ready`; `send_class: campaign`; audience is the named170subscribers list; content is digest-bound; preflight and human approval are171required; the provider actions are compose/review/test, then gated schedule.172No live send is authorized until the approval gate is satisfied.173174## Inputs175176- `objective` (required): bounded send or delivery objective.177- `principal` (required): who the message is sent as.178- `provider_context` (optional): provider/account readiness, connector, or MCP179 status.180- `audience` (optional): recipient, list, segment, thread, channel, or audience181 brief.182- `content_ref` (optional): digest, draft id, template id, campaign id, or183 stable content reference.184- `consent_basis` (optional): why the recipient/audience may receive this.185- `operator_context` (optional): approval posture, legal constraints, or extra186 guardrails.187- `connector` (required for `send`, `apply`, and `verify`): provider name and188 bounded account, workspace, channel, campaign, or equivalent target. It189 contains no credentials or caller-authored operation grammar.