1实现原理 · 为什么它能做到
两条流水线共享同一终点外观与同一哲学:脚本只干执行,agent 保留两个不可自动化的判断——按内容排序页面、整档验证。
**Division of labor**: scripts carry execution; you (the agent) carry the two judgment steps — content-based page ordering, and whole-document verification. Neither can be automated away: filenames lie about order, and per-page spot checks miss wrong-slot bugs.
透视矫正与白平衡用自研 OpenCV 脚本:photo_to_scan.py 找最大亮斑四边形 warp 到 A4(200dpi),--raw 模式只矫正;默认模式多做『除以纸色背景』白平衡给彩纸页预洗。EXIF 旋转由 PIL exif_transpose 先修(cv2.imread 忽略 EXIF)。
The script handles EXIF rotation internally (`cv2.imread` ignores EXIF; phone photos come rotated — this silently produces sideways pages if you rectify with raw OpenCV).
『扫描感』由 noteshrink(uvx 外部工具)量化调色板实现:白纸批量一次 -w -g -K 全局调色板统一墨/章色,-c "true" 跳过其内部 PDF 步骤由本 skill 自组装。
uvx noteshrink -w -g -K -q -b ns -c "true" page_03.jpg page_01.jpg page_07.jpg ...
A4 组装带边缘裁剪:assemble_pdf.py 每页先裁 24px 顶/12px 侧(200dpi)去除矫正拖入的桌面边条,img2pdf 直接嵌调色板 PNG 不重编码,输出 ~0.05MB/页。
Edge crop (default 24px top / 12px sides at 200 dpi) removes the sliver of desk surface that rectification drags in along page borders; document margins dwarf it.
验证纪律是『全档 contact sheet 必读』:make_contact_sheet.py 出一张总览图,agent 逐页核对顺序/色偏/印章签名,再抽查 1-2 页全分辨率锐度。
**"I verified the pages I changed" is not verification.**
数字签名分支(digital-signature-synthesis.md)用 synthesize_signature.py 五子命令完成:fonts/candidates/generate/locate/composite/scanify,字体必须经 candidates 页给用户挑(agent 不得自选),--seed 保证可复现。
**Send the candidates sheet to the user and get a number back — do not pick one yourself.** Which style reads as a plausible signature is a taste call, not something derivable from the document or the font's technical properties.
合成签名的定位靠 pdftotext -bbox 找签名行标签,并内建防错机制:标签与下划线被合并成一个 word 时会打 WARNING 并指导用像素扫描右缘,避免签名浮空。
This means `pdftotext` tokenized your label together with whatever sits right after it on the same line — most commonly a signature blank authored as underscores immediately following the label with no space (`簽名:_____`, an entirely ordinary way to type this in Word).
2核心能力
3外部依赖
| Kind | Dependency / Endpoint |
|---|---|
| cli | uvx noteshrink(扫描感增强,PEP 723 首跑 ~30s 构建) |
| cli | poppler pdftoppm / pdftotext(contact sheet / -bbox 定位) |
| package | opencv-python-headless / numpy / pillow / img2pdf(PEP 723 内联依赖) |
| cli | LibreOffice soffice(签名分支把 docx 渲染成页图) |
| cli | fc-list(fontconfig,发现手写体字体) |
4管控建议与判定依据
- scripts/: 执行本地脚本或命令: python photo_to_scan.py / assemble_pdf.py / make_contact_sheet.py / synthes
- 外部端点: 将本地内容或会话向第三方云存储外发
- 本地工作目录: 文件读写与工件输出: rectify/enhance 中间 PNG、assembled scanned.pdf、contact.png 写入用户指定工作目录;签名分支写签名
5第二遍独立确认
- [ok] 主流水线 rectify→noteshrink→assemble→contact sheet — 四个环节命令与脚本均在;photo_to_scan.py --raw 与默认白平衡模式分支存在。
- [ok] EXIF/quad/白平衡实现 — load_exif_corrected 用 ImageOps.exif_transpose;find_page_quad/warp_a4/flatten_whitebalance 函数在 photo_to_scan.py 源码可定位。
- [ok] 边缘裁剪默认值 24/12px — assemble_pdf.py argparse default crop_top=24/crop_side=12 与 SKILL 一致。
- [ok] noteshrink 参数 -w -g -K -c "true" — SKILL 命令与外部工具语义一致(noteshrink 为 uvx 外部包,未在本仓捆绑,命令调用方式可核)。
- [ok] 『只查改动页不算验证』纪律 — SKILL 原文 + 两个 shipped-bug 叙事(错槽覆盖邻页、调色板污染)在 Step 5。
- [ok] 签名分支六子命令 — synthesize_signature.py subparsers fonts/candidates/generate/locate/composite/scanify 均实现;candidates→用户挑选→generate 流程与 reference 一致。
- [ok] 候选人选门禁(agent 不自选字体) — reference 原文 'do not pick one yourself';脚本 generate 需 --font/--face/--ink 显式参数。
- [ok] 无网络/凭证/删除面 — 全脚本扫描零网络代码、零 env 密钥读取;无删除用户文件逻辑;子进程均列表参数。
6结论
0e8f936e0a123f3a…