Nexlem Agents
The 16 registered agents of Nexlem v2.0: 14 pipeline agents (10 blog + 4 social channels) plus 2 standalone orchestrator tools that do not participate in any pipeline. Each agent is a Claude Code subagent: a markdown file in agents/<name>.md with a YAML frontmatter contract on top and a prompt body below.
All 16 agents are at the v1.0.0 baseline immediately after Phase 41 (the D-41-02 baseline). Individual agents bump per the strict D-41-03 policy: any change to an
agents/*.mdfile requires a version bump in the same PR. Seedocs/CONFIG.mdfor the canonical frontmatter spec including theversion:field and bump rules.
Channels
Agents live in three channels:
| Channel | Count | Order Range | Purpose |
|---|---|---|---|
| blog | 10 | 1–10 | Produce the polished article and extract atoms |
| orchestrator | 2 | (no pipeline participation) | Standalone planning tools |
| social | 4 | (parallel after atomizer) | Derive social media assets from atoms |
Pipeline Topology
For a full campaign type:
research (1)
↓
writer (2)
↓
fact-check (3)
↓
eeat (4)
↓
humanizer (5)
↓
seo (6)
↓
disclaimer (7)
↓
image-planner (8)
↓
quality-gate (9) ← verdict gate; REJECTED halts the campaign here
↓
atomizer (10) ← bridge: extracts atoms into atom_library
↓
├── carousel
├── caption ← all four run in parallel
├── reel-script
└── youtube-short
Campaign type variants:
| Campaign Type | Agents Excluded from Pipeline |
|---|---|
full | (none) |
blog-only | atomizer, all social agents |
social-only | research, writer, fact-check, eeat, humanizer, seo, disclaimer, image-planner, quality-gate (atomizer + social only) |
silo-cluster | research (shared from pillar — D-12) |
blog-sibling | research (shared from first site — D-17) |
refresh | image-planner, atomizer, all social agents (content re-run only) |
Blog Channel (10 agents)
research
Order: 1
Version: 1.0.0
Executor: real (Claude Code subagent)
Accepts: topic, config.language, config.site_name (from campaign context)
Produces: 01-research.json
Tools: WebSearch, WebFetch, Write
Campaign types: full, blog-only, refresh
Purpose: Web research for the article topic. Emits competitor analysis, key facts, suggested outline, keywords list, and a minimum of 3 sources.
Output shape:
{
"topic": "string",
"sources": [{ "url": "string", "title": "string", "summary": "string" }],
"competitor_analysis": "string",
"key_facts": ["string"],
"suggested_outline": ["string"],
"keywords": ["string"]
}Acceptance criteria: minimum 3 sources; topic, sources, competitor_analysis, key_facts, suggested_outline, keywords all present.
writer
Order: 2
Version: 1.0.0
Executor: real
Accepts: 01-research.json, config.language, config.site_name, config.role, config.relationship
Produces: 02-writer.md
Tools: Read, Write
Campaign types: full, blog-only, silo-cluster, blog-sibling, refresh
Purpose: Writes the full article from the research. Enforces minimum 800 words, image-placeholder embedding (placeholder:img-N tags), and relationship voice.
Acceptance criteria: minimum 800 words; valid markdown; includes placeholder:img-N image tags; relationship voice enforced.
fact-check
Order: 3
Version: 1.0.0
Executor: real
Accepts: 02-writer.md, 01-research.json
Produces: 03-fact-check.md, 03-fact-check-report.json
Tools: Read, Write, WebSearch
Campaign types: full, blog-only, silo-cluster, blog-sibling, refresh
Purpose: Verifies factual claims in the draft against research sources. Emits both a corrected article and a structured verification report.
Acceptance criteria: report JSON present; claims_verified field present.
eeat
Order: 4
Version: 1.0.0
Executor: real
Accepts: 03-fact-check.md, 01-research.json
Produces: 04-eeat.md, 04-eeat-meta.json
Tools: Read, Write
Campaign types: full, blog-only, silo-cluster, blog-sibling, refresh
Purpose: E-E-A-T polish — strengthens Expertise, Experience, Authoritativeness, and Trust signals in the article.
Acceptance criteria: E-E-A-T signals present in output; meta JSON present.
humanizer
Order: 5
Version: 1.0.0
Executor: real
Accepts: 04-eeat.md
Produces: 05-humanizer.md
Tools: Read, Write
Campaign types: full, blog-only, silo-cluster, blog-sibling, refresh
Purpose: Humanizes prose — removes AI-detectable patterns, enforces the configured relationship voice, and adds natural stylistic variation while preserving all facts and image placeholders.
Acceptance criteria: article rewritten; all facts preserved; all image placeholders preserved.
seo
Order: 6
Version: 1.0.0
Executor: real
Accepts: 05-humanizer.md, 01-research.json
Produces: 06-seo.md, 06-seo-meta.json
Tools: Read, Write
Campaign types: full, blog-only, silo-cluster, blog-sibling, refresh
Purpose: SEO pass — rewrites headings, injects target keywords at appropriate density, generates meta title and description, and adds internal link suggestions.
Output shape (06-seo-meta.json):
{
"title": "string",
"description": "string",
"target_keyword": "string",
"slug": "string"
}Acceptance criteria: meta JSON present; title and description present.
disclaimer
Order: 7
Version: 1.0.0
Executor: real
Accepts: 06-seo.md
Produces: 07-disclaimer.md
Tools: Read, Write
Campaign types: full, blog-only, silo-cluster, blog-sibling, refresh
Purpose: Appends the brand disclaimer when the article matches disclaimer_required_for tags (see docs/CONFIG.md business.json). Original article content is always preserved.
Acceptance criteria: disclaimer present if required; original article content preserved.
image-planner
Order: 8
Version: 1.0.0
Executor: real
Accepts: 07-disclaimer.md, config.visual_brand
Produces: 08-image-planner.json
Tools: Read, Write
Campaign types: full, blog-only, silo-cluster, blog-sibling
Purpose: Maps image placeholders in the article to alt-text and production briefs. Reads all placeholder:img-N tags and generates a detailed image-generation prompt for each, incorporating the visual_brand config. Excluded from refresh (refresh is content-only).
Output shape:
{
"images": [
{
"id": "img-1",
"prompt": "string",
"alt": "string",
"placement": "hero|inline"
}
]
}Acceptance criteria: prompts generated for all placeholders; visual_brand config applied.
quality-gate
Order: 9
Version: 1.0.0
Executor: real
Accepts: 07-disclaimer.md, 04-eeat-meta.json, 06-seo-meta.json, 08-image-planner.json, config.quality_gates
Produces: 09-quality-gate.json
Tools: Read, Write
Campaign types: full, blog-only, silo-cluster, blog-sibling, refresh
Purpose: Scores the final article across 5 weighted criteria (clarity, E-E-A-T, originality, relevance, tone/voice) and issues an APPROVED or REJECTED verdict. Campaign halts here on rejection — social pipeline does not start.
Output shape:
{
"verdict": "APPROVED|REJECTED",
"overall_score": 0.0,
"scores": {
"clareza": 0.0,
"eeat": 0.0,
"originalidade": 0.0,
"relevancia": 0.0,
"tom_voz": 0.0
},
"feedback": "string"
}Acceptance criteria: all score fields present; overall_score present.
atomizer
Order: 10
Version: 1.0.0
Executor: real (flipped from mock by Phase 38 ATOM-05)
Accepts: 01-research.json, 07-disclaimer.md, 08-image-planner.json, config.social.enabled_channels
Produces: 10-atomizer.json
Tools: Read, Write
Campaign types: full, blog-only, social-only, silo-cluster, blog-sibling
Purpose: Extracts reusable content atoms (quotes, stats, definitions, examples, checklists) organized per social channel. Persists atoms with persist_to_library and atom_type flags into the atom_library table. Bridge into social fan-out — excluded from refresh (refresh is content-only).
Output shape:
{
"carousel": { "hook": "string", "atoms": [...] },
"captions": { "hook": "string", "atoms": [...] },
"reel": { "hook": "string", "atoms": [...] },
"youtube_short": { "hook": "string", "atoms": [...] }
}Acceptance criteria: all enabled-channel keys present; each channel has a hook; atoms carry persist_to_library and atom_type flags.
Orchestrator Channel (2 agents — standalone)
These agents are NOT part of any pipeline. They are invoked by operator-driven commands and have campaign_types: [] in the registry.
silo-advisor
Version: 1.0.0
Executor: mock (intentional per D-40-08 — mock_allowed_in_uat: true)
Accepts: 01-research.json
Produces: 01b-silo-advisor.json
Tools: Read, Write
Campaign types: (none — standalone)
Invoked by: /nexlem silo plan
Purpose: Analyzes research and recommends single post vs silo, with a cluster plan when silo is recommended. Today's executor is a deterministic mock; future phases may flip to a real Claude Code subagent.
Output shape:
{
"recommendation": "silo|single",
"confidence": "high|medium|low",
"content_density": "string",
"topic_breadth": "string",
"rationale": "string",
"recommended_post_count": 0,
"count_range": "string",
"silo_plan": {}
}keyword-expander
Version: 1.0.0
Executor: mock (intentional per D-40-08 — mock_allowed_in_uat: true)
Accepts: seed_keyword, site_context (optional), count (optional, default 10, max 25)
Produces: JSON array (stdout)
Tools: Read, Write
Campaign types: (none — standalone)
Invoked by: /nexlem keywords expand
Purpose: Expands a seed keyword into N related terms with rationale and relevance scores. LLM-only — no external paid APIs. Mock executor; same future-real path as silo-advisor.
Output shape:
[
{
"keyword": "string",
"rationale": "string",
"relevance": 0.85
}
]Acceptance criteria: valid JSON array; each item has keyword, rationale, relevance; relevance in [0, 1]; no external API calls.
Social Channel (4 agents — parallel)
All four run in parallel after the atomizer. Each consumes the atomizer output and the polished article. None depend on each other. All four were flipped from mock to real in Phase 39 (SOCIALV2-01).
carousel
Version: 1.0.0
Executor: real (flipped from mock by Phase 39 SOCIALV2-01)
Accepts: 10-atomizer.json, social brand compliance config, social atom targets (carousel)
Produces: 11-carousel.json
Tools: Read, Write
Campaign types: full, social-only
Purpose: Generates an Instagram/LinkedIn carousel script — slide-by-slide content (headline, body, CTA) from atomizer output, applying brand voice and tone rules.
Output shape:
{
"slides": [{ "headline": "string", "body": "string" }],
"caption": "string",
"hashtags": ["string"],
"cta": "string"
}Acceptance criteria: 3–10 slides; slides, caption, hashtags present.
caption
Version: 1.0.0
Executor: real (flipped from mock by Phase 39 SOCIALV2-01)
Accepts: 10-atomizer.json, social hashtag config, social CTA rules (caption)
Produces: 12-caption.json
Tools: Read, Write
Campaign types: full, social-only
Purpose: Standalone post caption generator — produces platform-specific captions (Instagram, TikTok, YouTube) with per-platform character limits, hashtag caps, and CTA placement rules.
Output shape:
{
"instagram": { "text": "string", "hashtags": ["string"], "cta": "string" },
"tiktok": { "text": "string", "hashtags": ["string"], "cta": "string" },
"youtube": { "text": "string", "hashtags": ["string"], "cta": "string" }
}Acceptance criteria: all three platforms present; each has text, hashtags, cta.
reel-script
Version: 1.0.0
Executor: real (flipped from mock by Phase 39 SOCIALV2-01)
Accepts: 10-atomizer.json, social CTA rules (reel)
Produces: 13-reel-script.json
Tools: Read, Write
Campaign types: full, social-only
Purpose: Short-form video script — hook-first 30–60 second script with scene breakdown, music mood, and CTA for reels and TikTok.
Output shape:
{
"hook": "string",
"scenes": [{ "duration_s": 0, "visual": "string", "narration": "string" }],
"duration_target": 30,
"music_mood": "string",
"cta": "string"
}Acceptance criteria: hook, scenes, duration_target, music_mood, cta all present.
youtube-short
Version: 1.0.0
Executor: real (flipped from mock by Phase 39 SOCIALV2-01)
Accepts: 10-atomizer.json, social CTA rules (youtube_short)
Produces: 14-youtube-short.json
Tools: Read, Write
Campaign types: full, social-only
Purpose: YouTube Shorts script with explicit hook and payoff structure — narrated script with visual brief, optimized title, and description for YouTube's short-form format.
Output shape:
{
"hook": "string",
"scenes": [{ "duration_s": 0, "visual": "string", "narration": "string" }],
"duration_target": 60,
"title": "string",
"description": "string",
"cta": "string"
}Acceptance criteria: hook, scenes, duration_target, title, description all present.
Frontmatter Spec
Every agent file's YAML frontmatter is validated against the FrontmatterSchema Zod 4 strict-object in src/lib/agent-frontmatter.ts. Required and optional fields are documented in docs/CONFIG.md under "Agent Prompt Frontmatter". The version: field (semver, required) was added in Phase 41 — all 16 agents start at 1.0.0.
Required fields: name, order, description, accepts, produces, acceptance_criteria, tools, version
Bump policy: Any change to an agents/*.md file — frontmatter or body, including typos — requires a version bump in the same PR. PATCH is the default; MINOR for additive changes; MAJOR for breaking output-shape changes. See docs/CONFIG.md for details.
See Also
docs/GETTING_STARTED.md— first-campaign walkthrough using these agentsdocs/COMMANDS.md— full command referencedocs/CONFIG.md— frontmatter spec, version bump policy, and all config schemassrc/lib/agents/registry.ts— canonical 16-agent registry in code (channel, executor, campaign_types)