diff --git a/src/generation/deployment_assignment.py b/src/generation/deployment_assignment.py
index 9e6d57e..9f9a1f6 100644
--- a/src/generation/deployment_assignment.py
+++ b/src/generation/deployment_assignment.py
@@ -65,14 +65,24 @@ def validate_and_resolve_targets(
def assign_site_for_article(article_index: int, resolved_targets: Dict[str, int]) -> Optional[int]:
"""
- Assign a site_deployment_id for an article based on round-robin logic
+ Assign deployment targets to the first N articles only (one-to-one mapping)
+
+ Sequential assignment: article 0 → target[0], article 1 → target[1], etc.
+ Articles beyond the number of targets return None and will be assigned
+ from the site pool during post-processing.
Args:
- article_index: Zero-based index of article in batch
+ article_index: Zero-based index of article in batch (0, 1, 2...)
resolved_targets: Dictionary mapping hostname -> site_deployment_id
Returns:
- site_deployment_id if article_index < len(targets), None otherwise
+ site_deployment_id for first N articles (where N = len(targets))
+ None for articles beyond target count
+
+ Example:
+ With 2 targets and 6 articles:
+ - Articles 0,1 get explicit targets
+ - Articles 2,3,4,5 return None (assigned later from pool)
"""
if not resolved_targets:
return None
diff --git a/src/generation/prompts/content_generation.json b/src/generation/prompts/content_generation.json
index cb97125..ca96093 100644
--- a/src/generation/prompts/content_generation.json
+++ b/src/generation/prompts/content_generation.json
@@ -1,5 +1,5 @@
{
"system_message": "You are an expert content writer who creates engaging, informative, and SEO-optimized articles that provide real value to readers while incorporating relevant keywords naturally.",
- "user_prompt": "Write a complete article based on:\nTitle: {title}\nOutline: {outline}\nKeyword: {keyword}\n\nEntities to include naturally: {entities}\nRelated searches to address: {related_searches}\n\nTarget word count range: {min_word_count} to {max_word_count} words\n\nReturn as an HTML fragment with
, , and
tags. Do NOT include , ,
, or tags. Start directly with the first heading.\n\nWrite naturally and informatively. Incorporate the keyword, entities, and related searches organically throughout the content."
+ "user_prompt": "Write a complete article based on:\nTitle: {title}\nOutline: {outline}\nKeyword: {keyword}\n\nEntities to include naturally: {entities}\nRelated searches to address: {related_searches}\n\nTarget token count range: {min_word_count} to {max_word_count} tokens.\n\nReturn as an HTML fragment with , , and
tags. Do NOT include , ,
, or tags. Start directly with the first heading.\n\nWrite naturally and informatively. Incorporate the keyword, entities, and related searches organically throughout the content."
}
diff --git a/src/generation/prompts/outline_generation.json b/src/generation/prompts/outline_generation.json
index 93d7308..105cd95 100644
--- a/src/generation/prompts/outline_generation.json
+++ b/src/generation/prompts/outline_generation.json
@@ -1,5 +1,5 @@
{
"system_message": "You are an expert content outliner who creates well-structured, comprehensive article outlines that cover topics thoroughly and logically.",
- "user_prompt": "Create an article outline for:\nTitle: {title}\nKeyword: {keyword}\n\nConstraints:\n- Between {min_h2} and {max_h2} H2 headings\n- Between {min_h3} and {max_h3} H3 subheadings total (distributed across H2 sections)\n\nEntities to incorporate: {entities}\nRelated searches to address: {related_searches}\n\nReturn ONLY valid JSON in this exact format:\n{{\"outline\": [{{\"h2\": \"Heading text\", \"h3\": [\"Subheading 1\", \"Subheading 2\"]}}, ...]}}\n\nEnsure the outline meets the minimum heading requirements and includes relevant entities and related searches."
+ "user_prompt": "Create an article outline for:\nTitle: {title}\nKeyword: {keyword}\n\nConstraints:\n- Between {min_h2} and {max_h2} H2 headings\n- Between {min_h3} and {max_h3} H3 subheadings total (distributed across H2 sections)\n\nEntities to incorporate: {entities}\nRelated searches to address: {related_searches}\n\nReturn ONLY valid JSON in this exact format:\n{{\"outline\": [{{\"h2\": \"Heading text\", \"h3\": [\"Subheading 1\", \"Subheading 2\"]}}, ...]}}\n\nEnsure the outline meets the minimum heading requirements and includes relevant entities and related searches. You can be creative in your headings and subheadings - they just need to be related to the topic {keyword}."
}