| name | support-send |
| description | Deliver a reviewed support request through the channel the registry names — send the email with whatever mail tool is available, fill and submit the vendor's web form in the user's own browser, post to a public forum, or hand the user a call briefing for a channel only a human can use. Confirms the exact destination and recipient before anything leaves the machine, records what was sent and when in the ticket log, and computes the date the response comes due. Use when the user approves a draft and says to send it, submit it, file it, or post it. |
support-send
The outward-facing step. Everything before this was reversible; this is not.
Preconditions
All three, before anything else:
- A draft exists and the user has seen it. Not a draft produced in this same turn and not yet
displayed. If there is no reviewed draft, run
support-request first.
- The user has approved it after seeing it. "Send it" said before the draft existed is not
approval of the draft.
- The destination is confirmed — read from the registry entry, quoted back to the user in the
confirmation, not recalled.
Procedure
1. Say what is about to happen
One short block, then wait:
Sending to: support@example.com (registry: example / email-support, verified 2026-07-30)
From: daniel@example.com
Subject: <subject line>
Contains: account number, subscription ID, three log excerpts (redacted)
This leaves the machine and reaches the vendor. Get an explicit yes. A single yes covers this one
send; it does not cover the follow-ups.
2. Deliver, by agent_reachable
yes — email. Use whatever mail capability the session actually has: a Gmail or Workspace MCP
tool, a transactional-mail tool, mail/sendmail if configured. Check what exists before
promising. Send from the address in contact_as or defaults.contact_email — the address the vendor
already associates with the account, which is often not the user's main one. Put the draft in the
body as text; avoid HTML, which some desks flatten badly.
If there is no working mail route, say so plainly and hand the user the draft plus the address. Do
not fall back to a different channel because it is the one that happens to be reachable — see
${CLAUDE_PLUGIN_ROOT}/references/channel-selection.md.
yes — public form. A form with no login can be filled directly. Map the draft onto the
registry's required_fields; a field the registry does not list and the form demands is a finding
for the entry.
browser — login-gated form or portal. Drive the user's browser. They must already be logged
in; do not attempt a login, and do not read a credential out of a store to do it. If the session is
not authenticated, ask them to log in and say when to continue.
Fill the fields, then stop before submitting and show what is in the form. Web forms mangle long
text, drop line breaks, and silently truncate; the version in the box is not always the version in
the draft. Submit only after the user confirms what they can see.
Capture the ticket reference from the confirmation screen. Without it, escalation has nothing to
point at.
user-only — phone, in-product chat, post. The deliverable is a briefing, formatted to be read
aloud or pasted:
- Who they are: account number, plan, the name on the account.
- The problem in one sentence.
- The ask in one sentence.
- The three or four facts most likely to be asked for, in the order they will be asked.
- The existing ticket number if there is one.
- What to write down: the reference, the agent's name, what was promised, by when.
Say plainly that this one needs them, and why — no phone number is published, or the widget only
exists inside the product.
Public forum or social. One more check before posting: reread the text for identifiers. Account
numbers, account emails, phone numbers, invoice numbers, object SIDs, internal hostnames. A public
post is not retractable in any meaningful sense — it is cached and indexed within minutes and stays
that way after deletion. If anything identifying survives in the text, do not post; go back to
support-request.
3. Record it
Update ~/.claude-plugins/contact-support/tickets/<slug>/<file>.md:
- Append the sent message under
## Correspondence with the date and — sent.
- Set
ticket_ref if the channel returned one.
- Set
last_contact to today.
- Compute
response_due from the registry's window for this plan and priority. Business hours mean
the vendor's, not the user's — use hours on the channel, and note the assumption where the
window is ambiguous.
- Keep
status: open.
4. Report
What went where, the reference if there is one, the date a response is due, and what happens if it
does not arrive — naming the first step of escalation[]. Then say that support-followup will pick
it up.
5. Feed back what you learned
If the send taught the registry something — a required field that was not listed, a bounced address,
a form that rejected the category, a confirmation naming a different queue — write it into the entry
now. known_dead for a bounce, required_fields for a field, gotchas for behaviour. This is the
only moment the knowledge is cheap to capture.
Guardrails
- One approval, one send. Approval does not roll forward to the next message, the next channel, or a
retry after a failure.
- Never send to an address or URL that is not in the merged registry entry, and never to one the
user typed from memory without confirming it against the entry.
- Never send a credential, however the vendor's form is worded. A support flow that requires one is
not a support flow.
- Never post identifiers publicly.
- Never open a second ticket for an issue that already has one. Reply on the thread; a duplicate
splits history and usually resets queue position.
- On failure — bounce, form error, submit rejected — stop and report. Do not retry through a
different channel without asking; the user chose that channel for reasons the failure has not
changed.