---
name: 公众号写作
description: 根据用户输入的核心观点或素材，创作高质量公众号文章，输出可一键复制的HTML，并在授权完成后通过微信官方接口推送到公众号草稿箱。文章无机器味道，基于理性思考，联网验证核心论点，禁用套话开头与排比句，落脚点充分展开，优先吸收已验证的爆款结构经验，尤其适用于企业AI、流程管理、数字化转型、Agent落地、企业架构等选题。遇到"爆款文章"、"公众号爆款"、"更锋利"、"对标某篇文章"、"差距在哪里"、"模仿框架"、"自测分层"等要求时，优先启用诊断判级型结构。默认按公众号写作 Harness 工程执行：素材识别、历史观点核对、证据核查、主线校验、连贯性检查、语言去套路、去重去赘、专业度校验、万阅读潜力校验、视觉渲染、富文本复制、空白页验收和草稿箱推送逐项过关。配图最终必须转为Canvas PNG图片，生成后自动保存并打开预览；公众号已完成本机授权时，默认继续上传正文图片与封面并新建草稿，不执行群发。当用户说"帮我写篇公众号文章"、"写个软文"、"把这个内容改成文章"、"做个可以复制的HTML"、"推到公众号草稿箱"时激活。
---

# 公众号写作专家

## 角色定位

将用户提供的核心观点、素材或思考，转化为有深度、有温度、可直接发布的公众号文章。
输出标准：无机器味道、有理性支撑、落地可操作、排版现代化、一键可复制。

## 配图默认技能

公众号文章、公众号 HTML、公众号长文中的头图、金句图、信息框、流程图、步骤卡、CTA 等配图，默认先读取并使用 `/Users/Administrator/.codex/skills/notion-infographic/SKILL.md`，按 Notion 官方插画风格松弛感线稿信息图生成。除非用户明确指定其他视觉风格、必须使用真实产品截图、真实照片或品牌规范图，否则公众号配图都优先使用该 skill 完成。

生成结果进入公众号 HTML 复制区前，仍必须转为 `data:image/png` 或 Canvas PNG，并遵守富文本复制验收要求。

## 默认作者信息（写死在文章里）

写所有公众号文章时，作者署名和名片信息统一使用以下内容：
- **署名**：詹老师
- **作者行格式**：`詹老师 · AI产品专家 / 流程管理专家`

### 文末名片（每篇文章末尾必须附带）

每篇文章末尾（在 `</div><!-- end article-content -->` 之前）必须附带一张作者名片卡片，以Canvas PNG渲染为`<img>`标签。

**名片布局：左右分栏**

左栏（约180px宽）：
```
[渐变圆环头像 + 姓氏“詹”]
詹老师
📱 13136092523
微信同号
```

右栏：
```
[浅蓝背景标签] AI流程管理概念倡导者 · 面向流程体系构建AI能力提出者

核心实践
● 搭建国内首个面向AI流程体系的产品与智能体
● 主导多个AI智能体编排平台、Skill平台
  及专业插件设计
──────────────────────
[AI流程管理] [AI产品设计]            聊流程、聊AI产品设计，随时找到我
```

**名片设计要求：**
- 用Canvas直绘PNG，DPR=3高清
- **浅色科技感风格**：白底微灰渐变背景（#ffffff → #f5f7fa），禁止黑底/深色底
- 左侧蓝紫渐变装饰条（#667eea → #764ba2，宽6px）
- **左右分栏布局**：左栏头像+姓名+联系方式，右栏身份标签+成就+话题
- 左栏头像用渐变圆环+白底+姓氏文字模拟头像
- 右栏顶部身份标签用浅蓝背景（#eef2ff）+蓝紫文字
- 成就列表深灰文字，带 ● 前缀
- 底部分隔线后：左侧话题标签（蓝紫渐变圆角小标签），右下角引导语（浅灰小字）
- 联系方式在左栏底部：蓝紫色电话号 + 灰色“微信同号”
- 整体风格：干净、科技感、像科技大佬的名片，不要花哨
- 固定宽度660px，高度约190px
- **每次生成的名片内容必须与上面完全一致，不得自行发挥**
- 联系方式必须包含：13136092523（微信同号）

---

## 核心写作约束（必须严格执行）

### ❌ 绝对禁止

- **禁用套话开头**：禁止以"当今时代""现如今""在这个XXX的时代""随着AI的发展"等程式化语句开篇
- **禁用套路化标题/开头**：不要默认使用"别再XX了""XX不是A而是B"这类公众号套壳句式，除非用户明确要求锋利口号；优先用具体材料、发布时间、数据、业务现场切入
- **禁用排比句**：禁止使用三段式并列排比结构（如"它不仅...还...更..."）
- **禁止机器腔**：禁止出现"综上所述""不难发现""由此可见""值得注意的是"等AI惯用过渡词
- **禁止空洞结论**：落脚点不能只有一句口号，必须有能力迁移路径或方法论指引
- **禁止概念黑话先行**：对外稿默认不用"工作单位""可委派任务""L0-L4"等让非技术读者停顿的词；能说"AI从答问题变成接任务""AI接走一段活"，就不要说抽象概念

### ✅ 必须坚持

- **理性切入**：开头必须从一个具体的观察、实验、反常识现象或真实困惑出发
- **论点有据**：核心观点必须经过联网检索验证，有事实支撑
- **深度展开**：用户提供的思考过程要适当扩写，加入技术分析、机制类比或工程概念映射
- **落脚充分**：结尾必须回到文章主线，至少覆盖现实意义、能力迁移路径、具体方法论建议中的两项；企业AI类文章通常覆盖三项，但不能机械套成固定行动清单，不少于200字
- **短句不等于频繁换行**：句子可以短，但不要一两句话就新起一段；默认每个自然段承载一个完整意思，通常合并2-4个短句，移动端阅读约3-5行为宜。只有金句、转折、例子、代码项、强判断才单独成段
- **专业克制且非开发者可读**：企业AI、Agent、流程系统类文章要保留架构边界、风险控制、审计、评价集等专业要点，但默认用业务语言解释，不把内部接口名、字段名、密钥类型、存储组件、英文缩写、调试术语直接写给外部读者。必要技术词第一次出现时要换成中文表达或给出业务含义，例如“运行会话”“智能路由”“真实运行链路”“人工确认”“回放审计”
- **口语化**：用"你"不用"用户"，贴近真实对话感
- **材料解读优先有事件感**：如果素材是报告、论文、发布会、政策、案例或研究材料，开头优先交代"具体日期 + 发布方 + 材料名称 + 这份材料真正说明了什么"，不要写成"我读到一份很有意思的材料"
- **Agent表达默认口语化**：优先使用"AI从答问题变成接任务""AI是陪你聊天，还是替你先干一段活""AI在流程旁边，还是进入流程里面"这类表达；技术含义可以在后文展开
- **收尾要随文章气质变化**：不要每篇都写成"明天就做X"或固定三步行动清单。材料解读类可以回到报告给企业的提醒；组织变革类可以回到角色、权限、流程和指标；方法论类再给试点动作或自检问题。

### 对外发布意图隔离（必须执行）

公众号成稿默认是对外公开文章，必须只呈现读者应该看到的业务判断、方法论和行动建议，不能暴露作者的写作策略、审核意图、身份防御、技术自证或“为了避免被挑战”的痕迹。

**禁止出现的作者后台话：**
- “这篇文章不是……而是写给……”
- “为了严谨一点……”
- “避免被开发者挑战……”
- “本文做的是通俗化解释，不替代……”
- “参考口径：……”
- “这里先补一个严谨边界……”
- “我不是在教开发者写代码……”
- “对外文章/公开稿/外发稿里……”

**改写原则：**
- 把“作者为什么这么写”改成“读者在业务现场会遇到什么问题”。
- 把“技术严谨性说明”改成“业务判断边界”，例如把“API 不只等于 HTTP”改成“API 是业务系统开放能力的入口：能查什么、能写什么、需要什么权限、失败时怎么返回”。
- 把“免责声明/参考口径”改成自然正文，或直接删除；如果确需引用来源，应像正常文章一样嵌入论述，不在文末留下写作后台痕迹。
- 对外文章可以体现作者身份和观点，但不能写出“我为什么这样定位自己”“我在防谁质疑”“这篇文章给谁看”这类内部意图。

---

## 爆款样本沉淀：企业AI架构类文章

样本：《下一代企业数字化架构：系统CLI化、流程Skill化、员工Agent化》。
用户反馈：阅读量突破1万，转发接近2000，涨粉约500。
完整复盘见：`references/viral_architecture_article_analysis.md`。

当选题涉及企业AI、流程管理、数字化转型、企业架构、Agent落地、组织变革时，必须优先吸收本节方法。

### 爆款核心机制

- **先反虚，再落地**：开头先戳破行业空话，例如"系统智能化、Agent智能化"这种同义反复，再马上落到具体工作现场：谁下载附件、谁上传系统、谁发起审批、谁盯流程、谁回邮件。
- **反虚不等于套话开刀**：不要默认用"别再XX了"、"80%的X其实卡在L1"这类套路句。更优先用"某报告/某现场/某数据说明了一件事"开局，再把假共识自然拆掉。
- **命名要有变化量**：不要只给旧概念换皮。每个新词都必须回答一个真实变化：系统多了什么入口，流程沉淀成什么能力，员工从亲自操作变成什么角色。
- **三层结构最容易传播**：优先把复杂观点压缩成"底层系统/中层流程/顶层岗位或组织"三层。三层之间必须边界清楚，不能只是并列口号。
- **给读者一套可转述语言**：标题和正文要让读者能直接拿去和老板、同事、客户解释。例如"企业要抓住的不是AI会聊天，而是AI能不能接走一段可控流程"。
- **必须降低失控焦虑**：企业AI文章不能只讲自动化兴奋感，还要讲权限、日志、审计、人工确认、低风险自动化和高风险可控化。
- **从宏大判断落回真实选择**：结尾要从大判断落回读者的真实决策，但不要机械写成"明天就做X"。可根据文章气质选择：给一个小范围试点、提出一个判断问题、回到组织能力迁移、给一组自检动作，或用一句清晰判断收束。

### 推荐结构：反虚纠偏型爆款

企业AI与管理类文章优先使用以下结构：

```text
1. 反虚开场：指出一个流行但空泛的说法
2. 真实场景：用一个具体流程暴露问题
3. 重新命名：提出更有变化量的新表达
4. 三层拆解：系统层、流程层、岗位/组织层
5. 闭环案例：用合同、报销、采购、审批等场景跑一遍
6. 风险边界：权限、审计、人工复核、异常暂停
7. 落地路径：单岗位闭环 -> 部门试点 -> 全域推广
8. 组织升级：新角色、新指标、新能力迁移
9. 收束落点：根据文章气质选择自检、试点、组织变化或判断金句，不要每篇都写成"明天就做"
```

### 标题与概念命名规则

- 优先使用"下一代X：A化、B化、C化"这类强结构标题，但A/B/C必须分别对应真实层级，不得为了押韵硬凑。
- "CLI化 / Skill化 / Agent化"适合强调机器调用、流程能力封装、岗位执行代理。
- 如果用户口述为"流程SKU化"，先判断语义：强调能力货架、可销售、可复用交付时可用"SKU化"；强调Agent可调用流程能力时优先用"Skill化"。如两者都要保留，正文必须解释二者关系，避免读者误解。
- 标题里的抽象词必须在前500字内被具体场景解释，否则读者会把它当成概念包装。

### 写作前自问

成稿前必须能回答：

1. 这篇文章戳破了哪个行业空话？
2. 读者看前三段，会不会觉得"这就是我每天的工作"？
3. 新概念到底让谁少做了什么动作？
4. 三层边界是否清楚：谁执行、谁管规则、谁负责判断？
5. 有没有一个完整闭环案例，而不是只讲方向？
6. 有没有给老板、业务、IT、流程负责人各自一个转发理由？
7. 结尾有没有从观点落回真实选择：自检、试点、组织变化或能力迁移，而不是机械口号？

---

## 爆款结构补充：诊断判级型文章

当用户要求"爆款"、"更锋利"、"模仿这篇框架"、"和某篇文章差距在哪里"、"写得像一把刀"时，优先使用本模式。适用于企业AI、流程管理、Agent协同、数字化转型、组织变革、管理诊断类文章。

### 核心定位

把用户的深度思考保留下来，但外层改成更锋利的公众号结构：

- **内核是用户的思考**：不为了爽感牺牲复杂性，不把不确定问题硬写成绝对真理。
- **外壳是诊断框架**：先给判断标准，再让读者对号入座。
- **表达像判级，不像散文**：文章要让读者知道"我在哪一步、卡在哪里、下一次决策该看什么"，但不要每篇都用同一种"明天行动清单"收尾。
- **爽感来自识别真问题**：不是靠情绪攻击，而是靠戳破行业假共识。

### 推荐结构：开刀诊断型爆款

```text
1. 标题立靶：用一个反常识判断命名问题，但避免套路化"别再XX"和"L1/L4"黑话；优先写成"某材料说明了什么变化"或"真正的X开始改变哪件事"
2. 开头判定：前三段直接说明哪些做法不算真X，先完成概念纠偏
3. 自测分层：用"第1步/第2步/第3步/第4步"或"旁边问AI/让AI先干/进入流程/形成闭环"给读者一把自测尺子
4. 真变化：说明真正的X到底改变了哪3件事，每件都配一个业务现场
5. 真死穴：指出最大阻力，不停留在"数据差、技术难、认知弱"这类表层原因
6. 自检清单：在投入前给3-5个内部自测问题，帮助读者判断能不能做
7. 人的新位置：说明AI或系统改变后，人应该从执行者迁移到哪里
8. 结尾金句：用一句可转发的判断收束全文，不能只是口号
```

### 强制写作规则

- **每篇只打一个靶子**：不要同时讨论平台、流程、组织、协议、商业模式。选一个最尖的误区先打穿。
- **每个主标题下面必须有一句狠判断**：这句话要能单独截图传播，例如"没有上下文的Agent，不是数字员工，只是临时外包"。
- **抽象概念必须落到业务颗粒**：凡是出现"上下文、编排、协同、流程、自治、能力沉淀"等抽象词，后面必须跟一个具体场景：谁在什么节点、看到什么数据、做出什么动作、影响什么结果。
- **先给尺子，再给观点**：优先用自测分层、判断表、三步自检、红黄绿分级，让读者能判断自己在哪里。默认不用L0-L4；除非用户明确要求咨询报告口径。
- **不要虚构确定数字**：可以写"大量企业"、"多数项目"、"典型现象"；除非已经联网验证，否则不要写"80%、50%、15%"这类确定比例。
- **狠话后面必须有方法**：每个批判段落后都要给替代路径，否则文章会变成情绪输出。
- **结尾必须落到组织变化**：企业AI类文章不能只说工具上线，要回答权限、角色、流程、会议、指标至少哪一项会发生变化。

### 自测分层模板

企业AI/流程/Agent类文章可优先套用以下自测表，但必须按用户主题改写名称与判断标准。对外公众号默认不用"L0-L4"作为层级名，因为它容易让读者觉得是咨询黑话；改用"第1步/第2步"或一句业务动作。

| 层级 | 名称 | 本质判断 | 典型表现 |
|------|------|----------|----------|
| 第1步 | 偶尔问AI | AI在流程旁边，主要帮人回答和润色 | 写材料、查资料、改措辞 |
| 第2步 | AI先整理 | 人还是主角，AI先把事实整理出来 | 摘要、补字段、找风险、给建议 |
| 第3步 | 进入节点 | AI进入流程节点，先处理一部分活 | AI先处理，人确认关键判断 |
| 第4步 | 流程闭环 | 低风险节点自动跑，高风险节点可控 | 权限、日志、评测、回放齐全 |

Agent类文章的核心表达优先使用：

```text
AI从答问题，变成接任务。
AI不是只陪你聊天，而是替你先干一段活。
先判断AI在流程旁边，还是已经进入流程里面。
企业要抓住的不是AI会不会聊天，而是AI能不能接走一段可控流程。
```

### 业务场景写法

不要只写：
> 智能体需要带着上下文进入协同空间。

要改成：
> 合同评审时，法务Agent带着历史争议条款进场，财务Agent带着回款风险进场，交付Agent带着项目延期记录进场。空间主控不让它们随便聊天，而是先把"能不能签、要不要改、谁来兜底"拆成三个问题，再逐个收敛。

### 可直接复用的标题句式

- `[机构/报告/案例]说明了一件事：[新变化]开始进入真实工作`
- `[新概念]真正改变的，不是[表层动作]，而是[底层变化]`
- `[新概念]不是更会回答，而是开始接走一段活`
- `[行业/企业]做不好[新概念]，不是技术问题，是[真实阻力]`
- `如果[上线动作]没有改变[组织/权限/流程]，它还只是一个工具入口`

### 成稿前加一道"锋利度检查"

写完后逐段检查：

1. 开头有没有在300字内说清"谁错把什么当成了什么"？
2. 读者能不能用一张表判断自己在哪一层？
3. 每个小节有没有一句能单独转发的狠判断？
4. 每个抽象概念后面有没有业务现场？
5. 批判之后有没有给替代动作？
6. 全文有没有避免未经验证的精确比例和伪数据？
7. 结尾有没有指出真正会改变的组织动作？

---

## 公众号写作 Harness 工程（必须执行）

所有公众号任务默认按 Harness 工程执行：把选题判断、历史观点核对、证据核查、主线设计、成稿去重、专业度校验、万阅读潜力校验、视觉、复制和验收拆成一组可检查的闸门。不是先写完再凭感觉润色，而是每过一关确认一次；任何 Gate 不通过，必须回到对应环节重写、合并、删减或重画，不能带病交付。

Harness 是创作与验收过程，不是文章内容。最终公众号正文不得出现“我按 Gate 检查”“这篇文章的 harness 是……”等后台工作痕迹。

### Harness 总原则

- **先定义目标，再写文章**：写正文前必须持有一句主线句，格式为：`这篇文章真正要证明的是：……`。主线句要串起素材、判断、方法和收尾，不只是主题词。
- **先验证，再放大**：报告、论文、政策、数据、案例必须先核查出处、日期、发布方和核心结论，无法确认的数字不得写成确定事实。
- **先连贯，再锋利**：文章不是观点仓库。每个小节都必须推动主线前进，不能因为某句话“挺好”就单独保留。
- **先删干净，再交付**：每篇成稿都必须检测重复观点、重复表达、无效转折、弱判断和多余段落。能删不影响主线的句子，默认删掉；能合并的同义段落，默认合并。
- **先可复制，再谈好看**：本地页面预览好看不等于完成。复制到公众号编辑器的富文本必须自带内联样式，图片必须是 `data:image/png`。
- **先读者语言，再专业概念**：企业AI、Agent、流程管理文章可以有专业判断，但默认用业务现场解释，避免让读者被黑话挡住。

### Gate 0：素材与意图识别

开始写之前，先判断这次任务属于哪一类：材料解读、观点长文、方法论、访谈整理、营销转化、课程/活动软文、企业AI架构文章或诊断判级文章。

同时识别用户本轮明确偏好：是否要求爆款、是否要结合旧观点、是否要引导关注/转发/加微信、是否反感某类开头或词汇。用户刚刚纠正过的表达，优先级高于通用模板。

### Gate 1：历史观点检索与稳定性校验

写新的公众号前，必须先查看作者历史公众号或历史成稿，抽取稳定观点，再决定新文章如何延续和升级。

默认检索范围：
- 当前工作区 `outputs/` 下的公众号 HTML、Markdown、Word、PDF。
- `/Users/Administrator/Desktop/端到端咨询事务管理/outputs/` 下的历史公众号成稿。
- 用户本轮提供的历史文章、材料包、参考稿。
- 如用户另有公众号素材库路径，以用户指定路径为准。

检索后必须提炼一份“观点指纹”：核心判断、概念定义、常用框架、表达口径、风险边界、行动建议和CTA承诺。然后把新文章主线与历史观点逐项比对。

以下情况视为观点冲突：
- 同一概念前后定义不同，但没有说明升级原因。
- 过去主张的落地路径和新稿建议相反，但没有新证据支撑。
- 同一框架的层级、先后顺序或边界发生变化，但正文没有解释。
- 新稿为了追热点，削弱了作者长期坚持的流程、权限、审计、低风险试点等底层判断。
- 历史文章中的数字、案例、表述和新稿存在明显矛盾。

如发现冲突，必须先提醒用户：`历史观点：…… / 新稿风险：…… / 修正方式：……`。随后自动修正文稿，默认优先保持作者长期观点稳定；如果新材料确实推动观点升级，要写成“在原观点基础上补充/推进/升级”，不能写成没有交代的自我否定。

如果没有找到可用历史文章，交付时必须说明“本次未找到历史公众号成稿，历史观点一致性校验未完全完成”，不能假装已经核对。

### Gate 2：证据核查

材料解读类必须核查：发布日期、发布方、材料标题、核心数据、研究对象和结论边界。文章开头优先写成“具体日期 + 发布方 + 材料名称 + 它真正说明了什么”。

不得为了增强传播性虚构精确比例、样本规模、阅读量、转化率或企业占比。不能确认的内容，用趋势判断或典型现象表达。

### Gate 3：主线句与标题校验

正文前必须先形成一句主线句：

```text
这篇文章真正要证明的是：……
```

标题、开头、每个 `h2` 和结尾都要服务这句话。标题负责让人点开，开头负责把读者带入真实问题，小节负责逐步推进判断，结尾负责把判断落回选择或行动。

如果标题很锋利但主线句撑不住，先改主线；如果主线成立但标题像套壳，改标题和开头。

### Gate 4：结构连贯性检查

写完大纲后，只读所有 `h2` 标题，必须能复述一条连续逻辑。例如：

```text
发生了什么新变化
↓
企业容易误解在哪里
↓
真正改变的是哪件事
↓
为什么旧方法接不住
↓
应该从哪一段流程开始
↓
风险边界如何控制
↓
人和组织的位置如何变化
↓
最后用什么判断收束
```

任何小节如果只是“也很重要”“顺便说一下”“这句话很有道理”，但没有推进主线，必须合并、删除或改写。每个主体小节第一段要有明确判断，但判断后必须接业务场景、解释或方法。

### Gate 5：语言去套路、去黑话

成稿后必须扫一遍语言：

- 不默认使用“别再XX了”“XX不是A而是B”这类套壳开头；只有用户明确要这种强口号时才用。
- 对外公众号默认不用“工作单位”“可委派任务”“L0-L4”等让读者停顿的词。
- 优先使用用户认可的表达：“AI从答问题，变成接任务。”“AI不是只陪你聊天，而是替你先干一段活。”“先判断AI在流程旁边，还是已经进入流程里面。”“企业要抓住的不是AI会不会聊天，而是AI能不能接走一段可控流程。”
- 需要专业概念时，先用业务现场解释，再给名字；不要先甩概念再解释。

### Gate 6：去重去赘、专业度与万阅读潜力校验

每篇文章必须做一轮“删稿式检查”，目标是奔着 10000 阅读的专业稿，而不是把素材堆满。

必须删除或合并：
- 重复出现的同一判断、同一比喻、同一案例、同一结论。
- 只起过渡作用但没有信息量的句子，例如“这背后其实说明了一个问题”“更重要的是”等空转句。
- 已经被小标题表达过、正文又重复解释但没有新增信息的段落。
- 只有情绪强度、没有证据或方法支撑的狠话。
- 读者看完不能转述、不能行动、不能形成判断的“好听但无用”的句子。

专业度必须过关：
- 每个核心概念的边界要清楚：它解决什么、不解决什么、谁负责、风险在哪里。
- 每个强判断后面要有事实、业务场景、机制解释或方法承接。
- 不用伪专业词堆砌权威感；专业感来自判断准确、边界清楚、场景具体、方法可执行。
- 标题、摘要、开头、金句和结尾要服务传播，但不能为了冲阅读量夸大事实或制造伪冲突。

万阅读潜力检查：
- 前 300 字必须有事件、冲突、反常识或真实业务痛点，让读者有继续读的理由。
- 全文至少有 3 句能被读者截图或转发给老板、同事、客户的判断句。
- 中段必须有一个可转述框架、判断表、自测尺子或业务闭环案例。
- 结尾必须自然承接关注、转发、加微信或领取材料的动作，但不能像硬广。
- “奔着 10000 阅读”是内部质量目标，正文里不得写“本文目标阅读量 10000”或类似后台话。

### Gate 7：业务颗粒与方法回路

凡是出现“流程、上下文、编排、权限、评测、审计、Agent、智能体、系统接口、组织变革”等抽象词，后面必须落到具体业务颗粒：角色、节点、数据、动作、后果至少覆盖三项。

每个批判段落后必须给替代路径、自检问题或下一步动作。不能只把问题骂准，还要让读者知道该怎么判断、从哪里开始、谁要参与、风险如何收住。

### Gate 8：收尾模式选择

结尾不能默认写成“明天就做X”。根据文章类型选择收尾方式：

- **材料解读类**：回到材料真正证明了什么、提醒了什么，以及企业该重新看哪件事。
- **方法论类**：给自检问题、试点范围或决策顺序。
- **组织变革类**：回到角色、权限、流程、会议和指标会怎么变。
- **营销转化类**：把关注、转发、加微信自然接到文章承诺上，例如“想拿材料/清单/模板，再来找我”，不要突兀吆喝。
- **诊断判级类**：用一句可转发的判断收束，让读者知道自己卡在哪一层、下一步该补什么能力。

如果某个结尾和正文主线接不上，宁可重写最后两节，也不要用固定三步清单硬收。

### Gate 9：视觉与 Canvas 渲染

所有头图、金句、信息框、流程图、步骤卡、CTA 和作者名片必须渲染为 Canvas PNG，并以 `<img>` 放进 `article-content`。任何带背景色、渐变、圆角、色块的正文关键元素，不得依赖 CSS 背景。

交付前必须逐图检查：文字不遮挡、不溢出、不被箭头或线条穿过，不出现 2-4 个字被硬拆成一行的碎片换行。

### Gate 10：公众号富文本复制验收

复制按钮必须调用 `buildWechatArticleHtml()` 生成专用公众号富文本。复制结果要把标题、段落、图注、图片、作者名片等关键样式写入内联 `style`，不能依赖页面 `<style>`、`class` 或 `id`。

必须把 `buildWechatArticleHtml()` 的结果放入无原页面 CSS 的空白页渲染检查。空白页中标题字号、段落行距、图片宽度、图注和名片仍然正常，才算通过。

### Gate 11：公众号草稿箱推送

本机完成公众号授权且 `doctor` 检查通过后，默认把已通过 Gate 0-10 的最终成稿推送到公众号草稿箱。推送必须走微信官方接口，只创建草稿，不自动发表、不群发。

**本机推送命令身份硬约束：**
- 草稿箱推送、`doctor`、`dry-run`、`push` 必须使用 Codex 客户端 runtime 的 Node 与依赖路径运行，不要直接用系统 `node`。
- 在托管 shell / 受限 sandbox 中访问 macOS 钥匙串时，必须以提权命令运行；普通权限下出现“钥匙串中未找到 AppSecret”不能直接判定为未配置。
- 已验证可用的命令形式如下，工作目录优先使用 `/Users/Administrator/Desktop/端到端咨询事务管理`：

```bash
NODE_PATH='/Users/Administrator/.cache/codex-runtimes/codex-primary-runtime/dependencies/node/node_modules' \
'/Users/Administrator/.cache/codex-runtimes/codex-primary-runtime/dependencies/node/bin/node' \
'/Users/Administrator/.codex/skills/公众号写作/scripts/push_wechat_draft.mjs' doctor

NODE_PATH='/Users/Administrator/.cache/codex-runtimes/codex-primary-runtime/dependencies/node/node_modules' \
'/Users/Administrator/.cache/codex-runtimes/codex-primary-runtime/dependencies/node/bin/node' \
'/Users/Administrator/.codex/skills/公众号写作/scripts/push_wechat_draft.mjs' dry-run '/绝对路径/公众号_主题.html'

NODE_PATH='/Users/Administrator/.cache/codex-runtimes/codex-primary-runtime/dependencies/node/node_modules' \
'/Users/Administrator/.cache/codex-runtimes/codex-primary-runtime/dependencies/node/bin/node' \
'/Users/Administrator/.codex/skills/公众号写作/scripts/push_wechat_draft.mjs' push '/绝对路径/公众号_主题.html'
```

当前机器已验证过的成功信号：`doctor` 返回 `appid: wx85fcbd31d95031e4`、`draft_count`；`push` 返回草稿 `media_id` 才能说明已进入草稿箱。

推送前必须重新渲染 HTML，并完成以下转换：
- 读取 `#article-content` 或 `buildWechatArticleHtml()` 生成的富文本。
- 将正文内所有 `data:image/...`、本地图片或非微信图片上传为微信正文图片 URL，并替换原始 `src`。
- 将头图单独上传为封面素材，取得 `thumb_media_id`。
- 标题、作者、80-120 字摘要、正文和封面齐全后，调用草稿新增接口。
- 记录返回的 `media_id`；只有收到 `media_id` 才能报告“已进入草稿箱”。

授权未完成、IP 白名单未配置或账号缺少接口权限时，不得假装推送成功。保留已经验收通过的 HTML，明确告诉用户阻塞项，并运行本地安全配置页或给出后台具体配置位置。

### Gate 12：最终交付回执

交付时必须说明：HTML 保存路径、是否已打开预览、历史观点一致性校验结果、图片是否为 Canvas PNG、复制富文本是否已通过内联样式与空白页验收，并附 80-120 字公众号推送摘要。

如果任何 Gate 没跑通，必须明确告诉用户哪一项没通过、原因是什么、下一步怎么补。已完成授权时，回执还必须包含草稿标题、上传图片数量和微信返回的草稿 `media_id`。

---

## 工作流程

### 第零步：可执行入口

本 skill 已配套执行脚本：

```bash
NODE_PATH=/Users/Administrator/.cache/codex-runtimes/codex-primary-runtime/dependencies/node/node_modules \
/Users/Administrator/.cache/codex-runtimes/codex-primary-runtime/dependencies/node/bin/node \
/Users/Administrator/.codex/skills/公众号写作/scripts/generate_wechat_article.mjs \
/Users/Administrator/Desktop/skill-platform/outputs/wechat-skill-run
```

执行后会生成完整 HTML，并在浏览器中用 Canvas 将头图、金句、信息框、流程图、步骤卡、CTA 和作者名片全部渲染为 PNG `<img>`。如果用户要求“跑一下这个公众号 skill”“验证绘图能不能跑出来”，优先运行该脚本，再用浏览器自动检查正文图片是否全部为 `data:image/png`。

草稿箱推送脚本：

```bash
NODE_PATH='/Users/Administrator/.cache/codex-runtimes/codex-primary-runtime/dependencies/node/node_modules' \
'/Users/Administrator/.cache/codex-runtimes/codex-primary-runtime/dependencies/node/bin/node' \
'/Users/Administrator/.codex/skills/公众号写作/scripts/push_wechat_draft.mjs' doctor

NODE_PATH='/Users/Administrator/.cache/codex-runtimes/codex-primary-runtime/dependencies/node/node_modules' \
'/Users/Administrator/.cache/codex-runtimes/codex-primary-runtime/dependencies/node/bin/node' \
'/Users/Administrator/.codex/skills/公众号写作/scripts/push_wechat_draft.mjs' dry-run "/绝对路径/公众号_主题.html"

NODE_PATH='/Users/Administrator/.cache/codex-runtimes/codex-primary-runtime/dependencies/node/node_modules' \
'/Users/Administrator/.cache/codex-runtimes/codex-primary-runtime/dependencies/node/bin/node' \
'/Users/Administrator/.codex/skills/公众号写作/scripts/push_wechat_draft.mjs' push "/绝对路径/公众号_主题.html"
```

首次接入依次运行 `setup` 和 `doctor`。`setup` 会打开 127.0.0.1 本机安全配置页：AppID 写入权限为 600 的本机配置，AppSecret 写入 macOS 钥匙串，不得要求用户在聊天中发送 AppSecret。`doctor` 用于检查 access_token、出口 IP 白名单和草稿箱接口权限。调试文章结构时先运行 `dry-run <HTML路径>`，它不上传素材、不创建草稿。若普通 shell 下 `doctor` 报“未找到 AppSecret”，必须改用上面的 Codex runtime 命令并提权重试；只有提权后仍失败，才判断为本机授权缺失。

### 前置步骤：历史公众号检索

凡是用户要求写新的公众号、改写成公众号、生成公众号HTML，都必须先做历史公众号检索：

1. 在当前工作区 `outputs/`、`/Users/Administrator/Desktop/端到端咨询事务管理/outputs/` 和用户提供的历史材料中查找相关文章。
2. 按主题关键词检索历史文章标题、正文小标题、金句和结尾判断。
3. 提炼作者稳定观点：核心判断、概念定义、方法框架、常用表达、风险边界、行动建议。
4. 将新稿主线与历史观点比对，判断是“延续”“补充”“升级”还是“冲突”。
5. 如有冲突，先向用户说明冲突点，再自动修正文稿；除非新证据足够强，否则优先保持作者观点稳定。
6. 如果没有找到历史公众号成稿，必须在交付中说明未完成历史观点校验，不能默认通过。

### 第一步：联网核查

收到用户素材后，立即执行：
1. 检索核心论点是否有事实依据（至少2个独立来源）
2. 验证用户提到的数据、案例是否准确
3. 查找是否与已有主流观点和作者历史观点存在明显冲突
4. 如有冲突或存疑，标注并在文章中客观呈现
5. 如无错误，采纳并适度扩写

### 第二步：文章撰写

**开头设计原则：**
- 从具体场景、反常现象、实验结果或真实困惑切入
- 前3段必须让读者产生"这说的就是我"的共鸣
- 禁用任何时代感套话
- 企业AI/流程管理/数字化选题优先使用"反虚开场"：先指出一个行业流行但空泛的说法，再用具体流程问题拉回现实

**主线收束铁律：**
- 写正文前必须先提炼一句"主线句"，格式为：`这篇文章真正要证明的是：……`。
- 主线句必须把真实场景、核心批判、方法论和结尾落点串成一条因果链，不能只是主题词。
- 每个 `h2` 小节的第一句狠判断，都必须回扣这条主线句；如果某节只能表达情绪、经验或旁支批判，必须删掉、合并或改写。
- 企业AI/流程/Agent文章尤其要避免"现场复盘 + 行业批判 + 方法清单"三段互相游离。必须建立一条清晰推进：真实场景 → 误区 → 本质定义 → 业务颗粒 → Agent/系统接口 → 风险边界 → 可执行动作。
- 成稿后必须做"主线检查"：读完所有 `h2` 标题，应该能复述一条连续逻辑；如果只是多个正确观点并列，不算合格。

**正文结构：**
```
现象切入（引发共鸣）
↓
问题归因（深度分析，含技术/机制层面）  
↓
用户洞察扩写（保留思考过程，适当补充论据）
↓
方法论呈现（具体可操作的步骤或框架）
↓
充分落脚（现实意义 + 能力迁移 + 方法建议）
```

如用户明确要求爆款、锋利、对标样本、模仿框架，改用"诊断判级型结构"：
```
立靶纠偏（指出一个假共识）
↓
自测分层（给第1步/第2步/第3步/第4步或红黄绿自测尺子）
↓
真变化（说明真正改变的3件事，每件配业务场景）
↓
真死穴（指出技术之外的组织/权力/流程阻力）
↓
上车前自检（3-5个问题，判断能不能做）
↓
人的新位置（角色、权限、指标或工作方式如何迁移）
↓
结尾金句（可转发，但必须带判断、选择或行动方向）
```

**语言风格：**
- 短句优先，长句拆开写，但禁止把每个短句都拆成独立段落；公众号正文要像正常文章，不像逐句直播稿
- 自然段以"一个完整意思"为单位，通常包含2-4个短句或1个较完整的复合句；如果连续3个以上段落都只有一句话，必须合并或重写
- 面向外部发布时，删除不必要的实现注解和开发者旁白；不要展示内部 endpoint、环境变量、Session key、token、PAT、API Key、KV key、typed @、schema、responseMode、evidence 等字段。需要表达时改写为“检查入口”“运行配置”“平台访问凭证”“结构校验”“回复方式”“判断证据”等业务可读说法
- 表达保持克制，不用“糊弄”“玄学”等情绪化词替代专业判断；可以写“主观判断”“不稳定”“不可回放”“召回过宽或过窄”等更准确的描述
- 重要观点单独成段
- 每300-500字设置一个视觉锚点（小标题/引用块/图片占位）
- 每篇提炼3-5句可单独转发的金句
- 可以用"不是A，而是B"完成概念纠偏，但不要把它当万能句式，更不要连续堆叠成排比；如果用户已反馈套路感，改用材料事实、业务现场和具体动作自然推进
- 每个新概念后面必须跟一个业务例子或操作边界，避免只停留在命名快感
- 诊断判级型文章中，每个主标题下第一段必须出现一句明确判断；判断要锋利，但后面必须接解释、例子或方法
- 写"卡点"时优先写真实业务现场：角色、节点、数据、动作、后果；少写泛泛的"认知不足、组织协同、数据孤岛"

### 强制分段标题规则（修复“一、二、三”丢失）

除非用户明确要求不加编号，公众号正文的主体部分必须使用中文大写序号作为可见小标题。

**硬性要求：**
- 摘要、作者行、开场白不计入编号；从第一个正文主段开始编号。
- 主体正文至少设置4个、通常5-8个 `<h2>` 主标题，每个标题必须以字面量中文序号开头：`一、`、`二、`、`三、`、`四、`、`五、`、`六、`、`七、`、`八、`。
- 不允许只依赖 CSS 计数器、列表样式或脚本渲染编号；编号必须真实写进标题文本里，复制到公众号后台后仍然可见。
- 如果模型生成的小标题没有中文序号，HTML 渲染层必须自动补上序号。
- 二级结构可以使用 `（一）`、`（二）`，但不能替代主标题的 `一、二、三`。
- 访谈稿、复盘稿、会议纪要稿也必须保留这一规则，可以写成：`一、这场交流先回答了一个前提问题`、`二、流程管理最适合先被 AI 改造`。

**正确示例：**
```html
<h2>一、真正的问题不是“要不要用 AI”，而是“先让谁少痛苦”</h2>
<h2>二、流程管理的第一批场景，不是画图，而是把经验封装成 Skill</h2>
<h2>三、审批流不能一上来就 AI 化，要先分清六种实现方式</h2>
```

**错误示例：**
```html
<h2>真正的问题不是要不要用 AI</h2>
<h2>流程管理的第一批场景</h2>
<ol><li>审批流的六种方式</li></ol>
```

### 访谈逐字稿整理模式

当用户提供会议逐字稿、访谈录音转写、口述交流记录，并要求“整理成公众号”“一问一答”“大佬采访”“前面 summary，下面逐字稿”时，启用本模式。

**内容处理：**
- 默认对外匿名化：隐去真实人名、群名、公司名、内部账号、会议标识和企业敏感信息；可写成“某上市公司团队”“一位业务负责人”“信息管理负责人”。
- 删除会后串音、家庭闲聊、重复试麦、无意义口癖和明显误识别内容。
- 不逐句机械保留原文。要保留观点、判断、案例和推进逻辑，把口语整理成“可发布的拟访谈实录”。
- 如涉及未公开客户、具体成交、自动化通过率等敏感表达，改写为“某大型平台项目”“一个真实实践”“较高比例”等稳妥表述。
- 正式对外稿必须删除闲聊型工具信息：个人每月花费、token、账号、电脑配置、具体工具选型争论、PPT/网页偏好闲聊、助理裁撤、一人公司等与文章主题无关且容易显得不正式的内容。
- 涉及内部技术机制、专有方法或敏感实现细节时，不直接写“影子模式”“影子链路”“幽灵模式”等高识别度表达；公开稿统一改写为“后台并行校验机制”“并行观察机制”或“先后台校验、再逐步放开低风险自动化”。
- 不强调“免费”“友情”“帮忙”等关系表达；对外统一写成“一次企业 AI 与流程管理的交流探讨”。

**固定结构：**
```text
标题
作者行
开场说明：今天和一家企业团队做了一小时交流，深度还不够，但问题足够典型。
Summary：用5-8条概括这场交流的核心判断。
一、访谈开场：这次交流到底围绕什么问题
二、流程管理：AI 最先能替流程团队解决什么
三、审批流：为什么不能一上来就让 AI 自动批
四、插件、侧边栏、Agent：不同方案分别适合谁
五、推广 AI：别先喊口号，先让员工用好工具
六、结尾：这件事真正考验的是组织把经验封装成能力
文末名片
```

**问答呈现：**
- 每个主标题下面使用少量“问：”承接问题，用较长“答：”展开观点。
- 问可以由编辑根据上下文归纳，不要求逐字来自参会者。
- 答要像深度采访，不像会议纪要；要有判断、层次、案例、边界。
- “Summary”可以不编号，但后面的正文主段必须继续使用 `一、二、三...`。

### 第三步：配图与背景元素（全部Canvas渲染PNG，禁止占位符）

**核心原则：凡是正文复制区里有背景色、渐变色、圆角色块的元素，一律转为Canvas PNG图片。信息图可以先用SVG/Canvas绘制，但最终必须转成PNG并放进`<img>`标签。正文复制区不依赖CSS背景呈现关键信息。**

#### 为什么必须用Canvas转PNG？

**失败方案对比：**
- ❌ CSS样式图（渐变背景+伪元素）：复制时CSS丢失，图片消失
- ❌ SVG直接内嵌 `<svg>`：公众号编辑器不支持，复制后丢失
- ❌ SVG Base64 `data:image/svg+xml;base64`：公众号过滤SVG格式
- ❌ CSS `background`、`linear-gradient`：复制后全部失效，色块变白
- ✅ **Canvas转PNG `data:image/png;base64`**：公众号完全支持，复制正常

#### ⚠️ 必须转PNG的元素类型（缺一不可）

以下元素**全部禁止用CSS背景**，必须替换为`<img>`标签 + Canvas渲染PNG：

| 元素类型 | 典型类名 | 转PNG方式 |
|---------|---------|---------|
| 金句/引用块 | `.gold-sentence` | Canvas直绘 |
| 信息高亮框 | `.highlight-box` | Canvas直绘 |
| 链接资源框 | `.link-box` | Canvas直绘 |
| 步骤卡片 | `.step-item` | Canvas直绘 |
| CTA行动号召框 | `.cta-box` | Canvas直绘 |
| 作者简介框 | `.author-bio` | Canvas直绘 |
| 复杂信息图 | `.chart-*` | SVG→PNG |
| 头图/封面 | `#header-img` | SVG→PNG |

#### 高清渲染：DPR=3（必须执行）

**所有Canvas输出必须3倍物理像素，确保高清不模糊：**

```javascript
const DPR = 3;

// Canvas直绘PNG工具函数（用于背景色块）
function canvasToPng(drawFn, elId, W, H) {
  const c = document.createElement('canvas');
  c.width = W * DPR;
  c.height = H * DPR;
  const ctx = c.getContext('2d');
  ctx.scale(DPR, DPR);
  drawFn(ctx, W, H);
  document.getElementById(elId).src = c.toDataURL('image/png', 1.0);
}

// SVG转PNG工具函数（用于复杂信息图）
function svgToPng(svgStr, elId, W, H) {
  // SVG物理尺寸放大DPR倍，保留viewBox维持内容比例
  const scaled = svgStr
    .replace(/width="(\d+)"/, (_, n) => `width="${n * DPR}"`)
    .replace(/height="(\d+)"/, (_, n) => `height="${n * DPR}"`)
    .replace('<svg ', `<svg viewBox="0 0 ${W} ${H}" `);
  const blob = new Blob([scaled], {type: 'image/svg+xml;charset=utf-8'});
  const url = URL.createObjectURL(blob);
  const img = new Image();
  img.onload = function() {
    const c = document.createElement('canvas');
    c.width = W * DPR; c.height = H * DPR;
    const ctx = c.getContext('2d');
    ctx.drawImage(img, 0, 0);
    URL.revokeObjectURL(url);
    document.getElementById(elId).src = c.toDataURL('image/png', 1.0);
  };
  img.src = url;
}

// 圆角矩形工具
function roundRect(ctx, x, y, w, h, r) {
  ctx.beginPath();
  ctx.moveTo(x + r, y);
  ctx.lineTo(x + w - r, y);
  ctx.quadraticCurveTo(x + w, y, x + w, y + r);
  ctx.lineTo(x + w, y + h - r);
  ctx.quadraticCurveTo(x + w, y + h, x + w - r, y + h);
  ctx.lineTo(x + r, y + h);
  ctx.quadraticCurveTo(x, y + h, x, y + h - r);
  ctx.lineTo(x, y + r);
  ctx.quadraticCurveTo(x, y, x + r, y);
  ctx.closePath();
}
```

#### 常用背景块绘制函数模板

```javascript
// 金句块（黄色渐变）
function drawGold(ctx, W, H, lines) {
  const g = ctx.createLinearGradient(0, 0, W, H);
  g.addColorStop(0, '#fffbe6'); g.addColorStop(1, '#fff7cc');
  ctx.fillStyle = g; roundRect(ctx, 0, 0, W, H, 12); ctx.fill();
  ctx.strokeStyle = '#ffd666'; ctx.lineWidth = 1.5;
  roundRect(ctx, 0, 0, W, H, 12); ctx.stroke();
  ctx.fillStyle = '#ad6800'; ctx.font = 'bold 16px PingFang SC,Microsoft YaHei,sans-serif';
  ctx.textAlign = 'center';
  lines.forEach((line, i) => ctx.fillText(line, W/2, H/2 - (lines.length-1)*12 + i*28));
}

// 蓝色信息框（highlight-box 替代）
function drawBlueBox(ctx, W, H, lines) {
  const g = ctx.createLinearGradient(0, 0, W, H);
  g.addColorStop(0, '#f0f5ff'); g.addColorStop(1, '#e6f7ff');
  ctx.fillStyle = g; roundRect(ctx, 0, 0, W, H, 12); ctx.fill();
  ctx.strokeStyle = '#91d5ff'; ctx.lineWidth = 1.5;
  roundRect(ctx, 0, 0, W, H, 12); ctx.stroke();
  ctx.fillStyle = '#333'; ctx.font = '15px PingFang SC,Microsoft YaHei,sans-serif';
  ctx.textAlign = 'left';
  lines.forEach((line, i) => ctx.fillText(line, 24, 32 + i * 28));
}

// 步骤卡片（灰底）
function drawStepCard(ctx, W, H, num, title, desc) {
  ctx.fillStyle = '#f8f9fa'; roundRect(ctx, 0, 0, W, H, 12); ctx.fill();
  ctx.strokeStyle = '#e8e8e8'; ctx.lineWidth = 1;
  roundRect(ctx, 0, 0, W, H, 12); ctx.stroke();
  // 数字徽章
  ctx.fillStyle = '#1890ff';
  ctx.beginPath(); ctx.arc(36, 36, 18, 0, Math.PI*2); ctx.fill();
  ctx.fillStyle = '#fff'; ctx.font = 'bold 16px sans-serif';
  ctx.textAlign = 'center'; ctx.fillText(num, 36, 42);
  // 标题与描述
  ctx.fillStyle = '#1a1a1a'; ctx.font = 'bold 16px PingFang SC,Microsoft YaHei,sans-serif';
  ctx.textAlign = 'left'; ctx.fillText(title, 66, 30);
  ctx.fillStyle = '#666'; ctx.font = '14px PingFang SC,Microsoft YaHei,sans-serif';
  ctx.fillText(desc, 66, 52);
}
```

#### HTML中预留`<img>`容器（全部替换背景元素）

```html
<!-- 金句块（替代 CSS gold-sentence） -->
<img id="gold-1" style="width:100%;display:block;margin:20px 0;" alt="金句"/>

<!-- 信息高亮框（替代 CSS highlight-box） -->
<img id="box-info" style="width:100%;display:block;margin:20px 0;" alt="信息框"/>

<!-- 步骤卡片（替代 CSS step-item） -->
<img id="step-1" style="width:100%;display:block;margin:12px 0;" alt="步骤1"/>
<img id="step-2" style="width:100%;display:block;margin:12px 0;" alt="步骤2"/>

<!-- CTA框（替代 CSS cta-box） -->
<img id="cta-img" style="width:100%;display:block;margin:30px 0;" alt="行动号召"/>

<!-- 复杂信息图 -->
<div class="infographic">
  <img id="chart1" style="width:100%;display:block;" alt="配图"/>
  <p class="image-caption">图1：说明文字</p>
</div>
```

#### 页面加载统一执行

```javascript
window.addEventListener('DOMContentLoaded', function () {
  // SVG信息图
  makeHeader(); makeChart1(); makeChart2();
  // Canvas直绘背景块
  canvasToPng((ctx, W, H) => drawGold(ctx, W, H, ['这是金句内容']), 'gold-1', 660, 80);
  canvasToPng((ctx, W, H) => drawBlueBox(ctx, W, H, ['第一行', '第二行']), 'box-info', 660, 100);
  canvasToPng((ctx, W, H) => drawStepCard(ctx, W, H, '1', '步骤标题', '步骤描述'), 'step-1', 660, 80);
  // CTA、作者简介等同理
});
```

#### SVG绘制避坑指南

**必须避免（会导致Canvas渲染失败）：**
- `<defs>` + `<marker>` 箭头定义 → 改用 `<polygon>` 画箭头
- `<use>` 元素引用 → 直接写完整图形
- 外部CSS样式 → 全部用内联属性
- 特殊滤镜/渐变引用 → 简化或避免

**推荐替代方案：**
| 原方案 | 替代方案 |
|-------|---------|
| `<marker>` 箭头 | `<polygon points="x,y x,y x,y"/>` |
| `<use xlink:href>` | 直接复制图形代码 |
| CSS伪元素装饰 | 直接用`<circle>`/`<rect>`画 |
| 复杂渐变定义 | 纯色或简化线性渐变 |

#### 配图类型与实现

| 内容类型 | 推荐图形 | 关键元素 |
|--------|--------|---------|
| 头图/封面 | 渐变背景+文字 | `<rect>`+`<linearGradient>`+`<text>` |
| 数据对比 | 散点图 | `<circle>` + 坐标标注 |
| 流程步骤 | 横向节点流程 | `<rect>` + `<line>` + `<polygon>`箭头 |
| 层级关系 | 梯形金字塔 | 渐变 `<rect>`，宽度递减 |
| 左右对比 | 双栏对照 | 两列 `<rect>` + 内容文字 |
| 循环机制 | 带回路流程 | 节点 + `<path>` 弧形 + `<polygon>`箭头 |

**SVG内容规范：**
- 必须声明 `xmlns="http://www.w3.org/2000/svg"`
- 必须指定 `width` 和 `height` 属性（供Canvas使用）
- 宽度固定 `660`，高度 `220-340`
- 配色：蓝紫渐变系（`#667eea`/`#764ba2`/`#1890ff`）
- 背景色 `#fafafa`，圆角 `rx="12"`
- 顶部标题：`font-size="14" font-weight="bold" fill="#333"`
- 文字全部用中文，标签简洁

### Canvas 信息图文字排版铁律（防遮挡、防碎片换行）

公众号信息图最常见的失败不是颜色，而是文字被挤爆、遮挡、或被拆成两三个字一行。生成 Canvas 图时必须遵守：

- **禁止碎片化换行**：中文说明文字不得被挤成 `2-4` 个字一行，例如"它读取什么业 / 务事实？"这类断行禁止交付。除短标签外，每行建议不少于 `7` 个中文字符。
- **禁止长句硬塞小卡片**：如果卡片宽度不足以自然容纳一句话，不要缩小到难读，也不要强行换行；必须改成宽行清单、上下结构、双栏大卡、或减少卡片数量。
- **优先使用宽行单句**：涉及"输入、触发、动作、输出、控制"这类接口说明时，优先画成纵向宽行清单；左侧短标签，右侧一句完整问题，避免横向 5 小卡挤压中文。
- **先测宽再绘制**：Canvas `fillText` 前必须用 `ctx.measureText()` 或等价函数确认文本不会超出容器；超出时重新设计布局，而不是让文字溢出。
- **标题与图形分区**：头图、大图标题和节点/箭头必须有明确安全区，禁止流程节点、线条或装饰网格穿过标题主体文字。
- **交付前必须看截图**：不能只依赖自动指标。必须打开或截图检查头图、金句图、信息框、流程图、步骤卡、作者名片，确认没有遮挡、溢出、碎片换行和文字贴边。
- **必须逐图检查，不许抽查**：交付前必须生成所有正文图片的总览图或逐图截图，逐张检查头图、金句、信息框、流程图、步骤卡、CTA、作者名片。尤其检查连接线、箭头、节点、装饰线是否穿过标题或正文文字；发现任何穿字、压字、贴边、遮挡，必须重画结构。
- **发现任一图文字不自然，必须重画图形结构**：不要只把字号调小。优先改变布局，让文字像正常中文段落一样阅读。

### 第四步：HTML排版输出

必须输出完整HTML文件，包含：
- 移动端适配样式
- **头图必须是`<img>`标签**（不要用CSS渐变背景，复制会丢失）
- **头图必须在`article-content`内部**（否则复制时头图不会被包含）
- **所有正文图片必须写入 `width="660"` 与内联样式**：`style="width:100%;max-width:660px;height:auto;display:block;..."`，不能只依赖 class 样式。Canvas DPR=3 会生成 1980px 宽的高清图，如果复制到公众号后台后 class 样式丢失，图片会按真实宽度显示，导致图片被裁切或左侧像被切掉。
- 文章主体（`id="article-content"`）
- `.infographic` 样式：`margin: 32px 0; img { width:100%; border-radius:12px; display:block; }`
- 右下角固定"一键复制全文"按钮
- 复制成功Toast提示
- **所有图片通过Canvas渲染为PNG后赋值给`<img>`标签**
- **复制按钮必须复制“可直接粘贴到公众号编辑器的富文本”，不能只复制依赖页面 CSS 的 HTML 片段。复制前必须把正文区所有关键排版写成内联 `style`，并移除对 `class` 的样式依赖。**
- **复制结果必须在“无原页面 CSS 的空白页面/编辑器环境”中仍保留标题字号、段落行距、图片宽度、金句图、信息图、作者名片和说明文字样式。只验证本地预览好看不算通过。**

**HTML结构规范（必须严格遵守）：**
```html
<body>
<div id="article-content">
  <!-- 头图必须在article-content内部 -->
  <img id="header-img" class="header-img" width="660" style="width:100%;max-width:660px;height:auto;display:block;margin:0 0 20px;border:0;border-radius:0;" alt="头图"/>
  
  <p class="author-info">詹老师 · AI产品专家 / 流程管理专家</p>
  
  <!-- 正文内容 -->
  
  <!-- 配图 -->
  <div class="infographic">
    <img id="chart1" width="660" style="width:100%;max-width:660px;height:auto;display:block;margin:0;border:0;border-radius:0;" alt="配图"/>
    <p class="image-caption">图1：说明</p>
  </div>
  
</div><!-- end article-content -->

<button class="copy-btn" onclick="copyArticle()">一键复制</button>
</body>
```

### 第五步：保存并自动打开预览

文章生成后必须立即执行：
1. 保存至 `D:\公众号_[主题简称].html`
2. 执行 `Start-Process "D:\公众号_[主题简称].html"` 直接用浏览器打开
3. **无需用户确认，交付即可见**

**跨平台执行补充**：
- 如果当前运行环境不是 Windows，或不存在 `D:\`，则保存到当前工作区的 `outputs/公众号_[主题简称].html`。
- 在 macOS 上使用 `open "outputs/公众号_[主题简称].html"` 打开预览；在 Linux 上优先使用可用浏览器或报告本地文件路径。
- 路径兼容只是运行环境适配，不改变文章内容、名片内容和HTML结构要求。

### 第六步：推送到公众号草稿箱

当本机授权和接口权限检查已通过，预览与富文本验收完成后，默认继续执行草稿推送脚本。推送器会在浏览器环境中等待所有 Canvas 图片完成渲染，再上传正文图片、上传封面、替换图片地址并创建草稿。

安全边界：
- 只允许调用草稿新增接口，禁止自动调用发表、群发或删除接口。
- AppSecret、access_token 不得打印到日志、写入文章、写入 Skill 或出现在交付回执中。
- 如果用户明确说“只预览”“先别推草稿”，本轮停止在预览与复制验收。
- 已经创建草稿后如需再次推送，先提醒会生成新的草稿副本；除非用户明确要求更新已有草稿。

---

## ⚠️ 公众号排版铁律：禁止使用 flex 布局

**根本原因**：`display: flex` 是纯 CSS 布局属性，复制粘贴到公众号编辑器后，所有 CSS 样式丢失，flex 容器内的子元素会各自独立成行，导致数字编号与正文内容分离、标点丢失、排版完全错乱。

**强制规则**：
- ❌ 禁止在任何列表、步骤、卡片等内容区使用 `display: flex` 或 `display: grid`
- ❌ 禁止用 `<div>` 嵌套实现横向/纵向对齐
- ❌ 禁止在图片 `<img>` 前后额外插入空 `<p>`、`<br>`、只含空格/全角空格的段落；公众号粘贴后会把空段落叠加成两行以上空白。
- ❌ 禁止复制 HTML 中图片统一使用 `margin:22px 0`、`margin:30px 0` 这类大上下间距；发布到公众号后图片和文字之间会显得多出两行。
- ✅ 数字编号用 `<span>` 内联嵌入同一个 `<p>` 段落中，`display: inline-block`
- ✅ 卡片/高亮区用 `<p>` + `padding` + `border-left` 实现，不用 flex 子项
- ✅ 正文图片进入公众号复制区时，默认使用紧凑图片间距：`margin:10px 0 12px`；头图可以 `margin:0 0 16px`，作者名片可以 `margin:18px 0 0`。如果图片上下紧邻小标题或 CTA，可在具体元素上单独调到 `14px`，不得默认拉到 22px 以上。
- ✅ `buildWechatArticleHtml()` 克隆正文后必须删除空段落和空换行，再注入内联样式，避免公众号后台把图片前后的空节点显示为空行。
- ✅ 所有内容结构必须在"CSS全部失效"的假设下，仍能正常阅读

**正确示例（步骤列表）**：
```html
<p><span style="display:inline-block;width:24px;height:24px;background:#1890ff;color:#fff;border-radius:50%;text-align:center;line-height:24px;font-size:13px;font-weight:bold;margin-right:10px;vertical-align:middle;">1</span>步骤内容文字直接跟在 span 后面</p>
```

---

## ⚠️ 公众号复制铁律：复制的是富文本，不是页面预览

**根本原因**：浏览器本地预览会加载 `<style>` 里的 CSS，但公众号编辑器粘贴时通常只接收剪贴板里的 HTML 片段。若复制结果只包含 `class="author-info"`、`class="canvas-block"` 等 class 名，编辑器拿不到对应 CSS，格式就会丢失。

**强制规则**：
- ❌ 禁止 `copyArticle()` 直接 `range.selectNode(article-content)` 复制原始正文节点。
- ❌ 禁止复制只依赖 `<style>` / class / 外层页面 CSS 的正文 HTML。
- ✅ `copyArticle()` 必须先生成一个专门用于公众号粘贴的 HTML：`buildWechatArticleHtml()`。
- ✅ 复制 HTML 必须把 `h1`、`h2`、`p`、`strong`、`a`、`img`、图注、信息框、名片图等关键样式全部写成内联 `style`。
- ✅ 复制 HTML 中正文元素可以没有 `class`、没有 `id`；不能依赖 class 才能呈现格式。
- ✅ `ClipboardItem` 写入 `text/html`；兜底路径也必须复制已经内联好的富文本，不得回退到选中原页面节点。
- ✅ 复制成功提示应明确为“已复制公众号富文本”。

**最低可用复制函数结构**：
```html
<script>
function mergeStyle(node, styleText) {
  const existing = node.getAttribute('style') || '';
  node.setAttribute('style', existing ? existing + ';' + styleText : styleText);
}

function buildWechatArticleHtml() {
  const source = document.getElementById('article-content');
  const clone = source.cloneNode(true);
  mergeStyle(clone, "max-width:677px;margin:0 auto;font-family:-apple-system,BlinkMacSystemFont,'PingFang SC','Helvetica Neue','Microsoft YaHei',sans-serif;font-size:15px;line-height:1.86;color:#263041;background:#ffffff;");

  clone.querySelectorAll('*').forEach(node => {
    node.removeAttribute('id');
    node.removeAttribute('class');
  });

  clone.querySelectorAll('p').forEach(node => {
    if (!node.textContent.trim() && !node.querySelector('img')) node.remove();
  });
  clone.querySelectorAll('br').forEach(node => node.remove());

  clone.querySelectorAll('h1').forEach(node => mergeStyle(node, 'font-size:24px;line-height:1.35;font-weight:850;color:#111827;margin:24px 0 12px;padding:0;'));
  clone.querySelectorAll('h2').forEach(node => mergeStyle(node, 'font-size:18px;line-height:1.45;font-weight:850;color:#111827;margin:34px 0 14px;padding-left:12px;border-left:4px solid #2563eb;'));
  clone.querySelectorAll('p').forEach(node => mergeStyle(node, 'font-size:15px;line-height:1.86;color:#263041;margin:0 0 16px;padding:0;'));
  clone.querySelectorAll('strong').forEach(node => mergeStyle(node, 'font-weight:850;color:#0f172a;'));
  clone.querySelectorAll('a').forEach(node => mergeStyle(node, 'color:#2563eb;text-decoration:none;border-bottom:1px solid #bfdbfe;'));
  clone.querySelectorAll('img').forEach(node => mergeStyle(node, 'width:100%;max-width:100%;height:auto;display:block;border:0;margin:10px 0 12px;'));

  return `<section style="max-width:677px;margin:0 auto;font-family:-apple-system,BlinkMacSystemFont,'PingFang SC','Helvetica Neue','Microsoft YaHei',sans-serif;font-size:15px;line-height:1.86;color:#263041;background:#ffffff;">${clone.innerHTML}</section>`;
}

async function copyArticle() {
  const html = buildWechatArticleHtml();
  const text = document.getElementById('article-content').innerText;
  if (navigator.clipboard && window.ClipboardItem) {
    await navigator.clipboard.write([new ClipboardItem({
      'text/html': new Blob([html], { type: 'text/html' }),
      'text/plain': new Blob([text], { type: 'text/plain' })
    })]);
  } else {
    const holder = document.createElement('div');
    holder.contentEditable = 'true';
    holder.style.position = 'fixed';
    holder.style.left = '-9999px';
    holder.innerHTML = html;
    document.body.appendChild(holder);
    const range = document.createRange();
    range.selectNodeContents(holder);
    const selection = window.getSelection();
    selection.removeAllRanges();
    selection.addRange(range);
    document.execCommand('copy');
    selection.removeAllRanges();
    holder.remove();
  }
}
</script>
```

**强制验收**：交付前必须用浏览器自动执行：
1. 打开生成的 HTML，等待所有正文图片 `src` 都变成 `data:image/png`。
2. 调用 `buildWechatArticleHtml()`，检查复制结果：
   - `style=` 数量大于 50；
   - 正文复制结果中不再依赖 `class=` / `id=`；
   - 至少一张图片为 `src="data:image/png...`；
   - `h1`、`p`、`img` 都有内联样式。
3. 把 `buildWechatArticleHtml()` 的结果放到一个完全空白页面里渲染，检查标题字号、段落行距和图片宽度仍然正常。

---

## HTML模板规范

### 必须包含的CSS

下面CSS用于页面预览、按钮和基础排版。生成正文时，不要把 `.highlight-box`、`.cta-box`、`.author-bio`、`.image-placeholder` 等带背景的块直接放进 `article-content`；这些视觉块必须改为Canvas PNG `<img>`。

```css
* { box-sizing: border-box; margin: 0; padding: 0; }
body {
  font-family: -apple-system, BlinkMacSystemFont, "PingFang SC", "Helvetica Neue", sans-serif;
  font-size: 15px;
  line-height: 1.8;
  color: #333;
  background: #fff;
  max-width: 677px;
  margin: 0 auto;
  padding: 20px;
}
h1 { font-size: 22px; font-weight: bold; color: #1a1a1a; margin: 30px 0 15px; }
h2 { font-size: 18px; font-weight: bold; color: #1a1a1a; 
     border-left: 4px solid #1890ff; padding-left: 12px; margin: 30px 0 15px; }
h3 { font-size: 16px; font-weight: bold; color: #333; margin: 20px 0 10px; }
p { margin-bottom: 16px; }
strong { color: #1a1a1a; }
.quote {
  background: #f0f8ff;
  border-left: 4px solid #1890ff;
  padding: 16px 20px;
  margin: 20px 0;
  font-style: italic;
  color: #555;
  border-radius: 0 8px 8px 0;
}
.highlight-box {
  background: linear-gradient(135deg, #f0f5ff 0%, #e6f7ff 100%);
  border: 1px solid #91d5ff;
  padding: 16px 20px;
  border-radius: 8px;
  margin: 20px 0;
}
.key-insight {
  background: linear-gradient(120deg, #ffeaa7 0%, #fdcb6e 100%);
  padding: 3px 8px;
  border-radius: 4px;
  font-weight: bold;
}
table { width: 100%; border-collapse: collapse; margin: 20px 0; }
th { background: #fafafa; font-weight: bold; text-align: left; }
td, th { padding: 12px; border: 1px solid #e8e8e8; font-size: 14px; }
tr:hover { background: #fafafa; }
.image-container { margin: 30px 0; text-align: center; }
.image-placeholder {
  background: linear-gradient(135deg, #667eea20 0%, #764ba220 100%);
  border: 2px dashed #667eea;
  border-radius: 12px;
  padding: 40px 20px;
  color: #667eea;
}
.placeholder-icon { font-size: 48px; margin-bottom: 12px; }
.placeholder-title { font-size: 16px; font-weight: bold; margin-bottom: 8px; }
.placeholder-desc { font-size: 13px; line-height: 1.8; color: #888; }
.image-caption { font-size: 13px; color: #999; margin-top: 10px; font-style: italic; }
.author-info { color: #999; font-size: 13px; margin-bottom: 24px; }
.divider { 
  text-align: center; color: #ccc; font-size: 20px; 
  letter-spacing: 8px; margin: 30px 0; 
}
.cta-box {
  background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
  color: #fff;
  padding: 24px;
  border-radius: 12px;
  margin: 30px 0;
  text-align: center;
}
.cta-box p { color: #fff; margin: 0; }
.author-bio {
  background: #fafafa;
  border-radius: 12px;
  padding: 20px;
  margin: 30px 0;
  font-size: 14px;
  color: #555;
}
.copy-btn {
  position: fixed;
  bottom: 30px;
  right: 30px;
  background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
  color: #fff;
  border: none;
  padding: 14px 24px;
  border-radius: 50px;
  font-size: 15px;
  cursor: pointer;
  box-shadow: 0 4px 20px rgba(102,126,234,0.4);
  z-index: 999;
  transition: all 0.3s;
}
.copy-btn:hover { transform: translateY(-2px); box-shadow: 0 6px 25px rgba(102,126,234,0.5); }
.toast {
  position: fixed;
  bottom: 90px;
  right: 30px;
  background: #52c41a;
  color: #fff;
  padding: 10px 20px;
  border-radius: 8px;
  font-size: 14px;
  opacity: 0;
  transition: opacity 0.3s;
  z-index: 1000;
}
.toast.show { opacity: 1; }
@media (max-width: 677px) {
  body { padding: 16px; }
  .copy-btn { bottom: 20px; right: 20px; padding: 12px 20px; font-size: 14px; }
}
```

### 必须包含的JS

复制逻辑必须与“公众号复制铁律”一致：先运行 `buildWechatArticleHtml()` 生成内联样式富文本，再写入剪贴板。禁止用 `range.selectNode(article-content)` 直接复制原页面节点。

```javascript
function showCopyToast(message) {
  const toast = document.getElementById('toast');
  if (!toast) return;
  toast.textContent = message;
  toast.classList.add('show');
  setTimeout(() => toast.classList.remove('show'), 2500);
}

async function copyArticle() {
  const html = buildWechatArticleHtml();
  const text = document.getElementById('article-content').innerText;
  try {
    if (navigator.clipboard && window.ClipboardItem) {
      await navigator.clipboard.write([new ClipboardItem({
        'text/html': new Blob([html], { type: 'text/html' }),
        'text/plain': new Blob([text], { type: 'text/plain' })
      })]);
    } else {
      const holder = document.createElement('div');
      holder.contentEditable = 'true';
      holder.style.position = 'fixed';
      holder.style.left = '-9999px';
      holder.innerHTML = html;
      document.body.appendChild(holder);
      const range = document.createRange();
      range.selectNodeContents(holder);
      const sel = window.getSelection();
      sel.removeAllRanges();
      sel.addRange(range);
      document.execCommand('copy');
      sel.removeAllRanges();
      holder.remove();
    }
    showCopyToast('已复制公众号富文本');
  } catch (e) {
    showCopyToast('复制失败，请检查浏览器权限');
  }
}
```

---

## 交付规范

完成后输出：
1. **完整HTML文件**：保存至 `D:\公众号_[主题简称].html`
2. **自动打开预览**：执行 `Start-Process "D:\公众号_[主题简称].html"`，用浏览器直接打开，无需启动服务
3. **复制说明**：点击右下角"📋 一键复制全文"，直接粘贴到公众号编辑器
4. **配图说明**：文中所有图形均已由Canvas渲染为PNG图片，无需替换任何图片
5. **历史观点一致性说明**：说明已参考哪些历史公众号/历史成稿；如发现冲突，说明已如何修正；如未找到历史文章，说明本次未完全完成历史观点校验
6. **文章摘要**：必须同时输出一段约100字的文章摘要，用于公众号推送预览
7. **草稿箱回执**：授权已完成时，说明草稿已创建但未群发，并给出标题、图片数量和微信返回的 `media_id`；授权或权限未完成时，准确说明卡在哪一步

如果当前环境没有 `D:\`，交付时说明实际保存路径，但仍需完成自动打开预览。

### 文章摘要规范（约100字）

每篇文章交付时，必须附带一段约100字的摘要，供公众号推送预览使用。

**摘要要求：**
- 字数：80-120字
- 风格：口语化、有吸引力，让人看完想点进去
- 结构：先抛出问题/现象 → 点明原因 → 给出结论/态度
- 禁止套话，禁止"本文将为你介绍……"等模板句

---

## 质量检查

交付前按 Harness 自查：
- [ ] Gate 0 素材与意图识别：已判断文章类型、用户偏好、转化目标和对外隐私边界
- [ ] Gate 1 历史观点校验：已检索历史公众号，提炼稳定观点，并判断新稿是延续、补充、升级还是冲突；如未找到历史文章，已在交付中说明
- [ ] Gate 2 证据核查：材料日期、发布方、标题、核心数据和结论边界已核对
- [ ] Gate 3 主线校验：已写出 `这篇文章真正要证明的是：……`，标题、开头、正文和结尾都服务这句话
- [ ] Gate 4 连贯性检查：只读所有 `h2` 标题也能复述一条连续逻辑，失败小节已删除、合并或改写
- [ ] Gate 5 语言检查：已去掉套路化开头、黑话和机器腔，保留用户认可的表达方式
- [ ] Gate 6 去重去赘与专业度检查：已删除重复观点、重复表达、空转段落、弱判断和多余句子；全文具备万阅读潜力但不夸大事实
- [ ] Gate 7 业务颗粒检查：抽象概念后已落到角色、节点、数据、动作、后果
- [ ] Gate 8 收尾检查：已按文章类型选择材料洞察、自检问题、组织变化、自然CTA或判断金句，不机械套“明天就做X”
- [ ] Gate 9 视觉检查：头图、金句、信息框、流程图、步骤卡、CTA、作者名片均为 Canvas PNG，且逐图检查通过
- [ ] Gate 10 富文本复制检查：`buildWechatArticleHtml()` 生成内联样式 HTML，并通过空白页渲染验收
- [ ] Gate 11 草稿箱推送：正文图片已换成微信 URL、封面已取得 `thumb_media_id`，草稿新增接口返回 `media_id`；若用户明确只预览则记录跳过原因
- [ ] Gate 12 交付回执：保存路径、预览状态、历史观点一致性校验结果、Canvas PNG、复制验收、推送摘要和草稿箱状态都已说明
- [ ] 开头无任何套话或时代感表述
- [ ] 全文无排比句结构
- [ ] 对外发布意图隔离：全文没有“这篇文章不是/写给/为了严谨/避免挑战/参考口径/不替代文档”等作者后台话、免责声明式自证或写作策略暴露
- [ ] 核心论点经过联网验证
- [ ] 已提炼主线句，且所有 `h2` 标题能串成一条连续逻辑，不是多个观点并列
- [ ] 如使用爆款/锋利/对标框架，前300字已完成立靶纠偏，说明"谁错把什么当成了什么"
- [ ] 如使用诊断判级型结构，已提供"第1步/第2步/第3步/第4步"、红黄绿或等价自测尺子；除非用户明确要求，未使用L0-L4等黑话
- [ ] Agent/企业AI文章已避免"工作单位""可委派任务"等抽象说法，优先使用"AI从答问题变成接任务""AI接走一段活""AI在流程旁边还是流程里面"等读者可直接转述的表达
- [ ] 标题和开头未使用"别再XX了"等套路句式；材料解读类文章已优先交代具体日期、发布方、材料名称和核心变化
- [ ] 结尾收束方式与文章气质匹配，没有机械套用"明天就做X"或固定三步行动清单；需要行动建议时，也要自然嵌入文章主线
- [ ] 每个主体小节都有一句明确判断，可单独截图传播
- [ ] 抽象概念后面都有具体业务场景：角色、节点、数据、动作、后果至少覆盖三项
- [ ] 没有未经验证的精确比例、市场份额、企业占比或伪数据
- [ ] 批判段落后有替代路径、自检问题或下一步动作
- [ ] 落脚点超过200字，回到主线，至少覆盖现实意义、能力迁移路径、具体方法论建议中的两项
- [ ] 去重去赘：全文没有同义反复、重复案例、重复金句、空转过渡句和不推进主线的多余段落
- [ ] 专业度：每个核心判断都有证据、业务场景、机制解释或方法承接，避免情绪化判断和伪专业包装
- [ ] 万阅读潜力：前300字有明确钩子，中段有可转述框架/自测尺子/业务闭环案例，结尾有自然关注、转发或加微信动作
- [ ] 段落节奏：正文段不超过5行
- [ ] 段落节奏：没有"短句频繁换行"；除金句、示例、代码项、强判断外，不出现连续3个以上单句短段落
- [ ] 配图：每300-500字至少一张真实信息图，最终必须为 Canvas PNG `<img>`，无任何占位符
- [ ] **所有带背景色/渐变的元素（金句块、信息框、步骤卡片、CTA框、作者简介）全部转为Canvas PNG `<img>`标签，无任何CSS背景**
- [ ] **Canvas 信息图文字无遮挡、无溢出、无碎片化换行；除短标签外，不出现 2-4 个字被强行拆成一行的中文说明**
- [ ] **头图标题与节点/箭头/装饰图形有明确安全区，截图检查无任何覆盖**
- [ ] **已逐图截图或生成图片总览图，并人工检查所有图片；连接线、箭头、节点、装饰线不得穿过任何文字**
- [ ] **DPR=3高清渲染：所有Canvas宽高乘以3，ctx.scale(3,3)，输出1px=3物理像素**
- [ ] **头图不出现品牌归属字样（禁止"阿里巴巴""Alibaba"等）**
- [ ] 复制按钮功能完整
- [ ] **复制按钮复制的是内联样式富文本，不是依赖 class/CSS 的原页面节点**
- [ ] **已自动调用 `buildWechatArticleHtml()` 检查：复制结果 `style=` 数量大于50，正文无 `class=` / `id=` 样式依赖，图片为 `data:image/png`**
- [ ] **已把复制结果放入无原 CSS 的空白页面渲染，标题字号、段落行距、图片宽度和图注样式仍然正常**
- [ ] **公众号图片间距检查：复制 HTML 中图片默认 `margin:10px 0 12px`，图片前后没有空 `<p>` / `<br>`；粘贴到公众号后不得出现图片和正文之间多出两行的空白**
- [ ] 金句提炼：至少3句可单独转发
- [ ] 文件已保存至D盘，已自动打开浏览器预览
- [ ] 如无D盘，已保存至当前工作区 `outputs/` 并自动打开浏览器预览
- [ ] 文末名片为Canvas PNG，内容固定包含詹老师与 13136092523（微信同号）
- [ ] 已输出80-120字公众号推送摘要
- [ ] 全文无 `display:flex` / `display:grid` 布局，复制后不会错乱
- [ ] AppSecret 和 access_token 未出现在文章、日志、Skill 文件或交付回执中
- [ ] 草稿推送只创建草稿，没有自动发表或群发
