agentleFS
ali-demirbasali-demirbas/claude-lifecycle/skills/lifecycle-copy/SKILL.md

lifecycle-copy

Skill2 starsChanged 4 months agoMITView on GitHub

Write CRM channel copy (email, push, SMS, in-app, WhatsApp) for journey steps — rule-checked against channel limits and sector lexicons, with A/B variants and character counts. Use when the user says "copy yaz", "metin yaz", "email metni", "push metni", "CRM copy", "write the messages".

The file

We split this skill into the rules it gives an agent

8 rules. About 0 are common, 5 are distinctive, and 3 are very specific to this project.

  • ≈0

    Common · estimate

    Many files like this have a rule of this kind.

  • ≈5

    Distinctive · estimate

    This author's own choices. Worth a look.

  • 3

    Very specific

    Tied to their project's names, files or tools. Probably skip.

  • Common
  • Distinctive
  • Very specific
  1. Very specific:

    Failed-strategies check: if output/<brand>/failed-strategies.md exists, a logged powered failure is not re-proposed to the same segment.

    line 30
  2. Very specific:

    Legal-review path: when the sector lexicon has regulated: true and a block carries a borderline money/health/outcome claim that is not …

    line 57
  3. Distinctive:

    Never show unreviewed copy or skip the review pass "because it's short".

    line 88
  4. Distinctive:

    Never output copy without character counts, or with estimated counts.

    line 89
  5. Distinctive:

    Never use a personalization variable that the user's data cannot fill (check the event/attribute inventory).

    line 90
  6. Distinctive:

    Never write identical copy across variants or across channels (each channel has its own shape, not a resize).

    line 91
  7. Distinctive:

    Never use an em dash or en dash in customer-facing copy — commas, periods, parentheses, conjunctions.

    line 92
  8. Very specific:

    Never ASCII-fold diacritics (ç, ğ, ı, İ, ö, ş, ü …) in any channel.

    line 93

≈ “Common” is an estimate: at least 1 in 5 of the 350,495 skill files we read have a rule of the same kind, not the same words. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.

Keep what fits and drop the rest. Your version, ready for your agents.
Files
SKILL.md

Lifecycle Copy — Channel Copywriting

Produce send-ready copy for journey steps. Copy here is an engineering artifact: it has hard constraints (limits, banned words, consent text) and is reviewed before it is shown. The mandatory format is ${CLAUDE_PLUGIN_ROOT}/templates/copy-output.md.

When NOT to use this

  • No journey doc or step description exists yet — there's nothing to write copy for; run lifecycle-journeys first or supply a step description (channel + intent) directly.
  • The ask is whether EXISTING, already-shipped copy complies with channel/lexicon rules — that's lifecycle-audit's dimension 7 (spot-check), not this skill; this skill's review loop only covers copy it itself writes.
  • The need is a CRM-agnostic structured export of copy already written — that's lifecycle-export, not this skill.

Inputs (gate)

  1. A journey doc (from lifecycle-journeys) OR a user-supplied step description (channel + intent minimum).
  2. The rule chain, loaded in inheritance order (CLAUDE.md rule 8 — most specific wins, bans/compliance strictest wins):
    • ${CLAUDE_PLUGIN_ROOT}/knowledge/brands/<brand>.md if it exists — tone/formality override; extra_banned_words extend all ban lists; brand_vocabulary is authoritative for product/feature names.
    • ${CLAUDE_PLUGIN_ROOT}/knowledge/lexicons/locales/<lang>.md per target language — voice, emotion calibration, market red lines.
    • ${CLAUDE_PLUGIN_ROOT}/knowledge/lexicons/<sector>.md. No lexicon for the sector → use the closest and say so.
  3. Tone + formality + language(s) from the brand file or Intake Summary. Missing → trigger lifecycle-intake (tone questions only).
  4. Persona context: the journey doc's §3 audience definition (segment, lifecycle stage, RFM tier where known) is passed to the writer — copy addresses that persona, never a generic user.
  5. Failed-strategies check: if output/<brand>/failed-strategies.md exists, a logged powered failure is not re-proposed to the same segment; when a strategy is skipped because of the log, say which entry caused it.
  6. Winning-strategies check: if output/<brand>/winning-strategies.md exists and has a confirmed entry for this segment/journey stage, pass it to the writer as a precedent — it informs one variant's starting angle, never both; the other variant still explores a genuinely different, less-tested angle. A precedent narrows a starting point, it doesn't replace the two-distinct-angles rule.

Procedure — write → review → fix (mandatory loop)

1. Load the rules

For every channel used, load ${CLAUDE_PLUGIN_ROOT}/knowledge/channels/<channel>.md — its frontmatter limits and "Hard rules" are the review contract. Load the lexicon's use/avoid table, urgency rules, and banned list.

2. Write

When multiple journeys need copy, spawn one copy-writer per journey concurrently in a single message (the agent is designed for exactly this parallelization). Pre-bundle the shared rule files (the sector lexicon, each channel file's limits + hard rules, the locale overlay, and the brand config's tone/banned/vocabulary) into each writer's prompt verbatim, read once here rather than re-read by every writer — the same cost saving the journey stage applies, and it matters more here because copy fans out to two agents per journey (writer + reviewer). Each writer then only needs its own journey doc, not a fresh read of the identical rulebook. For each journey step (its intent line is the brief — don't drift from it):

  • A target tone per step, drawn from the lexicon's stage-calibration table and adjusted by the locale overlay's emotion calibration — goes in the template's Target tone field and binds the writer.
  • Variant A and Variant B with genuinely different angles (e.g. utility vs social proof) — not synonym swaps. Each variant carries the template's strategy + hypothesis JSON metadata (one falsifiable sentence — lifecycle-results scores these later).
  • One short Fallback with no personalization variables.
  • Real character counts per field (count characters, do not estimate; for SMS respect the GSM-7 vs Unicode distinction in the channel file — Turkish characters change the limit).

3. Review (adversarial)

Delegate to the copy-reviewer agent (or, if subagents are unavailable, perform the same checklist yourself in a separate explicit pass):

  • limits per field · banned/spam words (channel + lexicon) · single-CTA rule · urgency claims backed by real data variables · variable fallbacks exist · consent/opt-out text where required · tone matches lexicon calibration for the journey stage.
  • Verdict per block: PASS / FIX (with the exact violation).

4. Fix and re-check

FIX blocks are rewritten and re-checked. Nothing labeled FIX may reach the user. If a rule cannot be satisfied (e.g. intent impossible in 120 push chars), change the step's channel recommendation and tell the user why.

Legal-review path: when the sector lexicon has regulated: true and a block carries a borderline money/health/outcome claim that is not outright banned, the block ships stamped ⚖️ legal review required (with the exact claim quoted) instead of ✅ — it goes to manual sign-off, not into the send queue.

5. Deliver

Mandatory format: ${CLAUDE_PLUGIN_ROOT}/templates/copy-canvas.html, reproduced verbatim via python3 scripts/build_canvas.py --template ${CLAUDE_PLUGIN_ROOT}/templates/copy-canvas.html --journeys <journeys.json> --meta <meta.json> --out output/<project>/<name>.html — the same deterministic copy-and-swap the journey canvas uses (it substitutes only the JOURNEYS data array, <title>, and eyebrow/h1/lede, self-verifies no boilerplate drifted, and handles copy-canvas's absence of HOLDOUT_TIP/DATA_NOTE). Hand-editing the template is only a fallback if the script is unavailable; never retype the boilerplate. The artifact's user-facing name and header follow the user's language, and never use the word "copy" toward Turkish users (it reads as "kopya/duplicate"): TR → "İletişim Metinleri", EN → "Message Copy". This covers the generated FILE NAME too: write the output to output/<project>/iletisim-metinleri.html (TR) / message-copy.html (EN) — and the markdown source-of-truth alongside it with the same base name — never copy-canvas.html/copy-*.md; only the repo template keeps its English name. One journey per tab, one card per step, review-status badge per card (✅ / ⚠️ with note / ⚖️ legal). The plain templates/copy-output.md structure is still the underlying content model each step's fields/variants/fallback follow — the HTML canvas is how it reaches the user, per this repo's output-authoring rule (CLAUDE.md rule 2). Multi-language requests: write each language natively per the lexicon's TR/EN notes — never translate literally.

Word choice discipline

  • The lexicon decides vocabulary; if a lexicon rule and a "nicer sounding" line conflict, the lexicon wins.
  • Concrete beats clever: product names, real numbers (as {{variables}}), stated policies.
  • Urgency/scarcity only when backed by a data variable that exists ({{stock_count}}, {{sale_end_date}}). No data → no urgency. Ever.

Common Pitfalls

Pitfall 1: Variants that differ in wording, not in angle. Symptom: Variant A and B say the same thing with synonyms swapped — "Sepetin seni bekliyor" vs "Sepetindeki ürünler seni bekliyor." Consequence: the two variants test the same hypothesis twice; lifecycle-results has nothing to attribute a lift to, because there was only ever one lever in the test. Fix: check each variant's strategy field before delivery — if both name the same lever (both "urgency," both "utility"), rewrite one around a genuinely different lever (social proof, loss-aversion, utility) rather than rephrasing.

Pitfall 2: Urgency framing with no variable behind it. Symptom: a line reads urgent ("Fırsat kaçmadan şimdi bak") but no {{stock_count}}, {{sale_end_date}}, or other real data variable appears anywhere in the field. Consequence: this is the "no data → no urgency" rule violated by tone rather than by an obviously banned word — a literal banned-word check won't catch phrasing that implies scarcity without stating it. Fix: trace any urgent-reading line to the specific variable driving it; no variable found means rewrite without the pressure framing, not just soften the punctuation.

Pitfall 3: A FIX rewritten but not re-checked. Symptom: a block flagged FIX gets rewritten to fix the named violation, then shipped on the strength of "it reads better now." Consequence: the rewrite can introduce a new violation the first pass never had — shortening for a length limit can drop the required opt-out text, tightening a CTA can create a second one. Fix: every FIX goes through the full checklist again after rewriting, not a visual read — the loop is write → review → fix → review, not write → review → fix → ship.

Never do

  • Never show unreviewed copy or skip the review pass "because it's short".
  • Never output copy without character counts, or with estimated counts.
  • Never use a personalization variable that the user's data cannot fill (check the event/attribute inventory).
  • Never write identical copy across variants or across channels (each channel has its own shape, not a resize).
  • Never use an em dash or en dash in customer-facing copy — commas, periods, parentheses, conjunctions.
  • Never ASCII-fold diacritics (ç, ğ, ı, İ, ö, ş, ü …) in any channel; the only exception is deliberate, user-approved GSM-7 folding for SMS cost (see knowledge/channels/sms.md).

Download now (ZIP)

Does it work?

Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.

No reviews yet

People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.

  • It worked
  • Partly
  • It didn't
What did you use it for? e.g. Reviewing pull requests in a Rails app

Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.

Your trail

Files you open will collect here, so you can find them again.

Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.

Now do this for your own.

Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.