content-publishing-suite

内容来源:clawhub · 原始地址 · 查看安装指南

原始内容


name: content-publishing-suite description: Turn a fact-checked and compliance-approved final Markdown draft into multi-channel publishing assets — WeChat article, LinkedIn post, standalone responsive HTML, and an archive ledger. It only orchestrates publishing and format conversion; it does not repeat fact-checking and does not auto-publish. description_zh: 内容发布套件 description_en: Content publishing suite version: 1.1.1 disable: false agent_created: true

Content Publishing Suite

Convert a reviewed, approved final draft into multi-channel publishing assets and generate an archive ledger. This skill is the publishing-orchestration layer — it does not repeat fact-checking, originality review, or cross-material auditing (those are upstream skills), and it never performs any external publish action automatically.

In this document {SKILL_DIR} is replaced automatically with the skill's actual install path.

When to use

  • The user has a final draft that passed final check (07-final.md from industry-deep-dive-pipeline, or an equivalent Markdown explicitly marked "已审核 / reviewed"), and wants WeChat / LinkedIn / standalone HTML / archive assets.
  • The user asks to "publish this to multiple platforms", "generate a publish package", or "lay out and archive".

Do not use

  • Content that has not completed fact-checking or compliance review → run industry-deep-dive-pipeline / claim-to-source-auditor / cross-material-consistency-auditor first.
  • Pure WeChat layout with a dedicated WeChat-layout skill already installed, or an existing platform drafting flow → use that tool directly; this suite is unnecessary.
  • Writing new body text, rewriting, or adding facts → that belongs to the writing / verification stage, not publishing orchestration.

Input

draft:
  path:                     # reviewed final Markdown
  title:
  author:
  date:
approval_gate:              # one of these must be satisfied
  final_check_json:         # product of industry-deep-dive-pipeline; needs Gate B approved, red-line hits 0, credential/privacy P0 0
  reviewed_marker: false    # or draft header carries `状态: 已审核` / `reviewed: true` AND user confirms
channels: [wechat, linkedin, html, archive]
output_dir:
external_action: dry-run    # default: generate only, do not send
read_only_upstream: true    # do not introduce new facts not covered upstream

One of the two gates must be satisfied, otherwise refuse to enter:

  1. Provide final-check.json (product of industry-deep-dive-pipeline) with Gate B: approved, red-line hits: 0, credential/privacy P0: 0; or
  2. The final draft header carries an explicit 状态: 已审核 or reviewed: true marker, AND the user confirms "已审核" in the request.

If the downstream introduces any new fact not covered upstream, pause and prompt to roll back to upstream for re-verification — never publish silently.

Output channels

Channel Artifact Notes
WeChat wechat_snippet.html (paste-ready fragment) + wechat_preview.html (mobile-frame preview) 135-editor-compatible inline styles; does not auto-create draft
LinkedIn linkedin-post.md hook + body + 3–5 hashtags; Chinese/English by target audience
Standalone HTML standalone.html responsive single page with TOC and reference links
Archive archive-ledger.json (local) + optional Notion entry title/channel/time/status; optional page-ID write with readback

Workflow

ingest final draft → input gate → generate per-channel assets → output gate (script validation) → package-manifest → archive ledger → external-action gate (confirm before send)

Step 1: [Deterministic + LLM] Ingest and input gate

Read the final draft Markdown and confirm the input gate is satisfied. Record title, author, date, and core judgment. Stop immediately if the gate fails.

Step 2: [LLM] Generate per-channel assets

  • WeChat: per references/wechat-style.md, convert Markdown to fully-inline <section> HTML. Title 22px centered, subhead 17px bold #1a3a5c, body 16px / line-height 1.8 / #333, key sentences <strong style="color:#1a3a5c;">, table with dark-blue header + white text + zebra rows. Must end with <v2></v2>. Never use <style>, <script>, external class, or an outer <div> container. Template: templates/wechat-snippet.html.
  • LinkedIn: per templates/linkedin-post.md, take the core judgment as the hook, compress body to 200–300 words, end with 3–5 hashtags. No Markdown, no internal notes, no unpublished data, no process meta.
  • Standalone HTML: per templates/standalone.html, generate a responsive single page with title/author/date/TOC/body/reference links. Flat-fill style, generous whitespace, absolutely no tech-circuit motifs, glow, or digital-grid patterns.
  • Archive ledger: append one record to archive-ledger.json (create if missing); fields per templates/archive-record.json.

Step 3: [Deterministic] Output gate (script validation)

Run the deterministic script to verify each channel file meets its format contract:

python3 {SKILL_DIR}/scripts/validate_publish_output.py --package <output_dir> --enforce

P0 blocks (e.g. WeChat missing <section>/<v2>, contains <script>, HTML without structure, ledger missing fields); P1 warnings (e.g. LinkedIn too long). Exit code 2 means a P0 exists. The author's internal pen-name list is passed via the PUBLISH_PEN_NAMES environment variable (comma-separated), never hardcoded.

Step 4: [Deterministic] Package and ledger

python3 {SKILL_DIR}/scripts/build_publish_package.py \
  --draft <final.md> \
  --approved-gate <final-check.json or --approved flag> \
  --channels wechat,linkedin,html,archive \
  --output <output_dir>

The script produces each channel file, updates archive-ledger.json, and outputs package-manifest.json.

Step 5: [Human] External-action gate

Before any actual push, article-platform draft creation, or Notion write, list the targets and obtain user confirmation. Default is generate-only (--dry-run). Execute only after confirmation, and always read back to verify after writing (Notion uses page-ID writes, idempotency key prevents duplicates).

Hard Rules

  1. Refuse to enter if the input gate is not satisfied (no final-check.json approved, no explicit "已审核" marker) — never substitute for upstream verification.
  2. Zero conversation traces, zero process meta, zero internal notes / pen-names / unauthorized data in any publish asset.
  3. WeChat assets must be fully inline-styled, wrapped in <section>, and end with <v2></v2>; forbid <style>/<script>/external class/outer <div>.
  4. Use the real name or neutral phrasing for any person in working docs and publish assets; the author's internal pen-name is read from PUBLISH_PEN_NAMES for blocking only, never hardcoded into this skill.
  5. Any external action (push, draft creation, Notion write) defaults to --dry-run; list targets and get user confirmation first; read back after writing.
  6. Credentials come only from environment variables (Notion uses NOTION_TOKEN, database ID uses NOTION_DB_ID; article platforms via their existing MCP/connectors) — never hardcoded.
  7. Scripts only read the user-specified final draft and write to the user-specified output directory; no network egress.

Failure Handling

Scenario Action
Input gate not satisfied Stop; list missing items, prompt to finish upstream verification
Output gate hits P0 (exit code 2) Do not generate manifest; list each P0 and its file, fix and re-run
Downstream finds a new fact not covered upstream Pause publishing, roll back upstream for re-verification, never publish silently
External write fails Retry once and cross-verify; if still failing, keep the local ledger, report the reason, leave no half-written state
Final draft has unparseable embedded content (charts/image-with-text) Mark as unparseable, request text extraction or manual confirmation
Target channel unspecified Default to generating all four channels and prompt

Output Format

<output_dir>/
├── wechat_snippet.html
├── wechat_preview.html
├── linkedin-post.md
├── standalone.html
├── archive-ledger.json        # append-style archive ledger
└── package-manifest.json      # this publish package manifest (file paths + gate results)

Gate report: P0/P1 list; when a P0 exists, explicitly mark "未通过、禁止发布 / failed, publishing forbidden".

References

Resource Purpose
references/wechat-style.md WeChat 135 inline-style spec and component styles
references/channel-contracts.md Output-format contracts per channel (validation basis)
templates/wechat-snippet.html WeChat fragment template
templates/linkedin-post.md LinkedIn post template
templates/standalone.html Standalone HTML single-page template
templates/archive-record.json Archive ledger entry template
templates/notion-mapping.example.json Notion mapping example (credentials via NOTION_TOKEN env var; database ID placeholder, never real value)
scripts/build_publish_package.py Organize artifacts, update ledger, output manifest
scripts/validate_publish_output.py Per-channel format-contract validation, outputs P0/P1 gate

Verification

  • validate_publish_output.py --enforce exits 0 (no P0).
  • WeChat fragment contains <section>, ends with <v2></v2>, no <script>/<style>/outer class.
  • LinkedIn has no Markdown markers, no internal notes / pen-names.
  • Standalone HTML starts with <!DOCTYPE html>, no tech-circuit / glow / digital-grid motifs.
  • package-manifest.json generated for all channels, archive-ledger.json appended one entry.
  • User confirmation obtained before any external action; default dry-run.

Pitfalls

  • Treating an unreviewed draft as reviewed and publishing directly — must pass the input gate first.
  • WeChat asset accidentally gets <style>/outer <div>, then the 135 editor strips the styles on paste.
  • LinkedIn retains Markdown bold/list symbols or an internal pen-name — the platform won't render it or it leaks internal info.
  • Writing a real Notion database ID or credential in an example/template — always use placeholders and environment variables.
  • External write without readback verification, causing duplicate writes or half-written state.
  • Downstream silently adds a "new fact" that bypasses upstream verification — any new fact must roll back upstream.

中文摘要(Chinese Summary)

本 Skill 是发布编排层:把一篇已通过终检的定稿(如 industry-deep-dive-pipeline07-final.md,或显式标记「已审核」的等价 Markdown)稳定转换为微信 / LinkedIn / 独立 HTML / 入库四类物料,并生成入库台账。

关键约束(双语要点 / Bilingual key points):

  • 输入门禁 Input gate:必须提供 final-check.json(Gate B approved、红线 0、凭据/隐私 P0 0)或定稿头部显式「已审核」标记且用户确认;否则拒绝进入。
  • 零泄漏 Zero leakage:发布物料中零对话痕迹、零流程元信息、零内部备注/笔名;作者笔名仅经 PUBLISH_PEN_NAMES 环境变量传入用于拦截,绝不硬编码。
  • 微信硬规则 WeChat hard rule:全内联样式、<section> 包裹、文末 <v2></v2>;禁止 <style>/<script>/外联 class/外层 <div>
  • 外部动作门禁 External-action gate:任何推送、建草稿、写 Notion 默认 --dry-run,须列目标并取得用户确认,写后必须回读核验。
  • 凭据 Credentials:只走环境变量(NOTION_TOKEN / NOTION_DB_ID),绝不硬编码。

它不重复事实核验、原创性复核或跨材料审计,也不自动执行任何发布动作。