Skip to content
Back to skills

Check Before

ASecurity

交付前對「使用者指定的一份文件」做易讀性自檢:跑十一項機械掃描(編號連續、未定義代號與代號先用後定義、術語首次出現沒說明、 交叉引用、重複、異動紀錄用語、樣式一致、表格欄寬、內部推導痕跡、公文式敬稱、目錄頁碼),並擋 AI 工具名稱再加五條人工判斷, 回報要改的地方;pptx/docx/pdf 另做視覺檢查(用 PowerPoint/Word 實際排版,抓疊字、字跑出方塊、 超出頁面、字太小,每頁輸出圖片逐張看過);docx/pptx/xlsx/pdf 另查文件屬性(標題、作者留著產生工具預設值)。 可選擇對照客戶最新來信、與上一版比對合約條款(票期、付款、金額)。 支援 .docx / .pptx / .xlsx / .md / .txt / .pdf,Windows/macOS/Linux 都能跑。 **需要使用者給檔案路徑或檔名**,沒給就先問。 當使用者說「check-before」「交付前檢查這份」「幫我自檢 XXX.docx」「這份文件可以交了嗎」 「掃一下這份文件的易讀性」「簡報有沒有疊字」「檢查投影片跑版」時觸發。 只檢查、不改檔;要改由使用者確認後另外做。要寫交...

  • 2 stars
  • 0 votes
  • 0 copies
  • 1 view
  • Added September 29, 2026
ai-agentstypescriptpythonshellnode

Works with

  • claude code
  • cursor
  • mcp

Security analysis

A92/100
  • mediumInstalls packages at runtime which could introduce malicious dependencies

Pro scans all 3 files and shows the line behind each finding

Scanned October 3, 2026

npx -y skills add abs1294/fulin-claude-plugins --skill check-before --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of Check Before?

Add the live security badge to your README. It updates with every re-scan.

Security grade badge for Check Before
[![Security: A — Skills Directory](https://www.skillsdirectory.com/api/skills/abs1294-check-before/badge)](https://www.skillsdirectory.com/skills/abs1294-check-before)

More formats (shields.io, HTML) on the badges page. Keep it an A: scan every change in CI with Pro.

Download with Pro
SKILL.md
---
name: check-before
description: >
  交付前對「使用者指定的一份文件」做易讀性自檢:跑十一項機械掃描(編號連續、未定義代號與代號先用後定義、術語首次出現沒說明、
  交叉引用、重複、異動紀錄用語、樣式一致、表格欄寬、內部推導痕跡、公文式敬稱、目錄頁碼),並擋 AI 工具名稱再加五條人工判斷,
  回報要改的地方;pptx/docx/pdf 另做視覺檢查(用 PowerPoint/Word 實際排版,抓疊字、字跑出方塊、
  超出頁面、字太小,每頁輸出圖片逐張看過);docx/pptx/xlsx/pdf 另查文件屬性(標題、作者留著產生工具預設值)。
  可選擇對照客戶最新來信、與上一版比對合約條款(票期、付款、金額)。
  支援 .docx / .pptx / .xlsx / .md / .txt / .pdf,Windows/macOS/Linux 都能跑。
  **需要使用者給檔案路徑或檔名**,沒給就先問。
  當使用者說「check-before」「交付前檢查這份」「幫我自檢 XXX.docx」「這份文件可以交了嗎」
  「掃一下這份文件的易讀性」「簡報有沒有疊字」「檢查投影片跑版」時觸發。
  只檢查、不改檔;要改由使用者確認後另外做。要寫交付訊息走 deliver-report,要產確認清單走 to-checklist。
---

# check-before:交付文件自檢

對使用者點名的一份文件,照 `../../references/document-readability.md` 的鐵則做交付前檢查。
判準與 Stop hook(`hooks/doc-readability-gate.js`)是**同一份程式**(`hooks/lib/readability-scan.core.js`),
所以這裡過了,交付時的自動閘也會過。差別:這裡由使用者點名、任何格式(docx/pptx/xlsx/md/txt/pdf)都能查,
且對 docx 多跑三項(重複偵測、內部推導痕跡、Markdown 標題編號)——Stop hook 掃 docx 時不跑這三項,避免交付時多出判不準的提醒。
文件屬性、客戶來信對照、合約條款比對也只在這裡跑,Stop hook 不跑。
其他 subskill 已經把這支腳本接進自己的腳本裡,會自動跑:to-checklist 在 `md_to_pdf.py` 轉檔前、test-report-docx 在 `report_gate.verify_docx()`(閘三)、daily-report 在寄送前置流程(`send_common.prepare_send`)與 MCP 建草稿前(PreToolUse hook `daily-draft-gate.js`)。deliver-report 沒有產檔腳本,由 Stop hook 掃本回合提到或寫過的交付檔(任何位置與格式,含 docx 目錄頁碼)。

## 流程

1. **確定檢查哪一份**:使用者給了路徑或檔名就用;沒給就問「要檢查哪一份檔案?給路徑或檔名都可以」,**不要自己猜最近改過的檔**。

2. **先問兩件可選的附帶資料**(使用者已經給了、或文件顯然用不到就不問):
   - 文件裡有「待確認/待客戶確認/TBD」時:「有沒有這個客戶的最新來信要對照?」有的話用 Gmail 工具(`search_threads`→`get_thread`)找出信件串,
     把每封的寄件人、日期與內文存成**暫存資料夾裡的純文字檔**,交給 `--thread`。不要存進專案目錄,信件內容是客戶原文。
   - 報價單、合約、提案這類有付款與條款的文件:「有沒有上一版要比對條款?」有的話把舊版路徑交給 `--prev`。
   - 沒有就照樣跑:docx/pptx/xlsx/pdf 腳本會把這兩項列在「這次沒檢查到的」;md/txt 腳本不列,回報時自己寫進「這次沒檢查到的」。

3. **跑機械掃描+視覺檢查**:
   ```
   node "${CLAUDE_PLUGIN_ROOT}/skills/check-before/scripts/check_doc.js" "<路徑或檔名>" --visual [--thread <信件串.txt>] [--prev <上一版>]
   ```
   - 只給檔名時,腳本從目前目錄往下找(最多 6 層);檔名可省略副檔名。
   - `--visual` 讓 docx/pdf 也跑視覺檢查(pptx 不加也會跑);md/txt 沒有版面,不跑。
   - **exit 2**=找不到、有多份同名候選、讀不到內容,或**要跑視覺檢查卻沒有排版軟體**。把腳本訊息原樣給使用者,不可回報「通過」。
   - 本機沒有 Python(或 pdf 缺 pypdf、視覺檢查缺 PyMuPDF/Pillow)**不是 exit 2**:xlsx/pdf 的內容、各格式的文件屬性、視覺檢查跑不了,腳本把它們列進「這次沒檢查到的」並附安裝方式,內容沒讀時硬缺陷那行寫「0 項——但文件內容沒有讀取」、--thread/--prev 也不比對;--json 的 pass 為 false。回報時照列、轉告使用者要裝什麼,不可說已通過。
   - **exit 1**=有硬缺陷;**exit 0**=硬缺陷 0(可能仍有提醒)。
   - 以「視覺」開頭的項目來自視覺檢查,見下方「視覺檢查」一節;「文件屬性」「客戶來信對照」「合約條款」見「文件屬性、來信對照、條款比對」一節。

4. **逐張看每頁畫面**(有跑視覺檢查時):腳本最後列出每頁的 PNG(問題處有紅框)。**每一張都用 Read 打開**,
   在回報裡逐頁寫一句看到什麼:有沒有疊字、被切掉、空白、字擠成一團。
   - 機器只判得準「字形互相壓到」;SmartArt、圖片裡的字、文字轉外框、字壓在圖案上,只有看圖才抓得到。
   - 總覽圖 `overview.png` 只當索引,縮圖看不出細微疊字,不能代替逐張看。
   - **Stop hook(`hooks/visual-view-gate.js`)會檢查**:清單上的每一張都要在清單印出後被 Read 過(讀取失敗的不算),漏看就擋下收尾。
     圖檔已被刪掉的不要求;同一回合連擋 3 次都沒有進展會放行並提醒,這時回報必須列出哪幾頁沒看、屬未驗證。

5. **人工判斷五條**(機器判不了,逐條讀過文件再下判斷,不能跳):
   - 鐵則 4/15:**從第一頁讀起,每個代號、術語在第一次出現時就看得懂嗎?** 先確認讀者是誰(PM、客戶主管、工程師),用那個讀者的眼睛讀結論頁與前三頁:「方案 B」「C1」「user_team」這類詞第一次出現時,同一句有沒有講它是什麼。腳本只抓得到代號形狀與英文術語形狀;中文行話(「聚合」「呼叫點」「去識別化」)只能靠這一條。
   - 鐵則 1:讀者是否要兩邊對照才能做完一件事?
   - 鐵則 2:同一件事的資訊是否散在正文與備註兩處?
   - 鐵則 6:有沒有「待確認」其實我方自己查得到?
   - 鐵則 10:有沒有機械性步驟該給腳本、卻叫對方手動做?

6. **逐條判斷腳本的「提醒」**:重複內容、推導痕跡、敬稱、代號先用後定義(鐵則4)、術語首次出現沒說明(鐵則15)都是判不準的項目——搜到不等於要改。代號先用後定義要對照第 5 步的人工判斷逐條看:機器沒認出的定義寫法很多,列出來不等於有問題,但「方案 B 第 2 頁首次出現、第 18 頁才定義」這種就是真問題。鐵則15 列出的數量本身是訊號:給決策者的文件列出幾十上百個,就是整份寫給工程師看的,要回頭改寫前幾頁。每條講清楚「要改/不用改,因為…」。
   - **客戶來信對照**:腳本只列出每條待確認與信件串最新日期。逐條讀信判斷「這條信裡答了沒」,答了就列進要改的,附出處(信件日期、寄件人)與一句摘要——**不要把信件內文整段貼進回報**。
   - **合約條款**:「舊版有、新版找不到」逐條問使用者是不是刻意刪除;「數字變動」確認新值是有意調整。不自己判對錯。
   腳本報的硬缺陷也要先確認**是文件錯還是檢查器錯**(檢查器會過時,踩過)。

7. **回報**,照這個結構:
   - 檔案、格式、段落數
   - **要改的**:每項附位置(章節或原句片段)與建議改法
   - **看過不用改的**:提醒項為什麼放行
   - **每頁畫面**:逐頁一句看到什麼(視覺檢查有跑時)
   - **這次沒檢查到的**:腳本「□ 這次沒檢查到的」段落列的每一項照列(沒給 --thread/--prev),提醒裡的「文件屬性未檢查」也列進來;md/pdf 不跑樣式一致與表格欄寬(沒有字級、欄寬資訊),請使用者目視或改用 docx 檢查;pdf 若是掃描圖檔沒有文字層,腳本會 exit 2;
     視覺檢查用的不是對方實際的軟體時(Keynote、LibreOffice),要明講版面問題都只是提醒、需在 PowerPoint/Word 確認
   - 兩份以上文件一起交付時,加做**跨文件一致性**:步驟數、項數、數字宣稱值兩份要一致

8. **不改檔**。使用者說要改再改,改完**同一類問題全文重掃**,再跑一次本腳本確認歸零。

## 文件屬性、來信對照、條款比對

| 項目 | 適用 | 判準 | 等級 |
|------|------|------|------|
| 產生工具預設值 | docx/pptx/xlsx/pdf | 欄位+值成對比對 `references/banned-patterns.json` 的 `generator_defaults`(PptxGenJS、python-pptx、python-docx、openpyxl 的預設標題、作者、描述、公司)。同一個值在別的欄位不算——Steve Canny 只有在「最後修改者」才是 python-pptx 的預設 | 硬缺陷 |
| AI 工具名稱、憑證、個資 | 同上 | 與內文同一套規則,掃每個屬性欄位 | 硬缺陷 |
| 沒有標題、標題與檔名看不出關聯 | 同上 | 中文標題配英文檔名不比;判不準 | 提醒 |
| 客戶來信對照 | 任何格式,給 `--thread` | 列出每條待確認(第幾段+原句)與信件串最新日期;「已答覆」是語意判斷,由人逐條判讀 | 提醒 |
| 合約條款比對 | 任何格式,給 `--prev` | 票期、付款、驗收、保固、報價有效期、稅別、金額、交期、違約九類:舊版有新版沒有、或該類句子裡的數字變了 | 提醒 |
| 隱藏工作表、儲存格註解 | xlsx | 隱藏(含深度隱藏)工作表列名稱;註解內容和工作表內容一起掃 | 提醒 |

- md/txt 沒有文件屬性,腳本表頭會註明「不適用」,回報照寫,不算沒檢查。
- PDF 的屬性從來源檔帶過來:PptxGenJS 產的簡報轉成 PDF,標題、作者、主旨照樣是 PptxGenJS 預設值。Chrome 列印的 PDF(to-checklist 的產出)Creator 是 HeadlessChrome、Producer 是 Skia/PDF,這是正常值,不擋。
- 改屬性:Word/PowerPoint/Excel 在「檔案 → 資訊 → 內容」;python-docx 用 `doc.core_properties`,python-pptx 用 `prs.core_properties`,PptxGenJS 設 `pptx.title/subject/author/company`(只設 title 的話 subject 仍是預設值)。
- 「這次沒檢查到的」只在 docx/pptx/xlsx/pdf 列(沒給 `--thread` 且文件有待確認、沒給 `--prev`)。md/txt 不列:日報寄送、確認清單轉檔也呼叫這支並照印輸出,印出「不算通過」會和放行結果矛盾。
- 文件屬性讀不到(壞掉的屬性檔、同一欄位出現兩次、本機沒有 Python、PDF 沒有 pypdf)記成提醒「文件屬性未檢查(此項屬未驗證)」,不 exit 2;缺 Python/pypdf 時提醒裡附安裝方式。Python 本身沒跑成(逾時、異常結束、查不出套件裝了沒)不算這種,是 exit 2。
- xlsx 一列接成一行(儲存格之間用全形空白),條款字眼與同列的金額數值才比對得到;資料格的 V2、S3、#4 這類代碼在 xlsx 降為提醒,不當成未定義代號擋下。
- 條款數字比對會去掉句首項次編號(1.、(2)),用出現次數比;同一類條款的數字在不同句子間互換,比不出來。

## 視覺檢查(`scripts/visual_check.py`)

**先排版、再判定**。排版交給對方實際會用的軟體,換行、字型替換、自動縮小文字才會跟對方看到的一樣:

| 檔案 | Windows | macOS | Linux |
|------|---------|-------|-------|
| pptx | PowerPoint → LibreOffice | PowerPoint → Keynote → LibreOffice | LibreOffice |
| docx | Word → LibreOffice | Word → LibreOffice | LibreOffice |
| pdf | 不必排版 | 不必排版 | 不必排版 |

前一個失敗(沒裝、開檔失敗、逾時)就換下一個,原因記在提醒裡;全都沒有 → exit 2(視覺未驗證)。
本機沒有 Python 或缺 PyMuPDF/Pillow 不算這種:視覺檢查列進「這次沒檢查到的」並附安裝方式,不 exit 2。
Keynote 與 LibreOffice 不是對方實際的軟體:字寬不同,換行位置跟著不同(實測兩份真實簡報,PowerPoint 0 處疊字、LibreOffice 各多 6~7 處,都是標題最後一個字被擠到下一行)。
所以用它們排版時,疊字、字跑出方塊、超出頁面**一律降為提醒**,標「PowerPoint 可能正常,請在 PowerPoint 確認」,紅框照畫、圖照樣逐張看;「溢出時縮小文字」改從檔案記錄的縮小比例推算 PowerPoint 會顯示的字級。
只關掉檢查器自己開的 PowerPoint/Word——使用者本來就開著的不會被關。
macOS 第一次跑會跳「允許終端機控制 PowerPoint/Keynote」,要有人按允許(系統設定 → 隱私權與安全性 → 自動化)。

判定只有一份,讀排版後每個字實際畫出來的位置:

| 項目 | 判準 | 等級 |
|------|------|------|
| 疊字 | 兩行字形互相壓到,面積超過較小那行的 5%;同一段字疊兩層(重複貼上)也算 | 硬缺陷 |
| 字跑出方塊外 | pptx 有底色或框線的方塊,裡面的字畫到方塊外(看不見的文字方塊不算,撞到別的字時由疊字抓) | 硬缺陷 |
| 超出頁面 | 字畫在頁面外;pptx 有字卻沒出現在畫面上(被裁掉、表格撐出投影片) | 硬缺陷 |
| 字太小 | 實際字級小於 10pt(含「溢出時縮小文字」縮出來的);頁首頁尾這種每頁都有的合併成一條 | 提醒 |
| 文字壓在圖上 | 文字和圖片重疊,整頁背景圖不算(pptx 看真正的圖片物件,方塊的陰影漸層不算) | 提醒 |
| 字型沒內嵌 | pptx 指定的字型沒內嵌,對方電腦沒有就會被替換、換行跟著變(Arial、Calibri 等 Windows 與 Mac 都有的不列) | 提醒 |
| 空白頁、重複頁 | 整頁同一顏色;兩頁畫面完全相同 | 提醒 |

輸出在系統暫存資料夾的 `deliver-report-visual/<檔名>-<時間>/`:`page-NNN.png`、`overview.png`、`rendered.pdf`、`visual-manifest.json`。
回歸測試:`python hooks/tests/visual/run_fixtures.py [--engine powerpoint|keynote|libreoffice]`(16 份測試文件,逐份對照預期)。
排版時一律開複本(暫存資料夾、不撞名的檔名),不會動到或關掉使用者正開著的原檔;只關掉、清掉用視窗代號確認是這次開的 PowerPoint/Word;逾時時若還沒拿到視窗代號(卡在啟動或開檔對話框),一律不殺,只在訊息列出可能殘留的程序編號,請使用者確認後手動關。
排版開的是複本,簡報或文件裡用相對路徑連結的外部檔(連結的圖片、OLE 物件)在複本位置找不到,這類內容的畫面可能和原檔不同。
隱藏投影片不會輸出,頁碼以放映時看到的順序為準;張數對不上時「字跑出方塊外」「文字被裁掉」「字被縮小」三項改記未檢查。

## 前置依賴

- Node.js(掃描本體;docx/pptx 用內建 zlib 解壓,不需 PowerShell,各平台都能跑)
- 檢查 docx 的目錄頁碼:Windows 上的 Microsoft Word(唯讀開檔、比對更新目錄前後,不存檔;約 5 秒)。沒有 Word 或非 Windows 時記成提醒「目錄頁碼未檢查(此項屬未驗證)」——腳本不會因此 exit 非 0,回報時要列進「這次沒檢查到的」,不可說目錄已檢查
- 檢查 xlsx 的內容、docx/pptx/xlsx 的文件屬性:Python 3(只用標準庫,不必另裝套件;XML 交給 `hooks/lib/office_xml.py` 解析)。沒有 Python 時不擋,列進「這次沒檢查到的」並附安裝方式
- 檢查 pdf 的文字與文件屬性:Python 3 與 `pypdf`(`pip install pypdf`)
- 視覺檢查:Python 3、`pip install pymupdf pillow`,加上排版軟體(見上表)。缺 Python 或這兩個套件時不擋,列進「這次沒檢查到的」並附安裝方式

## AI 工具名稱怎麼擋(不必逐一加名字)

- **品牌族規則**:`references/banned-patterns.json` 的 `ai_tool_names`,一條規則涵蓋整個系列與未來版號(GPT-任意版號、Llama 加數字、Claude/Codex/Gemini…)。
- **本機自動蒐集**:每次掃描時自動讀取本機已安裝的 Claude Code plugin、marketplace、MCP 伺服器名稱(只收含連字號或數字的,如 `deliver-report`、`openai-codex`),以及描述標為 AI/LLM/agent 的全域 npm 工具(如 `codex`、`openspec`)。以後裝了新的 AI 工具,不用改任何設定就會一起擋。
- 一般工具(Playwright、TypeScript、Figma、資料庫 cursor)不會被擋。命中時會印出原字,照提示改寫或刪除。

Files in this skill

  • SKILL.md10.2 KB
  • scripts/check_doc.js8.1 KB
  • scripts/visual_check.py49.1 KB

Attribution

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

Comments

Loading comments…

Newsletter

Get the weekly list of safe new skills, and the ones we pulled.