Files

47 KiB
Raw Permalink Blame History

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