47 KiB
Development specification: AI Content Pipeline v1
1. Objective
Build an extendable content production pipeline for writers and editors.
The system accepts a short article description, asks boundary-setting questions, generates an article plan, stops for editor review, then continues through research, evidence gathering, section scaffolding, visual generation, SEO, linguistic review, final approval, and Git-backed publishing into a Next.js content repository.
v1 is an internal or single-tenant editorial tool. It is not a customer-facing multi-tenant SaaS product.
Main principle
The workflow is a first-class Admin-managed product object, not a hard-coded backend status chain. The pipeline is gate-driven: each workflow stage defines its purpose, ordered parts, owner role, runner profile, required inputs, outputs, and acceptance criteria. Runtime execution cannot move to the next stage until the current stage is complete and every required human approval or validation gate has passed.
Chosen architecture:
React / Next.js UI
FastAPI backend
LangGraph workflow engine
Postgres state store
Agent Runner Service using Codex CLI subscription authentication
Optional Claude Code runner for internal-only workflows
Object storage for files and assets
Git-backed publishing adapter layer for multiple target websites
LangGraph is appropriate because it supports durable execution, human-in-the-loop workflow control, and stateful orchestration. These are central to the required “stop, wait for edits, resume” behavior. ([docs.langchain.com][1])
Codex should be the primary subscription-based agent runner because Codex supports ChatGPT sign-in for subscription access, while Codex CLI also supports ChatGPT account login, API key login, or access-token login. For this project, use one managed runner identity per environment through ChatGPT subscription login or enterprise access-token auth, not usage-based API-key calls. ([OpenAI Разработчики][2])
Claude Code can be supported as an optional internal runner, but not as the main backend for routing third-party user jobs through consumer subscription credentials. Anthropic documents OAuth and API-key authentication as serving different purposes and states limits around third-party product/service usage. ([Claude Code][3])
2. Product scope
In scope for v1
1. Article intake
2. Boundary question generation
3. Plan generation
4. Plan approval gate
5. Web research task
6. Evidence matrix generation
7. Parallel section scaffolding
8. Hero image prompt generation
9. Table and diagram specification generation
10. SEO pass
11. Linguistic and tone review
12. Final approval gate
13. Git-backed publish commit creation
14. Multi-site configuration
15. Job history and audit trail
16. Codex CLI-based agent execution
17. Admin-managed workflow templates and editable workflow stages
Out of scope for v1
1. Fully autonomous publishing without human approval
2. Multi-language localization
3. A/B testing
4. Content performance analytics
5. Legal/compliance review workflows
6. Real-time collaborative editing
7. Direct Anthropic/OpenAI API-token usage for generation
8. Complex media editing pipeline
9. Owning CI/CD deployment orchestration
10. Multi-tenant customer isolation
11. Per-user Codex runner credentials
The publishing step in v1 should create a direct commit to the configured production branch of a Git-backed Next.js site repository after final editor approval and a best-effort content-shape dry run. The target repository's existing CI/CD owns deployment.
3. Core user roles
Admin
Can configure target websites, workflow templates, workflow stages, pipeline parameters, agent runner profiles, prompt versions, publishing YAML, and site-specific transformation/upload scripts.
Editor
Can create briefs, answer boundary questions, run the pipeline, edit intermediate results, approve plans, edit drafts, approve final content, and create publish commits.
Only Admins can edit workflow configuration, upload scripts, and pipeline configuration. Admins are fully trusted code operators because admin-defined transformation scripts run directly on the runner host inside checked-out site repositories.
4. High-level workflow
ARTICLE_BRIEF_CREATED
|
v
BOUNDARY_QUESTIONS_GENERATED
|
v
BOUNDARY_ANSWERS_SUBMITTED
|
v
PLAN_GENERATED
|
v
PLAN_REVIEW_REQUIRED
|
+--> editor requests changes --> PLAN_REVISION_REQUIRED --> PLAN_GENERATED
|
+--> editor approves
v
RESEARCH_RUNNING
|
v
EVIDENCE_MATRIX_READY
|
v
PARALLEL_PRODUCTION_RUNNING
|
+--> section scaffolds
+--> hero image prompt
+--> table specs
+--> diagram specs
+--> SEO brief
+--> FAQ block
|
v
DRAFT_ASSEMBLED
|
v
SEO_AND_LANGUAGE_REVIEW_READY
|
v
FINAL_REVIEW_REQUIRED
|
+--> editor requests changes --> FINAL_REVISION_REQUIRED
|
+--> editor approves
v
PUBLISH_DRY_RUN_REQUIRED
|
v
PUBLISH_COMMIT_READY
|
v
PUBLISH_COMMIT_CREATED
|
v
DONE
5. System architecture
Frontend
React / Next.js
|
v
Backend API
FastAPI
|
+--> Auth service
+--> Article service
+--> Site config service
+--> Workflow service
+--> Review service
+--> Asset service
+--> Publishing service
|
v
Workflow engine
LangGraph
|
v
Queue
Redis Queue / Celery / Dramatiq
|
v
Agent Runner Service
|
+--> Codex CLI runner
+--> Optional Claude Code runner
+--> Web research script
+--> Diagram script
+--> Git-backed publishing script
|
v
Storage
+--> Postgres
+--> Object storage
+--> Optional vector store
FastAPI’s built-in background tasks are useful for small post-response actions, but this system should use a real queue for long-running agent jobs, because article generation, research, retries, and approval waits are workflow-level tasks rather than short request-level tasks. FastAPI supports background tasks, but the durable workflow should live in LangGraph plus a queue. ([fastapi.tiangolo.com][4])
6. Main components
6.1 Frontend UI
Required screens
1. Dashboard
2. New article brief
3. Boundary questions
4. Plan review
5. Research pack view
6. Evidence matrix view
7. Draft editor
8. Asset review
9. SEO review
10. Final approval
11. Publishing settings
12. Site configuration
13. Workflow history
14. Media library
15. Generic Markdown/MDX rich preview
v1 frontend should feel like a full editorial workspace, including rich preview, media management, and advanced draft editing. If timeline forces scope reduction, scheduling slips before rich preview.
Dashboard fields
Article title
Target website
Workflow status
Assigned editor
Last updated
Next required action
Publishing status
Plan review UI must support
Approve plan
Request revision
Edit plan directly
Add section-level notes
Add source requirements
Add excluded sources
Add visual requirements
Change tone
Change target audience
Change SEO keyword
Final review UI must support
Approve final draft
Request revision
Edit title
Edit meta description
Edit article body
Edit images
Edit tables
Edit diagrams
Edit internal links
Edit frontmatter, content path, category, and tags
Create publish commit
6.2 Backend API
Backend stack:
FastAPI
Postgres
SQLAlchemy or SQLModel
Pydantic models
Redis Queue / Celery / Dramatiq
LangGraph workflow module
Object storage SDK
Git publishing adapter interfaces
API design principles
1. Every workflow-changing action must be explicit.
2. Every human approval must be recorded.
3. Every agent output must be validated before entering the article state.
4. Every generated claim must be traceable to evidence or marked unsupported.
5. Every target website must be driven by config, not hardcoded logic.
6. Article/domain tables are authoritative for product state; LangGraph checkpoints are execution state only.
7. Every approval-relevant plan or draft edit creates a new immutable version.
7. Data model
7.1 Article
{
"id": "uuid",
"target_site_id": "uuid",
"created_by": "uuid",
"assigned_editor_id": "uuid",
"status": "PLAN_REVIEW_REQUIRED",
"brief_description": "string",
"working_title": "string",
"language": "en",
"content_type": "longform_guide",
"primary_keyword": "string",
"created_at": "datetime",
"updated_at": "datetime"
}
7.2 TargetSite
{
"id": "uuid",
"name": "B2B SaaS Blog",
"slug": "b2b_saas_blog",
"publishing_type": "git_next",
"default_language": "en",
"brand_voice": "direct, useful, evidence-backed",
"audience": "B2B SaaS founders and content leads",
"seo_rules": {},
"visual_rules": {},
"source_rules": {},
"publishing_rules": {
"repository_url": "git@github.com:example/site.git",
"production_branch": "main",
"content_format": "mdx",
"content_path_template": "content/articles/{slug}.mdx",
"asset_path_template": "public/articles/{slug}/{filename}",
"frontmatter_mapping": {},
"transform_script_version_id": "uuid"
},
"created_at": "datetime",
"updated_at": "datetime"
}
7.3 BoundaryQuestion
{
"id": "uuid",
"article_id": "uuid",
"question": "Who is the article for?",
"question_type": "audience",
"answer": "Content operations leads",
"required": true,
"sort_order": 1
}
7.4 ArticlePlan
{
"id": "uuid",
"article_id": "uuid",
"version": 1,
"status": "PENDING_REVIEW",
"title_options": [],
"recommended_title": "string",
"search_intent": "string",
"thesis": "string",
"sections": [],
"claims_to_prove": [],
"visuals_needed": [],
"seo_notes": {},
"risks": [],
"editor_notes": [],
"created_at": "datetime"
}
7.5 PlanSection
{
"id": "uuid",
"article_plan_id": "uuid",
"sort_order": 1,
"heading": "string",
"purpose": "string",
"key_points": [],
"claims_to_support": [],
"evidence_needed": [],
"visuals_needed": [],
"target_word_count": 500
}
7.6 EvidenceItem
{
"id": "uuid",
"article_id": "uuid",
"source_title": "string",
"source_url": "string",
"source_domain": "string",
"source_type": "official_docs | research | news | company_blog | other",
"source_quality_score": 0.9,
"summary": "string",
"relevant_quotes": [],
"supports_claims": [],
"used_in_sections": [],
"artifact_manifest_id": "uuid",
"snapshot_object_key": "s3://bucket/research-runs/run_123/source_001.json",
"snapshot_content_hash": "sha256",
"retrieved_at": "datetime"
}
7.7 Claim
{
"id": "uuid",
"article_id": "uuid",
"section_id": "uuid",
"claim_text": "string",
"support_status": "SUPPORTED | UNSUPPORTED | NEEDS_REVIEW",
"evidence_item_ids": [],
"risk_level": "low | medium | high"
}
7.8 ArticleDraft
{
"id": "uuid",
"article_id": "uuid",
"version": 1,
"title": "string",
"slug": "string",
"meta_title": "string",
"meta_description": "string",
"body_markdown": "string",
"faq_block": [],
"schema_json": {},
"internal_links": [],
"external_links": [],
"status": "DRAFT_ASSEMBLED"
}
7.9 Asset
{
"id": "uuid",
"article_id": "uuid",
"asset_type": "hero_image | diagram | table | inline_image",
"title": "string",
"prompt": "string",
"file_url": "string",
"alt_text": "string",
"caption": "string",
"status": "PENDING | GENERATED | APPROVED | REJECTED"
}
7.10 WorkflowEvent
{
"id": "uuid",
"article_id": "uuid",
"event_type": "PLAN_APPROVED",
"actor_type": "user | system | agent",
"actor_id": "uuid",
"payload": {},
"created_at": "datetime"
}
7.11 AgentJob
{
"id": "uuid",
"article_id": "uuid",
"job_type": "PLAN_GENERATION",
"agent_profile": "codex_subscription_default",
"status": "QUEUED | RUNNING | SUCCEEDED | FAILED | CANCELLED",
"workspace_path": "string",
"input_files": [],
"output_files": [],
"error_message": "string",
"started_at": "datetime",
"finished_at": "datetime"
}
7.12 ResearchRunManifest
{
"id": "uuid",
"article_id": "uuid",
"agent_job_id": "uuid",
"s3_prefix": "research-runs/article_123/run_001/",
"artifacts": [
{
"artifact_type": "source_section_snapshot",
"source_url": "https://example.com/article",
"object_key": "research-runs/article_123/run_001/source_001.json",
"content_hash": "sha256",
"metadata": {
"search_path": [],
"agent_selection_criteria": "string",
"head_metadata": {},
"server_ip_address": "string",
"domain_whois_owner": "string"
}
}
],
"created_at": "datetime"
}
Research source sections and metadata are stored indefinitely in object storage, not as large database blobs. Postgres stores manifests, object keys, hashes, source URLs, and artifact types.
7.13 PublishCommit
{
"id": "uuid",
"article_id": "uuid",
"target_site_id": "uuid",
"repository_url": "string",
"branch": "main",
"commit_sha": "string",
"content_bundle_manifest": {},
"status": "PUBLISH_COMMIT_CREATED | PUBLISH_VERIFICATION_FAILED",
"deployment_status": "UNKNOWN | DISCOVERED | FAILED | SUCCEEDED",
"created_at": "datetime"
}
7.14 ScriptConfigVersion
{
"id": "uuid",
"target_site_id": "uuid",
"version": 1,
"author_id": "uuid",
"yaml_config": {},
"transform_script": "string",
"diff_from_previous": "string",
"rollback_target_version_id": "uuid",
"created_at": "datetime",
"activated_at": "datetime"
}
Every Admin script/config change stores author, timestamp, diff, and rollback target. v1 does not require second Admin approval for activation.
8. Agent Runner Service
8.1 Purpose
Run subscription-authenticated local agents in isolated workspaces without exposing direct model API keys to the application.
Primary runner:
Codex CLI with one managed ChatGPT subscription or enterprise access-token identity per environment
Optional runner:
Claude Code for internal-only workflows
8.2 Runner requirements
1. Create isolated workspace per job.
2. Write input files into workspace.
3. Run allowed CLI command.
4. Capture stdout, stderr, exit code.
5. Enforce timeout.
6. Validate output JSON against schema.
7. Store generated artifacts.
8. Return result to backend.
9. Record full job log.
10. Prevent access to unrelated article workspaces.
8.3 Example workspace
/workspaces/article_123/job_plan_generation_001/
input/
brief.json
target_site.json
boundary_answers.json
output_schema.json
instructions.md
output/
plan.json
logs/
stdout.log
stderr.log
command.json
8.4 Example Codex job command
codex exec "Read input/instructions.md. Use input files. Produce output/plan.json only. Follow input/output_schema.json exactly."
8.5 Agent output validation
All agent outputs must pass validation before workflow state changes.
Validation rules:
1. JSON must be valid.
2. JSON must match expected schema.
3. Required fields must be present.
4. No empty section plan.
5. Every generated claim must be tied to a plan section.
6. Research output must include source URL, retrieval timestamp, artifact manifest reference, and content hash.
7. Draft cannot include unsupported factual claims unless marked for editor review.
8. Final approval cannot proceed while high-risk unsupported claims remain unresolved.
9. Workflow nodes
9.1 Intake node
Input:
{
"brief_description": "string",
"target_site_id": "uuid",
"content_type": "longform_guide",
"primary_keyword": "optional string"
}
Output:
Article created
Initial workflow event stored
Status: ARTICLE_BRIEF_CREATED
Acceptance criteria:
Given a valid brief
When the user submits it
Then an article record is created
And workflow status is ARTICLE_BRIEF_CREATED
And target site config is attached
9.2 Boundary question node
Purpose:
Generate 5-10 questions to define scope, audience, angle, constraints, SEO, and evidence expectations.
Required question categories:
Audience
Purpose
Reader outcome
Depth
Tone
Excluded topics
Primary keyword
Competitor angle
Evidence standard
Visual expectations
Output:
{
"questions": [
{
"question": "Who is the article for?",
"question_type": "audience",
"required": true
}
]
}
Acceptance criteria:
Questions are generated from brief plus target site config.
Questions are editable before submission.
Required questions block plan generation until answered.
9.3 Plan generation node
Purpose:
Generate article production contract.
Plan must include:
Title options
Recommended title
Reader persona
Search intent
Thesis
Detailed section outline
Claims to prove
Evidence needs
Visual needs
SEO notes
Tone guidance
Risks
Suggested internal links
Output schema:
{
"title_options": ["string"],
"recommended_title": "string",
"reader_persona": "string",
"search_intent": "informational | commercial | navigational | transactional",
"thesis": "string",
"sections": [
{
"heading": "string",
"purpose": "string",
"key_points": ["string"],
"claims_to_support": ["string"],
"evidence_needed": ["string"],
"visuals_needed": ["string"],
"target_word_count": 500
}
],
"seo": {
"primary_keyword": "string",
"secondary_keywords": ["string"],
"meta_title_draft": "string",
"meta_description_draft": "string"
},
"risks": ["string"]
}
Acceptance criteria:
Plan contains at least 4 sections.
Each section has purpose, key points, and evidence needs.
Plan is saved as version 1.
Workflow stops at PLAN_REVIEW_REQUIRED.
No research starts before approval.
9.4 Plan review gate
Purpose:
Human approval checkpoint.
Allowed editor actions:
Approve
Request revision
Edit directly
Reject article
Add notes
Change target site
Change content type
Acceptance criteria:
Workflow cannot continue until plan is approved.
Every approval or revision request is stored as WorkflowEvent.
Plan revisions create new versions.
Previous versions remain accessible.
9.5 Research node
Purpose:
Gather information from the web after plan approval through an explicit web search/fetch script, not free-form agent browsing alone.
Inputs:
Approved plan
Target site source rules
Claims to prove
Required source types
Excluded domains
Editor notes
Output:
Research pack
Evidence matrix
Source summaries
Claim-source mapping
Unsupported claims list
Research run manifest with S3 object keys and content hashes
Research artifact storage:
1. Store broader discovered source content sections, not only final-used evidence snippets.
2. Store page metadata, search path to the article, agent criteria used to select it as evidence, page <head> metadata, server IP address, and domain WHOIS owner.
3. Store source sections and metadata indefinitely in object storage.
4. Store only manifest records, S3 object keys, source URLs, content hashes, and artifact types in Postgres.
Evidence quality scoring:
Official documentation: high
Peer-reviewed research: high
Government or standards body: high
Reputable news/reporting: medium-high
Company blog: medium
Generic SEO blog: low-medium
Forum/reddit: context only
Unattributed content: low
Acceptance criteria:
Each factual claim has at least one source or is marked unsupported.
Each source has URL, title, domain, source type, summary, and retrieval timestamp.
Each research run writes an object-storage manifest.
If enough acceptable evidence cannot be found for the approved plan, workflow returns to PLAN_REVISION_REQUIRED before drafting.
Unsupported claims are visible in the editor UI.
9.6 Parallel production node
Purpose:
Run production tasks in parallel after evidence matrix is ready.
Parallel tasks:
Section scaffold generation
Hero image prompt
Diagram specifications
Table specifications
FAQ block
SEO metadata
Internal link suggestions
Tone guide
Section scaffold output:
{
"section_id": "uuid",
"heading": "string",
"draft_markdown": "string",
"used_evidence_ids": ["uuid"],
"unsupported_claims": ["string"],
"suggested_visuals": ["string"]
}
Acceptance criteria:
Every section from approved plan has one scaffold.
Each section lists used evidence IDs.
No scaffold silently introduces unsupported factual claims.
High-risk unsupported claims block final approval until resolved.
Parallel jobs can fail independently and be retried.
9.7 Visual asset node
Purpose:
Create visual production instructions and optionally generate assets.
v1 requirement:
Generate prompts and specifications.
Store generated files if image tool is configured.
Allow editor approval or replacement.
Asset types:
Hero image
Inline diagram
Table
Flowchart
Comparison matrix
Architecture diagram
Diagram output example:
{
"asset_type": "diagram",
"format": "mermaid",
"title": "AI content pipeline workflow",
"diagram_code": "graph TD; A[Brief] --> B[Questions];",
"alt_text": "Workflow showing article brief moving through planning, research, drafting, review, and publishing."
}
Acceptance criteria:
Each visual has title, type, prompt or code, alt text, and status.
Hero image prompt follows target site visual rules.
Tables and diagrams are linked to article sections.
9.8 Draft assembly node
Purpose:
Merge scaffolds, evidence, SEO metadata, and visual placeholders into one article draft.
Markdown is the canonical editable draft format in v1. Rich preview renders Markdown/MDX for editor UX, but the stored approval artifact remains versioned Markdown plus metadata.
Output:
Markdown draft
Metadata
Asset references
Evidence references
Unsupported claim warnings
Acceptance criteria:
Draft includes all planned sections.
Draft includes title, meta title, meta description, body, FAQ block if applicable, and visual placeholders.
Draft is saved as version 1.
9.9 SEO review node
Purpose:
Apply target-site SEO rules.
Checks:
Title length
Meta title length
Meta description length
H1/H2 structure
Keyword placement
Internal links
External citations
Schema type
Slug
FAQ eligibility
Image alt text
Readability
Duplicate headings
SEO output:
{
"score": 82,
"issues": [
{
"severity": "medium",
"field": "meta_description",
"message": "Meta description is too long.",
"suggested_fix": "Shorten to 150-155 characters."
}
],
"recommended_title": "string",
"recommended_slug": "string",
"schema_json": {}
}
Acceptance criteria:
SEO report is visible in final review.
Editor can accept or reject each SEO suggestion.
Target-site SEO rules override global rules.
9.10 Linguistic and tone review node
Purpose:
Check clarity, grammar, tone, brand voice, and consistency.
Checks:
Grammar
Spelling
Sentence length
Passive voice
Jargon density
Brand tone
Forbidden phrases
Repetition
Weak claims
Unsupported certainty
CTA consistency
Acceptance criteria:
Issues are shown with severity and suggested rewrite.
Editor can accept, reject, or edit suggestions.
Final draft version stores accepted changes.
9.11 Final approval gate
Purpose:
Stop before Git-backed publish commit creation.
Final approval checklist:
Plan followed
Evidence reviewed
Unsupported claims resolved
SEO metadata approved
Images approved
Tables and diagrams approved
Internal links approved
Frontmatter fields selected
Content path selected
Author selected
Publishing mode selected
Acceptance criteria:
Publish commit cannot be created until final approval is complete.
High-risk unsupported claims block final approval.
Approval event stores actor, timestamp, article version, and selected publishing settings.
9.12 Git-backed publish commit node
Purpose:
Create a content bundle and commit it directly to the configured production branch of a target Next.js site repository.
Adapter interface:
class GitSitePublisher:
def build_content_bundle(self, article: ArticleDraft, config: dict) -> ContentBundle:
pass
def run_transform(self, bundle: ContentBundle, site_workspace: str) -> TransformedBundle:
pass
def dry_run_preview(self, bundle: TransformedBundle) -> DryRunResult:
pass
def commit_to_production_branch(self, bundle: TransformedBundle) -> PublishCommit:
pass
v1 publishing target:
Git-backed Next.js content repository
Content bundle: Markdown/MDX file plus frontmatter JSON/YAML and referenced asset files
Primary done state: PUBLISH_COMMIT_CREATED
Acceptance criteria:
System materializes versioned site publishing YAML/scripts into the checked-out site repository workspace.
Admin-defined transformation scripts run directly on the runner host inside the checked-out site repository.
Final editor approval is required before publishing.
Best-effort dry-run validation uses the pipeline app's generic Markdown/MDX preview renderer, not the target site's actual build.
Accepted v1 validation risk: site-specific build/runtime errors may reach production.
System commits directly to the configured production branch.
Target repository's existing CI/CD handles deployment after commit.
Git conflicts or non-fast-forward pushes fail the publish step and require retry after refreshing from remote.
If delayed deployment verification fails, system alerts Admin/Editor and leaves the production commit in place.
System stores commit SHA, repository URL, branch, content bundle manifest, and publish status.
10. Multi-site configuration
10.1 Site config structure
{
"site_id": "b2b_saas_blog",
"name": "B2B SaaS Blog",
"publishing_target": {
"type": "git_next",
"repository_url": "git@github.com:example/site.git",
"production_branch": "main",
"commit_author_name": "AI Content Pipeline",
"commit_author_email": "pipeline@example.com"
},
"editorial": {
"audience": "B2B SaaS founders and content leads",
"tone": "direct, expert, practical",
"forbidden_phrases": ["revolutionary", "game-changing"],
"preferred_structure": ["intro", "framework", "examples", "implementation", "conclusion"]
},
"seo": {
"title_max_chars": 60,
"meta_description_max_chars": 155,
"slug_style": "kebab-case",
"schema_type": "Article"
},
"sources": {
"preferred_domains": ["official docs", "research papers", "government sources"],
"excluded_domains": [],
"minimum_sources": 5
},
"visuals": {
"hero_ratio": "16:9",
"style": "clean editorial illustration",
"diagram_format": "mermaid"
},
"publishing": {
"content_format": "mdx",
"content_path_template": "content/articles/{slug}.mdx",
"asset_path_template": "public/articles/{slug}/{filename}",
"frontmatter_mapping": {
"title": "title",
"description": "description",
"date": "date",
"author": "author",
"category": "category",
"tags": "tags"
},
"transform_script_version_id": "uuid",
"dry_run_renderer": "generic_mdx_preview"
}
}
10.2 Acceptance criteria
Adding a new website must not require workflow code changes.
Each site can define repository target, tone, SEO, visual, source, publishing, frontmatter, asset-path, and transformation rules.
Workflow reads target site config at every generation step.
11. API endpoints
Articles
POST /api/articles
GET /api/articles
GET /api/articles/{article_id}
PATCH /api/articles/{article_id}
DELETE /api/articles/{article_id}
Boundary questions
POST /api/articles/{article_id}/boundary-questions/generate
GET /api/articles/{article_id}/boundary-questions
PATCH /api/articles/{article_id}/boundary-questions/{question_id}
POST /api/articles/{article_id}/boundary-questions/submit
Plans
POST /api/articles/{article_id}/plan/generate
GET /api/articles/{article_id}/plans
GET /api/articles/{article_id}/plans/{plan_id}
POST /api/articles/{article_id}/plans/{plan_id}/approve
POST /api/articles/{article_id}/plans/{plan_id}/request-revision
PATCH /api/articles/{article_id}/plans/{plan_id}
Research
POST /api/articles/{article_id}/research/start
GET /api/articles/{article_id}/research
GET /api/articles/{article_id}/evidence
PATCH /api/articles/{article_id}/evidence/{evidence_id}
Drafts
POST /api/articles/{article_id}/draft/assemble
GET /api/articles/{article_id}/drafts
GET /api/articles/{article_id}/drafts/{draft_id}
PATCH /api/articles/{article_id}/drafts/{draft_id}
SEO and language
POST /api/articles/{article_id}/seo/review
GET /api/articles/{article_id}/seo/report
POST /api/articles/{article_id}/language/review
GET /api/articles/{article_id}/language/report
Assets
POST /api/articles/{article_id}/assets/generate-specs
GET /api/articles/{article_id}/assets
PATCH /api/articles/{article_id}/assets/{asset_id}
POST /api/articles/{article_id}/assets/{asset_id}/approve
Final approval
POST /api/articles/{article_id}/final-approval
POST /api/articles/{article_id}/final-revision-request
Publishing
POST /api/articles/{article_id}/publishing/dry-run
POST /api/articles/{article_id}/publishing/create-commit
GET /api/articles/{article_id}/publishing/status
GET /api/articles/{article_id}/publishing/commits
Site config
POST /api/sites
GET /api/sites
GET /api/sites/{site_id}
PATCH /api/sites/{site_id}
DELETE /api/sites/{site_id}
GET /api/sites/{site_id}/publishing-config/versions
POST /api/sites/{site_id}/publishing-config/versions
POST /api/sites/{site_id}/publishing-config/versions/{version_id}/activate
POST /api/sites/{site_id}/publishing-config/versions/{version_id}/rollback
Agent jobs
GET /api/agent-jobs
GET /api/agent-jobs/{job_id}
POST /api/agent-jobs/{job_id}/retry
POST /api/agent-jobs/{job_id}/cancel
12. Prompt and instruction management
Prompt modules
boundary_questions.md
plan_generation.md
research_brief.md
evidence_matrix.md
section_scaffold.md
hero_image_prompt.md
table_spec.md
diagram_spec.md
seo_review.md
language_review.md
draft_assembly.md
publish_bundle.md
Prompt versioning requirements
Each prompt has version.
Each agent job stores prompt version.
Article history shows which prompt version generated each artifact.
Admin can activate/deactivate prompt versions.
Prompt input format
All prompts receive structured input:
{
"article": {},
"target_site": {},
"boundary_answers": {},
"approved_plan": {},
"editor_notes": [],
"evidence": [],
"output_schema": {}
}
13. Security requirements
Credentials
1. Do not store OpenAI or Anthropic API keys for generation in the app.
2. One managed Codex CLI subscription or enterprise access-token identity lives only on the runner host per environment.
3. Git credentials for target repositories are stored in a secrets manager or runner-local secure credential store.
4. The backend stores references to credentials, not raw secrets.
5. Agent generation jobs run in isolated workspaces with limited filesystem access.
6. Admin-defined publishing transform scripts are trusted host-level code and may run directly in checked-out site repositories.
Workspace isolation
1. One workspace per agent job.
2. Workspace path must be generated by backend.
3. Runner cannot access sibling workspaces.
4. Job artifacts are copied to object storage after completion.
5. Workspace can be deleted after retention period.
Publishing safety
1. v1 commits directly to the configured production branch.
2. Final approval is required before publish commit creation.
3. A generic Markdown/MDX content-shape dry run must pass before commit.
4. The dry run is best-effort and does not guarantee target-site build/runtime correctness.
5. Git conflicts and non-fast-forward pushes fail instead of auto-rebasing.
6. All publishing actions and script/config versions are logged.
14. Error handling
Agent job errors
FAILED_SCHEMA_VALIDATION
CLI_EXIT_CODE_FAILURE
TIMEOUT
MISSING_OUTPUT_FILE
UNSUPPORTED_CLAIMS_FOUND
SOURCE_RETRIEVAL_FAILED
RESEARCH_ARTIFACT_UPLOAD_FAILED
PUBLISH_DRY_RUN_FAILED
GIT_CHECKOUT_FAILED
GIT_COMMIT_FAILED
GIT_PUSH_NON_FAST_FORWARD
PUBLISH_VERIFICATION_FAILED
Retry rules
Plan generation: retry manually only
Research: retry allowed
Section scaffold: retry allowed per section
SEO review: retry allowed
Language review: retry allowed
Publish commit creation: retry allowed only if no publish commit exists
Failure UI
Each failure should show:
Job type
Status
Error category
Error message
Last successful step
Retry button
Logs for admin
15. Audit trail
Every important action must be logged:
Article created
Boundary questions generated
Boundary answers submitted
Plan generated
Plan edited
Plan approved
Research started
Evidence added
Draft assembled
SEO review completed
Language review completed
Asset approved
Final approval granted
Publishing dry run completed
Publish commit created
Delayed publish verification failed
Site publishing config changed
Site transform script changed
Job failed
Job retried
Audit event fields:
{
"event_type": "PLAN_APPROVED",
"actor": "user_id",
"article_id": "uuid",
"payload": {},
"created_at": "datetime"
}
16. Development tasks
Epic 1: Project foundation
Task 1.1: Initialize repositories
Deliverables:
Frontend app
Backend app
Runner service
Shared schemas package
Docker compose environment
Acceptance criteria:
Developer can run full local stack with one command.
Frontend can call backend health endpoint.
Backend can connect to Postgres.
Runner service can receive test job.
Task 1.2: Database schema
Deliverables:
Postgres migrations
Core tables
Indexes
Seed site config
Tables:
users
target_sites
articles
boundary_questions
article_plans
plan_sections
evidence_items
claims
article_drafts
assets
workflow_events
agent_jobs
research_run_manifests
publish_commits
script_config_versions
prompt_versions
Acceptance criteria:
Migrations run cleanly.
Seed creates one sample target site.
Article can be created and queried.
Epic 2: Article intake and boundary questions
Task 2.1: Article creation API
Acceptance criteria:
POST /api/articles creates article.
Article status is ARTICLE_BRIEF_CREATED.
Target site config is attached.
WorkflowEvent is created.
Task 2.2: Boundary question generation
Acceptance criteria:
System generates questions based on brief and site config.
Questions are stored.
User can edit answers.
Required unanswered questions block plan generation.
Task 2.3: Boundary questions UI
Acceptance criteria:
User can submit brief.
User can answer generated questions.
User can save partial answers.
User can submit answers and continue.
Epic 3: Plan generation and approval
Task 3.1: Codex runner MVP
Acceptance criteria:
Backend can create AgentJob.
Runner creates isolated workspace.
Runner writes input files.
Runner invokes Codex CLI.
Runner captures logs.
Runner validates output JSON.
Runner updates job status.
Task 3.2: Plan generation workflow node
Acceptance criteria:
Plan generated from brief, boundary answers, and site config.
Plan saved as version 1.
Workflow stops at PLAN_REVIEW_REQUIRED.
Task 3.3: Plan review UI
Acceptance criteria:
Editor can review full plan.
Editor can edit plan.
Editor can request revision.
Editor can approve plan.
Approval creates WorkflowEvent.
Epic 4: Research and evidence
Task 4.1: Research job
Acceptance criteria:
Research runs only after approved plan.
Research gathers sources for claims through explicit search/fetch scripts.
Evidence items are stored.
Each evidence item includes URL, title, source type, summary, quality score, retrieval timestamp.
Research source sections and expanded metadata are uploaded to object storage.
Research run manifest stores S3 keys, content hashes, source URLs, and artifact types.
Insufficient acceptable evidence forces PLAN_REVISION_REQUIRED before drafting.
Task 4.2: Evidence matrix
Acceptance criteria:
System maps claims to evidence.
Unsupported claims are marked.
Editor can view evidence by section.
Editor can add or remove evidence manually.
Task 4.3: Evidence UI
Acceptance criteria:
Editor can filter by section.
Editor can filter unsupported claims.
Editor can open source URLs.
Editor can mark evidence as approved or rejected.
Epic 5: Parallel production
Task 5.1: Section scaffold jobs
Acceptance criteria:
One job is created per approved plan section.
Jobs run independently.
Each output includes draft markdown, evidence IDs, unsupported claims, and suggested visuals.
Failed section can be retried alone.
Task 5.2: Asset spec jobs
Acceptance criteria:
System creates hero image prompt.
System creates table specs.
System creates diagram specs.
Each asset is linked to section or article.
Task 5.3: Draft assembly
Acceptance criteria:
All successful section scaffolds are merged.
Draft includes metadata and visual placeholders.
Draft is saved as version 1.
Workflow moves to SEO_AND_LANGUAGE_REVIEW_READY.
Epic 6: SEO and linguistic review
Task 6.1: SEO review job
Acceptance criteria:
SEO report generated from target site rules.
Report includes score, issues, suggested fixes, metadata, slug, schema.
Editor can accept or reject suggestions.
Task 6.2: Language review job
Acceptance criteria:
Language report includes grammar, clarity, tone, repetition, and forbidden phrase issues.
Suggestions are linked to exact draft locations.
Editor can accept or reject suggestions.
Task 6.3: Final review UI
Acceptance criteria:
Editor sees draft, assets, SEO report, language report, and evidence warnings.
Editor can edit final draft.
Editor can approve final version.
Workflow stops until final approval.
Epic 7: Git-backed Next publishing
Task 7.1: Git publisher interface
Acceptance criteria:
GitSitePublisher interface implemented.
Publisher builds Markdown/MDX content bundles with frontmatter and referenced assets.
Publisher materializes versioned YAML config and transform scripts into the site repository workspace.
Publisher captures transform logs and output manifest.
Task 7.2: Publish commit creation
Acceptance criteria:
Publish commit creation requires final approval.
Generic Markdown/MDX dry-run preview must pass.
System commits directly to the configured production branch.
Non-fast-forward push or conflict fails the publish step.
Commit SHA, repository URL, branch, and content bundle manifest are stored.
Publishing event is logged.
Task 7.3: Publishing UI
Acceptance criteria:
Editor can edit frontmatter, content path, author, category, and tags.
Editor can run generic Markdown/MDX preview.
Editor can click Create publish commit.
Publishing result shows PUBLISH_COMMIT_CREATED, commit SHA, and opportunistic deployment status if discoverable.
Epic 8: Multi-site support
Task 8.1: Site config CRUD
Acceptance criteria:
Admin can create, edit, and deactivate target sites.
Site config includes editorial, SEO, source, visual, publishing, Git repository, frontmatter mapping, asset path, and transform script rules.
Every Admin config/script change stores author, timestamp, diff, and rollback target.
Task 8.2: Site-aware workflow
Acceptance criteria:
Every generation step receives target site config.
Different sites produce different tone, SEO metadata, visual specs, frontmatter, asset paths, and content bundles.
No hardcoded website logic exists outside adapters.
Epic 9: Observability and operations
Task 9.1: Job logs
Acceptance criteria:
Each agent job stores stdout, stderr, status, duration, and error category.
Admin can inspect logs.
Sensitive values are redacted.
Task 9.2: Workflow history
Acceptance criteria:
Article detail page shows workflow timeline.
Timeline includes user actions, system actions, and agent jobs.
Task 9.3: Retry and cancel
Acceptance criteria:
Admin/editor can retry failed jobs where allowed.
Admin/editor can cancel queued or running jobs.
Cancelled jobs do not update article state.
17. MVP milestone plan
Milestone 1: Foundation
Goal:
Local stack, database, article creation, target site config.
Exit criteria:
User can create article brief for one target website.
Article appears in dashboard.
Milestone 2: Plan approval loop
Goal:
Boundary questions, Codex runner, plan generation, plan review.
Exit criteria:
Editor can approve or revise an article plan.
Workflow stops correctly before research.
Milestone 3: Research and evidence
Goal:
Research job, evidence matrix, claim-source mapping, object-storage research artifacts.
Exit criteria:
Approved plan produces evidence matrix.
Research run manifest points to S3 source-section artifacts.
Unsupported claims are visible.
Insufficient evidence returns workflow to plan revision.
Milestone 4: Draft production
Goal:
Parallel section scaffolding, asset specs, draft assembly.
Exit criteria:
System creates full markdown draft from approved plan and evidence.
Milestone 5: Review and Git-backed publish commit
Goal:
SEO review, linguistic review, final approval, generic preview dry run, Git-backed publish commit.
Exit criteria:
Editor can approve final article and create a production-branch publish commit.
Milestone 6: Multi-site extension
Goal:
Second target website with different config.
Exit criteria:
Same workflow works for two websites through site config and versioned publishing YAML/scripts.
18. Definition of done for v1
1. User can create article from short description.
2. System generates boundary questions.
3. User can answer questions.
4. System generates article plan.
5. Workflow stops for plan approval.
6. Editor can revise or approve plan.
7. Research starts only after approval.
8. Evidence matrix is created.
9. Section scaffolds run in parallel.
10. Visual specs are generated.
11. Draft is assembled.
12. SEO review is generated.
13. Linguistic review is generated.
14. Workflow stops for final approval.
15. Publish commit is created only after final approval and successful generic dry-run validation.
16. At least one target website works end to end.
17. A second target website can be added through config.
18. Agent generation runs through Codex CLI subscription auth, not direct API-key calls.
19. Every major action is logged.
20. Failed jobs can be inspected and retried.
21. High-risk unsupported claims block final approval.
22. Research source-section artifacts are stored in S3 with manifest records in Postgres.
23. Publishing validation is explicitly best-effort content-shape validation only.
19. Technical risks and mitigations
| Risk | Impact | Mitigation |
|---|---|---|
| Codex CLI output is malformed | High | Use schema files, JSON-only instructions, validation, retry |
| CLI auth expires | High | Runner health check, admin alert, re-auth flow |
| Long jobs block backend | High | Use queue and runner service, not request thread |
| Research creates weak evidence | High | Source scoring, unsupported claim flags, plan revision loop, editor review |
| Expanded research corpus creates storage/legal burden | Medium | Store artifacts in S3 with manifests and hashes; document indefinite retention |
| Multi-site rules become messy | Medium | Strict site config schema, versioned YAML/scripts, audit diffs |
| Direct production-branch commit contains site-specific error | High | Final approval, generic dry run, explicit accepted validation risk, alerts |
| Git push conflict or non-fast-forward | Medium | Fail publish step and require retry after refresh |
| Admin transform script damages runner/site workspace | High | Treat Admins as trusted code operators, audit every version, rollback |
| Agent invents unsupported claims | High | Claim extraction, evidence mapping, unsupported-claim gate |
| Claude Code subscription use creates compliance issue | Medium | Keep Claude optional and internal-only |
| Prompt changes break output | Medium | Prompt versioning and schema validation |
20. First development ticket
Ticket: Build v1 foundation for AI Content Pipeline
Goal
Create the initial backend, frontend, database, and runner-service foundation for the article workflow.
Scope
Implement:
1. Article creation
2. Target site configuration with Git-backed publishing fields
3. Workflow state storage
4. Agent job table
5. Codex runner test job
6. Dashboard list
7. Article detail shell
Backend deliverables
FastAPI app
Postgres migrations
Article model
TargetSite model
WorkflowEvent model
AgentJob model
ScriptConfigVersion model
POST /api/articles
GET /api/articles
GET /api/articles/{id}
GET /api/sites
POST /api/sites
POST /api/agent-jobs/test-codex
Frontend deliverables
Dashboard page
New article form
Article detail page
Status badge component
Target site selector
Publishing status display
Runner deliverables
Runner service process
Workspace creation
Input file writer
Codex CLI command execution
Log capture
Output validation placeholder
Job status update
Acceptance criteria
Given a configured target site
When a user submits a short article brief
Then the system creates an article with ARTICLE_BRIEF_CREATED status
And the article appears on the dashboard
And the article detail page shows workflow history
And the target site can store repository, production branch, and initial publishing YAML config
And an admin can run a test Codex job from backend
And the runner stores stdout, stderr, exit code, and job status
21. Recommended implementation order
1. Database schema
2. Backend article/site APIs
3. Frontend dashboard and article form
4. Workflow event logging
5. Agent job model
6. Runner service
7. Codex CLI test job
8. Boundary question generation
9. Plan generation
10. Plan review gate
11. Research and evidence
12. Parallel scaffolding
13. Draft assembly
14. SEO and language review
15. Git-backed publishing adapter
16. Second target website config