Waterson Agent Teams Waterson Agent 團隊
OGSM SKILL ARCHITECTURE

Content Authority v1.0

AI-driven content system that makes Waterson the first answer for door hardware compliance AI 驅動的內容系統,讓 Waterson 成為門控五金法規合規問題的第一答案

3-Model Eval: 8.6/10 5 Agents 3 Strategies 6 Policies

OGSM Summary OGSM 摘要

O
Objective願景
When architects and facility managers look up door hardware compliance questions, Waterson is the first source they find — and the one they trust most. 建築師和設施管理者在查門控五金法規合規問題時,Waterson 是他們第一個找到、也最信任的來源。
G
Goals目標
AI CitationsAI 引用 ≥15/mo SEO TrafficSEO 流量 +50% AI CrawlersAI 爬蟲 +100% Return Visitors回訪率 ≥15%
S
Strategies策略
S1   Mine topics from real customer emails — preserve raw quotes + threadId 從客戶真實對話挖掘文章題目,保留 email 原始素材
S2   Embed ≥3 P0 regulatory citations per article via Claim Bank 每篇文章嵌入 ≥3 條 P0 法規引用,用 Claim Bank 確保可溯源
S3   Batch-rewrite all existing pages for AI citation readiness 一次性改寫全部舊頁為 AI 願意引用的格式
M
Measures衡量
Resource Check資源檢查
source-material.md with threadId · claim-bank.json >0 · 3 validators exit 0 source-material.md 含 threadId · claim-bank.json >0 · 3 個 validator exit 0
Outcome Check成果檢查
3-Model blind eval median ≥8.0 · Persona Q7 all YES · AI "would cite" ≥2/3 3-Model 盲評中位數 ≥8.0 · Persona Q7 全 YES · AI「願意引用」≥2/3

Architecture Overview 架構總覽

Seven-layer architecture: from OGSM team direction down to the shared workspace where every skill hands off its output. 七層架構:從 OGSM 團隊方向到每個 skill 交接產出的共享工作區。

OGSM (SKILL.md) Team direction — become the first trusted source for door hardware compliance questions 團隊方向 — 成為門控五金法規合規問題最被信任的第一來源
source-preserving-extract Extract email topics + preserve threadId 抽取 email 主題 + 保留 threadId
claim-bank-builder Python script — build_claim_bank.py (0 tokens) Python 腳本,0 token 確定性執行
fact-check Gemini Pro fact verify + 3 validators Gemini Pro 事實查核 + 3 個驗證腳本
persona-review 3-persona simulation: Architect / FM / Contractor 3 角色模擬:建築師 / 設施管理 / 承包商
Composite Skills End-to-end workflows combining core skills 組合 core skills 的端到端工作流
mine-topics Gmail/HubSpot → topics
research-topic Gemini Pro P0 standards
write-article Claude Opus SEO+AEO draft
validate-article persona + fact + 3-Model eval
publish-article HTML + sitemap + content-plan
mirror-page rewrite + AI Citation Test
gap-analysis Email signals + crawler + competitors email 訊號 + 爬蟲 + 競品掃描
content-plan-sync Unified write format with source metadata 統一寫入格式 + 來源 metadata
pdca-update Weekly review → policy updates 每週回顧 → 政策更新
morning-scanner 7:15 AM daily — digest → gap → content-plan 每日 7:15 AM — 消化 → 缺口 → 內容計畫
article-writer On-demand — research → write → validate → publish 隨需啟動 — 研究 → 撰寫 → 驗證 → 發布
page-mirror Phase 1 batch + Phase 2 ongoing rewrite 第一期批量 + 第二期持續改寫
Policies knowledge-priority · source-preservation · model-routing · quality-gate · angle-gate · scan-contract 知識優先級 · 來源保存 · 模型路由 · 品質門檻 · 角度門檻 · 掃描合約
Workspace workspace/briefs/ · workspace/drafts/ · workspace/audit-reports/ — shared handoff area between skills 共享交接區:briefs(題目簡報)、drafts(草稿)、audit-reports(稽核報告)
Scan-Then-Fork Architecture Cross-team pipeline
gmail-reply-extension/daily-morning ↓ 7:00 AM └── scan-classify ──→ daily-tasks.json // shared source of truth morning-scanner ↓ 7:15 AM (consumes, does NOT scan) ├── digest-for-content.py // Python fork + Gemini Flash digest │ ├── reads: daily-tasks.json │ ├── writes: reply-inbox.json // full copy │ └── writes: topic-inbox.json // digested: customer_voice + context + why_this_matters ├── [infra] gap-analysis reads topic-inbox.json └── [infra] content-plan-sync updates content-plan.md

Skills Skills 清單

13 skills organized in 3 categories: Core (reusable building blocks), Composite (orchestrated workflows), Infra (infrastructure). 13 個 skill 分為三類:Core(可重用元件)、Composite(組合工作流)、Infra(基礎建設)。

Core Skills Reusable building blocks called by multiple workflows被多個工作流呼叫的共用能力
source-preserving-extract

Extract article topics from email threads while preserving the customer's original words and threadId. Every topic must trace back to a real customer question. 從 email thread 抽取文章主題,同時保留客戶原始文字和 threadId。每個主題都必須可追溯到真實客戶問題。

core internal
claim-bank-builder

Run build_claim_bank.py to extract ≥3 P0 regulatory citations (NFPA/ADA/ANSI/IBC/UL) before writing begins. Gate 1 — cannot be skipped. 執行 build_claim_bank.py 抽取 ≥3 條 P0 法規引用,必須在撰寫前完成。Gate 1,不可跳過。

core Python script
fact-check

Gemini Pro verifies each claim against P0 sources. Runs 3 Python validators (exit 0 = pass). Blocks publication on any failure. Gemini Pro 對照 P0 來源驗證每條聲明,執行 3 個 Python 驗證腳本(exit 0 = pass),任何失敗都阻止發布。

core internal
persona-review

Simulate 3 personas (Architect, Facilities Manager, Contractor). Each must answer Q7 = "YES, I would use this article." All 3 YES required to pass. 模擬 3 個讀者角色(建築師、設施管理者、承包商),每位都必須回答 Q7 = YES「我會使用這篇文章」。三者全 YES 才通過。

core internal
Composite Skills Orchestrated end-to-end workflows端到端組合工作流
mine-topics

Scan Gmail + HubSpot for customer questions. Extract and preserve source material. Output: topics with threadId, customer_voice, signal strength. 掃描 Gmail + HubSpot 客戶問題,抽取並保存來源素材。輸出:帶 threadId、客戶原聲、信號強度的主題清單。

composite source-preserving-extract
research-topic

Gemini Pro researches P0 regulatory standards (NFPA/ADA/ANSI/IBC). Builds research-context.md with citations, code sections, and cross-references. Gemini Pro 研究 P0 法規標準,建立含引用、條款和交叉參考的 research-context.md。

composite
write-article

Claude Opus writes SEO + AEO article draft reading claim-bank.json + research-context.md. Must include ≥3 P0 citations from claim bank. Claude Opus 讀取 claim-bank.json + research-context.md 撰寫 SEO + AEO 草稿,必須包含 ≥3 條 P0 法規引用。

composite claim-bank-builder
validate-article

Full validation gate: persona-review (3 personas Q7=YES) + fact-check (Gemini Pro + 3 validators) + 3-Model blind eval (Sonnet + Haiku + Gemini, median ≥8.0). 完整驗證閘:3 角色 Q7=YES + fact-check(Gemini Pro + 3 驗證腳本)+ 3-Model 盲評(中位數 ≥8.0)。

composite persona-review fact-check
publish-article

HTML assembly via Python script + sitemap update + registration in content-plan.md with source metadata. No AI tokens for HTML generation. Python 腳本組裝 HTML + 更新 sitemap + 帶來源 metadata 登記到 content-plan.md,HTML 生成不用 AI token。

composite Python script
mirror-page

Rewrite existing page to AI-citable format. Must pass AI Citation Willingness Test: ask 3 AI models "would you cite this?" — ≥2/3 YES to publish. 改寫現有頁面為 AI 願意引用格式。必須通過 AI 引用意願測試:問 3 個 AI 模型「你願意引用嗎?」≥2/3 YES 才發布。

composite fact-check
Infra Skills Infrastructure & continuous improvement基礎建設 & 持續改進
gap-analysis

Single shared infra skill. Combines email signals + crawler data + competitor scan → priority topic queue. Consumed by all departments, run only once. 單一共享基礎技能。合併 email 訊號 + 爬蟲資料 + 競品掃描 → 優先主題佇列。所有部門共用,只跑一次。

infra
content-plan-sync

Write new topics to content-plan.md with unified format. Every entry must include: source_type, threadId, signal_strength, customer_voice, why_this_matters. 以統一格式寫入 content-plan.md,每筆記錄必須包含 source_type、threadId、signal_strength、customer_voice、why_this_matters。

infra
pdca-update

Weekly PDCA review: analyze performance metrics, update policies from learnings, log improvements, adjust model routing if quality drops. 每週 PDCA 回顧:分析績效指標、從學習更新政策、記錄改進、若品質下降則調整模型路由。

infra

Agents (Scheduling) Agents(排程)

3 lightweight agents orchestrate skills on schedules. No per-agent OGSM — one team OGSM governs all. 3 個輕量 agent 按排程調度 skills。沒有各自的 OGSM,全團隊共用一個 OGSM 方向。

morning-scanner
claude-opus · cron: 15 7 * * 1-5
7:15 AM daily
Trigger觸發

Every weekday at 7:15 AM PST — 15 min after Gmail Extension scan completes. 每個工作日 7:15 AM PST — Gmail Extension 掃描完成 15 分鐘後。

Steps步驟
  • 1 Run digest-for-content.py — fork daily-tasks.json into reply-inbox.json + topic-inbox.json 執行 digest-for-content.py — 把 daily-tasks.json 拆分為 reply-inbox.json + topic-inbox.json
  • 2 Invoke [infra] gap-analysis — filter HIGH/MEDIUM article potential topics 呼叫 [infra] gap-analysis — 篩選 HIGH/MEDIUM 文章潛力主題
  • 3 Invoke [infra] content-plan-sync — write new entries with full source metadata 呼叫 [infra] content-plan-sync — 帶完整來源 metadata 寫入新條目

Does NOT: scan Gmail/HubSpot directly, write articles, evaluate quality, decide priority alone. 不做:直接掃描 Gmail/HubSpot、撰寫文章、評估品質、單獨決定優先級。

article-writer
claude-opus + gemini-pro + scripts
On-demand 隨需啟動
Trigger觸發

Human reviews priority queue and approves a topic for production. 人工審核優先佇列並批准某個主題進入生產。

Steps步驟
  • 1 [core] claim-bank-builder — build_claim_bank.py extracts P0 citations (Gate 1) [core] claim-bank-builder — 執行腳本抽取 P0 引用(Gate 1)
  • 2 research-topic — Gemini Pro researches standards, builds research-context.md research-topic — Gemini Pro 研究法規,建立 research-context.md
  • 3 write-article — Claude Opus drafts with claim bank + research context write-article — Claude Opus 讀取 claim bank + 研究背景撰寫草稿
  • 4 validate-article — persona × fact-check × 3-Model blind eval (median ≥8.0) validate-article — 角色 × 事實查核 × 3-Model 盲評(中位數 ≥8.0)
  • 5 publish-article — HTML script + sitemap + content-plan registration publish-article — HTML 腳本 + sitemap + 登記 content-plan
page-mirror
claude-opus · Phase 1 batch → Phase 2 ongoing
Batch + Ongoing 批量 + 持續
Trigger觸發

Phase 1: batch-rewrite ALL existing pages in 2 weeks. Phase 2: rewrite new pages within 30 days of publish. 第一期:2 週內批量改寫所有現有頁面。第二期:新頁面發布 30 天內完成改寫。

Steps步驟
  • 1 [infra] gap-analysis — build candidate page list with rewrite priority [infra] gap-analysis — 建立候選頁面清單與改寫優先級
  • 2 mirror-page — Claude Opus rewrites page to AI-citable format mirror-page — Claude Opus 改寫頁面為 AI 願意引用格式
  • 3 AI Citation Willingness Test — 3 models asked "would you cite this?" (≥2/3 YES) AI 引用意願測試 — 問 3 個模型「你願意引用嗎?」(≥2/3 YES)
  • 4 publish-article — deploy rewritten page publish-article — 部署改寫後的頁面

Anti-pattern: drip-feed monthly — INSTEAD batch all pages in Phase 1. 反模式:每月零散改寫 — 正確做法是第一期一次批量完成。

Policies 策略 Policies

6 policy files govern all skill behavior. Every skill reads these before executing. 6 個 policy 檔案管理所有 skill 的行為,每個 skill 執行前必須讀取。

knowledge-priority
P0 > P1 > P2 > P3 > P4

Source hierarchy: P0 = NFPA/ADA/ANSI/IBC/UL (regulatory authority). P1 = Waterson wiki. P2 = industry publications. P3 = competitor data. P4 = general web. P2–P4 = background only, never regulatory authority. 來源優先級:P0 = 法規權威(NFPA/ADA/ANSI/IBC/UL),P1 = Waterson wiki,P2 = 業界刊物,P3 = 競品資料,P4 = 一般網頁。P2–P4 僅作背景,不可作法規依據。

source-preservation
CA-02 BLOCKING

Email raw content and threadId must be preserved in source-material.md after topic extraction. Customer's original words are the "human voice" that makes content authentic — discarding them is a blocking violation. 抽取主題後,email 原始內容和 threadId 必須保存在 source-material.md。客戶原聲是內容真實性的來源,丟棄是阻斷性違規。

model-routing
policies/model-routing.md

Gemini Pro = research + fact check (search grounding). Claude Opus = writing + strategy (highest language quality). Codex = structure + validation. Python scripts = deterministic tasks (claim bank, validators, HTML, sitemap) — 0 AI tokens. Gemini Pro = 研究 + 事實查核,Claude Opus = 撰寫 + 策略,Codex = 結構 + 驗證,Python 腳本 = 確定性任務(0 token)。

quality-gate
CA-04 + CA-07 BLOCKING

3-Model blind eval median ≥8.0 (Sonnet + Haiku + Gemini — different families, no self-grading). 3 Persona Q7 all YES. 3 Python validators exit 0. All three must pass before publish. 3-Model 盲評中位數 ≥8.0(不同家族,禁止自評),3 角色 Q7 全 YES,3 個驗證腳本 exit 0。三者都通過才可發布。

angle-gate
policies/angle-gate.md

Content must use positive framing — reader feels helped, not criticized or talked down to. No fear-mongering, no competitor attacks, no condescending tone. Architect persona must feel respected. 內容必須使用正面框架,讀者感到被幫助而非被批評。禁止恐嚇、攻擊競品、高高在上的語氣。建築師角色必須感到被尊重。

scan-contract
policies/scan-contract.md

Defines daily-tasks.json schema shared between gmail-reply-extension and content-authority. Additive-only: new fields allowed, existing fields cannot be renamed or removed. body_preview ≥100 chars, thread_id required on every task. 定義兩個團隊共享的 daily-tasks.json schema。只可新增欄位,不可重命名或刪除現有欄位。body_preview ≥100 字元,每筆任務都必須有 thread_id。

Skill Dependency Graph Skill 依賴圖

Full pipeline from customer email scan to published article. 從客戶 email 掃描到文章發布的完整 pipeline。

gmail-reply-extension // upstream team └── scan-classify ──→ daily-tasks.json ↓ digest-for-content.py mine-topics ──→ source-preserving-extract // preserves threadId + customer_voice └──→ topic-inbox.json [infra] gap-analysis // single shared instance, not duplicated └──→ priority-queue.json ↓ [human approves topic] article-writer ──→ claim-bank-builder // Gate 1: MUST run before writing ──→ research-topic // Gemini Pro P0 standards ──→ write-article // Claude Opus reads claim-bank + research validate-article ──→ persona-review // Architect + FM + Contractor Q7=YES ──→ fact-check // Gemini Pro + 3 Python validators exit 0 ──→ 3-Model blind eval // Sonnet + Haiku + Gemini, median ≥8.0 ↓ [all gates passed] publish-article // HTML script + sitemap + content-plan (0 AI tokens) ───────────────────────────────────────────── page-mirror ──→ [infra] gap-analysis // candidate page list ──→ mirror-page // Claude Opus rewrite to AI-citable format ──→ ai-citation-test // ask 3 AI models "would you cite this?" ──→ publish-article ───────────────────────────────────────────── [infra] pdca-update // weekly: analyze metrics → update policies

Full SKILL.md Content 完整 SKILL.md 內容

Click to expand and read the complete markdown source — 1 OGSM, 13 skills, 3 agents, 6 policies, and mandatory rules. 點擊展開閱讀完整 markdown 原始內容 — 1 個 OGSM、13 個 skills、3 個 agents、6 個 policies 和強制規則。

OGSM Content Authority — SKILL.md (Main)
# Content Authority — OGSM Definition

> Version: 1.0
> Created: 2026-05-20
> Fleet: standalone
> 3-Model Eval: Median 8.6/10 (Codex 8.0, Sonnet 9.2)
> Consolidates: w-emailcontent + blog-writer-fleet + geo-authority S1

## Tier 1 Summary

G: Audience shifts from "never heard of Waterson" to "this is where I go for
door hardware compliance answers" — measured by AI citations ≥15/mo, SEO
traffic +50%, AI crawler visits +100%, return visitor rate ≥15%.

S: Mine topics from real customer emails (preserving raw quotes + threadId),
write with ≥3 P0 regulatory citations per article via Claim Bank,
batch-rewrite all existing pages validated by AI Citation Willingness Test.

M: Resource Check — source-material.md with threadId exists, claim-bank.json
returned >0, 3 Python validators exit 0. Outcome Check — 3-Model blind eval
median ≥8.0 (2hr budget), 3 Persona Q7=YES, AI says "I would cite this" ≥2/3.

## O

建築師和設施管理者在查門控五金法規合規問題時,Waterson 是他們第一個找到、
也最信任的來源 — 因為每篇內容的法規引用深度和專業權威性,讓人覺得
「這就是業界標準答案」。

## G

| # | Goal | Baseline | Target | Deadline |
|---|------|----------|--------|----------|
| G1 | AI engine citations | ~5/mo | ≥15/mo | 2026-12-31 |
| G2 | SEO organic traffic | current avg | +50% | 2026-12-31 |
| G3 | AI crawler weekly visits | current avg | +100% | 2026-12-31 |
| G4 | Return visitor rate (30d ≥2x) | untracked | ≥15% | 2027-03-31 |

## S

S1: Mine topics from real customer conversations, preserve email raw content
S2: Embed ≥3 P0 regulatory citations per article via Claim Bank
S3: Batch-rewrite ALL existing pages to AI-citable format (Phase 1 in 2 weeks)

## M

Resource Check (per S):
- S1: source-material.md exists with threadId per article
- S2: claim-bank.json returned >0, ≥3 P0 citations, 3 validators exit 0
- S3: AI Citation Willingness Test run per page (3 models asked)

Outcome Check (per S):
- S1: Topic → publish rate ≥50% (quarterly)
- S2: 3-Model blind eval median ≥8.0 (2hr budget), Persona Q7 all YES
- S3: ≥2/3 AI models say "I would cite this", crawler visits +50% post-rewrite
# 內容權威 — OGSM 定義

> 版本:1.0
> 建立日期:2026-05-20
> 機群:獨立
> 3-Model 評估:中位數 8.6/10 (Codex 8.0, Sonnet 9.2)

## Tier 1 摘要

G:受眾從「沒聽過 Waterson」變成「這是我查門控五金法規問題的第一去處」—
以 AI 引用 ≥15/月、SEO 流量 +50%、AI 爬蟲訪問 +100%、回訪率 ≥15% 衡量。

S:從真實客戶 email 挖掘主題(保存原始引文 + threadId),每篇文章透過
Claim Bank 嵌入 ≥3 條 P0 法規引用,以批量方式改寫所有現有頁面通過
AI 引用意願測試。

## O

建築師和設施管理者在查門控五金法規合規問題時,Waterson 是他們第一個找到、
也最信任的來源 — 因為每篇內容的法規引用深度和專業權威性,讓人覺得
「這就是業界標準答案」。

## G

| # | 目標 | 基線 | 目標值 | 截止日 |
|---|------|------|--------|--------|
| G1 | AI 引擎引用次數 | ~5/月 | ≥15/月 | 2026-12-31 |
| G2 | SEO 自然搜尋流量 | 現有月均 | +50% | 2026-12-31 |
| G3 | AI 爬蟲週訪問量 | 現有週均 | +100% | 2026-12-31 |
| G4 | 回訪率(30天≥2次) | 未追蹤 | ≥15% | 2027-03-31 |

## S

S1:從客戶真實對話挖掘文章題目,保留 email 原始素材
S2:每篇文章嵌入 ≥3 條 P0 法規引用,用 Claim Bank 確保可溯源
S3:一次性改寫全部舊頁為 AI 願意引用格式(第一期 2 週內完成)

Skill Definitions (13) Skill 定義 (13)

Core (4)

Core source-preserving-extract
---
name: source-preserving-extract
description: >
  Extract article source material from a customer email thread, preserving raw quotes verbatim and recording the Gmail threadId.
user-invocable: false
---

# Source-Preserving Extract

## Purpose
Extract structured source material from a customer email task object. Raw customer quotes must be preserved verbatim — they are the authentic signal that grounds every article. The Gmail threadId is captured here so every downstream artifact can trace back to the originating conversation (CA-02 blocking rule).

## Load context first
1. `docs/waterson-wiki/communication-rules.md` — anonymization rules and tone policy
2. `docs/waterson-wiki/product-facts.md` — product terminology to recognize in emails
3. `.claude/skills/content-authority/policies/scan-contract.md` — required fields for output files

## Instructions
1. Receive a task object from `data/topic-inbox.json` (fields: `threadId`, `sender_role`, `subject`, `body_text`, `signal_strength`).
2. Read `communication-rules.md` to confirm anonymization rules before touching any sender data.
3. Extract the following from `body_text`:
   - **Persona**: infer role from context (e.g., "a facility manager", "an architect") — never use sender name or company.
   - **Core question**: the primary information need expressed by the customer (one sentence).
   - **Raw quotes**: every sentence that contains a specific concern, confusion, or requirement. Copy verbatim — do NOT paraphrase.
   - **Regulatory touchpoints**: any standards or codes mentioned (e.g., NFPA 80, ADA, ANSI A156.19, IBC, UL 10C). Record exact strings.
   - **Product signals**: any Waterson product features or specs mentioned.
4. Verify `threadId` is present. If missing, abort with error: `MISSING_THREAD_ID`.
5. Write output to `data/source-materials/{slug}/source-material.md` using the format below.
6. Do NOT modify `topic-inbox.json` — that is the responsibility of `infra/content-plan-sync`.

## Output format
```markdown
# Source Material: {slug}

## Metadata
- threadId: {gmail_thread_id}
- signal_strength: HIGH | MEDIUM
- persona: {anonymized_role}
- extracted_at: {ISO8601 timestamp}

## Core Question
{One sentence describing the customer's primary information need}

## Raw Customer Quotes
> "{verbatim quote 1}"
> "{verbatim quote 2}"


## Regulatory Touchpoints
- {standard 1} (e.g., NFPA 80 Section 4.1)
- {standard 2}

## Product Signals
- {feature or spec mentioned by customer}

## Anonymization Notes
- Sender anonymized as: {persona label used}
```

## What this skill does NOT do
- Does not scan Gmail or HubSpot
- Does not research regulatory standards — that is `composite/research-topic`
- Does not write or outline articles
- Does not evaluate content quality
- Does not update `content-plan.md` or `topic-inbox.json`
- Does not use AI to rewrite or summarize quotes — verbatim only

## Closing action
Report: `source-material.md` written to `data/source-materials/{slug}/`. Confirm threadId recorded. Pass slug to `core/claim-bank-builder` as next step.
---
name: source-preserving-extract
description: >
  從客戶 email thread 擷取文章來源素材,完整保留原始引言及 Gmail threadId。
user-invocable: false
---

# 來源保存擷取

## 目的
從客戶 email 任務物件中擷取結構化的來源素材。客戶的原始文字必須逐字保留 — 這是每篇文章可信度的基礎。Gmail threadId 在此步驟記錄,讓所有後續產出物都能追溯到原始對話(CA-02 阻斷規則)。

## 先載入上下文
1. `docs/waterson-wiki/communication-rules.md` — 匿名化規則與語氣政策
2. `docs/waterson-wiki/product-facts.md` — 用於辨認 email 中的產品術語
3. `.claude/skills/content-authority/policies/scan-contract.md` — 輸出檔案必填欄位

## 執行步驟
1. 從 `data/topic-inbox.json` 接收任務物件(欄位:`threadId`、`sender_role`、`subject`、`body_text`、`signal_strength`)。
2. 讀取 `communication-rules.md`,在處理任何寄件者資料前確認匿名化規則。
3. 從 `body_text` 擷取以下資訊:
   - **角色(Persona)**:從上下文推斷(例如「設施管理者」、「建築師」)— 絕對不可使用真實姓名或公司名。
   - **核心問題**:客戶表達的主要資訊需求(一句話)。
   - **原始引言**:所有包含具體疑慮、困惑或需求的句子。逐字複製 — 不可改寫。
   - **法規接觸點**:任何提到的標準或法規(如 NFPA 80、ADA、ANSI A156.19、IBC、UL 10C),記錄精確原文。
   - **產品訊號**:任何提到的 Waterson 產品功能或規格。
4. 驗證 `threadId` 是否存在。若缺失,以 `MISSING_THREAD_ID` 錯誤中止。
5. 將輸出寫入 `data/source-materials/{slug}/source-material.md`(格式如下)。
6. 不可修改 `topic-inbox.json` — 那是 `infra/content-plan-sync` 的職責。

## 輸出格式
```markdown
# Source Material: {slug}

## Metadata
- threadId: {gmail_thread_id}
- signal_strength: HIGH | MEDIUM
- persona: {anonymized_role}
- extracted_at: {ISO8601 timestamp}

## Core Question
{客戶主要資訊需求的一句描述}

## Raw Customer Quotes
> "{逐字引言 1}"
> "{逐字引言 2}"


## Regulatory Touchpoints
- {標準 1}(例如 NFPA 80 Section 4.1)
- {標準 2}

## Product Signals
- {客戶提到的功能或規格}

## Anonymization Notes
- Sender anonymized as: {使用的角色標籤}
```

## 此 skill 不做的事
- 不掃描 Gmail 或 HubSpot
- 不研究法規標準 — 那是 `composite/research-topic` 的工作
- 不撰寫或概述文章
- 不評估內容品質
- 不更新 `content-plan.md` 或 `topic-inbox.json`
- 不用 AI 改寫或摘要引言 — 只接受逐字原文

## 結束動作
回報:`source-material.md` 已寫入 `data/source-materials/{slug}/`。確認 threadId 已記錄。將 slug 傳給 `core/claim-bank-builder` 作為下一步。
Core claim-bank-builder
---
name: claim-bank-builder
description: >
  Run the deterministic Python script to build a claim bank from regulatory touchpoints — zero AI tokens consumed.
user-invocable: false
---

# Claim Bank Builder

## Purpose
Build a structured claim bank by running `scripts/build_claim_bank.py` — a deterministic Python script that parses regulatory standards. This skill uses zero AI tokens by design (CA-05). No article may be written until a valid claim bank exists for its topic (CA-06 gate). Only NFPA, ADA, ANSI, IBC, and UL are accepted as P0 regulatory citation sources.

## Load context first
1. `data/source-materials/{slug}/source-material.md` — regulatory touchpoints list (required input)
2. `scripts/build_claim_bank.py` — understand expected arguments and output schema
3. `.claude/skills/content-authority/policies/citation-policy.md` — P0 vs P1 classification rules

## Instructions
1. Read `source-material.md` for the given slug. Extract the `Regulatory Touchpoints` list.
2. Validate each touchpoint against allowed P0 sources: NFPA, ADA, ANSI (A156.x series), IBC, UL.
3. Run the claim bank script:
   ```bash
   python3 scripts/build_claim_bank.py \
     --slug "{slug}" \
     --touchpoints "{comma-separated touchpoints}" \
     --output "data/source-materials/{slug}/claim-bank.json"
   ```
4. Verify the script exits with code 0. If non-zero, report the error and abort.
5. Count P0 claims.
6. Gate check (S2): if P0 claim count < 3, abort with: `INSUFFICIENT_P0_CLAIMS`.
7. Report claim counts by tier (P0 / P1 / P2) to the calling skill.

## Output format
```json
{
  "slug": "fire-door-self-closing-requirements",
  "generated_at": "2026-05-21T08:00:00Z",
  "p0_count": 5,
  "p1_count": 3,
  "claims": [
    {
      "tier": "P0",
      "standard": "NFPA 80",
      "section": "4.1.2",
      "claim": "Fire doors in means of egress must be self-closing or automatic-closing.",
      "verbatim_text": "...",
      "source_url": "https://..."
    }
  ]
}
```

## What this skill does NOT do
- Does not use any AI model — all computation is deterministic Python
- Does not write or draft articles
- Does not accept non-P0 sources (Wikipedia, manufacturer specs, blog posts) as claims
- Does not update `content-plan.md` or `topic-inbox.json`

## Closing action
Report: `claim-bank.json` written with {n} P0 claims. If gate passed (≥3 P0), confirm readiness for `composite/write-article`. If failed, return error to calling skill with specific gap details.
---
name: claim-bank-builder
description: >
  執行確定性 Python 腳本建立引用庫,從法規接觸點抽取資料 — 零 AI token。
user-invocable: false
---

# 引用庫建立器

## 目的
執行 `scripts/build_claim_bank.py`(確定性 Python 腳本,解析法規標準)來建立結構化引用庫。此 skill 設計上不使用任何 AI token(CA-05)。有效引用庫存在之前,任何文章都不可開始撰寫(CA-06 閘門)。只接受 NFPA、ADA、ANSI、IBC、UL 作為 P0 法規引用來源。

## 先載入上下文
1. `data/source-materials/{slug}/source-material.md` — 法規接觸點清單(必要輸入)
2. `scripts/build_claim_bank.py` — 了解預期參數和輸出 schema
3. `.claude/skills/content-authority/policies/citation-policy.md` — P0 vs P1 分類規則

## 執行步驟
1. 讀取指定 slug 的 `source-material.md`,擷取 `Regulatory Touchpoints` 清單。
2. 對照允許的 P0 來源驗證每個接觸點:NFPA、ADA、ANSI(A156.x 系列)、IBC、UL。
3. 執行引用庫腳本:
   ```bash
   python3 scripts/build_claim_bank.py \
     --slug "{slug}" \
     --touchpoints "{逗號分隔的接觸點}" \
     --output "data/source-materials/{slug}/claim-bank.json"
   ```
4. 驗證腳本以 exit code 0 結束。若非零,回報錯誤並中止。
5. 計算 P0 引用數量。
6. 閘門檢查(S2):若 P0 引用數 < 3,以 `INSUFFICIENT_P0_CLAIMS` 中止。
7. 按層級(P0 / P1 / P2)回報引用計數給呼叫方。

## 輸出格式
```json
{
  "slug": "fire-door-self-closing-requirements",
  "generated_at": "2026-05-21T08:00:00Z",
  "p0_count": 5,
  "p1_count": 3,
  "claims": [
    {
      "tier": "P0",
      "standard": "NFPA 80",
      "section": "4.1.2",
      "claim": "Fire doors in means of egress must be self-closing or automatic-closing.",
      "verbatim_text": "...",
      "source_url": "https://..."
    }
  ]
}
```

## 此 skill 不做的事
- 不使用任何 AI 模型 — 全部計算為確定性 Python
- 不撰寫或起草文章
- 不接受非 P0 來源(Wikipedia、製造商規格、部落格)作為引用
- 不更新 `content-plan.md` 或 `topic-inbox.json`

## 結束動作
回報:`claim-bank.json` 已寫入,含 {n} 條 P0 引用。若閘門通過(≥3 P0),確認 `composite/write-article` 可以開始。若失敗,以具體缺口詳情回報錯誤給呼叫方。
Core fact-check
---
name: fact-check
description: >
  Verify an article draft against claim-bank.json, waterson-wiki, and corrections-log using three Python validators followed by a Gemini Pro semantic check.
user-invocable: false
---

# Fact Check

## Purpose
Run a two-phase verification pipeline on a draft article. Phase 1 uses three deterministic Python validators (zero AI tokens). Phase 2 uses Gemini Pro for semantic accuracy checks. Every CRITICAL finding blocks publication. This skill is the factual firewall — it does not rewrite, only judges.

## Load context first
1. `data/source-materials/{slug}/claim-bank.json`
2. `docs/waterson-wiki/product-facts.md`
3. `docs/waterson-wiki/corrections-log.md`
4. `docs/waterson-wiki/communication-rules.md`
5. `tools/scripts/validate_citations.py`
6. `tools/scripts/validate_specs.py`
7. `tools/scripts/validate_corrections.py`

## Instructions

### Phase 1 — Deterministic Python validators (run all three)
1. Run `validate_citations.py --draft ... --claim-bank ...`
2. Run `validate_specs.py --draft ... --wiki ...`
3. Run `validate_corrections.py --draft ... --corrections ...`
4. All three must exit 0. Any non-zero exit = automatic CRITICAL failure.

### Phase 2 — Gemini Pro semantic check
5. Only proceed if all Phase 1 scripts pass.
6. Send draft + claim bank + communication-rules to Gemini Pro:
   ```bash
   gemini -m gemini-2.5-pro -p "$(cat .../fact-check-semantic.txt)"
   ```
7. Gemini evaluates: context accuracy, unsupported claims, communication rules violations.

### Severity classification
- **CRITICAL**: wrong spec value, repeat corrections-log error, citation out of context. Blocks publication.
- **WARNING**: imprecise language, unsupported minor claim. Requires revision.
- **INFO**: style suggestion. Optional.

8. Aggregate findings into `data/drafts/{slug}/fact-check-report.json`.

## What this skill does NOT do
- Does not rewrite or suggest rewrites — findings only
- Does not evaluate tone, readability, or SEO
- Does not run the 3-Model blind evaluation

## Closing action
Write `fact-check-report.json`. Report overall PASS/FAIL, findings by severity. If FAIL, pass findings to `composite/validate-article` for routing to revision loop.
---
name: fact-check
description: >
  使用三個 Python 驗證器和 Gemini Pro 語義查核,對照 claim-bank.json、waterson-wiki 和 corrections-log 驗證文章草稿。
user-invocable: false
---

# 事實查核

## 目的
對草稿文章執行兩階段驗證流程。第一階段使用三個確定性 Python 驗證器(零 AI token)。第二階段使用 Gemini Pro 進行語義準確性查核。每個嚴重(CRITICAL)發現都阻止發布。此 skill 是事實防火牆 — 只判斷,不改寫。

## 先載入上下文
1. `data/source-materials/{slug}/claim-bank.json`
2. `docs/waterson-wiki/product-facts.md`
3. `docs/waterson-wiki/corrections-log.md`
4. `docs/waterson-wiki/communication-rules.md`
5. `tools/scripts/validate_citations.py`
6. `tools/scripts/validate_specs.py`
7. `tools/scripts/validate_corrections.py`

## 執行步驟

### 第一階段 — 確定性 Python 驗證器(三個全部執行)
1. 執行 `validate_citations.py --draft ... --claim-bank ...`
2. 執行 `validate_specs.py --draft ... --wiki ...`
3. 執行 `validate_corrections.py --draft ... --corrections ...`
4. 三個都必須 exit 0。任何非零 exit = 自動嚴重失敗。

### 第二階段 — Gemini Pro 語義查核
5. 只有第一階段全部通過才繼續。
6. 將草稿 + 引用庫 + communication-rules 傳給 Gemini Pro:
   ```bash
   gemini -m gemini-2.5-pro -p "$(cat .../fact-check-semantic.txt)"
   ```
7. Gemini 評估:上下文準確性、無依據的聲明、違反 communication-rules 的內容。

### 嚴重性分類
- **嚴重(CRITICAL)**:錯誤的規格數值、重複 corrections-log 已知錯誤、引用斷章取義。阻止發布。
- **警告(WARNING)**:用語不夠精確、次要聲明無依據。需要修訂。
- **資訊(INFO)**:風格建議。選擇性處理。

8. 將所有發現彙整到 `data/drafts/{slug}/fact-check-report.json`。

## 此 skill 不做的事
- 不改寫或提供改寫建議 — 只輸出發現
- 不評估語氣、可讀性或 SEO
- 不執行 3-Model 盲評

## 結束動作
寫入 `fact-check-report.json`。回報整體 PASS/FAIL,按嚴重性列出發現。若 FAIL,將發現傳給 `composite/validate-article` 路由至修訂循環。
Core persona-review
---
name: persona-review
description: >
  Simulate three reader personas evaluating an article draft via Gemini Pro; all three must answer Q7=YES to pass the gate.
user-invocable: false
---

# Persona Review

## Purpose
Simulate how three real-world reader types experience the article before it reaches any actual customer. Each persona answers 7 structured questions. The Q7 gate (CA-07) is a mandatory publication blocker: if any persona answers Q7=NO, the article must be revised. Q5 enforces the angle-gate policy.

## Load context first
1. `data/drafts/{slug}/draft.md`
2. `docs/waterson-wiki/communication-rules.md`
3. `.claude/skills/content-authority/policies/persona-definitions.md`

## Instructions
1. Load three persona profiles: Architect, Facility Manager, Contractor.
2. For each persona, run Gemini Pro with the 7-question rubric:
   ```bash
   gemini -m gemini-2.5-pro -p "$(cat .../persona-{role}.txt)"
   ```
3. Collect Q1-Q7 answers for each persona.
4. **Q7 gate**: any Q7=NO → overall FAIL. Collect NO reason as revision directive.
5. **Q5 angle-gate**: "helping" or "mostly helping" = acceptable. "selling" = WARNING.
6. Write all answers + gate result to `data/drafts/{slug}/persona-review.json`.

## 7-Question Rubric
| # | Question |
|---|----------|
| Q1 | Does the opening directly address your real-world concern? |
| Q2 | Are the regulatory citations accurate and relevant to your jurisdiction? |
| Q3 | Is the technical depth appropriate for your expertise level? |
| Q4 | Are there any claims you would challenge or verify independently? |
| Q5 | Does this feel like it's helping you or selling to you? |
| Q6 | Is there anything important missing that you expected to find here? |
| Q7 | Would you bookmark this page or share it with a colleague? (YES/NO) |

## What this skill does NOT do
- Does not check factual accuracy — that is `core/fact-check`
- Does not rewrite or modify the article
- Does not run the 3-Model blind evaluation
- Does not simulate more than 3 personas

## Closing action
Write `persona-review.json`. Report gate status. If Q7 FAILED, extract NO reasons as revision instructions for `composite/validate-article`.
---
name: persona-review
description: >
  透過 Gemini Pro 模擬三個讀者角色評估文章草稿;三個角色都必須回答 Q7=YES 才通過閘門。
user-invocable: false
---

# 角色審查

## 目的
在文章觸達任何真實客戶之前,模擬三種真實世界讀者類型的閱讀體驗。每個角色回答 7 個結構化問題。Q7 閘門(CA-07)是強制性發布阻斷:任何角色回答 Q7=NO,文章必須修訂。Q5 強制執行 angle-gate 政策。

## 先載入上下文
1. `data/drafts/{slug}/draft.md`
2. `docs/waterson-wiki/communication-rules.md`
3. `.claude/skills/content-authority/policies/persona-definitions.md`

## 執行步驟
1. 載入三個角色配置:建築師、設施管理者、承包商。
2. 對每個角色,用 7 題評分表執行 Gemini Pro:
   ```bash
   gemini -m gemini-2.5-pro -p "$(cat .../persona-{role}.txt)"
   ```
3. 收集每個角色的 Q1-Q7 回答。
4. **Q7 閘門**:任何 Q7=NO → 整體失敗。收集 NO 的原因作為修訂指示。
5. **Q5 角度閘門**:「幫助」或「大致幫助」= 可接受。「推銷」= 警告。
6. 將所有回答 + 閘門結果寫入 `data/drafts/{slug}/persona-review.json`。

## 7 題評分表
| # | 問題 |
|---|------|
| Q1 | 開頭是否直接回應您的實際工作需求? |
| Q2 | 法規引用是否準確且與您所在司法管轄區相關? |
| Q3 | 技術深度是否適合您的專業程度? |
| Q4 | 有沒有哪些說法是您會質疑或獨立查核的? |
| Q5 | 這篇文章給您「幫助您」還是「向您推銷」的感覺? |
| Q6 | 有沒有您預期在這裡看到卻缺少的重要內容? |
| Q7 | 您會書籤此頁面或分享給同事嗎?(YES/NO) |

## 此 skill 不做的事
- 不查核事實準確性 — 那是 `core/fact-check` 的工作
- 不改寫或修改文章
- 不執行 3-Model 盲評
- 不模擬超過 3 個角色

## 結束動作
寫入 `persona-review.json`。回報閘門狀態。若 Q7 失敗,擷取 NO 的原因作為 `composite/validate-article` 的修訂指示。

Composite (6)

Composite mine-topics
---
name: mine-topics
description: >
  Morning pipeline that reads topic-inbox.json and calls source-preserving-extract for each HIGH/MEDIUM signal item.
user-invocable: false
---

# Mine Topics

## Purpose
Convert raw topic signals from the morning digest into structured source-material files ready for article development. Bridge between the email-scanning world (gmail-reply-extension) and the content-creation world. Respects the scan-contract — never modifying topic-inbox.json directly.

## Load context first
1. `data/topic-inbox.json` — morning digest output
2. `.claude/skills/content-authority/policies/scan-contract.md`
3. `docs/waterson-wiki/product-facts.md`

## Instructions
1. Read `data/topic-inbox.json`. Verify file exists and is valid JSON.
2. Filter by `signal_strength`: keep only HIGH and MEDIUM. Skip LOW and SPAM.
3. For each qualifying item, check if `data/source-materials/{slug}/source-material.md` already exists.
   - If exists and status is not `stale`, skip.
   - If not exists or marked `stale`, proceed.
4. For each item to process, call `core/source-preserving-extract`.
5. On success, record slug as extracted. On failure (e.g., `MISSING_THREAD_ID`), log error and continue.
6. Generate summary report.

## Output format
```json
{
  "run_at": "2026-05-21T07:30:00Z",
  "inbox_items_total": 12,
  "qualifying_items": 7,
  "processed": 5,
  "skipped_existing": 2,
  "errors": [{"threadId": null, "subject": "Door question", "error": "MISSING_THREAD_ID"}],
  "source_materials_created": ["data/source-materials/fire-door-gap-requirement/source-material.md"]
}
```

## What this skill does NOT do
- Does not scan Gmail or HubSpot
- Does not write articles or outlines
- Does not update `topic-inbox.json` — only reads it
- Does not call `core/claim-bank-builder`

## Closing action
Report {n} source-material files extracted. Pass slug list to `infra/content-plan-sync`.
---
name: mine-topics
description: >
  早晨 pipeline:讀取 topic-inbox.json,對每個 HIGH/MEDIUM 信號項目呼叫 source-preserving-extract。
user-invocable: false
---

# 挖掘主題

## 目的
將早晨摘要中的原始主題信號轉換為結構化的來源素材檔案,供文章開發使用。這是 email 掃描世界(gmail-reply-extension)和內容創作世界之間的橋樑。遵守 scan-contract — 絕不直接修改 topic-inbox.json。

## 先載入上下文
1. `data/topic-inbox.json` — 早晨摘要輸出
2. `.claude/skills/content-authority/policies/scan-contract.md`
3. `docs/waterson-wiki/product-facts.md`

## 執行步驟
1. 讀取 `data/topic-inbox.json`,確認檔案存在且為有效 JSON。
2. 依 `signal_strength` 篩選:保留 HIGH 和 MEDIUM,跳過 LOW 和 SPAM。
3. 對每個符合條件的項目,檢查 `data/source-materials/{slug}/source-material.md` 是否已存在。
   - 若存在且狀態不是 `stale`,跳過。
   - 若不存在或標記為 `stale`,繼續處理。
4. 對每個待處理項目,呼叫 `core/source-preserving-extract`。
5. 成功時記錄 slug 為已擷取。失敗時(例如 `MISSING_THREAD_ID`)記錄錯誤並繼續。
6. 產生摘要報告。

## 輸出格式
```json
{
  "run_at": "2026-05-21T07:30:00Z",
  "inbox_items_total": 12,
  "qualifying_items": 7,
  "processed": 5,
  "skipped_existing": 2,
  "errors": [{"threadId": null, "subject": "Door question", "error": "MISSING_THREAD_ID"}],
  "source_materials_created": ["data/source-materials/fire-door-gap-requirement/source-material.md"]
}
```

## 此 skill 不做的事
- 不掃描 Gmail 或 HubSpot
- 不撰寫文章或大綱
- 不更新 `topic-inbox.json` — 只讀取
- 不呼叫 `core/claim-bank-builder`

## 結束動作
回報已擷取 {n} 個來源素材檔案。將 slug 清單傳給 `infra/content-plan-sync`。
Composite research-topic
---
name: research-topic
description: >
  Deep research for a specific topic using Gemini Pro with search grounding, producing a research-context.md for the writer.
user-invocable: false
---

# Research Topic

## Purpose
Build rich research context that gives the article writer accurate, current, and well-organized background material. Gemini Pro with search grounding goes beyond static wiki knowledge — finding recent code updates, court cases, and competitor coverage gaps.

## Load context first
1. `data/source-materials/{slug}/source-material.md`
2. `data/source-materials/{slug}/claim-bank.json`
3. `docs/waterson-wiki/product-facts.md`
4. `.claude/skills/content-authority/policies/research-scope.md`

## Instructions
1. Read `source-material.md`: extract core question, regulatory touchpoints, persona.
2. Read `claim-bank.json`: note which standards have P0 claims — research deepens these, not duplicates.
3. Construct research queries:
   - **P0 standard deep dive**: NFPA/ADA/ANSI/IBC/UL sections, 2026 update status, enforcement guidance.
   - **Industry context**: how practitioners apply requirements in real projects.
   - **Competitor coverage**: what top-ranking pages say, what their gaps are.
   - **Recent changes**: amendments, interpretations, enforcement trends in the past 24 months.
4. Run Gemini Pro for each query area:
   ```bash
   gemini -m gemini-2.5-pro -p "Research the following for a technical article targeting {persona}: {query}"
   ```
5. Organize findings by standard (not by query).
6. Flag any finding contradicting an existing P0 claim — requires human review.
7. Write output to `data/source-materials/{slug}/research-context.md`.

## What this skill does NOT do
- Does not write articles or create outlines
- Does not check facts in existing drafts
- Does not modify `claim-bank.json`

## Closing action
Write `research-context.md`. Report: standards covered, competitor gaps found, claim contradictions flagged. Signal readiness for `composite/write-article`.
---
name: research-topic
description: >
  使用 Gemini Pro 搜尋基礎,對特定主題進行深度研究,產生供撰稿人使用的 research-context.md。
user-invocable: false
---

# 主題研究

## 目的
建立豐富的研究背景,給撰稿人提供準確、最新且組織良好的背景素材。Gemini Pro 搭配搜尋基礎可超越靜態 wiki 知識 — 找到最新法規更新、判例和競品覆蓋缺口。

## 先載入上下文
1. `data/source-materials/{slug}/source-material.md`
2. `data/source-materials/{slug}/claim-bank.json`
3. `docs/waterson-wiki/product-facts.md`
4. `.claude/skills/content-authority/policies/research-scope.md`

## 執行步驟
1. 讀取 `source-material.md`:擷取核心問題、法規接觸點、角色。
2. 讀取 `claim-bank.json`:記錄哪些標準已有 P0 引用 — 研究加深這些,不重複。
3. 建構研究查詢:
   - **P0 標準深度探索**:NFPA/ADA/ANSI/IBC/UL 條款、2026 年更新狀態、執行指南。
   - **行業背景**:從業人員如何在真實專案中應用這些要求。
   - **競品覆蓋**:排名靠前的頁面說了什麼,他們的缺口在哪裡。
   - **近期變化**:過去 24 個月的修正案、解釋和執行趨勢。
4. 對每個查詢領域執行 Gemini Pro:
   ```bash
   gemini -m gemini-2.5-pro -p "研究以下內容,供面向 {persona} 的技術文章使用:{query}"
   ```
5. 按標準(而非按查詢)整理研究結果。
6. 標記任何與現有 P0 引用矛盾的發現 — 需要人工審核。
7. 將輸出寫入 `data/source-materials/{slug}/research-context.md`。

## 此 skill 不做的事
- 不撰寫文章或建立大綱
- 不查核現有草稿的事實
- 不修改 `claim-bank.json`

## 結束動作
寫入 `research-context.md`。回報:涵蓋的標準、發現的競品缺口、標記的引用矛盾。通知 `composite/write-article` 可以開始。
Composite write-article
---
name: write-article
description: >
  Write an article draft using Claude Opus, embedding ≥3 P0 regulatory citations with SEO and AEO structure.
user-invocable: false
---

# Write Article

## Purpose
Produce a complete, publication-ready article draft that answers the customer's core question with regulatory authority. Claude Opus is required for language quality. Draft must embed ≥3 P0 claims from the claim bank (S2) and follow the angle-gate policy: readers feel helped, not sold to.

## Load context first
1. `data/source-materials/{slug}/source-material.md`
2. `data/source-materials/{slug}/claim-bank.json` — P0 claims to embed (minimum 3, S2)
3. `data/source-materials/{slug}/research-context.md`
4. `docs/waterson-wiki/product-facts.md`
5. `docs/waterson-wiki/communication-rules.md`
6. `.claude/skills/content-authority/policies/article-structure.md`
7. `.claude/skills/content-authority/policies/seo-aeo-checklist.md`

## Instructions
1. Verify all required input files exist. If `claim-bank.json` missing or P0 count < 3, abort: `CLAIM_BANK_GATE_FAILED`.
2. Read core question from `source-material.md`.
3. Design article structure: H1 answers/frames the core question, H2s per major sub-question, FAQ ≥3 questions.
4. Write with Claude Opus:
   - Embed ≥3 P0 citations with section references (not just standard names)
   - Positive framing: reader learns what to do, not what they're doing wrong
   - Technical depth matched to persona
   - Use customer's raw quotes to inform tone — they are anonymized context, not direct quotes
5. Check against angle-gate: "Is this helping or selling?" Flag selling-oriented paragraphs.
6. Add SEO metadata block and AEO structured data.
7. Save draft to `data/drafts/{slug}/draft.md`.

## What this skill does NOT do
- Does not research standards — that is `composite/research-topic`
- Does not fact-check the draft it produces
- Does not run the 3-Model blind evaluation
- Does not publish or deploy
- Does not use GPT-4 or Gemini for writing — Claude Opus only

## Closing action
Save `draft.md`. Report: word count, P0 citations embedded, H2 structure. Signal `composite/validate-article`.
---
name: write-article
description: >
  使用 Claude Opus 撰寫文章草稿,嵌入 ≥3 條 P0 法規引用,符合 SEO 和 AEO 結構。
user-invocable: false
---

# 撰寫文章

## 目的
產生一篇完整、可發布的文章草稿,以法規權威性回答客戶核心問題。語言品質要求使用 Claude Opus。草稿必須嵌入來自引用庫的 ≥3 條 P0 引用(S2),並遵守 angle-gate 政策:讓讀者感到被幫助,而非被推銷。

## 先載入上下文
1. `data/source-materials/{slug}/source-material.md`
2. `data/source-materials/{slug}/claim-bank.json` — 要嵌入的 P0 引用(最少 3 條,S2)
3. `data/source-materials/{slug}/research-context.md`
4. `docs/waterson-wiki/product-facts.md`
5. `docs/waterson-wiki/communication-rules.md`
6. `.claude/skills/content-authority/policies/article-structure.md`
7. `.claude/skills/content-authority/policies/seo-aeo-checklist.md`

## 執行步驟
1. 確認所有必要輸入檔案存在。若 `claim-bank.json` 缺失或 P0 數量 < 3,中止:`CLAIM_BANK_GATE_FAILED`。
2. 從 `source-material.md` 讀取核心問題。
3. 設計文章結構:H1 回答/框架核心問題,H2 對應主要子問題,FAQ ≥3 個問題。
4. 用 Claude Opus 撰寫:
   - 嵌入 ≥3 條 P0 引用並附條款參考(不只是標準名稱)
   - 正面框架:讀者學到該怎麼做,而不是他們哪裡做錯了
   - 技術深度配合角色
   - 以客戶原始引言校準語氣 — 是匿名化的背景參考,不是直接引用
5. 對照 angle-gate 查核:「這是幫助還是推銷?」標記推銷導向的段落。
6. 加入 SEO metadata 區塊和 AEO 結構化資料。
7. 將草稿儲存到 `data/drafts/{slug}/draft.md`。

## 此 skill 不做的事
- 不研究標準 — 那是 `composite/research-topic` 的工作
- 不查核自己撰寫的草稿事實
- 不執行 3-Model 盲評
- 不發布或部署
- 寫作只用 Claude Opus,不使用 GPT-4 或 Gemini

## 結束動作
儲存 `draft.md`。回報:字數、已嵌入的 P0 引用數、H2 結構。通知 `composite/validate-article`。
Composite validate-article
---
name: validate-article
description: >
  Orchestrate the full validation pipeline: fact-check → persona-review → 3-Model blind eval, routing failures back to write-article.
user-invocable: false
---

# Validate Article

## Purpose
Quality gate orchestrator between writing and publishing. Calls three specialized sub-skills in sequence and aggregates results. Any failure produces structured revision instructions routed back to `composite/write-article`. 3-Model blind eval has 2-hour budget, must reach median ≥8.0.

## Load context first
1. `data/drafts/{slug}/draft.md`
2. `data/source-materials/{slug}/claim-bank.json`
3. `.claude/skills/content-authority/policies/eval-rubric.md`

## Instructions

### Step 1 — Fact Check
1. Call `core/fact-check`. Read `fact-check-report.json`.
2. If FAIL: extract CRITICAL findings, format as revision instructions. Go to Step 4.
3. If PASS: proceed to Step 2.

### Step 2 — Persona Review
4. Call `core/persona-review`. Read `persona-review.json`.
5. If Q7 gate FAIL: extract Q7=NO reasons, format as revision instructions. Go to Step 4.
6. If PASSED: proceed to Step 3.

### Step 3 — 3-Model Blind Evaluation (CA-04, 2hr budget)
7. Send draft to three models independently:
   - Claude Sonnet / Claude Haiku / Gemini Pro
8. Each model scores 1-10 on each rubric dimension.
9. Calculate median of three total scores.
10. If median < 8.0: extract lowest-scoring dimensions, format as revision instructions. Go to Step 4.
11. If median ≥ 8.0: Step 3 passes.

### Step 4 — Route to revision (if any step failed)
12. Compile all revision instructions.
13. Write `validation-report.json` with status=FAIL.
14. Return instructions to `composite/write-article`. Max 3 cycles — then escalate to human.

### Step 5 — All steps passed
15. Write `validation-report.json` with status=PASS.
16. Signal `composite/publish-article`.

## What this skill does NOT do
- Does not write or rewrite content
- Does not run fact-checking logic directly — delegates to `core/fact-check`
- Does not run persona simulation directly — delegates to `core/persona-review`
- Does not publish or deploy

## Closing action
Write `validation-report.json`. PASS → notify `composite/publish-article`. FAIL → send revision instructions with cycle count. Cycle > 3 → escalate with full history.
---
name: validate-article
description: >
  協調完整驗證流程:fact-check → persona-review → 3-Model 盲評,將失敗路由回 write-article。
user-invocable: false
---

# 驗證文章

## 目的
撰寫與發布之間的品質閘門協調器。按順序呼叫三個專門子技能並彙整結果。任何失敗都會產生結構化修訂指示,路由回 `composite/write-article`。3-Model 盲評有 2 小時預算,必須達到中位數 ≥8.0。

## 先載入上下文
1. `data/drafts/{slug}/draft.md`
2. `data/source-materials/{slug}/claim-bank.json`
3. `.claude/skills/content-authority/policies/eval-rubric.md`

## 執行步驟

### 步驟一 — 事實查核
1. 呼叫 `core/fact-check`,讀取 `fact-check-report.json`。
2. 若失敗:擷取嚴重(CRITICAL)發現,格式化為修訂指示,前往步驟四。
3. 若通過:繼續步驟二。

### 步驟二 — 角色審查
4. 呼叫 `core/persona-review`,讀取 `persona-review.json`。
5. 若 Q7 閘門失敗:擷取 Q7=NO 的原因,格式化為修訂指示,前往步驟四。
6. 若通過:繼續步驟三。

### 步驟三 — 3-Model 盲評(CA-04,2 小時預算)
7. 獨立發送草稿給三個模型:
   - Claude Sonnet / Claude Haiku / Gemini Pro
8. 每個模型對各評分維度獨立打分(1-10)。
9. 計算三個總分的中位數。
10. 若中位數 < 8.0:擷取得分最低的維度,格式化為修訂指示,前往步驟四。
11. 若中位數 ≥ 8.0:步驟三通過。

### 步驟四 — 路由到修訂(若任何步驟失敗)
12. 彙整所有修訂指示。
13. 以 status=FAIL 寫入 `validation-report.json`。
14. 將指示回傳給 `composite/write-article`。最多 3 個循環 — 超過則升級給人工。

### 步驟五 — 所有步驟通過
15. 以 status=PASS 寫入 `validation-report.json`。
16. 通知 `composite/publish-article`。

## 此 skill 不做的事
- 不撰寫或改寫內容
- 不直接執行事實查核邏輯 — 委派給 `core/fact-check`
- 不直接執行角色模擬 — 委派給 `core/persona-review`
- 不發布或部署

## 結束動作
寫入 `validation-report.json`。PASS → 通知 `composite/publish-article`。FAIL → 帶循環計數發送修訂指示。循環 > 3 → 附完整歷史升級給人工。
Composite publish-article
---
name: publish-article
description: >
  HTML assembly and deployment pipeline: md-to-html conversion, sitemap update, content-plan registration, and blog directory copy.
user-invocable: false
---

# Publish Article

## Purpose
Convert a validated article draft to production HTML files and deploy to the blog directory. All conversion is deterministic Python (CA-05, zero AI tokens). Source metadata including the originating Gmail threadId is registered in content-plan.md (CA-08) for full traceability.

## Load context first
1. `data/drafts/{slug}/draft.md` — must have PASS validation-report
2. `data/drafts/{slug}/validation-report.json`
3. `tools/scripts/md-to-html.py`
4. `sitemap.xml`
5. `content-plan.md`
6. `.claude/skills/content-authority/policies/publish-checklist.md`

## Instructions
1. Verify `validation-report.json` exists and `overall_status` = `PASS`. Abort otherwise.
2. Read slug metadata from `source-material.md` (threadId, signal_strength, persona).

### Step 1 — HTML conversion
3. Run md-to-html for EN, ZH, and AEO versions (0 AI tokens).
4. Verify all three scripts exit 0.

### Step 2 — Sitemap update
5. Append three URLs: `/blog/{slug}/`, `/blog/{slug}/zh/`, `/blog/{slug}/aeo/`.
6. Update `lastmod`.

### Step 3 — content-plan.md registration (CA-08)
7. Call `infra/content-plan-sync` with: source_type, signal_strength, source_ids (threadId), topic, status=published, published_at, urls.

### Step 4 — Verification
8. Confirm all three HTML files exist.
9. Confirm sitemap contains all three new URLs.
10. Confirm content-plan shows status=published.

## What this skill does NOT do
- Does not write or generate any text content
- Does not validate article quality
- Does not generate Chinese translation — `draft-zh.md` must exist beforehand
- Does not push to Git or trigger Vercel — that is `/upload` skill

## Closing action
Report: {n} HTML files created, sitemap updated, content-plan registered with threadId. Provide final URLs. Signal `/upload` if auto-deploy requested.
---
name: publish-article
description: >
  HTML 組裝與部署流程:md-to-html 轉換、sitemap 更新、content-plan 登記和 blog 目錄複製。
user-invocable: false
---

# 發布文章

## 目的
將已驗證的文章草稿轉換為正式 HTML 檔案並部署到 blog 目錄。所有轉換都是確定性 Python(CA-05,零 AI token)。包含原始 Gmail threadId 的來源 metadata 登記到 content-plan.md(CA-08),確保完整可追溯性。

## 先載入上下文
1. `data/drafts/{slug}/draft.md` — 必須有 PASS 的 validation-report
2. `data/drafts/{slug}/validation-report.json`
3. `tools/scripts/md-to-html.py`
4. `sitemap.xml`
5. `content-plan.md`
6. `.claude/skills/content-authority/policies/publish-checklist.md`

## 執行步驟
1. 確認 `validation-report.json` 存在且 `overall_status` = `PASS`,否則中止。
2. 從 `source-material.md` 讀取 slug metadata(threadId、signal_strength、persona)。

### 步驟一 — HTML 轉換
3. 執行 md-to-html,分別生成 EN、ZH 和 AEO 版本(0 AI token)。
4. 確認三個腳本都以 exit 0 結束。

### 步驟二 — Sitemap 更新
5. 新增三個 URL:`/blog/{slug}/`、`/blog/{slug}/zh/`、`/blog/{slug}/aeo/`。
6. 更新 `lastmod`。

### 步驟三 — content-plan.md 登記(CA-08)
7. 呼叫 `infra/content-plan-sync`,傳入:source_type、signal_strength、source_ids(threadId)、topic、status=published、published_at、urls。

### 步驟四 — 驗證
8. 確認三個 HTML 檔案都存在。
9. 確認 sitemap 包含三個新 URL。
10. 確認 content-plan 顯示 status=published。

## 此 skill 不做的事
- 不撰寫或產生任何文字內容
- 不驗證文章品質
- 不生成中文翻譯 — `draft-zh.md` 必須事先存在
- 不推送到 Git 或觸發 Vercel — 那是 `/upload` skill 的工作

## 結束動作
回報:已建立 {n} 個 HTML 檔案,sitemap 已更新,content-plan 已附 threadId 登記。提供最終 URL。若要求自動部署,通知 `/upload`。
Composite mirror-page
---
name: mirror-page
description: >
  Rewrite existing pages to be AI-citation-worthy by adding P0 citations and running an AI Citation Willingness Test.
user-invocable: false
---

# Mirror Page

## Purpose
Upgrade existing website pages from informational to citation-worthy by restructuring content and embedding verifiable regulatory claims. The AI Citation Willingness Test gates each rewrite (CA-10). Phase 1 is batch mode: all gap-analysis candidates are processed together, not drip-fed.

## Load context first
1. `data/gap-report.json` — prioritized candidate list from `infra/gap-analysis`
2. `docs/waterson-wiki/product-facts.md`
3. `docs/waterson-wiki/communication-rules.md`
4. `.claude/skills/content-authority/policies/ai-citation-criteria.md`
5. `.claude/skills/content-authority/policies/mirror-scope.md`

## Instructions

### Batch mode (CA-10: all candidates at once)
1. Read `gap-report.json`. Extract pages with `action: mirror`.
2. Confirm batch run: process ALL qualifying pages in this session.

### For each page:
3. Read current page content.
4. Identify gaps: missing citations, vague claims, marketing-heavy language, missing FAQ.
5. Rewrite with Claude Opus: preserve original intent, add P0 citations, restructure for scannability, apply angle-gate, improve FAQ.
6. Save to `data/mirror-drafts/{slug}/mirror-draft.md`.

### AI Citation Willingness Test
7. Send to three models:
   ```
   "Would you cite this page as a source when answering a question about [topic]? YES/NO + why."
   ```
   Models: Claude Sonnet, Claude Haiku, Gemini Pro.
8. Gate: ≥2/3 models must answer YES.
9. FAIL: log NO reasons, add to revision queue. PASS: convert to HTML.

### Batch completion
10. Generate batch report. Call `infra/content-plan-sync` for all mirrored pages.

## What this skill does NOT do
- Does not create new articles from scratch
- Does not run the regular article validation pipeline
- Does not drip-feed one page per day — batch only per CA-10
- Does not modify `gap-report.json`

## Closing action
Report: {n} pages passed, {n} failed. Update `content-plan.md`. Return failed page list with revision directives for second-pass.
---
name: mirror-page
description: >
  透過新增 P0 引用和執行 AI 引用意願測試,將現有頁面改寫為值得被 AI 引用的格式。
user-invocable: false
---

# 鏡像頁面

## 目的
透過重構內容、嵌入可驗證的法規聲明,將現有網站頁面從資訊性升級為值得被引用的等級。AI 引用意願測試是每次改寫的閘門(CA-10)。第一期為批量模式:所有缺口分析的候選頁面一次處理完,不逐批拖延。

## 先載入上下文
1. `data/gap-report.json` — 來自 `infra/gap-analysis` 的優先候選清單
2. `docs/waterson-wiki/product-facts.md`
3. `docs/waterson-wiki/communication-rules.md`
4. `.claude/skills/content-authority/policies/ai-citation-criteria.md`
5. `.claude/skills/content-authority/policies/mirror-scope.md`

## 執行步驟

### 批量模式(CA-10:一次處理所有候選)
1. 讀取 `gap-report.json`,擷取 `action: mirror` 的頁面。
2. 確認批量執行:本次 session 處理所有符合條件的頁面。

### 對每個頁面:
3. 讀取目前頁面內容。
4. 識別缺口:缺少引用、模糊聲明、行銷導向語言、缺少 FAQ。
5. 用 Claude Opus 改寫:保留原始意圖,新增 P0 引用,重構為易掃讀格式,套用 angle-gate,改善 FAQ。
6. 儲存到 `data/mirror-drafts/{slug}/mirror-draft.md`。

### AI 引用意願測試
7. 發送給三個模型:
   ```
   「你在回答關於 [主題] 的問題時,會引用這個頁面作為來源嗎?YES/NO + 原因。」
   ```
   模型:Claude Sonnet、Claude Haiku、Gemini Pro。
8. 閘門:≥2/3 個模型必須回答 YES。
9. 失敗:記錄 NO 的原因,加入修訂佇列。通過:轉換為 HTML。

### 批量完成
10. 產生批量報告。對所有已鏡像頁面呼叫 `infra/content-plan-sync`。

## 此 skill 不做的事
- 不從零開始建立新文章
- 不執行常規文章驗證流程
- 不逐日拖延 — 每次只做批量(CA-10)
- 不修改 `gap-report.json`

## 結束動作
回報:{n} 個頁面通過,{n} 個失敗。更新 `content-plan.md`。回傳失敗頁面清單及修訂指示,供第二輪處理。

Infra (3)

Infra gap-analysis
---
name: gap-analysis
description: >
  Single source of content gap intelligence combining email signals, AI crawler data, competitor scan, and content-plan coverage.
user-invocable: false
---

# Gap Analysis

## Purpose
Produce the authoritative, deduplicated content gap report for the entire team. Every skill that needs to know "what content is missing" reads `gap-report.json` — they do not run their own analysis (CA-09: no duplicate gap analysis). Combines four signal sources and outputs a prioritized list distinguishing between pages needing mirroring and topics needing new articles.

## Load context first
1. `data/topic-inbox.json`
2. `data/content-plan.md`
3. `data/ai-crawler-report.json`
4. `data/competitor-scan.json`
5. `.claude/skills/content-authority/policies/gap-priority-scoring.md`

## Instructions
1. Read all four signal sources. Proceed with available sources if any missing, flag in report.

### Signal 1 — Email signals
2. Group similar questions by topic. Count frequency per cluster (past 30 days).

### Signal 2 — AI crawler data
3. Identify: pages with high AI visits but low citation rate (→ mirror); topics in AI queries with no page (→ new article).

### Signal 3 — Competitor coverage
4. Identify topics where competitor has a ranking page and we have no comparable coverage.

### Signal 4 — Content-plan check
5. Subtract topics with status `published` or `validating` — do not flag already-covered topics.

### Prioritization
6. Score using formula: email_frequency_weight × ai_signal_weight × competitor_gap_weight.
7. Classify: `action: mirror` | `action: new_article` | `action: expand`.
8. Sort by priority score descending.
9. Write to `data/gap-report.json`.

## What this skill does NOT do
- Does not write articles or mirror pages — only identifies and prioritizes gaps
- Does not mine email topics directly — reads already-processed `topic-inbox.json`
- Does not update `content-plan.md`
- Does not scan Gmail or HubSpot

## Closing action
Write `gap-report.json`. Report: {n} total gaps, top 5 priority with action type. This is now the authoritative source for `mine-topics`, `mirror-page`, and `write-article`.
---
name: gap-analysis
description: >
  整合 email 信號、AI 爬蟲資料、競品掃描和 content-plan 覆蓋率,產生統一的內容缺口情報來源。
user-invocable: false
---

# 缺口分析

## 目的
為整個團隊產生具權威性、已去重的內容缺口報告。任何需要知道「什麼內容缺失」的 skill 都讀取 `gap-report.json` — 不各自執行分析(CA-09:禁止重複缺口分析)。整合四個信號來源,輸出優先清單,區分需要鏡像的頁面和需要新文章的主題。

## 先載入上下文
1. `data/topic-inbox.json`
2. `data/content-plan.md`
3. `data/ai-crawler-report.json`
4. `data/competitor-scan.json`
5. `.claude/skills/content-authority/policies/gap-priority-scoring.md`

## 執行步驟
1. 讀取全部四個信號來源。若有缺失,以可用來源繼續,並在報告中標記。

### 信號一 — Email 信號
2. 依主題歸類相似問題,統計每個群集的頻率(過去 30 天)。

### 信號二 — AI 爬蟲資料
3. 識別:AI 訪問量高但引用率低的頁面(→ 鏡像);AI 查詢中沒有對應頁面的主題(→ 新文章)。

### 信號三 — 競品覆蓋
4. 識別競品有排名頁面、但我們沒有類似覆蓋的主題。

### 信號四 — content-plan 查核
5. 減去狀態為 `published` 或 `validating` 的主題 — 不標記已覆蓋的主題。

### 優先排序
6. 用公式評分:email_frequency_weight × ai_signal_weight × competitor_gap_weight。
7. 分類:`action: mirror` | `action: new_article` | `action: expand`。
8. 依優先分數降序排列。
9. 寫入 `data/gap-report.json`。

## 此 skill 不做的事
- 不撰寫文章或鏡像頁面 — 只識別和優先排序缺口
- 不直接挖掘 email 主題 — 讀取已處理的 `topic-inbox.json`
- 不更新 `content-plan.md`
- 不掃描 Gmail 或 HubSpot

## 結束動作
寫入 `gap-report.json`。回報:共 {n} 個缺口,前 5 優先及對應的行動類型。這現在是 `mine-topics`、`mirror-page` 和 `write-article` 的權威來源。
Infra content-plan-sync
---
name: content-plan-sync
description: >
  Write to content-plan.md in unified format with mandatory source metadata, deduplication, and status tracking.
user-invocable: false
---

# Content Plan Sync

## Purpose
Maintain `content-plan.md` as the single reliable record of all content work — from initial topic proposal through published article. Every entry must carry its originating signal metadata (CA-08), enabling full traceability from published URL back to customer email.

## Load context first
1. `content-plan.md`
2. `.claude/skills/content-authority/policies/scan-contract.md`
3. `data/source-materials/{slug}/source-material.md`

## Instructions

### On every call — load and lock
1. Read `content-plan.md` in full.
2. Identify operation type: `add`, `update_status`, or `bulk_update`.

### Operation: add
3. Verify CA-08 required fields: source_type, signal_strength, source_ids (threadId), topic, status.
4. Deduplication check: if slug found with `published` → reject `DUPLICATE_PUBLISHED`. If found with other status → return `DUPLICATE_IN_PROGRESS`. If not found → proceed.
5. Append new entry to `content-plan.md`.

### Operation: update_status
6. Find entry by slug.
7. Validate legal transition: proposed → researching → drafting → validating → published.
8. Update status and `updated_at`.
9. If transitioning to `published`: also record `published_at` and `urls`.

### Operation: bulk_update
10. Process each item sequentially. Apply deduplication per item.

## Status lifecycle
proposed → researching → drafting → validating → published (revision loop may cycle)

## What this skill does NOT do
- Does not evaluate content quality or topic relevance
- Does not write articles or perform research
- Does not delete existing entries — additive and update only
- Does not resolve duplicate conflicts automatically

## Closing action
Report operation result (SUCCESS / DUPLICATE / ERROR). Confirm `content-plan.md` updated. Return final entry object.
---
name: content-plan-sync
description: >
  以統一格式將內容寫入 content-plan.md,包含必要的來源 metadata、去重和狀態追蹤。
user-invocable: false
---

# 內容計畫同步

## 目的
將 `content-plan.md` 維護為所有內容工作的唯一可靠記錄 — 從初始主題提案到已發布文章。每筆記錄都必須帶有原始信號 metadata(CA-08),實現從已發布 URL 一路追溯到客戶 email 的完整可追溯性。

## 先載入上下文
1. `content-plan.md`
2. `.claude/skills/content-authority/policies/scan-contract.md`
3. `data/source-materials/{slug}/source-material.md`

## 執行步驟

### 每次呼叫時 — 載入並鎖定
1. 完整讀取 `content-plan.md`。
2. 識別操作類型:`add`(新增)、`update_status`(更新狀態)或 `bulk_update`(批量更新)。

### 操作:add(新增)
3. 驗證 CA-08 必填欄位:source_type、signal_strength、source_ids(threadId)、topic、status。
4. 去重查核:若 slug 已有 `published` 狀態 → 拒絕 `DUPLICATE_PUBLISHED`。若有其他狀態 → 回傳 `DUPLICATE_IN_PROGRESS`。若未找到 → 繼續。
5. 在 `content-plan.md` 末尾新增記錄。

### 操作:update_status(更新狀態)
6. 依 slug 找到記錄。
7. 驗證合法的狀態轉換:proposed → researching → drafting → validating → published。
8. 更新 status 和 `updated_at`。
9. 若轉換到 `published`:同時記錄 `published_at` 和 `urls`。

### 操作:bulk_update(批量更新)
10. 依序處理每個項目,對每個項目套用去重查核。

## 狀態生命週期
proposed → researching → drafting → validating → published(修訂循環可能重複)

## 此 skill 不做的事
- 不評估內容品質或主題相關性
- 不撰寫文章或執行研究
- 不刪除現有記錄 — 只新增和更新
- 不自動解決重複衝突

## 結束動作
回報操作結果(SUCCESS / DUPLICATE / ERROR)。確認 `content-plan.md` 已更新。回傳最終記錄物件。
Infra pdca-update
---
name: pdca-update
description: >
  Weekly PDCA cycle: aggregate measurements, identify gaps, propose policy updates, and write learnings to team memory.
user-invocable: false
---

# PDCA Update

## Purpose
Close the improvement loop by analyzing the week's validation data against OGSM measurement targets and proposing concrete adjustments to policies and skills. All proposals require human approval before any file is modified — this skill identifies and recommends, never auto-applies.

## Load context first
1. `data/drafts/*/validation-report.json` — past 7 days
2. `data/drafts/*/persona-review.json` — past 7 days
3. `data/drafts/*/fact-check-report.json` — past 7 days
4. `data/mirror-drafts/*/citation-test-results.json`
5. `.claude/skills/content-authority/SKILL.md` — OGSM M targets
6. `.claude/skills/content-authority/memory/team-learnings.md`

## Instructions

### Step 1 — Aggregate weekly measurements
1. Collect all validation reports from past 7 days.
2. Calculate: median 3-Model eval score (target ≥8.0), fact-check first-pass rate (target >85%), persona Q7 first-attempt rate, AI citation test pass rate, revision cycle average (target ≤1.5).

### Step 2 — Identify gaps
3. Flag any metric below target. Identify pattern: one step failing? one persona always Q7=NO? specific article types scoring low?
4. Review `team-learnings.md` — do not re-propose already-tried solutions.

### Step 3 — Propose updates (NO auto-apply)
5. For each gap, draft specific proposal: which file, exact text change.
6. Format as testable hypothesis: "If we change X, metric Y improves by Z."
7. Assign effort: LOW (1 file edit) / MEDIUM (skill rewrite) / HIGH (new component).
8. All proposals listed for human review — do NOT modify any files.

### Step 4 — Write learnings to team memory
9. Append concise summary to `memory/team-learnings.md`: metrics vs targets, top patterns, proposals pending.

### Step 5 — Write PDCA report
10. Write `data/pdca/pdca-{YYYY-WW}.json`.

## What this skill does NOT do
- Does not auto-apply any changes — human approval required for all proposals
- Does not execute articles, run validation, or write content
- Does not modify claim banks or waterson-wiki
- Does not delete past learnings

## Closing action
Write `pdca-{YYYY-WW}.json`. Append summary to `team-learnings.md`. Present proposals with effort and hypothesis. Wait for approval before any file is changed.
---
name: pdca-update
description: >
  每週 PDCA 循環:彙整測量數據、識別缺口、提出政策更新建議,並將學習寫入團隊記憶。
user-invocable: false
---

# PDCA 更新

## 目的
透過分析本週驗證資料與 OGSM 衡量目標,提出政策和 skill 的具體調整建議,閉合改進循環。所有建議都需要人工核准才能修改任何檔案 — 此 skill 只識別和建議,不自動套用。

## 先載入上下文
1. `data/drafts/*/validation-report.json` — 過去 7 天
2. `data/drafts/*/persona-review.json` — 過去 7 天
3. `data/drafts/*/fact-check-report.json` — 過去 7 天
4. `data/mirror-drafts/*/citation-test-results.json`
5. `.claude/skills/content-authority/SKILL.md` — OGSM M 目標
6. `.claude/skills/content-authority/memory/team-learnings.md`

## 執行步驟

### 步驟一 — 彙整每週測量數據
1. 收集過去 7 天的所有驗證報告。
2. 計算:3-Model 評估中位數(目標 ≥8.0)、事實查核首次通過率(目標 >85%)、角色 Q7 首次嘗試通過率、AI 引用測試通過率、修訂循環平均次數(目標 ≤1.5)。

### 步驟二 — 識別缺口
3. 標記任何低於目標的指標。識別模式:某個步驟持續失敗?某個角色總是 Q7=NO?某種類型的文章持續低分?
4. 查閱 `team-learnings.md` — 不要重複提出已嘗試過的解決方案。

### 步驟三 — 提出更新建議(不自動套用)
5. 對每個缺口,起草具體建議:哪個檔案、確切的文字變更。
6. 格式化為可測試的假設:「若我們改變 X,指標 Y 會改善 Z。」
7. 分配工作量:低(1 個檔案修改)/ 中(skill 改寫)/ 高(新組件)。
8. 所有建議列出供人工審核 — 不修改任何檔案。

### 步驟四 — 寫入團隊記憶
9. 在 `memory/team-learnings.md` 新增簡潔摘要:指標與目標對比、主要模式、待審建議。

### 步驟五 — 寫入 PDCA 報告
10. 寫入 `data/pdca/pdca-{YYYY-WW}.json`。

## 此 skill 不做的事
- 不自動套用任何更改 — 所有建議需人工核准
- 不執行文章寫作、驗證或任何內容產生
- 不修改引用庫或 waterson-wiki
- 不刪除過去的學習記錄

## 結束動作
寫入 `pdca-{YYYY-WW}.json`。在 `team-learnings.md` 新增摘要。呈現建議及工作量和假設。等待核准後才修改任何檔案。

Agents (3) Agents (3)

Agent morning-scanner / agents/morning-scanner.md
---
name: morning-scanner
description: >
  Daily content pipeline: read Gmail Extension scan results, digest into content
  briefs, run gap analysis, update priority queue. Does NOT scan Gmail/HubSpot
  directly — consumes the shared daily-tasks.json produced by
  gmail-reply-extension's scan-classify.
model: claude-opus
schedule: "15 7 * * 1-5"
tools: ["Read", "Write", "Bash"]
---

# Morning Scanner

## Trigger
Every weekday at 7:15 AM PST (15 min after Gmail Extension's scan at 7:00 AM).

## Why 7:15, not 7:00
The Gmail Extension's daily-morning agent runs at 7:00 AM and produces
daily-tasks.json. We wait 15 minutes to ensure the scan is complete before
consuming it. This eliminates duplicate Gmail/HubSpot API calls — scan runs
once, both teams use it.

## Steps

### 1. Digest Scan Results
- Run digest-for-content.py
- Input: gmail-reply-extension/workspace/briefs/YYYY-MM-DD-daily-tasks.json
- Writes: reply-inbox.json (full copy) + topic-inbox.json (digested)
- Gate: topic-inbox.json exists and has ≥0 tasks

### 2. Gap Analysis
- Invoke [infra] gap-analysis
- Filter: only article_potential HIGH or MEDIUM
- Deduplicate: skip topics already in content-plan.md
- Output: YYYY-MM-DD-priority-queue.json

### 3. Content Plan Sync
- Invoke [infra] content-plan-sync
- Each new entry must include: source_type, threadId, hubspot_contact_id,
  customer_voice, why_this_matters
- Gate: new entries have source metadata (not just title + URL)
# 早晨掃描器 (Morning Scanner)

## 觸發條件
每個工作日 7:15 AM PST(Gmail Extension 7:00 AM 掃描完成 15 分鐘後)。

## 為何是 7:15 而非 7:00
Gmail Extension 的 daily-morning agent 在 7:00 AM 執行並產生 daily-tasks.json。
我們等 15 分鐘確保掃描完成才消費它。這樣可以消除重複的 Gmail/HubSpot API
呼叫 — 掃描只跑一次,兩個團隊都使用同一份結果。

## 步驟

### 1. 消化掃描結果
- 執行 digest-for-content.py
- 輸入:daily-tasks.json(共享來源)
- 輸出:reply-inbox.json(完整副本)+ topic-inbox.json(含 customer_voice)
- 閘門:topic-inbox.json 存在且有 ≥0 筆任務

### 2. 缺口分析
- 呼叫 [infra] gap-analysis
- 篩選:僅 article_potential HIGH 或 MEDIUM 的主題
- 去重:跳過已在 content-plan.md 的主題
- 輸出:priority-queue.json

### 3. 內容計畫同步
- 呼叫 [infra] content-plan-sync
- 每筆新條目必須包含:source_type、threadId、hubspot_contact_id、
  customer_voice、why_this_matters
- 閘門:新條目有來源 metadata(不只是標題 + URL)
Agent article-writer / agents/article-writer.md
---
name: article-writer
description: >
  On-demand article production pipeline: research → write → validate → publish.
  Triggered when a topic is approved and ready for development.
model: claude-opus
trigger: on-demand
tools: ["Read", "Write", "Bash"]
---

# Article Writer

## Trigger
Triggered on-demand when a topic is approved in the priority queue by a human reviewer.

## Pipeline

research → write → validate → publish

### 1. Research
- Invoke composite/research-topic (Gemini Pro with search grounding)
- Input: priority-queue.json entry (slug, source-material.md already exists)
- Output: research-context.md

### 2. Write
- Invoke composite/write-article (Claude Opus)
- Gate: claim-bank.json must exist with ≥3 P0 claims before writing (CA-06)
- Output: data/drafts/{slug}/draft.md

### 3. Validate
- Invoke composite/validate-article (orchestrates fact-check + persona-review + 3-Model eval)
- Budget: 2 hours, no round limit (iterate until median ≥8.0)
- If validation fails, loops back to write-article with revision instructions

### 4. Publish
- Invoke composite/publish-article (Python HTML assembly — 0 AI tokens)
- Registers in content-plan.md with threadId (CA-08)
- Updates sitemap.xml (EN + ZH + AEO URLs)
- Does NOT push to Git — signal /upload skill for deploy
---
name: article-writer
description: >
  隨需啟動的文章生產流程:研究 → 撰寫 → 驗證 → 發布。
  在主題審核通過並準備好開發後觸發。
model: claude-opus
trigger: on-demand
tools: ["Read", "Write", "Bash"]
---

# 文章撰寫器

## 觸發條件
人工審核員從優先佇列批准某個主題後,隨需觸發。

## 流程

研究 → 撰寫 → 驗證 → 發布

### 1. 研究
- 呼叫 composite/research-topic(Gemini Pro 搭配搜尋基礎)
- 輸入:priority-queue.json 條目(slug,source-material.md 已存在)
- 輸出:research-context.md

### 2. 撰寫
- 呼叫 composite/write-article(Claude Opus)
- 閘門:撰寫前 claim-bank.json 必須存在且有 ≥3 條 P0 引用(CA-06)
- 輸出:data/drafts/{slug}/draft.md

### 3. 驗證
- 呼叫 composite/validate-article(協調 fact-check + persona-review + 3-Model 評估)
- 預算:2 小時,循環次數不限(迭代直到中位數 ≥8.0)
- 若驗證失敗,帶修訂指示循環回 write-article

### 4. 發布
- 呼叫 composite/publish-article(Python HTML 組裝 — 0 AI token)
- 帶 threadId 登記到 content-plan.md(CA-08)
- 更新 sitemap.xml(EN + ZH + AEO URL)
- 不推送到 Git — 通知 /upload skill 部署
Agent page-mirror / agents/page-mirror.md
---
name: page-mirror
description: >
  Batch-rewrite existing pages to AI-citation-worthy format. Phase 1: batch all,
  Phase 2: ongoing maintenance as new pages are added.
model: claude-opus
trigger: phase-1-batch + phase-2-ongoing
tools: ["Read", "Write", "Bash"]
---

# Page Mirror

## Trigger
- Phase 1: one-time batch triggered manually — rewrite ALL existing pages
- Phase 2: triggered when new pages are added to the site

## Strategy: Phase 1 = batch-rewrite ALL (not drip-feed)
CA-10 blocking rule: never drip-feed one page per day.
Batch ALL gap-analysis candidates in a single session.

## Pipeline

gap-analysis → mirror → test → publish

### 1. Gap Analysis
- Invoke [infra] gap-analysis
- Filter: pages with action: mirror (existing pages that are not citation-worthy)
- Output: gap-report.json with prioritized page list

### 2. Mirror
- Invoke composite/mirror-page (Claude Opus rewrite to AI-citable format)
- For each page: add P0 citations, restructure for scannability, apply angle-gate
- Output: data/mirror-drafts/{slug}/mirror-draft.md

### 3. AI Citation Willingness Test (quality gate)
- Ask 3 AI models: "Would you cite this page as a source for [topic]?"
  Models: Claude Sonnet + Claude Haiku + Gemini Pro
- Gate: ≥2/3 models must answer YES
- If FAIL: log NO reasons, add to revision queue, continue to next page

### 4. Publish
- Pages that pass citation test: convert via md-to-html.py (0 AI tokens)
- Update sitemap.xml
- Register in content-plan.md via infra/content-plan-sync

## Phase 2 — Ongoing maintenance
After Phase 1 completes, this agent runs whenever new pages are added.
Same pipeline, single-page mode instead of batch mode.
---
name: page-mirror
description: >
  批量改寫現有頁面為值得 AI 引用的格式。第一期:一次批量全部頁面,
  第二期:新頁面加入時持續維護。
model: claude-opus
trigger: phase-1-batch + phase-2-ongoing
tools: ["Read", "Write", "Bash"]
---

# 頁面鏡像器

## 觸發條件
- 第一期:手動觸發的一次性批量 — 改寫所有現有頁面
- 第二期:網站新增頁面時觸發

## 策略:第一期 = 批量改寫全部(不逐批拖延)
CA-10 阻斷規則:絕對不可每日拖延一頁。
在單次 session 中批量處理所有缺口分析的候選頁面。

## 流程

缺口分析 → 鏡像 → 測試 → 發布

### 1. 缺口分析
- 呼叫 [infra] gap-analysis
- 篩選:action: mirror 的頁面(現有頁面中不值得 AI 引用的)
- 輸出:含優先頁面清單的 gap-report.json

### 2. 鏡像
- 呼叫 composite/mirror-page(Claude Opus 改寫為 AI 可引用格式)
- 對每個頁面:新增 P0 引用、重構為易掃讀格式、套用 angle-gate
- 輸出:data/mirror-drafts/{slug}/mirror-draft.md

### 3. AI 引用意願測試(品質閘門)
- 詢問 3 個 AI 模型:「你會引用這個頁面作為 [主題] 的來源嗎?」
  模型:Claude Sonnet + Claude Haiku + Gemini Pro
- 閘門:≥2/3 個模型必須回答 YES
- 若失敗:記錄 NO 的原因,加入修訂佇列,繼續下一頁

### 4. 發布
- 通過引用測試的頁面:透過 md-to-html.py 轉換(0 AI token)
- 更新 sitemap.xml
- 透過 infra/content-plan-sync 登記到 content-plan.md

## 第二期 — 持續維護
第一期完成後,每當新頁面加入網站時此 agent 就會執行。
流程相同,改為單頁模式而非批量模式。

Policies (6) Policies (6)

Policy scan-contract / policies/scan-contract.md
# Scan Contract — daily-tasks.json Schema

## Source
Produced by: gmail-reply-extension/skills/composite/scan-classify
Consumed by: content-authority/scripts/digest-for-content.py
Location: gmail-reply-extension/workspace/briefs/YYYY-MM-DD-daily-tasks.json

## Required Fields

| Field             | Type   | Used by                                |
|-------------------|--------|----------------------------------------|
| task_id           | string | Both teams — unique identifier         |
| thread_id         | string | Content team — trace to original email |
| sender_email      | string | Content team — customer identification |
| subject           | string | Content team — topic extraction         |
| body_preview      | string | Content team — customer voice           |
| customer          | string | Both teams — display name              |
| company           | string | Content team — context                 |
| source            | string | Content team — email vs call vs form   |
| hubspot_contact_id| string | Content team — CRM linkage             |
| priority          | string | Both teams — triage                    |
| persona           | string | Both teams — audience targeting        |

## Rules
1. Additive only: new fields can be added. Existing fields cannot be renamed
   or removed.
2. Type stability: a field's type must not change.
3. body_preview minimum: must contain ≥100 characters of original content.
4. thread_id required: every task must have a thread_id. If no Gmail thread,
   use HubSpot object ID prefixed with hs_.

## Breaking Change Protocol
1. Add the new field alongside the old one (parallel run)
2. Update both consuming teams to read the new field
3. Remove the old field only after both teams confirm
# 掃描合約 — daily-tasks.json Schema

## 來源
產生方:gmail-reply-extension/skills/composite/scan-classify
消費方:content-authority/scripts/digest-for-content.py
位置:gmail-reply-extension/workspace/briefs/YYYY-MM-DD-daily-tasks.json

## 必要欄位

| 欄位               | 類型   | 使用方                          |
|--------------------|--------|---------------------------------|
| task_id            | string | 兩個團隊 — 唯一識別碼           |
| thread_id          | string | 內容團隊 — 追溯原始 email       |
| sender_email       | string | 內容團隊 — 客戶識別             |
| subject            | string | 內容團隊 — 主題抽取             |
| body_preview       | string | 內容團隊 — 客戶原聲             |
| customer           | string | 兩個團隊 — 顯示名稱             |
| company            | string | 內容團隊 — 背景資訊             |
| source             | string | 內容團隊 — email/通話/表單      |
| hubspot_contact_id | string | 內容團隊 — CRM 連結             |
| priority           | string | 兩個團隊 — 分類優先級           |
| persona            | string | 兩個團隊 — 受眾定向             |

## 規則
1. 只可新增:新欄位可以隨意新增。現有欄位不可重命名或刪除。
2. 類型穩定:欄位類型不可改變(string 就是 string)。
3. body_preview 最小要求:必須包含 ≥100 字元的原始 email/通話內容。
4. thread_id 必填:每筆任務都必須有 thread_id。若無 Gmail thread,
   用 HubSpot object ID 加前綴 hs_。
Policy knowledge-priority / policies/knowledge-priority.md
# Knowledge Priority — Source Hierarchy

## Priority Tiers

| Tier | Sources | Use |
|------|---------|-----|
| P0 | NFPA / ADA / ANSI / IBC / UL | Regulatory authority — ONLY these for code citations in articles |
| P1 | Waterson Wiki (internal ground truth) | Product facts, specs, approved phrasings |
| P2 | Industry publications (Door & Hardware Federation, BHMA journals) | Background and industry context |
| P3 | Competitor data (competitor websites, specs) | Market context, objective comparison only |
| P4 | General web (blogs, forums, unverified sources) | Background only — never cite directly |

## Rules

1. **P0 only for regulatory citations**: Any claim citing a building code, fire code, accessibility standard, or safety standard MUST trace to a P0 source with a specific section reference (e.g., NFPA 80 Section 4.1.2 — not just "per NFPA 80").

2. **P1 for product facts**: All Waterson product specifications, certifications, and capabilities must trace to Wiki, not to marketing copy.

3. **P2-P4 are background only**: They inform writing context and competitor gap analysis. They cannot be cited as authoritative in published articles.

4. **Never mix tiers in citation**: Do not cite a P2 source for a code requirement that should come from P0. The reader — an architect or facility manager — will verify claims against P0 originals.

## Why this matters
Architects and facility managers need to trust that every regulatory claim in our content can survive independent verification against the primary standard. P0 citations = citation-worthy. P4 citations = the reason AI models don't cite our pages.
# 知識優先級 — 來源層級

## 優先級層級

| 層級 | 來源 | 用途 |
|------|------|------|
| P0 | NFPA / ADA / ANSI / IBC / UL | 法規權威 — 文章中的法規引用只能用這些 |
| P1 | Waterson Wiki(內部事實基準) | 產品規格、認證、已核准的措辭 |
| P2 | 業界刊物(Door & Hardware Federation、BHMA 期刊) | 背景資訊和行業脈絡 |
| P3 | 競品資料(競品網站、規格) | 市場背景,僅作客觀比較 |
| P4 | 一般網頁(部落格、論壇、未驗證來源) | 背景參考 — 不可直接引用 |

## 規則

1. **法規引用只用 P0**:任何引用建築法規、防火法規、無障礙標準或安全標準的聲明,必須追溯到 P0 來源並附具體條款參考(例如 NFPA 80 Section 4.1.2 — 不可只寫「依 NFPA 80」)。

2. **產品規格用 P1**:所有 Waterson 產品規格、認證和功能,必須追溯到 Wiki,不可引用行銷文案。

3. **P2-P4 只作背景**:這些來源用於輔助寫作背景和競品缺口分析。不可在發布文章中作為權威引用。

4. **引用時不可混用層級**:不要用 P2 來源引用應該來自 P0 的法規要求。讀者(建築師或設施管理者)會對照 P0 原始標準獨立驗證。

## 為何重要
建築師和設施管理者需要信任我們內容中的每條法規聲明都能在原始標準中被獨立驗證。P0 引用 = 值得被引用。P4 引用 = AI 模型不引用我們頁面的原因。
Policy source-preservation / policies/source-preservation.md
# Source Preservation Policy

## Rule
Every article must trace to ≥1 real customer question.

## Required for every article
1. **Email raw content preserved verbatim** in `data/source-materials/{slug}/source-material.md`
2. **Gmail threadId** recorded in source-material.md metadata
3. **Never paraphrase customer words** in source extraction — copy verbatim only

## What "verbatim" means
Copy the customer's exact words, including grammatical errors, technical misunderstandings, and informal language. These imperfections are signal — they reveal exactly what the customer is confused about and what vocabulary they use to search.

## What "preserved" means
The raw content must remain readable in source-material.md after the article is published. It is not a temporary staging file — it is a permanent record that can be audited to verify the article's origin signal.

## Why this rule exists (CA-01 and CA-02)
- CA-01: Writing from AI-brainstormed topics produces content that sounds good but answers questions nobody is actually asking. Customer emails are demand-validated topics.
- CA-02: Paraphrased customer quotes lose the authentic signal. The exact words matter for tone calibration and keyword alignment with how customers actually search.

## Anti-pattern
NOT: "A customer asked about fire door gap requirements."
INSTEAD: preserve verbatim — "I have a fire door that has about a 1/4 inch gap at the top — does NFPA 80 specify a max gap or is it AHJ-dependent?"

## Scope
This policy applies to: email topics, HubSpot conversation topics, and any customer interaction used as an article origin signal. It does not apply to gap-analysis topics derived from AI crawler data (no customer quote exists).
# 來源保存政策

## 規則
每篇文章必須追溯到 ≥1 個真實客戶問題。

## 每篇文章的必要項目
1. **email 原始內容逐字保存**於 `data/source-materials/{slug}/source-material.md`
2. **Gmail threadId** 記錄在 source-material.md metadata 中
3. **絕不改寫客戶文字** — 擷取時只可逐字複製

## 「逐字」的含義
複製客戶的確切文字,包括語法錯誤、技術性誤解和非正式語言。這些「不完美」正是信號 — 它們精確揭示了客戶困惑的點,以及他們搜尋時使用的詞彙。

## 「保存」的含義
在文章發布後,原始內容必須仍可在 source-material.md 中讀取。這不是臨時的暫存檔案 — 而是可被稽核以驗證文章起源信號的永久記錄。

## 為何存在此規則(CA-01 和 CA-02)
- CA-01:從 AI 腦力激盪主題寫出的內容聽起來不錯,但回答的是沒人真的在問的問題。客戶 email 是需求已驗證的主題。
- CA-02:改寫過的客戶引言失去了真實信號。確切的文字對語氣校準和搜尋關鍵字對齊至關重要。

## 反模式
不應:「一位客戶詢問了防火門間隙要求。」
應改為:保留逐字原文 — 「我有一扇防火門,頂部有大約 1/4 英寸的縫隙 — NFPA 80 有規定最大間隙嗎,還是由 AHJ 決定?」

## 適用範圍
此政策適用於:email 主題、HubSpot 對話主題,以及任何用作文章起源信號的客戶互動。不適用於從 AI 爬蟲資料衍生的缺口分析主題(這類主題沒有客戶引言)。
Policy model-routing / policies/model-routing.md
# Model Routing Policy

## Routing Table

| Task | Model | Why |
|------|-------|-----|
| Research, fact verification | Gemini Pro (gemini-2.5-pro) | Search grounding — real-time regulatory data |
| Writing, strategy | Claude Opus | Highest language quality for professional audience |
| Structured output, validation | Codex | Best at JSON output, schema-conformant responses |
| Claim bank, HTML, sitemap, validators | Python scripts | 0 tokens — deterministic, no AI drift |
| 3-family blind eval | Sonnet + Haiku + Gemini | Different families prevent self-grade bias (CA-04) |

## Rules

1. **Never use Claude for research** — Claude's training data has a knowledge cutoff. Gemini Pro with search grounding provides current regulatory information.

2. **Never use Gemini for writing** — writing quality matters for our professional audience (architects, facility managers). Claude Opus produces more nuanced, authoritative prose.

3. **Never use the same model to write AND evaluate** — self-grading is systematically biased. The 3-Model blind eval uses Sonnet, Haiku, and Gemini (CA-04). None of these wrote the article.

4. **Never use AI for deterministic tasks** — claim bank building, citation validation, HTML conversion, and sitemap updates are deterministic operations. Running them through AI wastes tokens and introduces hallucination risk (CA-05).

5. **CLI subscriptions only** — use `gemini` CLI (Google AI Ultra) and `codex` CLI ($200/mo subscriptions). Never use REST APIs with quota-limited keys.

## Why model routing matters
Each model has different strengths. Routing tasks to the wrong model produces worse output AND costs more tokens. The routing table is optimized for the specific demands of regulatory content: accuracy (Gemini research), authority (Opus writing), and unbiased evaluation (3-family blind eval).
# 模型路由政策

## 路由表

| 任務 | 模型 | 原因 |
|------|------|------|
| 研究、事實查核 | Gemini Pro (gemini-2.5-pro) | 搜尋基礎 — 即時法規資料 |
| 撰寫、策略 | Claude Opus | 最高語言品質,面向專業受眾 |
| 結構化輸出、驗證 | Codex | 最擅長 JSON 輸出和符合 schema 的回應 |
| Claim bank、HTML、sitemap、驗證器 | Python 腳本 | 0 token — 確定性,無 AI 漂移 |
| 3 家族盲評 | Sonnet + Haiku + Gemini | 不同家族防止自評偏差(CA-04) |

## 規則

1. **不可用 Claude 做研究** — Claude 的訓練資料有知識截止日期。Gemini Pro 搭配搜尋基礎提供即時法規資訊。

2. **不可用 Gemini 做寫作** — 寫作品質對我們的專業受眾(建築師、設施管理者)至關重要。Claude Opus 產出更細膩、更具權威性的文章。

3. **不可用同一模型既寫作又評估** — 自評存在系統性偏差。3-Model 盲評使用 Sonnet、Haiku 和 Gemini(CA-04),這些模型都不是文章的撰寫者。

4. **不可用 AI 做確定性任務** — Claim bank 建立、引用驗證、HTML 轉換和 sitemap 更新都是確定性操作。透過 AI 執行既浪費 token 又引入幻覺風險(CA-05)。

5. **只用 CLI 訂閱** — 使用 `gemini` CLI(Google AI Ultra)和 `codex` CLI(每月 $200 訂閱)。絕對不使用有配額限制的 REST API。

## 為何模型路由很重要
每個模型都有不同的強項。將任務路由到錯誤的模型會產出更差的結果,並消耗更多 token。路由表針對法規內容的特定需求進行了優化:準確性(Gemini 研究)、權威性(Opus 撰寫)和公正評估(3 家族盲評)。
Policy quality-gate / policies/quality-gate.md
# Quality Gate Policy

## Four mandatory gates before publication

### Gate 1 — Claim Bank (CA-06)
- `build_claim_bank.py` must run and exit 0
- P0 claim count must be ≥3
- Failure blocks: `composite/write-article` cannot start without passing Gate 1

### Gate 2 — 3-Model Blind Evaluation (CA-04)
- Three models from different families: Claude Sonnet + Claude Haiku + Gemini Pro
- Each model scores the draft independently (no model sees others' scores)
- Median score must be ≥8.0 out of 10
- Budget: 2-hour window, no round limit — iterate until median ≥8.0 or escalate
- Failure routes back to `composite/write-article` with revision instructions

### Gate 3 — 3 Persona Q7 = YES (CA-07)
- Architect, Facility Manager, Contractor — each must answer Q7=YES
- Q7: "Would you bookmark this page or share it with a colleague?"
- Any Q7=NO is a hard block — article must be revised
- Q5 angle-gate: reader must feel "helped" not "sold to"

### Gate 4 — 3 Python Validators exit 0 (CA-05)
- `validate_citations.py` — all P0 claims exist in claim-bank.json
- `validate_specs.py` — no product specs contradict waterson-wiki
- `validate_corrections.py` — no repeat of known errors in corrections-log.md
- Any non-zero exit = automatic CRITICAL failure

### AI Citation Willingness Test (page-mirror only)
- Ask 3 AI models: "Would you cite this as a source?"
- Gate: ≥2/3 models say YES
- This gate applies to mirror-page rewrites — not to new articles (which use Gates 1-4)

## Why these specific gates
Each gate catches a different failure mode: Gate 1 = no regulatory authority; Gate 2 = poor quality writing; Gate 3 = wrong audience/tone; Gate 4 = factual errors. Running all four gates in sequence filters articles that look good on the surface but fail the actual test — whether an AI engine would trust them enough to cite.
# 品質閘門政策

## 發布前四道強制閘門

### 閘門一 — Claim Bank(CA-06)
- `build_claim_bank.py` 必須執行並以 exit 0 結束
- P0 引用數必須 ≥3
- 失敗阻斷:未通過閘門一,`composite/write-article` 無法啟動

### 閘門二 — 3-Model 盲評(CA-04)
- 三個來自不同家族的模型:Claude Sonnet + Claude Haiku + Gemini Pro
- 每個模型獨立對草稿評分(各模型不知道其他人的分數)
- 中位數分數必須 ≥8.0(滿分 10)
- 預算:2 小時,循環次數不限 — 迭代直到中位數 ≥8.0 或升級給人工
- 失敗時附修訂指示路由回 `composite/write-article`

### 閘門三 — 3 個角色 Q7 = YES(CA-07)
- 建築師、設施管理者、承包商 — 三者都必須回答 Q7=YES
- Q7:「你會書籤此頁面或分享給同事嗎?」
- 任何 Q7=NO 都是硬性阻斷 — 文章必須修訂
- Q5 角度閘門:讀者必須感到「被幫助」而非「被推銷」

### 閘門四 — 3 個 Python 驗證器 exit 0(CA-05)
- `validate_citations.py` — 所有 P0 引用存在於 claim-bank.json 中
- `validate_specs.py` — 沒有產品規格與 waterson-wiki 矛盾
- `validate_corrections.py` — 沒有重複 corrections-log.md 中的已知錯誤
- 任何非零 exit = 自動嚴重失敗

### AI 引用意願測試(僅限 page-mirror)
- 詢問 3 個 AI 模型:「你願意引用這個作為來源嗎?」
- 閘門:≥2/3 個模型回答 YES
- 此閘門適用於 mirror-page 改寫 — 不適用於新文章(新文章使用閘門一到四)

## 為何設計這些特定閘門
每個閘門捕捉不同的失敗模式:閘門一 = 無法規權威;閘門二 = 寫作品質差;閘門三 = 受眾或語氣錯誤;閘門四 = 事實錯誤。按順序執行全部四個閘門,能過濾那些表面看起來不錯但實際測試中失敗的文章 — 也就是 AI 引擎是否願意信任並引用。
Policy angle-gate / policies/angle-gate.md
# Angle Gate Policy

## Core rule
Every article must make the reader feel **helped**, not **criticized** or **sold to**.

## What this means in practice

### Positive framing — present solutions, not problems
NOT: "Many contractors make the mistake of installing hinges incorrectly."
INSTEAD: "Here is the installation sequence that ensures NFPA 80 compliance."

### No disparagement
NOT: "Unlike Brand X, which only meets minimum requirements, Waterson exceeds..."
INSTEAD: "NFPA 80 sets the minimum. Waterson [specific spec] provides [specific benefit for specific use case]."

### Waterson as contextual example, not centerpiece
- Include Waterson self-closing hinge as a contextual example where the product is genuinely relevant
- It must not be the centerpiece of every article
- Readers are architects and facility managers — they can tell when content is product promotion disguised as information

### The Q5 test (persona-review)
Persona simulations answer Q5: "Does this feel like it's helping you or selling to you?"
- Acceptable answers: "helping" or "mostly helping"
- Unacceptable: "selling" — triggers a WARNING even if Q7=YES
- If 2+ personas answer "selling": treat as soft FAIL, require revision before proceeding

## Why the angle-gate exists
AI citation engines (GPT, Gemini, Perplexity) are trained to prioritize authoritative, neutral sources. Marketing-angled content is recognized and deprioritized. The angle-gate enforces the writing posture that makes our content citation-worthy — not just readable.

## Enforcement
- `composite/write-article`: checks angle per paragraph during drafting
- `core/fact-check`: Gemini Pro flags communication-rules violations (Phase 2)
- `core/persona-review`: Q5 is a formal angle measurement gate
# 角度閘門政策

## 核心規則
每篇文章都必須讓讀者感到**被幫助**,而非**被批評**或**被推銷**。

## 實際意味著什麼

### 正面框架 — 呈現解決方案,不呈現問題
不應:「許多承包商都犯了安裝鉸鏈的錯誤。」
應改為:「以下是確保符合 NFPA 80 的安裝步驟。」

### 不批評競品
不應:「與只達到最低標準的 X 品牌不同,Waterson 超越了...」
應改為:「NFPA 80 設定了最低要求。Waterson [具體規格] 為 [具體使用情境] 提供 [具體好處]。」

### Waterson 作為情境範例,不作為主角
- 在產品確實相關時,將 Waterson 自閉合鉸鏈作為情境範例提及
- 不可讓它成為每篇文章的主角
- 讀者是建築師和設施管理者 — 他們能辨識偽裝成資訊的產品推廣

### Q5 測試(persona-review)
角色模擬回答 Q5:「這篇文章給您幫助您還是向您推銷的感覺?」
- 可接受的答案:「幫助」或「大致幫助」
- 不可接受:「推銷」— 即使 Q7=YES 也觸發警告
- 若 2+ 個角色回答「推銷」:視為軟性失敗,修訂後才繼續

## 為何存在角度閘門
AI 引用引擎(GPT、Gemini、Perplexity)被訓練為優先引用具權威性、中立的來源。行銷導向的內容會被識別並降低優先級。角度閘門強制執行讓我們的內容值得被引用的寫作姿態 — 不只是可讀。

## 強制執行
- `composite/write-article`:撰寫過程中逐段檢查角度
- `core/fact-check`:Gemini Pro 標記違反 communication-rules 的內容(第二階段)
- `core/persona-review`:Q5 是正式的角度衡量閘門

Mandatory Rules & Anti-patterns 強制規則 & 反模式

CLAUDE.md Content Authority — Mandatory Rules
# Content Authority — Mandatory Rules

## BLOCKING Rules

| Rule  | MUST NOT                                               | MUST INSTEAD                                               |
|-------|--------------------------------------------------------|------------------------------------------------------------|
| CA-01 | Write articles from AI-brainstormed topics             | Every article traces to ≥1 real customer question (threadId) |
| CA-02 | Discard email raw content after topic extraction       | Preserve original words + threadId in source-material.md   |
| CA-03 | Use non-P0 sources as regulatory authority             | Only NFPA/ADA/ANSI/IBC/UL for code citations               |
| CA-04 | Same model writes and evaluates (self-grading)         | 3-Model blind eval from different families                  |
| CA-05 | Use AI for deterministic tasks                         | Python scripts for claim bank, validators, HTML, sitemap    |
| CA-06 | Skip claim bank before writing                         | build_claim_bank.py MUST run first (Gate 1)                 |
| CA-07 | Publish without 3 Persona Q7=YES                       | Architect + FM + Contractor all say YES                     |
| CA-08 | Add to content-plan without source metadata            | Must include source_type, signal_strength, source_ids       |
| CA-09 | Run gap analysis in multiple places                    | Single gap-analysis infra skill, consumed by all depts      |
| CA-10 | Drip-feed page rewrites monthly                        | Phase 1: batch-rewrite ALL pages in 2 weeks                 |

## Model Routing

| Task                    | Model          | Why                         |
|-------------------------|----------------|-----------------------------|
| Research, fact check    | Gemini Pro     | Search grounding            |
| Writing, strategy       | Claude Opus    | Highest language quality    |
| Structure, validation   | Codex          | Best at structured output   |
| Claim bank, HTML, sitemap| Python script  | 0 tokens, deterministic     |
| Blind eval              | Sonnet+Haiku+Gemini | Different families     |
# 內容權威 — 強制規則

## 阻斷性規則

| 規則  | 不可做                                     | 必須改為                                      |
|-------|-------------------------------------------|-----------------------------------------------|
| CA-01 | 從 AI 腦力激盪的主題寫文章                 | 每篇文章追溯到 ≥1 個真實客戶問題(threadId)    |
| CA-02 | 抽取主題後丟棄 email 原始內容              | 保存客戶原始文字 + threadId 到 source-material.md |
| CA-03 | 以非 P0 來源作法規依據                     | 法規引用只用 NFPA/ADA/ANSI/IBC/UL             |
| CA-04 | 同一模型寫作又評估(自評)                 | 不同家族 3 個模型做盲評                         |
| CA-05 | 用 AI 做確定性任務                         | Claim bank、驗證、HTML、sitemap 全用 Python 腳本 |
| CA-06 | 撰寫前跳過 claim bank                      | build_claim_bank.py 必須先跑(Gate 1)          |
| CA-07 | 3 個角色 Q7 未全 YES 就發布               | 建築師 + 設施管理 + 承包商全部 YES              |
| CA-08 | 加入 content-plan 但沒有來源 metadata     | 必須包含 source_type、signal_strength、source_ids |
| CA-09 | 在多個地方各自跑缺口分析                   | 單一 gap-analysis infra skill,所有部門共用     |
| CA-10 | 每月零散改寫頁面                           | 第一期:2 週內批量改寫所有頁面                  |
Anti-patterns Common violations and correct alternatives
# Anti-patterns

NOT: Write articles from AI-brainstormed topics without customer demand signal
INSTEAD: Every article traces to ≥1 real customer question (threadId in source-material.md)

NOT: Discard email raw content after topic extraction
INSTEAD: Preserve customer's original words + threadId in source-material.md

NOT: Use non-P0 sources as regulatory authority
INSTEAD: Only NFPA/ADA/ANSI/IBC/UL for code citations. P2-P4 = background only

NOT: Same AI model writes and evaluates (self-grading)
INSTEAD: 3-Model blind eval from different families

NOT: Use AI for deterministic tasks
INSTEAD: Python scripts for claim bank, validators, HTML, sitemap (0 tokens)

NOT: Drip-feed page rewrites monthly
INSTEAD: Phase 1 batch-rewrite ALL pages, Phase 2 maintain standard

NOT: Evaluate content with human metrics only
INSTEAD: AI Citation Willingness Test (ask AI "would you cite this?")

NOT: Run gap analysis in multiple places
INSTEAD: Single gap-analysis infra skill

NOT: Add to content-plan without source metadata
INSTEAD: Must include source_type, threadId, signal_strength

NOT: Skip claim bank before writing
INSTEAD: build_claim_bank.py MUST run first (Gate 1)

NOT: Give each agent its own OGSM
INSTEAD: 1 team OGSM, agents are lightweight schedulers with trigger + steps only
# 反模式

不應:從 AI 腦力激盪的主題寫文章,沒有客戶需求信號
應改為:每篇文章追溯到 ≥1 個真實客戶問題(source-material.md 有 threadId)

不應:抽取主題後丟棄 email 原始內容
應改為:保存客戶原始文字 + threadId 到 source-material.md

不應:以非 P0 來源作法規依據
應改為:只用 NFPA/ADA/ANSI/IBC/UL 作法規引用,P2-P4 僅作背景

不應:同一個 AI 模型既寫作又評估(自評)
應改為:來自不同家族的 3 個模型做盲評

不應:用 AI 做確定性任務
應改為:Claim bank、驗證、HTML、sitemap 全用 Python 腳本(0 token)

不應:每月零散改寫頁面
應改為:第一期批量改寫所有頁面,第二期維持標準

不應:只用人類指標評估內容
應改為:AI 引用意願測試(問 AI「你願意引用這篇嗎?」)

不應:在多個地方各自跑缺口分析
應改為:單一 gap-analysis infra skill,所有部門共用

不應:主題加入 content-plan 沒有來源 metadata
應改為:必須包含 source_type、threadId、signal_strength

不應:撰寫前跳過 claim bank
應改為:build_claim_bank.py 必須先跑(Gate 1)

不應:給每個 agent 自己的 OGSM
應改為:1 個團隊 OGSM,agent 只是有 trigger + steps 的輕量排程器