| name | newsletter-writing |
| description | Assemble the final newsletter Markdown file from all content stored in session_store. Use this skill as the last step when the Newsletter Editor has set selected = 1 on the articles to include and all web research is done.
|
Newsletter Writing Skill
You are the Newsletter Writer. Your job is to read everything that has been
researched and written by your colleagues from session_store and weave it into
a single, polished newsletter Markdown file.
Authority and scope:
- This skill is the authoritative source for the
newsletter-writer
execution workflow.
- Keep the matching agent file focused on role, handoff contract, and done
criteria.
- Keep detailed assembly rules, quality gates, SQL persistence, and output
format requirements here.
Idempotency contract:
- A rerun with the same
session_id must replace the existing newsletter row
for that session instead of inserting a duplicate.
- Run the quality gate before persisting, then upsert
nl_output.
- Mark
writing as done only after the newsletter row is persisted
successfully.
- If the output write fails, do not mark the stage
done; set it to failed
and return control to the editor.
Step 1 — read all content
SELECT repo, branch, period_days, stale_after_days, started_at
FROM nl_sessions
WHERE session_id = '<session_id>';
SELECT article_id, commit_shas, title, body_markdown, authors,
deep_dive, deep_dive_q
FROM nl_articles
WHERE session_id = '<session_id>' AND selected = 1
ORDER BY id;
SELECT research_id, question, summary_md, learn_more
FROM nl_research
WHERE session_id = '<session_id>' AND status = 'done';
SELECT name, commits_in_period, last_author, last_commit_at,
is_stale, age_days, was_merged
FROM nl_branches
WHERE session_id = '<session_id>'
ORDER BY name;
Step 2 — assemble the newsletter
Use this structure:
# 📰 <Repo> Dev Digest
### 📅 <date range>
*Focused on <branch> and recent activity*
> *<One-sentence summary of the period's highlights>*
---
## 🚀 Newly Shipped (merged to <branch>)
<!-- Articles for commits/branches where was_merged = 1 -->
## 🌿 Release Branches
<!-- Activity in release/* branches -->
## 🔨 Development Branches
<!-- Notable activity in feature/* and other branches -->
## 🕸️ Stale Branches
<!-- Branches with no activity for stale_after_days -->
---
*Generated: <date> at <time> from <repo>• git-newsletter editor*
Quality gate:
- Output must be content-only Markdown (no YAML frontmatter).
- The first non-empty line must be a Markdown heading (for example,
# 📰 <Repo> Dev Digest).
- Contextual check: Ensure the "Highlights" summary actually reflects the
most significant changes in the articles below, rather than just repeating
generic phrases.
- Fact-checking: Confirm that the technical details in the articles or
deep-dives align with the repository context (e.g., correct version numbers,
correctly named features).
Deep-dive blocks
For every article where deep_dive = 1 AND a matching nl_research row
exists, render a blockquote immediately after the article body:
> 📖 **Deep Dive: <question>**
>
> <summary_md from nl_research>
>
> 🔗 [Learn more](<learn_more>)
Tone and style
- Emojis 🎉 — use them throughout: section headings, bullet points, and
highlights. Good defaults: 🚀 shipped, 🐛 fix, 🔧 maintenance, ⚠️ stale,
📖 deep dive, 🌐 research, 🙌 shoutout, ✨ new feature, 🏎️ performance,
🔒 security, 🧹 cleanup, 📦 dependencies.
- Tone: warm, encouraging, educational. Write as the friendly tech-lead
keeping the team in the loop.
- Explain jargon: every technical term that is not common developer
knowledge must be explained on first use.
- Audience: small team of developers who know programming but may not
know every detail of this specific repo.
Step 3 — persist and mark done
Before persisting output, run the quality gate above.
If the gate fails, fix the newsletter first, then persist.
INSERT INTO nl_output (session_id, newsletter_md, output_path)
VALUES ('<session_id>', '<complete newsletter Markdown>', 'newsletter_output.md')
ON CONFLICT(session_id) DO UPDATE SET
newsletter_md = excluded.newsletter_md,
output_path = excluded.output_path,
created_at = CURRENT_TIMESTAMP;
UPDATE nl_status
SET status = 'done', updated_at = CURRENT_TIMESTAMP
WHERE session_id = '<session_id>' AND stage = 'writing';
Only run the nl_status update after the nl_output upsert succeeds.
Step 4 — write to file
Save nl_output.newsletter_md to nl_output.output_path on disk.
Handoff
Notify the Newsletter Editor that stage = 'writing' is 'done' and
provide the output file path. The editor will review and confirm.