# Frontmatter Specification ## Required Fields All drafts in `01-topics/`, `02-drafts/`, `03-review/`, `04-published/` must contain these fields: ```yaml --- id: "YYYY-MM-DD-slug" # Unique identifier, matches filename title: "文章标题" # Display title slug: "article-slug" # URL-friendly identifier status: "draft" # inbox | topic | draft | formatting | review | polish | publishing | published | revision | blocked | archived content_type: "article" # article | thread | x-post | wechat-post | infographic channels: ["wechat", "x"] # Target publish channels language: "zh-CN" # Language code source_urls: [] # Original source URLs if any assets: [] # Vault-relative paths to images/files cover_image: "" # Path to cover image template: "article" # Template used owner: "content-forge" # Content owner created_at: "YYYY-MM-DDT00:00:00+08:00" # ISO 8601 timestamp updated_at: "YYYY-MM-DDT00:00:00+08:00" # ISO 8601 timestamp published_at: null # Set when published --- ``` ## Optional Fields ```yaml # Cycle tracking cycle_days: null # Days from creation to publish stage_days: # Days spent in each stage inbox: 0 topic: 0 draft: 0 review: 0 total: 0 # Promotion fields (for /promote command) promotion_status: null # null | planned | promoting | converted | paused promotion_channels: [] # ["newsletter", "webinar", "x-thread", "linkedin"] holding_patterns: [] # ["email-list", "youtube", "podcast"] conversion_type: null # null | "lead-magnet" | "webinar" | "product-sale" repurposed_from: null # slug of original content repurposed_to: [] # slugs of derivative content evergreen: false # Can be re-promoted? # Write-article skill extensions style: "tech_blog" # tech_blog | opinion | tutorial | social_short audience: "developers" # Target audience tags: [] # Content tags source_notes: [] # Obsidian note paths used as source # Review & Polish (managed by /review command) review_status: null # null | pending | in_progress | passed | failed review_issues: [] # [{id, category, severity, description, status}] # category: structure | factual | style | format # severity: critical | high | medium | low review_passed_at: null # ISO 8601 timestamp when review passed polish_status: null # null | pending | skipped | done polish_version: 0 # Incremented on each polish iteration polished_at: null # ISO 8601 timestamp when polish completed revision_count: 0 # Number of revision cycles (max 3) revision_history: [] # [{date, issues_fixed: [], notes}] ``` ## Status Workflow ``` inbox → topic → draft → formatting → review → polish → publishing → published ↓ ↓ ↓ revision ←───────── blocked ↓ archived ``` ### Review → Polish Flow ``` ┌─────────────┐ │ review │ └──────┬──────┘ │ ┌────────────┼────────────┐ ▼ ▼ ▼ ┌──────────┐ ┌──────────┐ ┌──────────┐ │ passed │ │ failed │ │ revision │ └────┬─────┘ └────┬─────┘ └────┬─────┘ │ │ │ ▼ ▼ │ ┌──────────┐ ┌──────────┐ │ │ polish │ │ blocked │◄┘ └────┬─────┘ └──────────┘ │ ▲ ▼ │ (revision_count > 3) ┌──────────┐ │ │publishing│───────────┘ └──────────┘ ``` ### Revision Rules - **Trigger**: Critical ≥ 1 OR High > 1 - **Limit**: revision_count ≤ 3 per article - **Overflow**: auto → blocked for human decision ## Field Constraints - `id` and `slug` must be unique across all stages - `status` can only progress forward (with exceptions for revision/blocked) - `assets` must use vault-relative paths (e.g., `05-assets/slug/image.png`) - `channels` determines which publish skills to use - `created_at` never changes after initial creation - `updated_at` changes on every modification ## Naming Convention Files: `YYYY-MM-DD-.md` - Date: creation or import date - Slug: lowercase, hyphens only, no special chars - Example: `2026-03-03-claude-code-auto-memory-deep-dive.md` Assets: `05-assets//filename.ext` - Assets live in a directory named after the slug - Example: `05-assets/claude-code-auto-memory/cover.png`