Kelly Campaigns
Overview
Kelly Campaigns is a Busabase Cloud App-in-Skill. Its canonical product
surface is the AirApp in Busabase, not a separate local-data product. The
same Hono source supports an explicitly requested local preview with OAuth
connection bootstrap. Use this skill as Kelly's outbound email-marketing
operator: it keeps a dashboard over audience segments, drafted sends
(campaign broadcasts, newsletter issues, and sequence steps), pre-send
deliverability and subject-line QA, and post-send performance. The skill
builds segments, drafts email copy, runs deliverability and quality checks,
and prepares sends; the human reviews, edits, and approves each send in the
app before anything is scheduled or sent.
This is outbound marketing to a subscriber list. It is distinct from
kelly-email, which triages an incoming inbox. Keep them separate:
kelly-email is about mail you received; kelly-campaigns is about mail you
send to many people.
Default behavior is AirApp-first. Unless the user explicitly asks only for
explanation, update Busabase directly and give the user the clickable AirApp
URL. Start localhost only when local preview/debugging is explicitly
requested; it uses the same Busabase resources and never offers another data
provider. Use chat-only mode only when the user says "纯聊天", "chat only", "不要打开 UI", or similar; in that mode present numbered sends (Send #1) and take verdicts in the conversation.
This skill is an implementation of the App-in-Skill pattern — a Codex/agent skill paired with a small companion UI for review and approval. See the spec paper: https://mr-kelly.github.io/research/app-in-skill-specification-for-pairing-agent-skills-with-a-local-companion-ui.pdf.
Mandatory Dependencies
- Read and follow
$kelly-app-skill-creator for product behavior, visual
quality, responsive layout, and the complete canonical content/kelly-campaigns-app/ artifact.
- Read and follow
$busabase for connection, target Space, node discovery,
ChangeRequests, review, and merge behavior.
- Read and follow
$busabase-app-creator for resource modeling, AirApp
runtime limits, security, validation, and deployment.
If a dependency is unavailable, preserve this skill's local artifact and
product contracts, stop before the unavailable Busabase operation, and report
the exact missing dependency. Do not invent a second data backend.
The SEND Discipline
Work is organized around four phases. Every send is tagged with the phase it belongs to, and the app groups by phase.
- Setup — the sending foundation: authentication and deliverability, audience segments, list growth, list hygiene.
- Engage — the creative: email copy, subject lines, HTML render / dark-mode, dynamic personalization.
- Nurture — the lifecycle: sequences (welcome, drip, win-back), newsletter cadence and monetization, preference/frequency management, reactivation.
- Deliver — getting it into the inbox: send experiments (A/B), inbox-placement monitoring, cold outbound, and the pre-send quality gate.
Capability taxonomy (16 sub-skills)
| Phase |
Sub-skills |
| Setup |
deliverability-qa · list-segment-builder · list-growth-designer · list-hygiene-monitor |
| Engage |
email-creative-builder · subject-line-lab · email-render-builder · dynamic-content-personalizer |
| Nurture |
email-sequence-designer · newsletter-monetization-planner · preference-frequency-manager · reactivation-specialist |
| Deliver |
send-experiment-designer · inbox-placement-monitor · cold-outbound-sequencer · email-quality-auditor ⛩ (the quality gate) |
The quality gate — email-quality-auditor ⛩
Before any send can be scheduled, it passes the SEND framework, which produces an EQS (Email Quality Score, 0–100) and a SHIP / FIX / BLOCK verdict:
- S — Sender & auth: SPF, DKIM, DMARC pass; correct from-identity.
- E — Engagement risk: segment quality, expected open/complaint behavior, re-permission for cold/lapsed lists.
- N — Not spammy: spam score, trigger words, link/image balance, working unsubscribe + physical address.
- D — Deliverability: inbox readiness against policy floors, IP/domain warm-up, render and dark-mode.
Verdicts: SHIP (ready to schedule), FIX (deliverable but revise first), BLOCK (hard stop — e.g. failing DKIM or a spam score above policy). The gate never sends; a human still approves. A send whose deliverability risk is high (SPF/DKIM/DMARC failing, spam score ≥ 5, or inbox readiness below 0.6 — see deliverabilityInfo() in content/kelly-campaigns-app/app/js/campaigns-model.js) is refused scheduling even if it carries an approved status.
App UI Screenshots
Boundary
- The skill may build segments, draft sends, run deliverability/quality checks, and write it all to Busabase.
- The AirApp reads and writes Busabase records only. It must never send email, call an ESP, mutate a subscriber list, or perform any other external side effect.
- Sending is always approval-required (outbound + volume). Real scheduling/sending is performed by the configured ESP by the skill, only after the user approves the specific send in the app or in chat.
scripts/execute_decisions.mjs only marks an approved send done in Busabase and reports the handoff operation the ESP still needs to perform; it performs no sending itself.
- Treat subscriber data as sensitive. Never commit real subscriber lists, ESP credentials, or Busabase credentials.
Busabase Resources
Four Bases under one application Folder (kelly-campaigns), declared in
content/kelly-campaigns-app/app/js/config.js and the generated template sidecars under content/:
segments: audience segments — id, name, description, audience size.
sends: the review queue — campaign/newsletter/sequence-step/cold-outbound sends: type, phase, subject/preview/body, segment + audience size, deliverability, subject A/B variants, the quality-gate (EQS + SHIP/FIX/BLOCK), workflow status, and the human verdict fields decision-note / decided-at.
suppression: the consent/suppression list — recipients or whole segments removed by unsubscribe, hard bounce, or complaint.
settings: one row per kind — kelly-campaigns-profile (operator/brand/ESP/from-identities/sending-policy/style-tone/list-health) and kelly-campaigns-lock.
Resources provision lazily through an idempotent Busabase ChangeRequest the
first time the app runs in a Space; see references/campaigns-schema.md for
exact field shapes. Metrics, the pre-send deliverability-risk derivation, and
the consent/suppression pre-send check are computed client-side from the
sends/suppression Bases on every read — they are never stored. The EQS
score and SHIP/FIX/BLOCK verdict are authored per send by the
email-quality-auditor gate and stored on the record.
First Run And Onboarding
On invocation, check the kelly-campaigns-profile settings row for
readiness. If it is absent, guide setup before doing real marketing work.
Ask for non-secret setup details only: operator profile (name, role, company, timezone), brand (name, homepage, unsubscribe URL), ESP provider name, from-identities (from-name/from-email/reply-to and when to use each), segments, sending policy (approval-required, daily/hourly caps, min inbox readiness, max spam score), risk keywords, and style/tone. Never ask the user to paste secret values into chat. Busabase authentication is ambient inside the deployed AirApp; ESP credentials belong to the trusted handoff process's own environment, never Busabase.
Local App
Default behavior is AirApp-first — give the user the clickable AirApp URL.
Start pnpm --dir content/kelly-campaigns-app dev only when local preview/debugging is explicitly
requested.
Required app views (hash routes):
#/overview: send desk. Human-attention counts, upcoming sends for the next weeks, list health (subscriber count, bounce/complaint/churn rates, avg open/click), and a SEND-phase breakdown.
#/campaigns and #/campaigns/<send_id>: the review queue over drafted sends in workflow states needs_review, changes_requested, approved, done, blocked. Each item shows a stable row ref (Send #1), type + phase + quality-gate verdict badges, the segment and audience size, deliverability risk, subject + preview text, an editable body draft, an A/B subject picker when variants exist, a Review note textarea, and Approve / Request changes / Block buttons that write the verdict directly onto the send record.
#/deliverability: pre-send QA table — SPF/DKIM/DMARC pass flags, spam score, inbox readiness, and the SEND verdict per send, plus the read-only suppression list, so weak auth or spammy copy is caught before scheduling.
#/performance: open/click/unsub/bounce by sent campaign.
#/settings: sanitized config summary — operator, brand, ESP + secret readiness, from-identities, segments, sending policy, and onboarding state. Never expose secret values.
Keep the sidebar workflow filters (All / Needs Review / Approved / Done / Blocked) as the primary nav, plus the views above.
Demo mode:
?demo=1 (or ?demo=overview) opens a deterministic mock program ("Northwind Coffee") for documentation and screenshots.
?demo=overview, ?demo=campaigns, ?demo=deliverability, ?demo=performance, and ?demo=detail select named mock scenes; detail deep-links to a send detail.
lang=en or lang=zh forces UI chrome language for screenshots.
- Demo mode never reads or writes Busabase.
UI language: support English and Chinese chrome with Auto default. Keep subject lines, body copy, segment names, and drafts in their original language.
Review Workflow
Read references/campaigns-schema.md before editing the app or its domain logic.
A human verdict (approve / request_changes / block / revise) writes
the new status plus decision-note / decided-at (and, for approve, the
edited body / chosen chosen-variant) directly onto the send record
through busabase-sdk. From a standalone local preview the write merges
immediately (trusted operator); from the deployed AirApp it creates a
pending ChangeRequest for the trusted process to merge.
Normal Workflow
- Detect mode. Default to App UI.
- When Kelly asks for a campaign, newsletter, or sequence: build/refresh the relevant segment, draft the send(s) into Busabase's
sends Base with status: "needs_review", the correct type and SEND phase, a clear reason, risk badges, a deliverability object, subject variants when A/B is intended, and run the email-quality-auditor gate to attach quality-gate (EQS + verdict). Metrics, deliverability risk, and the consent/suppression check recompute automatically on every read.
- Give Kelly the AirApp URL (or local preview URL) to review the queue, deliverability, and quality gates.
- For a send moved to
changes_requested, re-draft it per the review comment, re-run the gate, and write it back to needs_review.
- On "schedule approved sends": run
node scripts/execute_decisions.mjs --apply to re-read approved sends from Busabase, re-check the quality gate/deliverability risk/suppression list, and mark each done. Then perform the actual scheduling/sending through the configured ESP with the approved, possibly user-edited body and chosen variant, one send at a time.
- Never schedule a send without an explicit
approve decision, never schedule one whose gate is BLOCK or whose deliverability risk is high, and never re-schedule sends already recorded as scheduled/sent.
Safety Defaults
- Treat every outbound send as approval-required (outbound + volume). Money offers, compliance-sensitive copy, cold outbound, and high send volume raise the bar further.
- A
BLOCK verdict or high deliverability risk is a hard stop; fix authentication or copy before the send is eligible.
- Store only the minimum content needed for review; keep raw subscriber lists and PII out of Busabase (segments carry names + sizes, not rows).
- Redact the ESP API key and any credential-like strings from logs, reports, and UI state; expose only boolean readiness for configured env vars.
- Keep stable ids (
send_id, segment_id) and ref numbers so repeated updates and executions are idempotent.
1---2name: kelly-campaigns3description: Outbound email-marketing desk (Busabase App-in-Skill) for building segments, drafting campaigns, newsletters, and sequences, running pre-send deliverability and subject-line QA, and approving every send before it is scheduled. Structured around the SEND discipline — Setup, Engage, Nurture, Deliver — with an email-quality-auditor gate (EQS score + SHIP/FIX/BLOCK verdict). Use when the user invokes $kelly-campaigns or /kelly-campaigns, or mentions email marketing, campaigns, newsletters, drip/welcome/win-back sequences, broadcasts, segments, subject-line A/B tests, deliverability (SPF/DKIM/DMARC/spam score/inbox placement), or wants to review and approve marketing email before it is sent. This is OUTBOUND marketing to a subscriber list, distinct from kelly-email inbox triage (incoming mail). 出站邮件营销:策划分群、起草营销活动 / 新闻邮件 / 邮件序列,发送前做可送达性与主题行质检,人工审批后再排期发送。4---56# Kelly Campaigns78## Overview910Kelly Campaigns is a Busabase Cloud App-in-Skill. Its canonical product11surface is the AirApp in Busabase, not a separate local-data product. The12same Hono source supports an explicitly requested local preview with OAuth13connection bootstrap. Use this skill as Kelly's outbound email-marketing14operator: it keeps a dashboard over audience segments, drafted **sends**15(campaign broadcasts, newsletter issues, and sequence steps), pre-send16deliverability and subject-line QA, and post-send performance. The skill17builds segments, drafts email copy, runs deliverability and quality checks,18and prepares sends; the human reviews, edits, and approves each send in the19app **before anything is scheduled or sent**.2021This is **outbound marketing to a subscriber list**. It is distinct from22`kelly-email`, which triages an incoming inbox. Keep them separate:23`kelly-email` is about mail you received; `kelly-campaigns` is about mail you24send to many people.2526Default behavior is AirApp-first. Unless the user explicitly asks only for27explanation, update Busabase directly and give the user the clickable AirApp28URL. Start localhost only when local preview/debugging is explicitly29requested; it uses the same Busabase resources and never offers another data30provider. Use chat-only mode only when the user says "纯聊天", "chat only", "不要打开 UI", or similar; in that mode present numbered sends (`Send #1`) and take verdicts in the conversation.3132This skill is an implementation of the **App-in-Skill** pattern — a Codex/agent skill paired with a small companion UI for review and approval. See the spec paper: <https://mr-kelly.github.io/research/app-in-skill-specification-for-pairing-agent-skills-with-a-local-companion-ui.pdf>.3334## Mandatory Dependencies35361. Read and follow `$kelly-app-skill-creator` for product behavior, visual37 quality, responsive layout, and the complete canonical `content/kelly-campaigns-app/` artifact.382. Read and follow `$busabase` for connection, target Space, node discovery,39 ChangeRequests, review, and merge behavior.403. Read and follow `$busabase-app-creator` for resource modeling, AirApp41 runtime limits, security, validation, and deployment.4243If a dependency is unavailable, preserve this skill's local artifact and44product contracts, stop before the unavailable Busabase operation, and report45the exact missing dependency. Do not invent a second data backend.4647## The SEND Discipline4849Work is organized around four phases. Every send is tagged with the phase it belongs to, and the app groups by phase.5051- **Setup** — the sending foundation: authentication and deliverability, audience segments, list growth, list hygiene.52- **Engage** — the creative: email copy, subject lines, HTML render / dark-mode, dynamic personalization.53- **Nurture** — the lifecycle: sequences (welcome, drip, win-back), newsletter cadence and monetization, preference/frequency management, reactivation.54- **Deliver** — getting it into the inbox: send experiments (A/B), inbox-placement monitoring, cold outbound, and the pre-send quality gate.5556### Capability taxonomy (16 sub-skills)5758| Phase | Sub-skills |59| --- | --- |60| **Setup** | `deliverability-qa` · `list-segment-builder` · `list-growth-designer` · `list-hygiene-monitor` |61| **Engage** | `email-creative-builder` · `subject-line-lab` · `email-render-builder` · `dynamic-content-personalizer` |62| **Nurture** | `email-sequence-designer` · `newsletter-monetization-planner` · `preference-frequency-manager` · `reactivation-specialist` |63| **Deliver** | `send-experiment-designer` · `inbox-placement-monitor` · `cold-outbound-sequencer` · **`email-quality-auditor` ⛩ (the quality gate)** |6465### The quality gate — `email-quality-auditor` ⛩6667Before any send can be scheduled, it passes the **SEND** framework, which produces an **EQS** (Email Quality Score, 0–100) and a **SHIP / FIX / BLOCK** verdict:6869- **S — Sender & auth**: SPF, DKIM, DMARC pass; correct from-identity.70- **E — Engagement risk**: segment quality, expected open/complaint behavior, re-permission for cold/lapsed lists.71- **N — Not spammy**: spam score, trigger words, link/image balance, working unsubscribe + physical address.72- **D — Deliverability**: inbox readiness against policy floors, IP/domain warm-up, render and dark-mode.7374Verdicts: **SHIP** (ready to schedule), **FIX** (deliverable but revise first), **BLOCK** (hard stop — e.g. failing DKIM or a spam score above policy). The gate never sends; a human still approves. A send whose deliverability risk is `high` (SPF/DKIM/DMARC failing, spam score ≥ 5, or inbox readiness below 0.6 — see `deliverabilityInfo()` in `content/kelly-campaigns-app/app/js/campaigns-model.js`) is refused scheduling even if it carries an `approved` status.7576## App UI Screenshots7778<table>79 <tr>80 <td width="50%"><img src="assets/screenshots/overview.webp" alt="Kelly Campaigns overview"></td>81 <td width="50%"><img src="assets/screenshots/campaigns.webp" alt="Kelly Campaigns queue"></td>82 </tr>83 <tr>84 <td><strong>Overview</strong><br>Send calendar plus list health — subscribers, bounce, churn, and complaint rates.</td>85 <td><strong>Campaigns</strong><br>Draft and approval queue across campaigns, newsletters, and sequence steps.</td>86 </tr>87 <tr>88 <td width="50%"><img src="assets/screenshots/deliverability.webp" alt="Kelly Campaigns deliverability QA"></td>89 <td width="50%"><img src="assets/screenshots/performance.webp" alt="Kelly Campaigns performance"></td>90 </tr>91 <tr>92 <td><strong>Deliverability</strong><br>Pre-send QA — SPF/DKIM/DMARC, spam score, and the EQS SHIP/FIX/BLOCK gate.</td>93 <td><strong>Performance</strong><br>Open, click, and unsubscribe rates by campaign.</td>94 </tr>95</table>9697## Boundary9899- The skill may build segments, draft sends, run deliverability/quality checks, and write it all to Busabase.100- The AirApp reads and writes Busabase records only. It must never send email, call an ESP, mutate a subscriber list, or perform any other external side effect.101- Sending is always approval-required (outbound + volume). Real scheduling/sending is performed by the configured ESP by the skill, only after the user approves the specific send in the app or in chat. `scripts/execute_decisions.mjs` only marks an approved send `done` in Busabase and reports the handoff operation the ESP still needs to perform; it performs no sending itself.102- Treat subscriber data as sensitive. Never commit real subscriber lists, ESP credentials, or Busabase credentials.103104## Busabase Resources105106Four Bases under one application Folder (`kelly-campaigns`), declared in107`content/kelly-campaigns-app/app/js/config.js` and the generated template sidecars under `content/`:108109- `segments`: audience segments — id, name, description, audience size.110- `sends`: the review queue — campaign/newsletter/sequence-step/cold-outbound sends: type, phase, subject/preview/body, segment + audience size, deliverability, subject A/B variants, the `quality-gate` (EQS + SHIP/FIX/BLOCK), workflow `status`, and the human verdict fields `decision-note` / `decided-at`.111- `suppression`: the consent/suppression list — recipients or whole segments removed by unsubscribe, hard bounce, or complaint.112- `settings`: one row per `kind` — `kelly-campaigns-profile` (operator/brand/ESP/from-identities/sending-policy/style-tone/list-health) and `kelly-campaigns-lock`.113114Resources provision lazily through an idempotent Busabase ChangeRequest the115first time the app runs in a Space; see `references/campaigns-schema.md` for116exact field shapes. Metrics, the pre-send deliverability-risk derivation, and117the consent/suppression pre-send check are computed client-side from the118`sends`/`suppression` Bases on every read — they are never stored. The EQS119score and SHIP/FIX/BLOCK verdict are authored per send by the120`email-quality-auditor` gate and stored on the record.121122## First Run And Onboarding123124On invocation, check the `kelly-campaigns-profile` settings row for125readiness. If it is absent, guide setup before doing real marketing work.126127Ask for non-secret setup details only: operator profile (name, role, company, timezone), brand (name, homepage, unsubscribe URL), ESP provider name, from-identities (from-name/from-email/reply-to and when to use each), segments, sending policy (approval-required, daily/hourly caps, min inbox readiness, max spam score), risk keywords, and style/tone. Never ask the user to paste secret values into chat. Busabase authentication is ambient inside the deployed AirApp; ESP credentials belong to the trusted handoff process's own environment, never Busabase.128129## Local App130131Default behavior is AirApp-first — give the user the clickable AirApp URL.132Start `pnpm --dir content/kelly-campaigns-app dev` only when local preview/debugging is explicitly133requested.134135Required app views (hash routes):136137- `#/overview`: send desk. Human-attention counts, upcoming sends for the next weeks, list health (subscriber count, bounce/complaint/churn rates, avg open/click), and a SEND-phase breakdown.138- `#/campaigns` and `#/campaigns/<send_id>`: the review queue over drafted sends in workflow states `needs_review`, `changes_requested`, `approved`, `done`, `blocked`. Each item shows a stable row ref (`Send #1`), type + phase + quality-gate verdict badges, the segment and audience size, deliverability risk, subject + preview text, an editable body draft, an A/B subject picker when variants exist, a `Review note` textarea, and Approve / Request changes / Block buttons that write the verdict directly onto the send record.139- `#/deliverability`: pre-send QA table — SPF/DKIM/DMARC pass flags, spam score, inbox readiness, and the SEND verdict per send, plus the read-only suppression list, so weak auth or spammy copy is caught before scheduling.140- `#/performance`: open/click/unsub/bounce by sent campaign.141- `#/settings`: sanitized config summary — operator, brand, ESP + secret readiness, from-identities, segments, sending policy, and onboarding state. Never expose secret values.142143Keep the sidebar workflow filters (All / Needs Review / Approved / Done / Blocked) as the primary nav, plus the views above.144145Demo mode:146147- `?demo=1` (or `?demo=overview`) opens a deterministic mock program ("Northwind Coffee") for documentation and screenshots.148- `?demo=overview`, `?demo=campaigns`, `?demo=deliverability`, `?demo=performance`, and `?demo=detail` select named mock scenes; `detail` deep-links to a send detail.149- `lang=en` or `lang=zh` forces UI chrome language for screenshots.150- Demo mode never reads or writes Busabase.151152UI language: support English and Chinese chrome with `Auto` default. Keep subject lines, body copy, segment names, and drafts in their original language.153154## Review Workflow155156Read `references/campaigns-schema.md` before editing the app or its domain logic.157158A human verdict (`approve` / `request_changes` / `block` / `revise`) writes159the new `status` plus `decision-note` / `decided-at` (and, for `approve`, the160edited `body` / chosen `chosen-variant`) directly onto the send record161through `busabase-sdk`. From a standalone local preview the write merges162immediately (trusted operator); from the deployed AirApp it creates a163pending ChangeRequest for the trusted process to merge.164165## Normal Workflow1661671. Detect mode. Default to App UI.1682. When Kelly asks for a campaign, newsletter, or sequence: build/refresh the relevant segment, draft the send(s) into Busabase's `sends` Base with `status: "needs_review"`, the correct `type` and SEND `phase`, a clear `reason`, risk badges, a `deliverability` object, subject variants when A/B is intended, and run the `email-quality-auditor` gate to attach `quality-gate` (EQS + verdict). Metrics, deliverability risk, and the consent/suppression check recompute automatically on every read.1693. Give Kelly the AirApp URL (or local preview URL) to review the queue, deliverability, and quality gates.1704. For a send moved to `changes_requested`, re-draft it per the review comment, re-run the gate, and write it back to `needs_review`.1715. On "schedule approved sends": run `node scripts/execute_decisions.mjs --apply` to re-read approved sends from Busabase, re-check the quality gate/deliverability risk/suppression list, and mark each `done`. Then perform the actual scheduling/sending through the configured ESP with the approved, possibly user-edited body and chosen variant, one send at a time.1726. Never schedule a send without an explicit `approve` decision, never schedule one whose gate is `BLOCK` or whose deliverability risk is `high`, and never re-schedule sends already recorded as scheduled/sent.173174## Safety Defaults175176- Treat every outbound send as approval-required (outbound + volume). Money offers, compliance-sensitive copy, cold outbound, and high send volume raise the bar further.177- A `BLOCK` verdict or `high` deliverability risk is a hard stop; fix authentication or copy before the send is eligible.178- Store only the minimum content needed for review; keep raw subscriber lists and PII out of Busabase (segments carry names + sizes, not rows).179- Redact the ESP API key and any credential-like strings from logs, reports, and UI state; expose only boolean readiness for configured env vars.180- Keep stable ids (`send_id`, `segment_id`) and `ref` numbers so repeated updates and executions are idempotent.