headlines
Generate headlines, titles, and subject lines: charge, volume, tighten.
Install
npx skills add https://github.com/notque/vexjoy-agent/tree/main/skills/content/headlines
claude plugin marketplace add https://llmmart.ai/marketplace.json && claude plugin install notque-vexjoy-agent@llmmart
git clone https://github.com/notque/vexjoy-agent.git
The skills CLI installs just this skill, for any of its supported agents. Claude Code installs the whole notque/vexjoy-agent collection as a plugin from our marketplace. Git is the plain clone.
Skill manifest
Headlines
Generate headlines, article titles, social posts, and email subject lines from a brief or draft. Four phases: find the charge, generate volume across named moves, tighten survivors, output per format. Core rule: volume over polish -- breadth beats optimization because word-level features predict winners weakly.
Phase 1: FIND THE CHARGE
Identify the single most compelling tension or stake in the material.
- Read the brief, draft, or topic statement in full.
- List every tension candidate: surprise, reversal, cost, conflict, a number that changes the picture, a stake the reader holds.
- Pick ONE -- the charge. Write it as one sentence naming who is affected and what is at stake.
- Test: would a reader who saw only this sentence want the rest? A topic label ("Kubernetes networking") fails; a live tension ("DNS resolved yesterday, fails today, nothing changed") passes.
Gate: Charge is one sentence, names a specific tension, is true to source. A weak charge produces 20 weak headlines.
Phase 2: GENERATE VOLUME
Produce 15-25 candidate headlines spread across these ten named moves. Write fast; judge later.
The Ten Headline Moves
| Move | Reflex | Example |
|---|---|---|
| Curiosity gap | Opens a question only reading can close | "The One-Line Nginx Default That Took Our API Down" |
| Specificity | Carries the concrete detail into the headline | "CoreDNS Returns NXDOMAIN for Internal Services After Upgrading to 1.31" |
| Stakes | Names what the reader loses or gains | "Your Postgres Backups May Be Silently Unrestorable" |
| Contrast | Two true things that should not coexist | "Local Build Passes, Cloudflare Deploy Fails -- Same Commit" |
| Question | Asks what the reader already wonders | "Is Your Standup Meeting Just a Status Email With Legs?" |
| How-to | Promises a capability, named precisely | "How to Cut Go CLI Startup From 400ms to 40ms" |
| Number | Count or measurement as the spine | "Three Config Lines That Halved Our CI Bill" |
| Voice-of-reader | Phrased in the reader's own words | "I Rotated the API Key and Production Still Worked. That's the Problem." |
| News peg | Anchored to a current event | "What the AWS Outage Reveals About Your Single-Region Bet" |
| Negative space | Leads with what is absent or refused | "The Test Suite Had No Test for the Thing That Broke" |
Rules:
- Cover at least 6 of the 10 moves. Tag each candidate with its move.
- Keep every candidate anchored to the Phase 1 charge.
- Pull concrete material from the brief: numbers, names, error messages, dates.
Gate: 15-25 candidates, each tagged, at least 6 moves represented. Fewer than 15 means the charge is under-mined -- return to the brief.
Phase 3: TIGHTEN
Select and sharpen 3-5 survivors.
- Score every candidate 1-5 on: specificity, tension, accuracy to the brief. Sum the three.
- Keep the top 3-5. Require move diversity -- two candidates from the same move compete for the same reader reflex; keep the stronger one.
- Tighten each survivor:
- Cut filler; front-load the charge into the first 3-4 words.
- Replace any vague noun with the concrete one from the brief.
- Verify every claim against the brief. The headline promises only what the content delivers.
- Drop any survivor that needs a hedge to stay accurate. Promote the next by score.
Gate: 3-5 survivors, each accurate, each from a distinct move where possible.
Phase 4: OUTPUT PER FORMAT
Adapt survivors to the formats the task needs.
| Format | Constraint | Adjustment |
|---|---|---|
| Article title | ~60-70 chars; sentence case | Full charge; specificity over wordplay |
| Social post | Platform length; standalone | Add the stake or number; end with pull, not summary |
| Email subject line | ~30-50 chars | Front-load the charge; cut articles and qualifiers first |
Per-platform specs from content-engine (references/platform-specs.md) win on length when both apply.
Output format:
## Headline Options
**Charge**: [one-sentence charge]
### Article titles
1. "[title]" -- [move]
2. ...
### Social posts
1. "[post]"
### Subject lines
1. "[subject]"
**Recommendation**: [pick one, one sentence why]
Gate: Each requested format has 2+ options. Recommendation given with reasoning.
Integration
- voice-writer: when voice-writer's hook scores below 8, the HOOK-GATE agent may run Phases 1-3 here against the article body to surface the concrete detail the opening should lead with.
- content-engine: supplies titles and subject lines for pipeline output; content-engine owns per-platform format specs.
- Standalone: usable directly on any brief, draft, or topic.
Error Handling
| Error | Cause | Solution |
|---|---|---|
| Brief has no tension | Input is a topic label or flat release notes | Ask for the one fact that surprised the author, the cost of the problem, or what changed. If none exists, produce plain utilitarian titles. |
| All candidates sound the same | Generation stayed in 1-2 moves | Walk the move catalog in order; force one candidate per unused move. |
| Accurate headlines feel flat | Charge is weak, not the wording | Return to Phase 1. Find a sharper tension or report that the brief needs a stronger finding. |
Files (vexjoy-agent)
-
evals
-
brief-01.md 621 B
# Brief 01 — Tech: silent backup failure **Premise**: A team discovered their nightly Postgres backups had been unrestorable for 11 months. The cron job exited 0 every night; pg_dump wrote zero-byte files because a password rotation broke auth and stderr went to /dev/null. A routine disaster-recovery drill caught it. **Key facts**: 11 months of zero-byte backups; exit code 0 throughout; discovered in a DR drill, not an incident; fix was a restore-test job that loads each backup into a scratch database weekly. **Audience**: backend engineers and SREs. **Formats requested**: article title, email subject line. -
brief-02.md 576 B
# Brief 02 — Tech: CLI rewrite speedup **Premise**: A developer rewrote an internal Python CLI in Go. Startup time dropped from 410ms to 38ms. The surprise: the win came almost entirely from removing import-time work, and a later Python refactor with lazy imports reached 95ms — the rewrite was mostly unnecessary. **Key facts**: 410ms → 38ms (Go rewrite); 410ms → 95ms (Python lazy imports, done afterward); tool runs ~200 times/day per developer; team of 40. **Audience**: working developers weighing rewrites. **Formats requested**: article title, social post. -
brief-03.md 639 B
# Brief 03 — Tech: DNS upgrade regression **Premise**: After a Kubernetes upgrade to 1.31, internal service discovery began failing intermittently. CoreDNS returned NXDOMAIN for services that existed. Root cause: a deprecated dual-stack flag silently changed default behavior, breaking resolution for IPv4-only services in dual-stack clusters. **Key facts**: failures intermittent (cache masked them ~70% of the time); pod-to-pod IP traffic worked throughout; root cause was a changed default, not a bug; three days to diagnose. **Audience**: platform engineers running Kubernetes. **Formats requested**: article title, social post. -
brief-04.md 584 B
# Brief 04 — Sports: tactical scoring surge **Premise**: A mid-table soccer club leads the league in scoring after switching to a high defensive line, despite selling its top striker in the summer. Goals now come from 14 different players; the previous season, one player scored 41% of them. **Key facts**: top striker sold for a club-record fee; 14 different scorers (league high); previous season one player scored 41% of goals; club sits 9th defensively (worse than last year). **Audience**: soccer fans who follow tactics. **Formats requested**: article title, social post. -
brief-05.md 625 B
# Brief 05 — Sports: marathoner's comeback without a sponsor **Premise**: A 34-year-old marathoner who lost her sponsorship after two injury-ruined years qualified for the national final. She trained while working full-time as a nurse, self-coached, running at 4:30 AM before shifts. Her qualifying time was a personal best by 71 seconds. **Key facts**: no sponsor, no coach; full-time nurse; 4:30 AM training runs; PB by 71 seconds at age 34; two prior years lost to a stress fracture and surgery. **Audience**: general sports readers; human-interest section. **Formats requested**: article title, email subject line. -
brief-06.md 649 B
# Brief 06 — Business: return-to-office attrition data **Premise**: A 2,000-person software company published internal data one year after its three-day return-to-office mandate. Overall attrition rose 4 points, but attrition among senior engineers (8+ years tenure) doubled, and 70% of departing seniors joined fully-remote competitors. **Key facts**: overall attrition +4 points; senior-engineer attrition doubled; 70% of departing seniors went to fully-remote firms; recruiting costs up 31%; the company published the data itself. **Audience**: engineering managers and executives. **Formats requested**: article title, email subject line. -
brief-07.md 663 B
# Brief 07 — Business: small bakery beats national brand **Premise**: A 12-person bakery chain in Ohio outsold a national packaged-bread brand across 40 regional grocery stores. The bakery's advantage: same-day delivery and a barcode that links to the production batch, which grocery managers used to cut waste by ordering against real sell-through. **Key facts**: 12 employees; 40 stores; outsold the national brand in those stores for two consecutive quarters; batch-linked barcode cut store waste ~18%; price is 15% higher than the national brand. **Audience**: small-business owners and retail buyers. **Formats requested**: article title, social post. -
brief-08.md 630 B
# Brief 08 — Business: record revenue, record layoffs **Premise**: A logistics company reported its highest-ever quarterly revenue the same week it announced its largest-ever layoff (9% of staff). The earnings call revealed the link: an automation rollout in sorting hubs drove both — throughput rose 22% while hub headcount fell. **Key facts**: record quarterly revenue; 9% layoff announced the same week; sorting throughput +22% after automation; affected roles concentrated in three hub cities; severance averaged 14 weeks. **Audience**: business-news readers. **Formats requested**: article title, email subject line. -
brief-09.md 634 B
# Brief 09 — Culture: library game nights triple teen visits **Premise**: A city library system facing a budget vote started weekly tabletop game nights run by teen volunteers. Eighteen months later, teen visits tripled and checkouts of any kind by teens rose 60%. The program costs $4,000 a year; the volunteers now design the catalog of games. **Key facts**: teen visits 3x in 18 months; teen checkouts +60%; cost $4,000/year; teen volunteers run and curate it; the system faces a budget referendum this fall. **Audience**: local-news and culture readers; library advocates. **Formats requested**: article title, social post. -
brief-10.md 659 B
# Brief 10 — Culture: museum's open-storage experiment **Premise**: A regional art museum moved 80% of its stored collection into a public "open storage" wing — dense shelving, minimal labels, visible conservation work. Attendance rose 35%, and the most-photographed object is a cracked 1970s ceramic mid-repair, not any headline painting. **Key facts**: 80% of stored collection now visible; attendance +35% in the first year; most-photographed object is a damaged ceramic under active repair; curators initially opposed the plan 7–2. **Audience**: arts and culture readers; museum professionals. **Formats requested**: article title, social post. -
rubric.md 1.8 KB
# Headlines Eval Rubric — Blind A/B ## Protocol - Arm A: agent generates headlines from a brief without the skill loaded. - Arm B: agent generates headlines with `skills/content/headlines/SKILL.md` loaded. - One blind judge per brief receives both outputs labeled "Output 1" / "Output 2" (arm order randomized), with the brief. The judge sees outputs only — method notes, move tags, and phase vocabulary are stripped before judging, so the skill cannot win on rubric-matching vocabulary. - Judge scores each dimension 1–5 per output, then picks a winner per brief. A tie scores 0 for both arms. ## Pre-registered win condition B promotes on **≥7 wins of 10 briefs** (ties excluded from wins). 5–6 wins: iterate the skill and re-run. ≤4 wins: skill loses; structural checks alone cannot promote it. ## Dimensions | Dimension | 5 looks like | 1 looks like | |-----------|--------------|--------------| | Specificity | Concrete number, name, or detail from the brief in the headline | Generic category words; could top any article on the topic | | Tension | A live stake, surprise, or conflict the reader must resolve | Flat statement of topic; nothing at risk | | Accuracy to brief | Every headline claim verifiable from the brief | Claims the brief does not support, or contradicts | | Distinctness | Options differ in approach, not just wording | Options are rephrasings of one idea | | Honesty | Headline promises exactly what the brief delivers; gaps the content closes | Overpromise, manufactured outrage, or a gap the content never closes | ## Briefs Ten self-contained briefs in this directory, `brief-01` through `brief-10`. Domains: tech (01–03), sports (04–05), business (06–08), culture (09–10). Each brief carries premise, key facts, audience, and requested formats — the judge and both arms see the identical brief.
-
-
SKILL.md 5.7 KB
--- name: headlines promoted_to: content description: "Generate headlines, titles, and subject lines: charge, volume, tighten." user-invocable: false allowed-tools: - Read - Write - Bash - Grep - Glob - Edit - Task routing: triggers: - "headline" - "headlines" - "article title" - "title options" - "subject line" - "better title" category: content-creation pairs_with: - writing - content --- # Headlines Generate headlines, article titles, social posts, and email subject lines from a brief or draft. Four phases: find the charge, generate volume across named moves, tighten survivors, output per format. Core rule: **volume over polish** -- breadth beats optimization because word-level features predict winners weakly. ## Phase 1: FIND THE CHARGE Identify the single most compelling tension or stake in the material. 1. Read the brief, draft, or topic statement in full. 2. List every tension candidate: surprise, reversal, cost, conflict, a number that changes the picture, a stake the reader holds. 3. Pick ONE -- the charge. Write it as one sentence naming who is affected and what is at stake. 4. Test: would a reader who saw only this sentence want the rest? A topic label ("Kubernetes networking") fails; a live tension ("DNS resolved yesterday, fails today, nothing changed") passes. **Gate**: Charge is one sentence, names a specific tension, is true to source. A weak charge produces 20 weak headlines. ## Phase 2: GENERATE VOLUME Produce 15-25 candidate headlines spread across these ten named moves. Write fast; judge later. ### The Ten Headline Moves | Move | Reflex | Example | |------|--------|---------| | **Curiosity gap** | Opens a question only reading can close | "The One-Line Nginx Default That Took Our API Down" | | **Specificity** | Carries the concrete detail into the headline | "CoreDNS Returns NXDOMAIN for Internal Services After Upgrading to 1.31" | | **Stakes** | Names what the reader loses or gains | "Your Postgres Backups May Be Silently Unrestorable" | | **Contrast** | Two true things that should not coexist | "Local Build Passes, Cloudflare Deploy Fails -- Same Commit" | | **Question** | Asks what the reader already wonders | "Is Your Standup Meeting Just a Status Email With Legs?" | | **How-to** | Promises a capability, named precisely | "How to Cut Go CLI Startup From 400ms to 40ms" | | **Number** | Count or measurement as the spine | "Three Config Lines That Halved Our CI Bill" | | **Voice-of-reader** | Phrased in the reader's own words | "I Rotated the API Key and Production Still Worked. That's the Problem." | | **News peg** | Anchored to a current event | "What the AWS Outage Reveals About Your Single-Region Bet" | | **Negative space** | Leads with what is absent or refused | "The Test Suite Had No Test for the Thing That Broke" | Rules: 1. Cover at least 6 of the 10 moves. Tag each candidate with its move. 2. Keep every candidate anchored to the Phase 1 charge. 3. Pull concrete material from the brief: numbers, names, error messages, dates. **Gate**: 15-25 candidates, each tagged, at least 6 moves represented. Fewer than 15 means the charge is under-mined -- return to the brief. ## Phase 3: TIGHTEN Select and sharpen 3-5 survivors. 1. Score every candidate 1-5 on: specificity, tension, accuracy to the brief. Sum the three. 2. Keep the top 3-5. Require move diversity -- two candidates from the same move compete for the same reader reflex; keep the stronger one. 3. Tighten each survivor: - Cut filler; front-load the charge into the first 3-4 words. - Replace any vague noun with the concrete one from the brief. - Verify every claim against the brief. The headline promises only what the content delivers. 4. Drop any survivor that needs a hedge to stay accurate. Promote the next by score. **Gate**: 3-5 survivors, each accurate, each from a distinct move where possible. ## Phase 4: OUTPUT PER FORMAT Adapt survivors to the formats the task needs. | Format | Constraint | Adjustment | |--------|-----------|------------| | Article title | ~60-70 chars; sentence case | Full charge; specificity over wordplay | | Social post | Platform length; standalone | Add the stake or number; end with pull, not summary | | Email subject line | ~30-50 chars | Front-load the charge; cut articles and qualifiers first | Per-platform specs from content-engine (`references/platform-specs.md`) win on length when both apply. Output format: ```markdown ## Headline Options **Charge**: [one-sentence charge] ### Article titles 1. "[title]" -- [move] 2. ... ### Social posts 1. "[post]" ### Subject lines 1. "[subject]" **Recommendation**: [pick one, one sentence why] ``` **Gate**: Each requested format has 2+ options. Recommendation given with reasoning. ## Integration - **voice-writer**: when voice-writer's hook scores below 8, the HOOK-GATE agent may run Phases 1-3 here against the article body to surface the concrete detail the opening should lead with. - **content-engine**: supplies titles and subject lines for pipeline output; content-engine owns per-platform format specs. - **Standalone**: usable directly on any brief, draft, or topic. ## Error Handling | Error | Cause | Solution | |-------|-------|----------| | Brief has no tension | Input is a topic label or flat release notes | Ask for the one fact that surprised the author, the cost of the problem, or what changed. If none exists, produce plain utilitarian titles. | | All candidates sound the same | Generation stayed in 1-2 moves | Walk the move catalog in order; force one candidate per unused move. | | Accurate headlines feel flat | Charge is weak, not the wording | Return to Phase 1. Find a sharper tension or report that the brief needs a stronger finding. |
Comments (0)
Sign in to join the conversation.
Reviews (0)
No reviews yet.
No comments yet.