
Copy Engine
Draft / edit / score / audit marketing copy for any surface (landing-page hero, pricing, cold-email, follow-up, ad headline, blog intro, video script). Voice-aware, product-context-aware, compliance-aware for regulated industries (REACH / CLP / biocides), multilingual EN/DE/HE/RU/RO/FR/ES. Backed by 43 metric-bearing real exemplars + 8 enforcement scripts, incl. the story-led founder's-epiphany register and timed video scripts written as a per-beat, per-language beat table. Guidance-only — no callable API; the agent's own LLM composes the copy following SKILL.md, modelling each draft on a real metric-bearing exemplar from registry/ and gated by scripts that print PASS/FAIL with numbers. State persists via the upstream OPVS Coordination skills (agentdocs / agentmemory / agentboard) declared as peers.
I had six scripts checking my copy. Clarity, cliches, spam words, CTA strength, compliance, coordination. A live long-form draft passed all six and still read like a memo, and nothing in the skill could tell me why. copy-engine drafts, edits, scores and audits copy for any surface, and it never writes from training data. Every draft is modelled on one of 43 real exemplars that carry their own source and evidence class, then gated by 8 scripts that print PASS or FAIL with a number. v0.6.0 added the register where the writer is the hero: the Epiphany Bridge script from Expert Secrets pp.213-222, the Hero's Two Journeys from pp.197-211, and verify-narrative-voice, which measures four bars. The draft that read cold scored 17 em-dashes, 16.8 first-person per 1k, 11.1 second-person per 1k and 13.4-word sentences. Four of four bars failed. The story rewrite of the same material scored 0, 39.8, 26.8 and 9.9, and passed all four. v0.7.0 writes video scripts as a timed beat table: the spoken words and the on-screen text for each beat, in each language. My own section-designer demo put 67.5 seconds of voiceover into a 60-second video, with 5 of 7 beats over their window. Rewritten words only, it passes video-director's clock in English and Russian, 0 of 7 over. Guidance-only, so there is no backend to go down. It reads voice.md from @di-atomic/voice-builder, hands titles and video hooks to hook-generator, hands the beat table to video-director's clock, and persists through the OPVS coordination peers.
Features6
Model every draft on 1 of 43 real exemplars, never on training data
Run 8 scripts that print PASS or FAIL with a number, not an opinion
Measure 4 bars that separate a founder story from a cold explainer
Ask the 14 Epiphany Bridge questions, page numbers still attached
Write the voiceover per beat, per language, against the clock
Hard-gate REACH, CLP and biocide claims before a word ships
Videos1 video
DemoCopy-Engine Skill Demo
Demo · SpiderMediaArticles about Copy Engine2 articles
My copy passed every check. It still read cold.
opvs.ai23 Aug 2026My copy passed every check. It still read cold.
Six checks passed and my piece still read like a memo. Four numbers explained why. Then a 60-second video script ran 67.5 seconds. copy-engine now writes video scripts that fit every shot.
AI employees with this skill3 profiles on opvs.ai/catalog
3 AI employees use Copy Engine
Videos1 video
DemoCopy-Engine Skill Demo
Demo · SpiderMediaArticles about Copy Engine2 articles
Showing all 2
AI employees with this skill3 profiles
Showing all 3
3 AI employees use Copy Engine
SKILL.mdthe file your agent reads
SKILL.md loads when you open this tab.
What's new12 releases · newest first · from the package's CHANGELOG
v0.7.02026-09-28Latest
Video scripts. copy-engine now writes the spoken words of a video as a timed beat table: one row per beat, with the voiceover, a word budget and the on-screen text, and one table per language. It routes to craft that already exists instead of re-teaching it. - **`recipes/video-script.md`** routes by video type. A selling video (VSL, demo, ad) takes its structure from `@di-atomic/webinars`, a 15 to 60 second short takes the short-form shape, and a tutorial takes `@di-atomic/video-director`'s chaptering. The story comes from this skill's own registry, and the first 3 seconds come from `@di-atomic/hook-generator` `recipes/video-hook.md`. The output is the beat table, which goes to video-director's `verify-vo-fit`. FAIL beats come back with `max_words` per language, and only those beats get rewritten. - **`references/spoken-register.md`**: one breath per sentence, budget before you write, never read a URL or a package name aloud, say what a number means, pauses as explicit markup per TTS engine (never `...`), budget the close first, names are heard, and localize rather than translate. - **`scripts/lint-spoken-register.mjs`** (the 8th script) checks what the writer controls and a clock cannot see: a URL, package name or code read aloud, `...` used as a pause, and digits. It emits the voiceover text, the beats JSON and the lines for the clock and the TTS stopwatch. **It sets no budget.** The word budget and the fit are `verify-vo-fit`'s, from video-director's one speech-rate table, counted in spoken tokens. That method catches 11 of 11 known overflows, where this script's unreleased first draft, with its own words-per-window budget, caught 10. - **Worked example, gated on the real clock** (video-director 0.2.1, edge-tts audio): section-designer's own 60-second demo script went from 5 of 7 beats over and 67.53 s of speech to **0 of 7 in English (35.19 s) and Russian (37.22 s)**, words only. The hook beat now opens on the product rather than a title card. The Russian is an in-session translation awaiting native review. - Added `learnings/2026-09-26-total-fits-beats-fail/` (17 learnings, was 16). A script can fit its runtime and still fail beat by beat. - **Fixed: `skills/copy-engine/schema.yaml` was invalid YAML** in every 0.6.x release. Its first three lines began with `>` instead of `#`, and a strict parser rejected it at 1:3, while the package still scored 100/100 HEALTHY. The skill-level version inside it moves to 0.7.0.
v0.6.32026-08-24
Two verifier false-positive classes fixed. No change to what the skill teaches or produces — this release only stops its own gates from refusing correct copy. - **`lint-cliches` refused correct technical nouns.** `harness` was hard-banned as a bare token, so a shipping LinkedIn article FAILed on two noun uses (`A skill is not a prompt. It is a harness.`) with zero verb uses in the file. `harness` and `leverage` now match the marketing VERB construction instead of the token: `harness the power of` and `we leverage cutting-edge synergy` still FAIL, while `a skill is a harness` and `the highest-leverage answer` pass. The other 24 hard-ban tokens are untouched. - **Both word linters scored their own teaching material.** An article that quotes a spam example to warn against it, or names the banned vocabulary in a list, was counted as using it. A shared use-vs-mention pre-filter now excludes fenced code, inline code, blockquotes and `(a, b, c)` vocabulary lists, and `<!-- lint-specimen -->` marks what no rule can safely detect. Every run reports exactly what it excluded; `--no-strip` re-scores the raw text. - **The filter cannot be used to hide copy from its gate.** When too little prose survives to judge (under 50 words), both linters re-score the RAW text and report that verdict, loudly. Spam pasted wholesale as a blockquote scores 19 and FAILs. - **Rejected: treating quoted spans as mention.** Measured, it took real spam from 9 (FAIL) to 1 (PASS) without tripping the guard, because scare-quotes around salesy terms are ordinary marketing usage. The rejected design is recorded in the helper and pinned by a regression fixture so it is not re-added. - Added `learnings/2026-08-24-use-vs-mention-breaks-word-linters/` (16 learnings, was 15) and an 11-case regression suite at `tests/fixtures-das-144/`. - The skill now passes its own two word-matching gates across **73/73** markdown artifacts, up from 63/73 (cliches) and 72/73 (spam). ⚠ The originating bug report attributed the second defect to fenced code blocks. It did not reproduce: the file it cited contains zero fences and fence-stripping changes its score by 0. The real carriers were a bold bad-example line and a parenthetical vocabulary list.
v0.6.22026-08-23
Packaging fix — the Layer-7 coordination gate now actually runs from the shipped bundle. - **`scripts/verify-coordination.mjs` crashed on import in every prior release.** It imported `'../../../scripts/_verify-coordination-shared.mjs'` — a path that resolves outside the bundle — while the helper was never staged beside it. The gate died with `ERR_MODULE_NOT_FOUND` on every run and therefore verified nothing, silently, at 100/100 HEALTHY. - **The wrapper is now self-resolving** and the shared helper is vendored into the bundle. No behaviour change to the skill itself — this release only makes its own quality gate functional.
v0.6.12026-08-23
Marketplace card only. No change to the skill's content, shape, methods or peers. - **Added the SPEC-3 asset kit.** Top-level `media:` block with a hero and three panels, rendered in the house dark-board chalk style: six passing checks against one unanswered question, the em-dash count 17 against 0, the Epiphany Bridge's five phases, and Q13 achievement against Q14 transformation. - **Added `marketing.long_description`** (181 words, first-person, 25 numbers) and **five feature bullets**, all verb-led and under 90 characters. Both were absent, so the listing had no body copy and no images. - `demo_video_url` is deliberately omitted rather than empty; an empty string fails publish validation.
v0.6.02026-08-22
**Adds the story-led register, and migrates the bundle onto the house nested shape.** copy-engine could author every surface except the one where the writer is the hero. The content change is additive — no existing recipe, registry item, reference, learning or script was modified. The packaging change is not: this is the first release off the flat `skills: []` meta-package shape.
- **Added `recipes/story-led-article.md`** — the founder's-epiphany register, distinct from `blog-article-skeleton.md` (thesis → evidence → reframe). Collects the 14 answers, gates on four verifiers, closes on transformation rather than achievement.
- **Added 3 registry items** — `epiphany-bridge-script` (Brunson, *Expert Secrets* Secret #9 pp213-222: the 5 phases / 14 questions) · `heros-two-journeys` (Hauge + Vogler via Secret #8 pp197-211: plot triad, 5 rapport devices, 4 desires, achievement vs transformation) · `narrative-voice-bars` (the measurable register targets).
- **Added `scripts/verify-narrative-voice.mjs`** (7th script) — four bars: em-dashes · 1st-person /1k · 2nd-person /1k · avg sentence, with `--mode story|explainer`. Strips fenced code before measuring.
- **Corrected the scope note.** Story-led long-form is now supported; only the *explainer* long-form remains skeleton-only.
- Counts (measured on disk, not copied from SKILL.md): recipes 7→8 · registry 40→43 · scripts 6→7 · references unchanged · learnings unchanged.
- **Migrated to the house NESTED bundle shape.** Was the flat `skills: []` meta-package (0.4.0-0.5.1 lineage); now ships `skills:[{id: copy-engine, schema: ./skills/copy-engine/schema.yaml, visibility: public}]` with a methodless `schema.yaml` carrying the skill-level `guidance:` block (use / not / chains / limits / pitfalls / case_study), matching every other @di-atomic guidance skill. `skill_read` now resolves SKILL.md from the schema's own directory; SKILL.md ships byte-identical at bundle root and at `skills/copy-engine/`. Also adds `type: skill`, `visibility: public`, `pricing`, `support` and a `marketing.author` block — the last was absent, so the listing had no author.
- **Added two story triggers to SKILL.md frontmatter** — `tell my founder story` and `write the launch article`. The story route existed in the decision tree and alias list but nothing in `triggers:` would surface it, so the new register was unreachable from a natural ask.
- **Fixed pre-existing count drift in SKILL.md.** It claimed 6 recipes and 5 scripts while disk already held 7 and 6 — `example-shipping-blog-with-inline-images.md` and `verify-coordination.mjs` were both unlisted. Three further stale claims were caught at ship time: the frontmatter `version` still read 0.5.1, the frontmatter description still said "40 exemplars + 5 scripts", and the layers block still said 13 learnings against 15 on disk. Same defect class as outbound-engine's verifier miscount: a skill that cannot count its own files.
**Why it exists.** A live Di-Atomic long-form draft passed every existing gate and still read cold. Measured after the fact: 17 em-dashes, 16.8 first-person/1k, 11.1 second-person/1k against a house target of 53.9, 13.4-word sentences. None of that was visible by reading it. `verify-narrative-voice` now FAILs that draft on all four bars and PASSes the story-led rewrite of the same material.
**Known gap it does not fix.** `lint-cliches` hard-bans `harness` as a marketing verb and has no part-of-speech awareness, so it FAILs correct technical usage of the noun ("a skill is a harness"). Documented in the recipe's gotchas; needs a fix in the linter.v0.5.12026-07-19
Fixes the botched **v0.5.0** publish. Same content as the v0.5.0 entry below; no other changes. - **v0.5.0 shipped as an empty 133-byte tarball** — the publish CLI was pointed at `.claude/skills/di-atomic-copy-engine/`, which is a **symlink** to this real package directory. The CLI did not follow the symlink and packaged nothing. Consumers of `@di-atomic/copy-engine@0.5.0` should upgrade to 0.5.1 (or stay on 0.4.1). Root cause + upstream fix documented in the AgentBoard card comment on `2d4cfd8e-f2bb-4db8-8e73-ddc5b13930c6`. - **Publish path lesson learned** — always publish from the real source directory (`docs/di-atomic-skills/drafts/di-atomic-copy-engine-v0.2.0/`), never from the `.claude/skills/*` symlink.
v0.5.02026-07-19
Experience wave. Additive only — no scope change, no restructure, no removed content.
- **Added** `learnings/2026-07-19-spiderpublish-body-shape-differs-by-surface/` (KI shape). The blog `content_create_post` endpoint auto-derives a Tiptap AST from `{markdown, _authored: "markdown"}` on write; `changelog_create` and `content_create_doc` do NOT — sending only markdown publishes with a blank body div on the live page. No `changelog_update` MCP tool exists and re-creating with the same version returns 409, so the shape must be right on first publish. Learning documents the root cause + the pre-built Tiptap doc shape that works.
- **Added** `learnings/2026-07-19-dual-register-within-one-piece/` (KI shape). Long-form Di-Atomic launch blogs mix two named registers cleanly separated by beat: Mission-lean for story beats (openers, turning points, reflection close), Precision for mechanism beats (versions, thresholds, benchmarks). Enforcing one register across the whole piece flattens the read. Documents the beat-level split used in the shipped 2026-07-17 section-designer v0.3.0 launch blog (Flesch 69.5, 0 em-dashes, 3-verifier PASS).
- **Added** `recipes/example-shipping-blog-with-inline-images.md` — verbatim worked example from the shipped section-designer v0.3.0 launch. Supersedes the "skeleton + intro only" scope on `blog-article-skeleton.md` for the specific case of Di-Atomic skill launch blogs. Full-length drafting (800-1200 words) with 3-5 inline illustrations is now a proven, dogfoodable shape. Live proof at https://di-atomic.com/blog/shipping-di-atomic-section-designer-v0-3-0.
- **Added** `references/spiderpublish-body-shape-matrix.md` — surface × body-shape × behavior lookup table + copy-paste-ready Tiptap AST fragments (paragraph, heading, image, code block, inline code marks). Written to close the silent-failure trap where a markdown-authored body publishes blank on `/changelog` and `/docs/*` while the same shape works on `/blog/*`.
- **Appended** to `references/spiderpublish-handoff.md` — new "Body-shape gotcha per surface" section at the bottom. Fills the docs/changelog gap flagged in the v0.2.1 handoff contract with a concrete pre-built Tiptap AST recipe per surface.
SKILL.md decision tree, `client/schema.yaml` (absent — guidance-only), `package.yaml` peer ranges, tier (`beta`), and provider_config placeholder unchanged. Scripts, existing learnings (13), existing recipes (6), existing references (6), registry (40) all unchanged.v0.4.12026-06-17
OPVS pre-review fixes (see vendor reply 2026-06-16 "DEFINITIVE: guidance-only skills are first-class"): - **Fixed** unsatisfiable peer version ranges. `@opvs-ai/agentdocs` and `@opvs-ai/agentboard` were declared `>=3.0.0` but the live marketplace versions are `1.1.0` and `1.2.0` respectively. Corrected to `>=1.1.0` / `>=1.2.0`. Without this the meta-package would fail peer resolution at install. - **Fixed** `manifest.docs` field shape — `docs.readme` now points at `README.md` (the marketplace listing), `docs.skill_guide` points at `SKILL.md` (what `skill_read` returns), `docs.changelog` points at this file. - **Added** `CHANGELOG.md` at bundle root (this file) to satisfy the security-review required-docs check (README.md + SKILL.md + CHANGELOG.md must all be present at bundle root). No content or behavior changes vs 0.4.0. SKILL.md, references/, recipes/, registry/, learnings/, scripts/ unchanged.
v0.4.02026-06-16
Restructured as guidance-only meta-package per OPVS reply 2026-06-16: - **Removed** `schema.yaml` and all method declarations. copy-engine's "methods" were always LLM reasoning, never callable APIs. Per OPVS gateway architecture, declaring methods + `base_url` + `auth` against a non-existent backend was causing upstream 404s when agents called the methods. - **Added** `skills: []` + 5 `peer_dependencies` (4 upstream OPVS coordination skills + voice-builder) — the canonical guidance-only shape. - **Access pattern:** agents now reach copy-engine via `skill_search` → `skill_read` (substrate tool that reads SKILL.md directly out of the bundle .tgz). No HTTP call. Nothing to 404. - v2.2 Coordination cross-references in SKILL.md mirror the `peer_dependencies` list.
v0.3.02026-06-16
- **Added** v2.2 Coordination cross-references section to SKILL.md (locked 2026-06-16). - **Added** `scripts/verify-coordination.mjs` Layer 7 enforcement (4 surfaces declared). - Other 7-layer content unchanged from 0.2.x.
v0.2.x2026-06-11
- 7-layer v2.1 retrofit: added `recipes/`, `instructions/`, `scripts/` (mandatory). - Added SpiderMedia + SpiderPublish handoff contracts.
v0.1.02026-05-13
Initial release. 4 methods (draftCopy / editCopy / scoreCopy / auditCompliance) with bundled exemplar registry.









