Author SHA1 Message Date
gbanyanandClaude Opus 4.8 0f7338175f Paper A v13 rev9.2: slim abstract (rev9.1 review R7)
Trim the single-paragraph abstract 436 -> 358 words (~18%) and roughly halve the
closing caveat, per the reviewer's optional R7. All headline numbers preserved
(86,071 reports, 150,442 signatures, unimodality p = 0.35, 1.2%/17.5% chance rates,
82% vs 24-35% benchmark, 262 byte-identical); the honest-scope sentence is kept but
condensed to "between-accountant specificity proxy — not a within-accountant error
rate, nor a bound on one; no pipeline separation; no single-signature labels."

Rebuild docx + PDF.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01K35dXhb9XEM1mnYz6SSHpU
2026-06-30 15:24:36 +08:00
gbanyanandClaude Opus 4.8 6781c00d5b Paper A v13 rev9.2: firm-key unification + canonical-number reconciliation (rev9.1 review R1-R6)
Resolve the Firm C/D "two-snapshot" inconsistency from the co-author rev9.1 review.
Root cause was NOT stale data but two live firm-assignment keys (assigned_accountant->
registry firm vs the excel_firm column) used inconsistently across tables; standardize
on the registry key, which the headline Table IV/II-b already use. Sole difference = 379
signatures with excel_firm=C but registry firm=D; A and B identical under both keys.

Numbers (all DB-verified, registry key, n=150,442):
- Table II-c Firm C/D recomputed (was mixing keys within firm C across periods, which
  manufactured the spurious "third value" 38,934); now C 22,449+16,164=38,613,
  D 9,945+7,188=17,133, all four firms reconcile.
- Table VI C/D counts + S III-B prose + Fig 3/6 captions -> 150,442.
- S V-B HC-rate text -> Firm C 21.6->26.7%, Firm D 22.0->28.0%.

Note on R4: the reviewer (PDF-only) asked to change S IV-C to 26.5/28.5 to match Table
II-c; DB verification showed the reverse - S IV-C's 26.7/28.0 are correct and Table II-c
was the stale outlier, so II-c was aligned to S IV-C (data-correct, opposite to the
literal instruction).

Accountant counts (R2 reviewer "179>171 impossible" = false positive; three distinct,
all-reproducible universes): Table I + S III-B -> 457 (>=2 sig, owns the 150,442
signatures); Table III documented as the 437 with >=10 signatures (K=3 GMM subset,
reproduces A=82.5/B=0.0/C=1.0/D=1.9% exactly); bootstrap 179/280 unchanged
(accountant_id key, correct and invariant to the A-vs-BCD contrast).

R3 (corpus scope): S III-B reworded - corpus = all retrievable reports, Big-4 as the
primary analysis sample (removes the "corpus = four firms" vs "non-Big-4 in robustness"
contradiction); per-firm counts now explicitly labelled A/B/C/D.
R5 (spelling): unify to American (artefact->artifact x11, centred->centered,
behaviour->behavior, analyse(d)->analyze(d), favours->favors).
R6: delete non-standard "(+)" marker in S IV-C.

Figures regenerated under the registry key: make_fig3_density.py and
make_fig6_sensitivity.py switched to the assigned_accountant join (fig3/fig6 n=150,442);
fig4/fig5 refreshed. FE/LOYO/bootstrap re-validated exactly (ORs 0.116/0.061/0.070,
LOYO 53.1-54.9pp, full 53.7pp).

Add CANONICAL_NUMBERS_rev9.1.md with full provenance, the analyzable/GMM definitions,
and the firm-key root cause.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01K35dXhb9XEM1mnYz6SSHpU
2026-06-30 15:19:18 +08:00
gbanyanandClaude Opus 4.8 dd7b0644d5 Paper A v13: add one-page Chinese change summary for co-author (Jimmy)
Standalone summary (md + docx) of the rev8->rev9.1 revisions for co-author
review: claim-honesty changes (retract 139x, HC != reuse, specificity proxy,
Firm A as known-positive, interviews as contextual), empirical additions
(Table VI same-pair, F5 four-check suite, Table V pipeline audit, byte-id era
split), three judgment calls needing sign-off (framing rebalance not relabel,
no within-CPA hand-sign benchmark, pipeline finding is double-edged), and
remaining author-only items.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Qn59FdF9JMyfFg3sjcUNNG
2026-06-23 15:56:50 +08:00
gbanyanandClaude Opus 4.8 2a13f0d985 Paper A v13 rev9.1: HC-meaning + same-pair table + interview/framing rebalance, plus typesetting polish
Respond to a second hostile GPT-5.5 reviewer pass on rev9. Four substantive
changes plus accumulated typesetting polish.

Reviewer points addressed:
- HC != reuse (Fatal 1): new Sec III-F "What HC Means and Does Not Mean" states
  plainly that HC denotes an extreme within-accountant repetition pattern that is
  rare between unrelated accountants, not a reuse label; reuse is one
  interpretation, carried at Firm A by byte-identity + context, never implied by
  HC alone; no reuse claim is made for Firms B/C/D.
- Any-pair construction (Fatal 2): new Table VI gives the per-signature HC flag
  rate by firm under the deployed any-pair rule vs the strict same-pair rule
  (cosine and dHash from the same partner). Same-pair lowers all rates but widens
  the firm gap: Firm A 57.3% vs baseline 5-9%, ratio 2.4-3.4x -> 6.4-10.8x, so
  the HC region is not an artefact of combining extrema from different pairs.
  Reproducible via samepair_hc.py (Hamming on stored dHash vectors).
- Interviews (Fatal 3): Sec III-A now states the interviews are used only to
  contextualize, are corroborative not confirmatory and not independently
  reproducible; their one load-bearing use (Firm A as known-positive benchmark)
  lowers rather than raises the claim. Empirical claims rest on calibration +
  byte-identity, which stand without them.
- Framing (Fatal 4, rebalance not relabel): contribution 3 elevated to the
  methodological core (label-free construction/characterization of an operating
  point without labels), explicitly demonstrated/stress-tested on audit
  signatures "rather than a finished, fully general framework." The audit finding
  is kept as a headline result, not demoted to a mere case study, and no
  general-framework claim is made.

Typesetting polish (verified by rendering pages to images):
- Unify scientific notation in Table II ([4x10^-6, 2.3x10^-5]).
- Tighten Table II row labels to cut excessive wrapping (3 lines -> 2).
- Fix duplicated figure captions (empty image alt-text so pandoc no longer
  auto-captions on top of the hand-written caption); unify caption punctuation.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Qn59FdF9JMyfFg3sjcUNNG
2026-06-23 15:37:13 +08:00
gbanyanandClaude Opus 4.8 cb38d413ad Paper A v13 rev9: sensitivity surface + honesty fixes (GPT-5.5 hostile review)
Pre-emptively address the three residual points from a hostile GPT-5.5
reviewer pass that rev8 had not fully closed (the rest of that review
matched the already-applied fusion revision):

- Sensitivity surface (Major 5): new Figure 6 maps the deployed rule over
  the full (cosine cut x dHash cut) plane - clean-group flag rate and the
  Firm A-minus-B/C/D contrast. Shows no cliff at (0.95, dHash<=5), contrast
  >45pp across a broad region (58pp at 0.97/dHash<=3), and that extending to
  the MC bound (dHash<=15) halves the contrast - so the thresholds are not
  cherry-picked and the weaker MC band is shown, not hidden. Reproducible
  via make_fig6_sensitivity.py (DB columns only).

- Soften "reuse-dominated" (Major 1): the assertion that Firm A "is" a
  reuse-dominated population now reads "behaves in the screen as," explicitly
  resting on interviews + byte-identity rather than per-signature ground
  truth; two other uses made conditional/generic.

- Shared-pipeline contamination of ICCR (Major 2): Sec III-E now names the
  shared within-firm imaging pipeline (scanners, PDF assembly, red-stamp
  removal) as a channel that can lift the inter-CPA rate above true chance,
  distinct from "shared template," supported by the Sec V-B pipeline audit;
  bias direction (higher floor) keeps the Firm-A contrast conservative.

rev9 docx rebuilt (6 figures embedded).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Qn59FdF9JMyfFg3sjcUNNG
2026-06-23 14:59:55 +08:00
gbanyanandClaude Opus 4.8 da455791de Paper A v13 rev8: fusion-review revision (29 items) + verified data analysis
Address all 29 items from the fused reviewer report (Gemini 3.1 Pro +
ChatGPT 5.5 + Opus 4.8): 3 fatal, 4 severe, arbitration A/B, 5 fusion-new,
15 minor. All new numbers computed from signature_analysis.db; nothing
fabricated.

Claim honesty (F1/F3/F4/F7/G3):
- Retract all "139x the floor" comparisons; ICCR -> between-accountant
  specificity proxy throughout; state within-accountant FPR is not
  estimable and ICCR is not even a bound (anti-conservative direction).
- Firm A reframed as quasi-positive known-positive benchmark (not blinded).
- byte-identity recast as prevalence signal, not a recall/sanity check.
- tunable -> single-direction conservativeness dial (no P-R frontier).

New data analysis (verified, bit-reproducible via committed scripts):
- F2/G1 (Sec V-B): 880-PDF imaging-pipeline audit (Table V) - plain scans
  82% (2013) -> 1% (2021); producer strings name scanner hardware
  (Fuji Xerox D125 etc.); substrate transforms at 2020/21 = named confound.
- F5 (Sec IV-C): four robustness checks - pool-size stratification,
  accountant-clustered bootstrap (gap 53.7pp [49.5,57.5]), firm+year FE
  logistic (B/C/D OR 0.06-0.12), leave-one-year-out (gap 53.1-54.9pp).
- byte-identity era split: 30 scan-era (18 Firm A, pipeline-robust) vs
  232 digital-era (detectability-inflated, hedged).
- G5: archive-wide 888 expected chance HC flags [677,1098].
- M4: Figure 3 replaced with real 2D density (n=150,441).

Structure/minor: abstract restructured (M1); operational definition (M2);
interview disclaimer (M3); Threats to Validity subsection (M8); review
protocol framed as design not evidence (M9); N reconciliations (M10/M11);
Table II-c 2020-23 five-way (M12); Section refs, American spelling,
notation table (M5/M13/M15); reference URLs verified (M14).

Open (author-only): placeholders (M13), II-b/IV table merge (M15).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Qn59FdF9JMyfFg3sjcUNNG
2026-06-23 14:36:51 +08:00
gbanyanandClaude Opus 4.8 61dd2dcaad Paper A v13: archive intermediate revision drafts (base + rev1-6)
Preserves the iterative trail from the v13 base fill (20260614) through
the six codex-review revisions that culminated in rev7 (66c9194).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-15 04:27:19 +08:00
gbanyanandClaude Opus 4.8 66c9194fcf Paper A v13: filled submission draft (rev7) + reproducible build bundle
Fill all 18 placeholders in the condensed v13 submission draft with
data verified against the analysis DB and LOCKED canonical scripts;
close 12/13 co-author review items (only #8b protocol first-run open).

Key changes (need co-author sign-off; see handoff doc):
- Firm A out-of-sample HC 0.01% -> 0.42% (buggy 0.0001 from Script 49
  same-pair bug, propagated v4.2->v13; never reuse 0.0001)
- §III-D empty cell ~=0 -> 7,681 honest reframe (not degenerate crops)
- low cosine cut 0.837 -> 0.8547 primary (BCD 2013-2019 closed-world,
  held-out discipline; 0.8489 confirmed = BCD all-period); HC/MC/HSC
  unchanged, UN/LH move <=0.4pp

Adds Figures 1-5 (real-data plots + schematics), full references,
Appendix A/B, UN/HSC ICCR, n-reconciliation, #13 MOPS-metadata
survival verification, "參" set-level feasibility probe (negative).
Two codex (gpt-5.5) adversarial rounds applied; no fabrication found.

Bundle: paper/v13_build/ (markdown source, harvest/figure scripts,
figures) for reproducibility. Handoff note for co-author included.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-15 03:24:50 +08:00
gbanyanandClaude Opus 4.8 1e8466f7a8 Paper A v4.3: unify Firm A positioning to out-of-sample templated-end target
Finishes the BCD re-anchor chassis (audit critique #1): Firm A was
inconsistently framed as both a "within-Big-4 case study" and an
"out-of-sample target". Harmonised to a single label, "out-of-sample
templated-end target" (held out of the calibration negative anchor;
scored against the normative Firms-B/C/D baseline), across:
- §I contribution #3 (title + body)
- §III-H.2 (opening trio BCD/Firm-A/non-Big-4; sub-header; role sentence)
- §V-C body (removed the dual case-study/out-of-sample phrasing)
(§V-C header already fixed in ac3372d.)

Zero "case study" wording remains; no numbers changed. codex gpt-5.5
focused check: all consistency items PASS, no new findings.

Also restore the BCD+non-Big-4 joint ICCR Wilson CI [0.000001, 0.000015]
to the §IV-M Table XXI note (three-scope CI symmetry; the one MINOR
completeness gap surfaced by a codex old-vs-new content diff, which
otherwise confirmed no substantive content was dropped by the trim).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-05 02:11:09 +08:00
gbanyanandClaude Opus 4.8 ac3372d2d2 Paper A v4.3: restructure §III baseline-first + deep trim (audit #3/#4)
#3 Reorder §III around "establish normative baseline → show who deviates":
new order A–O with I=Normative Baseline + inter-CPA coincidence floor
(old L.0–L.3), J=Firm-Level Deviation (old L.4+L.6), K=Why the
distribution gives no threshold (old §I distributional + L.5), L=K=3
partition (old §J), M=Convergent checks (old §K), N=limits (old §M),
O=data source (old §N). ~170 cross-refs remapped (two-pass tokenized),
incl. 5 spelled-out "Section III-X" refs.

#4 Deep trim: §III 10,960→8,461w (−23%). Removed §III↔§IV-M and
§III↔§IV-F table duplication (Results keeps canonical tables; §III keeps
method+headline+pointer); condensed distributional diagnostics;
consolidated repeated caveat. No locked number changed.

Also: §V-C header "Case Study"→"Out-of-Sample Target"; abstract 251→250w;
housekeeping (rm superseded draft_section_L_bcd.md + v4.0 pandoc docx,
remove stale OCR/handoff docs, gitignore .serena/).

codex gpt-5.5 review: 0 BLOCKER / 3 MAJOR / 3 MINOR; 3 MAJOR fixed
(§III-J.2 observed-vs-counterfactual transition, §III-M table pointers
κ→XI/pixel→XIV, §III-N stale tightening figures); 2nd pass clean.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-05 01:49:09 +08:00
gbanyanandClaude Opus 4.8 17156516a0 §III-L.0: reword e-signature-adoption rationale as industry background (no interview citation)
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-04 21:52:05 +08:00
gbanyanandClaude Opus 4.8 1eb323e959 Paper A v4.2: re-anchor primary calibration to clean BCD 2013-2019 baseline
- Restrict the calibration negative anchor to Firms B/C/D, fiscal years
  2013-2019 (pre-electronic-signature hand-signing period); B/C/D adopted
  e-signing post-2020 at staggered times, so 2013-2019 is the construct-clean
  baseline. Firm A scored across its full 2013-2023 record against it.
- New locked numbers (codex-audited, Scripts 54/55): per-comparison HC floor
  0.000010; per-signature HC floor 0.0059 [boot 0.0045-0.0073]; per-document
  HC 0.0117 / HC+MC 0.1753; per-firm HC+MC B 0.162 / C 0.225 / D 0.089.
  Firm A observed 0.817 = ~139x the clean floor (was ~70x on all-period BCD);
  Firm A out-of-sample vs clean pool 0.0001 (below floor -> never resembles
  genuine hand-signing). BCD 2020+ robustness: per-sig 0.0105, per-comparison
  0.000036 (~2x pre-2020) quantifies the e-signing contamination.
- Propagated through abstract / Sec. I / III-L / IV-M / V / conclusion;
  0.837 crossover kept corpus-wide; ABCD retained as contamination comparison.
- Grounded the 2013-2019 choice on data (floor drift) + e-sign-adoption
  background, not on in-text interview claims (double-blind).
- Add Scripts 54 (temporal floor stability) and 55 (BCD 2013-2019 primary
  calibration + Firm A scoring).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-04 21:30:06 +08:00
gbanyanandClaude Opus 4.8 3c7fcc010f Paper A v4.1: BCD-baseline reframe + screening positioning + trim
- Re-anchor inter-CPA coincidence-rate (ICCR) calibration on a normative
  non-Firm-A baseline (Firms B/C/D); Firm A held out as an out-of-sample
  target. Locked canonical numbers (codex-audited; Scripts 46/52/53):
  per-comparison HC 0.00014->0.000018, per-signature HC 0.0116, per-document
  HC+MC 0.34->0.1905; KDE crossover 0.837 retained corpus-wide.
- Reposition as an operator-tunable, semi-automated screening/triage framework
  (title -> "Automated Screening..."): HC = high-specificity operating point;
  MC band demoted to low-specificity advisory; Firm A = demonstration that the
  screening surfaces a templated end, audit-quality implications deferred.
- Apply codex prose-review fixes: triage-neutral five-way labels, soften
  mechanism/specificity wording, supersede MC claim-strength, update stale
  Appendix script references (40b/43/45 -> 46/52/53).
- Trim pass: compress Sec. V discussion + Sec. III echoes (27.7k -> 26.8k
  words); no substantive content removed.
- Add analysis scripts 45-53 (firm-year trends; BCD-only ICCR recompute;
  canonical-sampler locked numbers; Firm-A out-of-sample; BCD regression +
  cross-firm hit matrix).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-04 19:35:10 +08:00
54 changed files with 2908 additions and 1743 deletions
+2
View File
@@ -61,3 +61,5 @@ node_modules/
# Sensitive/large data # Sensitive/large data
*.xlsx *.xlsx
.serena/
-432
View File
@@ -1,432 +0,0 @@
# 新对话交接文档 - PP-OCRv5研究
**日期**: 2025-10-29
**前序对话**: PaddleOCR-Cover分支开发
**当前分支**: `paddleocr-improvements` (稳定)
**新分支**: `pp-ocrv5-research` (待创建)
---
## 🎯 任务目标
研究和实现 **PP-OCRv5** 的手写签名检测功能
---
## 📋 背景信息
### 当前状况
**已有稳定方案** (`paddleocr-improvements` 分支):
- PaddleOCR 2.7.3 + OpenCV Method 3
- 86.5%手写保留率
- 区域合并算法工作良好
- 测试: 1个PDF成功检测2个签名
⚠️ **PP-OCRv5升级遇到问题**:
- PaddleOCR 3.3.0 API完全改变
- 旧服务器代码不兼容
- 需要深入研究新API
### 为什么要研究PP-OCRv5
**文档显示**: https://www.paddleocr.ai/main/en/version3.x/algorithm/PP-OCRv5/PP-OCRv5.html
PP-OCRv5性能提升:
- 手写中文检测: **0.706 → 0.803** (+13.7%)
- 手写英文检测: **0.249 → 0.841** (+237%)
- 可能支持直接输出手写区域坐标
**潜在优势**:
1. 更好的手写识别能力
2. 可能内置手写/印刷分类
3. 更准确的坐标输出
4. 减少复杂的后处理
---
## 🔧 技术栈
### 服务器环境
```
Host: 192.168.30.36 (Linux GPU服务器)
SSH: ssh gblinux
目录: ~/Project/paddleocr-server/
```
**当前稳定版本**:
- PaddleOCR: 2.7.3
- numpy: 1.26.4
- opencv-contrib-python: 4.6.0.66
- 服务器文件: `paddleocr_server.py`
**已安装但未使用**:
- PaddleOCR 3.3.0 (PP-OCRv5)
- 临时服务器: `paddleocr_server_v5.py` (未完成)
### 本地环境
```
macOS
Python: 3.14
虚拟环境: venv/
客户端: paddleocr_client.py
```
---
## 📝 核心问题
### 1. API变更
**旧API (2.7.3)**:
```python
from paddleocr import PaddleOCR
ocr = PaddleOCR(lang='ch')
result = ocr.ocr(image_np, cls=False)
# 返回格式:
# [[[box], (text, confidence)], ...]
```
**新API (3.3.0)** - ⚠️ 未完全理解:
```python
# 方式1: 传统方式 (Deprecated)
result = ocr.ocr(image_np) # 警告: Please use predict instead
# 方式2: 新方式
from paddlex import create_model
model = create_model("???") # 模型名未知
result = model.predict(image_np)
# 返回格式: ???
```
### 2. 遇到的错误
**错误1**: `cls` 参数不再支持
```python
# 错误: PaddleOCR.predict() got an unexpected keyword argument 'cls'
result = ocr.ocr(image_np, cls=False) # ❌
```
**错误2**: 返回格式改变
```python
# 旧代码解析失败:
text = item[1][0] # ❌ IndexError
confidence = item[1][1] # ❌ IndexError
```
**错误3**: 模型名称错误
```python
model = create_model("PP-OCRv5_server") # ❌ Model not supported
```
---
## 🎯 研究任务清单
### Phase 1: API研究 (优先级高)
- [ ] **阅读官方文档**
- PP-OCRv5完整文档
- PaddleX API文档
- 迁移指南 (如果有)
- [ ] **理解新API**
```python
# 需要搞清楚:
1. 正确的导入方式
2. 模型初始化方法
3. predict()参数和返回格式
4. 如何区分手写/印刷
5. 是否有手写检测专用功能
```
- [ ] **编写测试脚本**
- `test_pp_ocrv5_api.py` - 测试基础API调用
- 打印完整的result数据结构
- 对比v4和v5的返回差异
### Phase 2: 服务器适配
- [ ] **重写服务器代码**
- 适配新API
- 正确解析返回数据
- 保持REST接口兼容
- [ ] **测试稳定性**
- 测试10个PDF样本
- 检查GPU利用率
- 对比v4性能
### Phase 3: 手写检测功能
- [ ] **查找手写检测能力**
```python
# 可能的方式:
1. result中是否有 text_type 字段?
2. 是否有专门的 handwriting_detection 模型?
3. 是否有置信度差异可以利用?
4. PP-Structure 的 layout 分析?
```
- [ ] **对比测试**
- v4 (当前方案) vs v5
- 准确率、召回率、速度
- 手写检测能力
### Phase 4: 集成决策
- [ ] **性能评估**
- 如果v5更好 → 升级
- 如果改进不明显 → 保持v4
- [ ] **文档更新**
- 记录v5使用方法
- 更新PADDLEOCR_STATUS.md
---
## 🔍 调试技巧
### 1. 查看完整返回数据
```python
import pprint
result = model.predict(image)
pprint.pprint(result) # 完整输出所有字段
# 或者
import json
print(json.dumps(result, indent=2, ensure_ascii=False))
```
### 2. 查找官方示例
```bash
# 在服务器上查找PaddleOCR安装示例
find ~/Project/paddleocr-server/venv/lib/python3.12/site-packages/paddleocr -name "*.py" | grep example
# 查看源码
less ~/Project/paddleocr-server/venv/lib/python3.12/site-packages/paddleocr/paddleocr.py
```
### 3. 查看可用模型
```python
from paddlex.inference.models import OFFICIAL_MODELS
print(OFFICIAL_MODELS) # 列出所有支持的模型名
```
### 4. Web文档搜索
重点查看:
- https://github.com/PaddlePaddle/PaddleOCR
- https://www.paddleocr.ai
- https://github.com/PaddlePaddle/PaddleX
---
## 📂 文件结构
```
/Volumes/NV2/pdf_recognize/
├── CURRENT_STATUS.md # 当前状态文档 ✅
├── NEW_SESSION_HANDOFF.md # 本文件 ✅
├── PADDLEOCR_STATUS.md # 详细技术文档 ✅
├── SESSION_INIT.md # 初始会话信息
├── paddleocr_client.py # 稳定客户端 (v2.7.3) ✅
├── paddleocr_server_v5.py # v5服务器 (未完成) ⚠️
├── test_paddleocr_client.py # 基础测试
├── test_mask_and_detect.py # 遮罩+检测
├── test_opencv_separation.py # Method 1+2
├── test_opencv_advanced.py # Method 3 (最佳) ✅
├── extract_signatures_paddleocr_improved.py # 完整Pipeline
└── check_rejected_for_missing.py # 诊断脚本
```
**服务器端** (`ssh gblinux`):
```
~/Project/paddleocr-server/
├── paddleocr_server.py # v2.7.3稳定版 ✅
├── paddleocr_server_v5.py # v5版本 (待完成) ⚠️
├── paddleocr_server_backup.py # 备份
├── server_stable.log # 当前运行日志
└── venv/ # 虚拟环境
```
---
## ⚡ 快速启动
### 启动稳定服务器 (v2.7.3)
```bash
ssh gblinux
cd ~/Project/paddleocr-server
source venv/bin/activate
python paddleocr_server.py
```
### 测试连接
```bash
# 本地Mac
cd /Volumes/NV2/pdf_recognize
source venv/bin/activate
python test_paddleocr_client.py
```
### 创建新研究分支
```bash
cd /Volumes/NV2/pdf_recognize
git checkout -b pp-ocrv5-research
```
---
## 🚨 注意事项
### 1. 不要破坏稳定版本
- `paddleocr-improvements` 分支保持稳定
- 所有v5实验在新分支 `pp-ocrv5-research`
- 服务器保留 `paddleocr_server.py` (v2.7.3)
- 新代码命名: `paddleocr_server_v5.py`
### 2. 环境隔离
- 服务器虚拟环境可能需要重建
- 或者用Docker隔离v4和v5
- 避免版本冲突
### 3. 性能测试
- 记录v4和v5的具体指标
- 至少测试10个样本
- 包括速度、准确率、召回率
### 4. 文档驱动
- 每个发现记录到文档
- API用法写清楚
- 便于未来维护
---
## 📊 成功标准
### 最低目标
- [ ] 成功运行PP-OCRv5基础OCR
- [ ] 理解新API调用方式
- [ ] 服务器稳定运行
- [ ] 记录完整文档
### 理想目标
- [ ] 发现手写检测功能
- [ ] 性能超过v4方案
- [ ] 简化Pipeline复杂度
- [ ] 提升准确率 > 90%
### 决策点
**如果v5明显更好** → 升级到v5,废弃v4
**如果v5改进不明显** → 保持v4,v5仅作研究记录
**如果v5有bug** → 等待官方修复,暂用v4
---
## 📞 问题排查
### 遇到问题时
1. **先查日志**: `tail -f ~/Project/paddleocr-server/server_stable.log`
2. **查看源码**: 在venv里找PaddleOCR代码
3. **搜索Issues**: https://github.com/PaddlePaddle/PaddleOCR/issues
4. **降级测试**: 确认v2.7.3是否还能用
### 常见问题
**Q: 服务器启动失败?**
A: 检查numpy版本 (需要 < 2.0)
**Q: 找不到模型?**
A: 模型名可能变化,查看OFFICIAL_MODELS
**Q: API调用失败?**
A: 对比官方文档,可能参数格式变化
---
## 🎓 学习资源
### 官方文档
1. **PP-OCRv5**: https://www.paddleocr.ai/main/en/version3.x/algorithm/PP-OCRv5/PP-OCRv5.html
2. **PaddleOCR GitHub**: https://github.com/PaddlePaddle/PaddleOCR
3. **PaddleX**: https://github.com/PaddlePaddle/PaddleX
### 相关技术
- PaddlePaddle深度学习框架
- PP-Structure文档结构分析
- 手写识别 (Handwriting Recognition)
- 版面分析 (Layout Analysis)
---
## 💡 提示
### 如果发现内置手写检测
可能的用法:
```python
# 猜测1: 返回结果包含类型
for item in result:
text_type = item.get('type') # 'printed' or 'handwritten'?
# 猜测2: 专门的layout模型
from paddlex import create_model
layout_model = create_model("PP-Structure")
layout_result = layout_model.predict(image)
# 可能返回: text, handwriting, figure, table...
# 猜测3: 置信度差异
# 手写文字置信度可能更低
```
### 如果没有内置手写检测
那么当前OpenCV Method 3仍然是最佳方案,v5仅提供更好的OCR准确度。
---
## ✅ 完成检查清单
研究完成后,确保:
- [ ] 新API用法完全理解并文档化
- [ ] 服务器代码重写并测试通过
- [ ] 性能对比数据记录
- [ ] 决策文档 (升级 vs 保持v4)
- [ ] 代码提交到 `pp-ocrv5-research` 分支
- [ ] 更新 `CURRENT_STATUS.md`
- [ ] 如果升级: 合并到main分支
---
**祝研究顺利!** 🚀
有问题随时查阅:
- `CURRENT_STATUS.md` - 当前方案详情
- `PADDLEOCR_STATUS.md` - 技术细节和问题分析
**最重要**: 记录所有发现,无论成功或失败,都是宝贵经验!
-195
View File
@@ -1,195 +0,0 @@
# Session Handoff Checklist ✓
## Before You Exit This Session
- [x] All documentation written
- [x] Test results recorded (7/10 signatures, 70% recall)
- [x] Session initialization files created
- [x] .gitignore configured
- [x] Commit guide prepared
- [ ] **Git commit performed** (waiting for user approval)
## Files Created for Next Session
### Essential Files ⭐
- [x] **SESSION_INIT.md** - Read this first in next session
- [x] **NEW_SESSION_PROMPT.txt** - Copy-paste prompt template
- [x] **PROJECT_DOCUMENTATION.md** - Complete 24KB history
- [x] **HOW_TO_CONTINUE.txt** - Visual guide
### Supporting Files
- [x] README.md - Quick start guide
- [x] COMMIT_SUMMARY.md - Git instructions
- [x] README_page_extraction.md - Page extraction docs
- [x] README_hybrid_extraction.md - Signature extraction docs
- [x] .gitignore - Configured properly
### Working Scripts
- [x] extract_pages_from_csv.py - Tested (100 files)
- [x] extract_signatures_hybrid.py - Tested (5 files, 70% recall)
- [x] extract_handwriting.py - Component script
## What's Working ✅
| Component | Status | Details |
|-----------|--------|---------|
| Page extraction | ✅ Working | 100 files tested |
| VLM name extraction | ✅ Working | 100% accurate on 5 files |
| CV detection | ⚠️ Conservative | Finds 70% of signatures |
| VLM verification | ✅ Working | 100% precision, no false positives |
| Overall system | ✅ Working | 70% recall, 100% precision |
## What's Not Working / Unknown ⚠️
| Issue | Status | Next Steps |
|-------|--------|------------|
| Missing 30% signatures | Known | Tune CV parameters |
| Text layer method | Untested | Need PDFs with text |
| Large-scale performance | Unknown | Test with 100+ files |
| Full dataset (86K) | Unknown | Estimate time & optimize |
## Critical Context to Remember 🧠
1. **VLM coordinates are unreliable** (32% offset on test file)
- Don't use VLM for location detection
- Use VLM for name extraction only
2. **Name-based approach is the solution**
- VLM extracts names ✓
- CV finds locations ✓
- VLM verifies regions ✓
3. **Test file with coordinate issue:**
- `201301_2458_AI1_page4.pdf`
- VLM found 2 names but coordinates pointed to blank areas
- Actual signatures at 26% (reported as 58% and 68%)
## To Start Next Session
### Simple Method (Recommended)
```bash
cat /Volumes/NV2/pdf_recognize/NEW_SESSION_PROMPT.txt
# Copy output and paste to new Claude Code session
```
### Manual Method
Tell Claude:
> "I'm continuing the PDF signature extraction project at `/Volumes/NV2/pdf_recognize/`. Please read `SESSION_INIT.md` and `PROJECT_DOCUMENTATION.md` to understand the current state. I want to [choose option from SESSION_INIT.md]."
## Quick Commands Reference
### View Documentation
```bash
less /Volumes/NV2/pdf_recognize/SESSION_INIT.md
less /Volumes/NV2/pdf_recognize/PROJECT_DOCUMENTATION.md
```
### Run Scripts
```bash
cd /Volumes/NV2/pdf_recognize
source venv/bin/activate
python extract_signatures_hybrid.py # Main script
```
### Check Results
```bash
ls -lh /Volumes/NV2/PDF-Processing/signature-image-output/signatures/*.png
```
### View Session Handoff
```bash
cat /Volumes/NV2/pdf_recognize/HOW_TO_CONTINUE.txt
```
## What Can Be Improved (Future Work)
### Priority 1: Increase Recall
- Current: 70%
- Target: 90%+
- Method: Tune CV parameters in lines 178-214 of extract_signatures_hybrid.py
### Priority 2: Scale Testing
- Current: 5 files tested
- Next: 100 files
- Future: 86,073 files (full dataset)
### Priority 3: Optimization
- Current: ~24 seconds per PDF
- Consider: Parallel processing, batch VLM calls
### Priority 4: Text Layer Testing
- Current: Untested (all PDFs are scanned)
- Need: Find PDFs with searchable text layer
## Verification Steps
Before next session, verify files exist:
```bash
cd /Volumes/NV2/pdf_recognize
# Check essential docs
ls -lh SESSION_INIT.md PROJECT_DOCUMENTATION.md NEW_SESSION_PROMPT.txt
# Check working scripts
ls -lh extract_pages_from_csv.py extract_signatures_hybrid.py
# Check test results
ls /Volumes/NV2/PDF-Processing/signature-image-output/signatures/*.png | wc -l
# Should show: 7 (the 7 verified signatures)
```
## Known Good State
### Environment
- Python: 3.9+ with venv
- Ollama: http://192.168.30.36:11434
- Model: qwen2.5vl:32b
- Working directory: /Volumes/NV2/pdf_recognize/
### Test Data
- 5 PDFs processed
- 7 signatures extracted
- All verified (100% precision)
- 3 signatures missed (70% recall)
### Output Files
```
201301_1324_AI1_page3_signature_張志銘.png (33 KB)
201301_1324_AI1_page3_signature_楊智惠.png (37 KB)
201301_2061_AI1_page5_signature_廖阿甚.png (87 KB)
201301_2458_AI1_page4_signature_周寶蓮.png (230 KB)
201301_2923_AI1_page3_signature_黄瑞展.png (184 KB)
201301_3189_AI1_page3_signature_黄益辉.png (24 KB)
201301_3189_AI1_page3_signature_黄辉.png (84 KB)
```
## Git Status (Pre-Commit)
Files staged for commit:
- [ ] extract_pages_from_csv.py
- [ ] extract_signatures_hybrid.py
- [ ] extract_handwriting.py
- [ ] README.md
- [ ] PROJECT_DOCUMENTATION.md
- [ ] README_page_extraction.md
- [ ] README_hybrid_extraction.md
- [ ] .gitignore
**Waiting for:** User to review docs and approve commit
## Session Health Check ✓
- [x] All scripts working
- [x] Test results documented
- [x] Issues identified and recorded
- [x] Next steps defined
- [x] Session continuity files created
- [x] Git commit prepared
**Status:** ✅ Ready for handoff
---
**Last Updated:** October 26, 2025
**Session End:** Ready for next session
**Next Action:** User reviews docs → Git commit → Continue work
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
+86
View File
@@ -0,0 +1,86 @@
# 融合審查 — 修訂 TODO 清單
**來源**`Fusion_Review_Crosscheck_Table.docx`Gemini 3.1 Pro + ChatGPT 5.5 + Opus 4.8 → Opus 4.8 融合,2026-06-19
**對象稿件**`paper/v13_build/paper_v13_filled.md`rev7 submission 單一真實來源)
**建議結論**Major Revision
**統計**:致命共識 ×3 · 嚴重 ×4 · 融合新增 ×5 · 改向/不採納 ×1 · 結構/Minor ×15
投票圖例:★ = 強烈標記 / ● = 提及 / ○ = 弱提及 / — = 未提。欄位 G=Gemini, C=ChatGPT, O=Opus。
執行順序:① F1 → ② F2+G1 → ③ F3、F7 與宣稱降溫 → ④ F4–F6 與 F5 穩健性套組 → ⑤ 結構與 Minor。
---
## Tier 1 — 致命(三審高共識,不修則中心宣稱垮)
- [x] **F1 — 校準 null 類別錯誤**(G★ C○ O★)|偏誤方向 anti-conservative ✅ 文字完成(abstract/§I/§III-D/§III-E/§IV-C/§V/§VI
- 已做:全文 ICCR→specificity proxy;撤回所有「139×/4059×」式比較;§III-E 新增 between vs within 區分、明說 within-CPA 偽陽率不可估計、ICCR 連 bound 都不是、偏誤 anti-conservative。
- ✅ benchmark 問題已 §III-E 主動防守:無 OUR-population 親簽標記、公開集屬不同族群/字體/管線→借入會重引跨分布假設(違 label-free 初衷),故報告限制非誤導 proxy。不做(用戶/領域判斷確認做不出)。
- [x] **F2 — Firm 為被混淆的 treatment**(G★ C★ O★)✅ 完成(PDF 解析具名證據)
- ✅ 880 份 PDF 管線審計:純掃描 2013 82% → 2021 崩到 1%metadata 點名掃描機型(Fuji Xerox D125/ApeosPort)→ Table V 寫入 §V-B;量測基底本身在 2020/21 轉變 = 混淆具名鐵證。
- ✅ byte-identical era split232 數位年代(偵測性放大,已 hedge)vs 30 掃描年代(管線無關鐵證,18 在 Firm A)→ §V-B + §IV-C 交叉註記。
- 腳本 pipeline_audit.py / pipeline_audit.csv 已存。
- [x] **F3 — 吃重輸出零驗證**G○ C★ O★)✅ 完成
- 已做:刪除 byte-identical「sanity check / recall 下界」修辭→改 prevalence signalheadline 全面 screening/triage/prevalence 口徑(abstract/貢獻/結論皆已轉),通讀確認無 detection-verdict 過度宣稱。
## Tier 2 — 嚴重(雙審共識)
- [x] **F4 — held-out ≠ blinded**(G○ C★ O★)|Firm A 為已知 institutional positive case ✅ 完成
- 已做:§IV-C 標題改「Held-Out Benchmark: Firm A (a Known Positive)」+ 新增 quasi-positive institutional benchmark 段;abstract/§II 資料切分/§VI 全部改「known-positive benchmark / not a blinded test」。
- [x] **F5 — 旗標率 pool-size / 極值依賴**G● C★ O●)|any-pair 爭議真正內核 ✅ 核心完成
- ✅ 已做:pool-size 分層(Firm A 每一層都壓制 BCD<50 66 vs 20%、…、400+ 82 vs 29%)→ pool size 無法解釋 firm gapaccountant-clustered bootstrap gap 53.7pp CI[49.5,57.5]。皆寫入 §IV-C。
- ✅ 增補完成:firm+year FE logistic(控時間/管線後 B/C/D OR 0.116/0.061/0.070,仍低一個量級);leave-one-year-out gap 53.154.9pp(任一年剔除皆穩,含 202223)。寫入 §IV-C「Four further checks」;腳本 f5_fe_loyo.py。
- [x] **F6 — clean reference exogeneity** ✅ 完成(文字+既有證據)
- §III-E 新增:floor 為 conditional-on-correct-clean;污染只會抬高 floor → 對 Firm A 對比保守(known-safe 方向);leave-one-baseline-firm-out 不動 floorcrossover scope 0.8547→0.8302(≤0.025)。ICCR 在不同 clean-group 下重算需 canonical sampler,未擅自重做。
- [x] **F7 — 宣稱範圍過大**G● C★ O●)|detection / operational labels / tunable / 中文語料可直接採用 ✅ 完成
- 已做:貢獻條列 operational labels→risk strata;全文 specificity→specificity proxy;中文語料「adopt directly」→「starting reference for comparable Chinese-signature pipelines, subject to recalibration」;tunable 見 G3。
## 仲裁(三審分歧,注意採納方向)
- [x] **A — 不 fine-tune 是 label-free 的必然** ✅ 完成
- §II 末新增主動論證段:supervised metric learning 需 labelled pairs = 正是 archive 沒有的 ground truthlabel-free 非弱化版而是唯一誠實選項;貢獻為方法論非架構;fine-tune 留待 protocol first-run 取得 labelled sample 後。
- [x] **B — any-pair 嚴重性分歧** ✅ 併入 F5(已完成)
## 融合新增(三審皆漏,全採納)
- [x] **G1 — staggered e-signing adoption → event study** |**改為誠實描述+招認限制(用戶定案)** ✅ 完成
- 硬發現:資料無乾淨 staggered adoptionA 全程高、C 2022 跳、B 2023 跳、D 緩升),跳升跨整年且集中審計季 → 內部時序無法分離 adoption vs 管線變動,且反推導入點會循環。
- ✅ 已做:§V-B 升級為「Time Trend and the FirmPipeline Confound」,注入真實異質時序 + F2 指紋 + 明列 event study(需外部導入日期)為 future work;不杜撰日期。firm_year_hc_panel.csv 已存備圖。
- [x] **G2 — 前處理壓縮 cosine 尺度** ✅ 完成(可驗證事實+constructablation 列 future
- §V-A 新增:cosine 97.7% ≥0.90、median 0.969、僅 0.3% <0.850.95 cut 坐落飽和區(~76% 在其上)→ cosine 單獨幾乎不分辨、靠 dHashpadding/normalization 完整量化需重跑 CNN ablationDB 做不到)列 future。注意:融合表「95.2%」我配對驗證對不上,未引用。
- [x] **G3 — 「tunable operating point」單向空心**(recall 不可觀測 → 無 PR trade-off)✅ 完成
- 已做:§III-D (i) + §V operating-point 改為「conservativeness dial, not a precisionrecall control」;只能單向收緊、無可校準的 recall 取捨面;abstract 移除 operator-tunable 措辭。
- [x] **G4 — byte-identical 跨案件/跨日期** ✅ 完成(DB 驗證)
- 驗證:262 筆 pixel-identical 全部 match 到**不同 source_pdf**0 同檔),170/262 跨月 → 排除重複申報/同報表雙計;§IV-C 補述。
- [x] **G5 — 低率 ≠ 少數** ✅ 完成
- ✅ 已做:§IV-A 補「888 期望巧合 HC flagsCI [677,1,098]= 0.59%×150,442」+「low rate ≠ small number、單一 HC flag 不單獨解讀」。
## 結構 / 格式 — Minor(含三審共識與細讀)
- [x] **M1** — 摘要重構 ✅;problem→method→data→finding→limitation 弧線,刪「This is not forgery」口語句,併入 F1/F4/F5/F7 誠實框架。
- [x] **M2** — §I 首次出現處新增 operational definition ✅;明確區分 handwritten/seal/overlay/e-sign/proxy + 排除 cryptographic digital signature,準則=image reuse 可見結果。
- [x] **M3** — §III-A 強化免責 ✅;訪談 self-reported/anonymized/不可重製,吻合=consistency with domain knowledge,非 accuracy/recall 量測。
- [x] **M4** — Figure 3 換真實 2D density ✅;make_fig3_density.py 產 n=150,441 log-density + 五區疊加 + 軸刻度;caption 改為描述真實分布。
- [x] **M5** — §X→Section X ✅(114 處全替換,無 malformed)。
- [x] **M6** — specificity→specificity proxy ✅(隨 F1/F7 完成)。
- [x] **M7** — Table II-b 後新增 reconciliation 段 ✅;直接解釋 within(2129%) vs between(0.59%) 不同量,「clean」=between 巧合罕見非 within 低。
- [x] **M8** — 新增 §V-D Threats to Validity ✅;8 條集中列出(含 bias 方向與交叉引用)。
- [x] **M9** — §IV-B 新增框架句 ✅;分清 empirical(比率/巧合率/byte-id) vs designed procedure(4 moves)protocol first-run 明列 future work。
- [x] **M10** — 對齊完成 ✅;168,755=matched、168,740=有測值(差 15=單簽會計師 pool=1,DB 驗證),§IV-A 補註;226=cell 全部、206=有足夠簽名子集,§V future-work 補「206 of 226」。
- [x] **M11**(半-Major)— 語料範圍釐清 ✅
- §III-B 新增一句:primary sample=Big-4150,442=valid∩有兩測值(60,448/38,993/34,248/16,752);non-Big-4 僅入 §V-C crossover 穩健性、不入 calibration/headline。
- [x] **M12** — 新增 Table II-cAD 20202023 五分類)✅;邏輯以 20132019 Firm B 重現 Table II-b 驗證通過。
- [x] **M13** — 拼寫統一美式 ✅(behaviour/labelled/centring/colour→美式,30 處;references 內保留原拼寫)。⏳ placeholder 作者/機構/DOI/biography 投稿前補(double-blind,待你)。
- [x] **M14** — 參考文獻體例 ✅(網路查證)
- 查證結論:[4]SigNetdblp=CoRR)、[8]Brimoh、[9]Woodruff、[24]Qwen2.5-VL **皆無正式刊出版本,維持 arXiv 即正確**reviewer 誤判有正式版)。[25] 補官方 docs URL;[27] 升級為精確永久連結 + 日期(Jan 21, 2013)。
- [x] **M15** — 新增 Table I-a 縮寫/門檻對照表 ✅(HC/MC/HSC/UN/LH + cuts + ICCR/c/d 記號)。⏳ II-b vs IV 整併為主觀排版判斷,建議你決定。
---
## 分類:可立即文字改 vs 需新分析/資料 vs 需 co-author 決策
**A. 純文字重構(無需新數據,可現在做)**:F1(術語/撤回 139×)、F4、F7、G3、G4(若資料已知)、M1、M2、M3、M5、M6、M8、M9、M13、M15、A(主動論證段落)
**B. 需新分析 / 跑資料**F2firm-metadata 抽取)、F3prevalence 數字)、F5subsampling + bootstrap + FE + LOYO 套組)、F6clean-group 敏感度)、G1event study)、G2(前處理量化)、G5(絕對期望數)、M4(真實 density 圖)、M7B/C/D HC 解釋需查數)、M11(語料分母核對)、M12(五分類表)
**C. 需 co-authorJimmy)決策 / 確認**:是否補 within-CPA 親簽 benchmarkF1 理想項)、G1 event study 範圍、最終宣稱降溫幅度
+226 -358
View File
@@ -1,10 +1,15 @@
---
title: "Automated Screening of Digitally Replicated Signatures in Large-Scale Financial Audit Reports"
author: "[Authors removed for double-blind review]"
---
# Abstract # Abstract
<!-- IEEE Access target: <= 250 words, single paragraph --> <!-- IEEE Access target: <= 250 words, single paragraph -->
Regulations require Certified Public Accountants (CPAs) to attest each audit report with a signature, but digitization makes it feasible to reuse a stored signature image across reports — through administrative stamping or firm-level electronic signing — thereby undermining individualized attestation. We build an end-to-end pipeline for screening such *non-hand-signed* signatures at scale: a Vision-Language Model identifies signature pages, YOLOv11 localizes signatures, ResNet-50 supplies deep features, and a dual-descriptor layer combines cosine similarity with an independent-minimum perceptual hash (dHash) to separate *style consistency* from *image reproduction*. Applied to 90,282 Taiwan audit reports (20132023), the pipeline yields 182,328 signatures from 758 CPAs; primary analyses are scoped to the Big-4 sub-corpus (437 CPAs; 150,442 signatures). Distributional diagnostics show that the apparent multimodality of the descriptor distribution dissolves under joint firm-mean centring and integer-tie jitter ($p$ rises to $0.35$), so no within-population bimodal antimode anchors the operational thresholds. We instead adopt an anchor-based inter-CPA coincidence-rate (ICCR) calibration at three units: per-comparison ($0.0006$ at cos$>0.95$; $0.0013$ at dHash$\leq 5$; $0.00014$ jointly), pool-normalised per-signature ($0.11$ under the deployed any-pair high-confidence rule), and per-document ($0.34$ for the operational HC+MC alarm). The framework surfaces pronounced firm-level heterogeneity: Firm A's per-document HC+MC ICCR is $0.62$ versus $0.09$$0.16$ at Firms B/C/D (gap persists after pool-size adjustment), and $77$$99\%$ of inter-CPA collisions concentrate within the source firm. This contrast is consistent with firm-level template-like reuse but not independently diagnostic, since descriptor-only data cannot separate reuse from digitisation-pipeline or signing-style homogeneity within a firm; we report it as a scope limitation rather than a mechanism finding. We position the system as a specificity-proxy-anchored screening framework with human-in-the-loop review, not as a validated forensic detector; no calibrated error rates are reportable without signature-level ground truth. Regulations require Certified Public Accountants (CPAs) to attest each audit report with a signature, but digitization makes it feasible to reuse a stored signature image across reports, undermining individualized attestation. We build an end-to-end pipeline to screen *non-hand-signed* signatures: a Vision-Language Model identifies signature pages, YOLOv11 localizes signatures, ResNet-50 supplies deep features, and a dual-descriptor layer combines cosine similarity with an independent-minimum perceptual hash (dHash), separating *style consistency* from *image reproduction*. Applied to 90,282 Taiwan audit reports (20132023), the pipeline yields 182,328 signatures from 758 CPAs; primary analyses cover the Big-4 sub-corpus (437 CPAs; 150,442 signatures). Diagnostics show no within-population antimode anchors a threshold ($p=0.35$ after firm-mean centring and integer-tie jitter). We instead calibrate via an inter-CPA coincidence-rate (ICCR) anchored on a clean pre-e-signature baseline (Firms B/C/D, 20132019), as Firm A's extreme within-firm collision structure would contaminate an all-firm anchor. On this clean baseline the high-confidence rule (cos$>0.95$, dHash$\leq 5$) has a low inter-CPA coincidence rate (per-comparison ICCR $0.000010$; per-signature $0.006$; per-document $0.012$), whereas the moderate-confidence band (dHash$\leq 15$) retains a $\sim 0.175$ per-document coincidence rate and is reported as advisory. Scored out-of-sample, Firm A never coincides cross-firm yet fires on $82\%$ of its own ($\sim 139\times$ floor); its signal is within-firm. We read this as consistent with firm-level template-like reuse but not independently diagnostic: descriptor-only data cannot separate reuse from digitisation-pipeline or signing-style homogeneity. We position it as a specificity-proxy screening framework with human-in-the-loop review, not a validated forensic detector; no calibrated error rates are reportable without ground truth.
<!-- Word count: 247 --> <!-- Word count: 250 -->
# I. Introduction # I. Introduction
@@ -21,15 +26,17 @@ A methodological concern shapes the research design. Many prior similarity-based
Despite the significance of the problem for audit quality and regulatory oversight, to our knowledge no prior work has specifically addressed non-hand-signing detection in financial audit documents at scale with these methodological safeguards. Woodruff et al. [9] developed an automated pipeline for signature analysis in corporate filings for anti-money-laundering investigations, but their work focused on author clustering rather than detecting image reuse. Copy-move forgery detection methods [10], [11] address duplicated regions within or across images but are designed for natural images and do not account for the specific characteristics of scanned document signatures. Research on near-duplicate image detection using perceptual hashing combined with deep learning [12], [13] provides relevant methodological foundations but has not been applied to document forensics or signature analysis. From the statistical side, the methods we adopt for distributional characterisation — the Hartigan dip test [37] and finite mixture modelling via the EM algorithm [40], [41], complemented by a Burgstahler-Dichev / McCrary density-smoothness diagnostic [38], [39] — have been developed in statistics and accounting-econometrics but have not been combined as a joint diagnostic toolkit for document-forensics threshold characterisation. Despite the significance of the problem for audit quality and regulatory oversight, to our knowledge no prior work has specifically addressed non-hand-signing detection in financial audit documents at scale with these methodological safeguards. Woodruff et al. [9] developed an automated pipeline for signature analysis in corporate filings for anti-money-laundering investigations, but their work focused on author clustering rather than detecting image reuse. Copy-move forgery detection methods [10], [11] address duplicated regions within or across images but are designed for natural images and do not account for the specific characteristics of scanned document signatures. Research on near-duplicate image detection using perceptual hashing combined with deep learning [12], [13] provides relevant methodological foundations but has not been applied to document forensics or signature analysis. From the statistical side, the methods we adopt for distributional characterisation — the Hartigan dip test [37] and finite mixture modelling via the EM algorithm [40], [41], complemented by a Burgstahler-Dichev / McCrary density-smoothness diagnostic [38], [39] — have been developed in statistics and accounting-econometrics but have not been combined as a joint diagnostic toolkit for document-forensics threshold characterisation.
In this paper we present a fully automated, end-to-end pipeline for screening non-hand-signed CPA signatures in audit reports at scale, together with an anchor-calibrated screening framework that characterises the pipeline's operational behaviour under explicit unsupervised assumptions. The pipeline processes raw PDF documents through (1) signature page identification with a Vision-Language Model; (2) signature region detection with a trained YOLOv11 object detector; (3) deep feature extraction via a pre-trained ResNet-50; (4) dual-descriptor similarity (cosine + independent-minimum dHash); (5) anchor-based threshold calibration at three units of analysis (per-comparison, pool-normalised per-signature, per-document) against an inter-CPA negative-anchor coincidence-rate proxy (§III-L); (6) firm-stratified per-rule reporting and a within-firm cross-CPA hit-matrix analysis (§III-L.4); (7) a composition decomposition that establishes the absence of a within-population bimodal antimode in the descriptor distributions (§III-I.4); and (8) disclosure of each diagnostic's untested assumption (§III-M). In this paper we present a fully automated, end-to-end pipeline for screening non-hand-signed CPA signatures in audit reports at scale, together with an anchor-calibrated screening framework that characterises the pipeline's operational behaviour under explicit unsupervised assumptions. The pipeline processes raw PDF documents through (1) signature page identification with a Vision-Language Model; (2) signature region detection with a trained YOLOv11 object detector; (3) deep feature extraction via a pre-trained ResNet-50; (4) dual-descriptor similarity (cosine + independent-minimum dHash); (5) anchor-based threshold calibration at three units of analysis (per-comparison, pool-normalised per-signature, per-document) against an inter-CPA negative-anchor coincidence-rate proxy (§III-I); (6) firm-stratified per-rule reporting and a within-firm cross-CPA hit-matrix analysis (§III-J.1); (7) a composition decomposition that establishes the absence of a within-population bimodal antimode in the descriptor distributions (§III-K.4); and (8) disclosure of each diagnostic's untested assumption (§III-N).
A key empirical finding is that the descriptor distributions do not support a within-population natural threshold. The apparent multimodality in the Big-4 accountant-level distribution is explained by between-firm location-shift effects (Firm A's mean dHash of $2.73$ versus Firms B/C/D's $6.46$, $7.39$, $7.21$) and integer mass-point artefacts on the integer-valued dHash axis. After joint firm-mean centring and uniform integer-tie jitter, the pooled dHash dip-test rejection disappears ($p_{\text{median}} = 0.35$ across five seeds). Within-firm diagnostics in every Big-4 firm fail to reveal stable bimodal structure after accounting for integer ties; eligible non-Big-4 firms provide corroborating raw-axis evidence on the cosine dimension (§III-I.4). We therefore treat mixture fits as descriptive summaries of firm-compositional structure rather than threshold-generating mechanisms, and calibrate the deployed operating rules using inter-CPA coincidence-rate anchors. We are deliberate about what the system claims. The operating thresholds are *operator-tunable* rather than asserted as ground-truth decision boundaries: the contribution is not a fixed detector that pronounces a signature non-hand-signed, but (a) a dual-descriptor design that separates *style consistency* from *image reproduction*, and (b) a methodology for choosing and characterising a screening operating point in the absence of labels, so that an operator can set a specificity target and read off what each setting yields. Operationally the framework is a semi-automated triage step that surfaces a tractable set of replication candidates from hundreds of thousands of signatures for human adjudication; it does not adjudicate. The firm-level results and the byte-identical capture check are reported as *demonstrations that this triage works at scale*, not as forensic determinations.
In place of distributional anchoring, we adopt an anchor-based inter-CPA coincidence-rate (ICCR) calibration. At the per-comparison unit, the cos$>0.95$ operating point yields ICCR $= 0.00060$ on a $5 \times 10^5$-pair Big-4 sample; the dHash$\leq 5$ structural cutoff yields ICCR $= 0.00129$; the joint rule cos$>0.95$ AND dHash$\leq 5$ yields joint ICCR $= 0.00014$ (any-pair semantics, matching the deployed extrema rule). At the pool-normalised per-signature unit, the same rule's effective coincidence rate is materially higher because the deployed classifier takes max-cosine and min-dHash over a same-CPA pool: pooled Big-4 any-pair ICCR is $0.1102$ (Wilson 95% CI $[0.1086, 0.1118]$; CPA-block bootstrap 95% $[0.0908, 0.1330]$). At the per-document unit, the operational HC$+$MC alarm fires on $33.75\%$ of Big-4 documents under the inter-CPA candidate-pool counterfactual. A key empirical finding is that the descriptor distributions do not support a within-population natural threshold. The apparent multimodality in the Big-4 accountant-level distribution is explained by between-firm location-shift effects (Firm A's mean dHash of $2.73$ versus Firms B/C/D's $6.46$, $7.39$, $7.21$) and integer mass-point artefacts on the integer-valued dHash axis. After joint firm-mean centring and uniform integer-tie jitter, the pooled dHash dip-test rejection disappears ($p_{\text{median}} = 0.35$ across five seeds). Within-firm diagnostics in every Big-4 firm fail to reveal stable bimodal structure after accounting for integer ties; eligible non-Big-4 firms provide corroborating raw-axis evidence on the cosine dimension (§III-K.4). We therefore treat mixture fits as descriptive summaries of firm-compositional structure rather than threshold-generating mechanisms, and calibrate the deployed operating rules using inter-CPA coincidence-rate anchors.
The pooled per-signature and per-document rates conceal striking firm heterogeneity. A logistic regression of the per-signature hit indicator on firm dummies (Firm A reference) and centred log pool size yields odds ratios of $0.053$ (Firm B), $0.010$ (Firm C), and $0.027$ (Firm D) — Firms B/C/D are an order of magnitude below Firm A even after controlling for the pool-size confound. Cross-firm hit matrix analysis under the deployed any-pair rule shows within-firm collision concentrations of $98.8\%$ at Firm A and $76.7$$83.7\%$ at Firms B/C/D (Table XXV; the stricter same-pair joint event saturates at $97.0$$99.96\%$ within-firm across all four firms). The pattern is consistent with firm-specific template, stamp, or document-production reuse mechanismsthough not by itself diagnostic of deliberate sharing. The deployed five-way box rule defines a reproducible screening classifier; the calibration contribution is to characterise its multi-level inter-CPA coincidence behaviour rather than to derive new thresholds. The high-confidence sub-rule (cos $> 0.95$ AND dHash $\leq 5$) and moderate-confidence sub-rule (cos $> 0.95$ AND $5 < \text{dHash} \leq 15$) are explicit decision rules whose calibrated false-positive and false-negative error rates remain unknown in the absence of signature-level labels. In place of distributional anchoring, we adopt an anchor-based inter-CPA coincidence-rate (ICCR) calibration on a clean pre-e-signature baseline (Firms B/C/D, 20132019); §III-I.0 explains why an all-Big-4 negative anchor is partially circular — Firm A's extreme within-firm cross-CPA collision structure loads the all-firm pool with the very structure the rule targets. On this BCD baseline the deployed high-confidence rule (cos$>0.95$ AND dHash$\leq 5$) yields per-comparison ICCR $= 0.000010$ (versus $0.00014$ on the contaminated all-Big-4 pool), pool-normalised per-signature ICCR $= 0.0059$ (CPA-block bootstrap 95% $[0.0045, 0.0073]$), and per-document ICCR $= 0.012$roughly an order of magnitude below the all-Big-4 figures, confirming that the HC rule has a very low inter-CPA coincidence rate against an uncontaminated baseline. The moderate-confidence band (cos$>0.95$ AND $5 < \text{dHash} \leq 15$), by contrast, retains a per-document coincidence rate of $0.175$ even on the clean baseline (and rises slightly when Firm A is removed), so we treat HC as the specificity-anchored operating point and reposition the MC band as a low-specificity advisory tier rather than a confident non-hand-signed label. The cosine LH/UN crossover ($\text{cos} = 0.837$) is a corpus-wide descriptor-space landmark robust to baseline choice (it moves $\leq 0.012$ across the corpus-wide, BCD, and BCD+non-Big-4 scopes) and is retained corpus-wide.
Three feature-derived scores converge on the per-CPA descriptor-position ranking with Spearman $\rho \geq 0.879$: the K=3 mixture posterior (a firm-compositional position score under §III-J's reading, not a mechanism cluster posterior), a reverse-anchor cosine percentile relative to a strictly-out-of-target non-Big-4 reference, and the box-rule less-replication-dominated rate. The three scores are deterministic functions of the same per-CPA descriptor pair, so the convergence is documented as internal consistency among feature-derived ranks rather than external validation. A conservative hard-positive subset for image replication is provided by 262 byte-identical signatures in the Big-4 subset (Firm A 145, Firm B 8, Firm C 107, Firm D 2), against which all three candidate checks achieve $0\%$ positive-anchor miss rate (Wilson 95% upper bound $1.45\%$). For the box rule this result is close to tautological at byte-identity; we discuss the conservative-subset caveat in §V-G. With Firm A treated as an out-of-sample target rather than a calibration input, the heterogeneity reads cleanly. Against the BCD floor (per-signature HC ICCR $0.0059$), the deployed rule fires on each firm's *actual* same-CPA pools far above the inter-CPA coincidence floor: Firm A at $0.82$ ($\sim 139\times$ floor), Firms B/C/D at $0.24$$0.35$ ($\sim 40$$59\times$). Firm A scored against the clean 20132019 baseline coincides essentially never ($0.0001$, below the clean-baseline floor itself) — so its elevation is entirely a within-firm phenomenon, not cross-firm distinctiveness. Two logistic regressions confirm Firm A is the singular extreme while the baseline is internally homogeneous: with Firm A as reference on the full Big-4 pool, odds ratios are $0.053$ (B), $0.010$ (C), $0.027$ (D); restricted to the BCD baseline with Firm D as reference, the residual spread collapses to within $\sim 3.5\times$ (odds ratio $1.73$ for B, $0.49$ for C). Under the deployed any-pair rule, within-firm collision concentration is a *universal* Big-4 pattern — $98.8\%$ at Firm A and, on the clean BCD pool, $89$$97\%$ at Firms B/C/D (Table XXV) — consistent with firm-specific template, stamp, or document-production reuse, though not by itself diagnostic of deliberate sharing. The deployed five-way box rule defines a reproducible screening classifier; the calibration contribution is to characterise its multi-level inter-CPA coincidence behaviour, not to derive new thresholds. The high-confidence sub-rule (cos $> 0.95$ AND dHash $\leq 5$) and the advisory moderate-confidence sub-rule (cos $> 0.95$ AND $5 < \text{dHash} \leq 15$) are explicit decision rules whose calibrated false-positive and false-negative error rates remain unknown in the absence of signature-level labels.
Three feature-derived scores converge on the per-CPA descriptor-position ranking with Spearman $\rho \geq 0.879$: the K=3 mixture posterior (a firm-compositional position score under §III-L's reading, not a mechanism cluster posterior), a reverse-anchor cosine percentile relative to a strictly-out-of-target non-Big-4 reference, and the box-rule less-replication-dominated rate. The three scores are deterministic functions of the same per-CPA descriptor pair, so the convergence is documented as internal consistency among feature-derived ranks rather than external validation. A conservative hard-positive subset for image replication is provided by 262 byte-identical signatures in the Big-4 subset (Firm A 145, Firm B 8, Firm C 107, Firm D 2), against which all three candidate checks achieve $0\%$ positive-anchor miss rate (Wilson 95% upper bound $1.45\%$). For the box rule this result is close to tautological at byte-identity; we discuss the conservative-subset caveat in §V-G.
We apply this pipeline to 90,282 audit reports filed by publicly listed companies in Taiwan between 2013 and 2023, extracting and analyzing 182,328 individual CPA signatures from 758 unique accountants. The Big-4 sub-corpus comprises 437 CPAs and 150,442 signatures with both descriptors available. We apply this pipeline to 90,282 audit reports filed by publicly listed companies in Taiwan between 2013 and 2023, extracting and analyzing 182,328 individual CPA signatures from 758 unique accountants. The Big-4 sub-corpus comprises 437 CPAs and 150,442 signatures with both descriptors available.
@@ -37,19 +44,19 @@ The contributions of this paper are:
1. **Problem formulation.** We define non-hand-signing detection as distinct from signature forgery detection and frame it as a detection problem on intra-signer similarity distributions. 1. **Problem formulation.** We define non-hand-signing detection as distinct from signature forgery detection and frame it as a detection problem on intra-signer similarity distributions.
2. **End-to-end pipeline.** We present a pipeline that processes raw PDF audit reports through VLM-based page identification, YOLO-based signature detection, ResNet-50 feature extraction, and dual-descriptor similarity computation, with automated inference and no manual intervention after initial training. 2. **End-to-end pipeline.** We present a pipeline that processes raw PDF audit reports through VLM-based page identification, YOLO-based signature detection, ResNet-50 feature extraction, and dual-descriptor similarity computation, with automated inference and no manual intervention before the human-adjudication step.
3. **Dual-descriptor similarity.** We demonstrate that combining deep-feature cosine similarity with independent-minimum dHash provides complementary evidence for screening cases where *style consistency* and *image reproduction* hypotheses diverge, and we support the backbone choice through a feature-backbone ablation. 3. **Dual-descriptor similarity.** We demonstrate that combining deep-feature cosine similarity with independent-minimum dHash provides complementary evidence for screening cases where *style consistency* and *image reproduction* hypotheses diverge, and we support the backbone choice through a feature-backbone ablation.
4. **Composition decomposition does not support the distributional-threshold path.** We show via a 2×2 factorial diagnostic (firm-mean centring × integer-tie jitter) that the apparent multimodality of the Big-4 accountant-level descriptor distribution is fully attributable to between-firm location shifts and integer mass-point artefacts. The descriptor distributions contain no within-population bimodal antimode; a distributional "natural threshold" reading of the operating points is not empirically supported. 4. **Composition decomposition does not support the distributional-threshold path.** We show via a 2×2 factorial diagnostic (firm-mean centring × integer-tie jitter) that the apparent multimodality of the Big-4 accountant-level descriptor distribution is fully attributable to between-firm location shifts and integer mass-point artefacts. The descriptor distributions contain no within-population bimodal antimode; a distributional "natural threshold" reading of the operating points is not empirically supported.
5. **Anchor-based multi-level inter-CPA coincidence-rate calibration.** We characterise the deployed high-confidence (HC) sub-rule and document-level HC$+$MC alarm derived from the five-way classifier at three units of analysis: per-comparison ICCR (cos$>0.95$: $0.0006$; dHash$\leq 5$: $0.0013$; joint: $0.00014$), pool-normalised per-signature ICCR ($0.11$ for the deployed any-pair high-confidence rule), and per-document ICCR ($0.34$ for the operational HC$+$MC alarm). We adopt "inter-CPA coincidence rate" as the metric name throughout and reserve "False Acceptance Rate" for terminology that requires ground-truth negative labels, which the corpus does not provide. 5. **Anchor-based multi-level ICCR calibration on a normative non-Firm-A baseline.** We characterise the deployed high-confidence (HC) sub-rule at three units of analysis against a clean Firms-B/C/D negative anchor (Firm A held out as an out-of-sample target to avoid circularity): per-comparison ICCR $0.000010$, pool-normalised per-signature ICCR $0.0059$, and per-document ICCR $0.012$ — each roughly an order of magnitude below the contaminated all-Big-4 figures ($0.00014$, $0.11$, $0.18$). The moderate-confidence band (dHash$\leq 15$) retains a $\sim 0.175$ per-document coincidence rate on the clean baseline and is repositioned as a low-specificity advisory tier rather than a confident non-hand-signed label. Because the deployed thresholds are operator-tunable, the contribution is this label-free calibration methodology — a principled way to choose and characterise a screening operating point and the specificity it yields — rather than any specific threshold. We adopt "inter-CPA coincidence rate" as the metric name throughout and reserve "False Acceptance Rate" for terminology that requires ground-truth negative labels, which the corpus does not provide.
6. **Firm heterogeneity quantification and within-firm cross-CPA collision concentration.** Per-document D2 inter-CPA proxy ICCRs differ by an order of magnitude across firms (Firm A: $0.62$ versus Firms B/C/D: $0.09$$0.16$); a per-signature logistic regression of the any-pair HC hit indicator on firm dummies and centred log pool size confirms the firm gap persists after pool-size control. Cross-firm hit matrix analysis shows within-firm collision concentrations of $98.8\%$ at Firm A and $76.7$$83.7\%$ at Firms B/C/D under the deployed any-pair rule (the stricter same-pair joint event saturates at $97.0$$99.96\%$ within-firm across all four firms); the pattern is consistent with but does not independently establish firm-level template-like reuse, digitisation-pipeline homogeneity, or signing-style homogeneity, which descriptor-only data cannot separate (§V-H). 6. **Firm A as a singular out-of-sample extreme; universal within-firm collision concentration.** Against the clean BCD floor (per-signature HC ICCR $0.0059$), the deployed rule fires on each firm's own pools far above the inter-CPA coincidence floor (Firm A $0.82$, $\sim 139\times$; Firms B/C/D $0.24$$0.35$, $\sim 40$$59\times$), while Firm A scored cross-firm against the clean 20132019 baseline coincides essentially never cross-firm ($0.0001$, below the floor itself) — localising the repeatability signal to within-firm comparisons. Two logistic regressions (full-Big-4 with Firm A reference: odds ratios $0.053$/$0.010$/$0.027$ for B/C/D; BCD-only with Firm D reference: residual spread within $\sim 3.5\times$, odds ratios $1.73$/$0.49$ for B/C) show Firm A is the lone outlier while Firms B/C/D form an internally homogeneous baseline. Within-firm collision concentration is a universal Big-4 pattern — $98.8\%$ at Firm A and $89$$97\%$ at Firms B/C/D on the clean pool — consistent with, but not independently establishing, firm-level template-like reuse, digitisation-pipeline homogeneity, or signing-style homogeneity, which descriptor-only data cannot separate (§V-H).
7. **K=3 as descriptive firm-compositional partition; three-score convergent internal consistency.** We fit a K=3 Gaussian mixture as a descriptive partition of the Big-4 accountant-level distribution (interpreted as firm-compositional structure, not as three mechanism clusters). Three feature-derived scores agree on the per-CPA descriptor-position ranking at Spearman $\rho \geq 0.879$; we report this as internal consistency rather than external validation, given that the scores share the underlying descriptor pair. 7. **K=3 as descriptive firm-compositional partition; three-score convergent internal consistency.** We fit a K=3 Gaussian mixture as a descriptive partition of the Big-4 accountant-level distribution (interpreted as firm-compositional structure, not as three mechanism clusters). Three feature-derived scores agree on the per-CPA descriptor-position ranking at Spearman $\rho \geq 0.879$; we report this as internal consistency rather than external validation, given that the scores share the underlying descriptor pair.
8. **Annotation-free positive-anchor capture check and unsupervised-setting disclosure.** We achieve $0\%$ positive-anchor miss rate (Wilson 95% upper bound $1.45\%$) on 262 byte-identical Big-4 signatures, with the conservative-subset caveat that byte-identical pairs are by construction near cos$=1$ and dHash$=0$. Each supporting diagnostic in §III-M addresses one specific failure mode of an unsupervised screening classifier — composition artefacts, inter-CPA coincidence, pool-size confounding, firm heterogeneity, threshold sensitivity, or positive-anchor capture — with an explicitly disclosed untested assumption. We do not claim a validated forensic detector; we position the system as a specificity-proxy-anchored screening framework with human-in-the-loop review. 8. **Annotation-free positive-anchor capture check and unsupervised-setting disclosure.** We achieve $0\%$ positive-anchor miss rate (Wilson 95% upper bound $1.45\%$) on 262 byte-identical Big-4 signatures, with the conservative-subset caveat that byte-identical pairs are by construction near cos$=1$ and dHash$=0$. Each supporting diagnostic in §III-N addresses one specific failure mode of an unsupervised screening classifier — composition artefacts, inter-CPA coincidence, pool-size confounding, firm heterogeneity, threshold sensitivity, or positive-anchor capture — with an explicitly disclosed untested assumption. We do not claim a validated forensic detector; we position the system as a specificity-proxy-anchored screening framework with human-in-the-loop review.
The remainder of the paper is organized as follows. Section II reviews related work on signature verification, document forensics, perceptual hashing, and the statistical methods used. Section III describes the proposed methodology. Section IV presents the experimental results — distributional characterisation, mixture fits, convergent internal-consistency checks, leave-one-firm-out reproducibility, pixel-identity positive-anchor check, and full-dataset robustness. Section V discusses the implications and limitations. Section VI concludes with directions for future work. The remainder of the paper is organized as follows. Section II reviews related work on signature verification, document forensics, perceptual hashing, and the statistical methods used. Section III describes the proposed methodology. Section IV presents the experimental results — distributional characterisation, mixture fits, convergent internal-consistency checks, leave-one-firm-out reproducibility, pixel-identity positive-anchor check, and full-dataset robustness. Section V discusses the implications and limitations. Section VI concludes with directions for future work.
@@ -130,7 +137,7 @@ Under mild regularity conditions, White's quasi-MLE result [41] supports interpr
The present study uses these tools diagnostically: first to test whether the descriptor distribution supports a natural operating boundary, and then, when that support fails under composition decomposition, to motivate anchor-based ICCR calibration of a fixed deployed rule. The present study uses these tools diagnostically: first to test whether the descriptor distribution supports a natural operating boundary, and then, when that support fails under composition decomposition, to motivate anchor-based ICCR calibration of a fixed deployed rule.
*Cross-validation in a small-cluster scope.* *Cross-validation in a small-cluster scope.*
Cross-validation methodology in the leave-one-out tradition has been developed extensively in statistics since Stone [42] and Geisser [43], and modern surveys including Vehtari et al. [44] discuss its application to mixture models. In document-forensics calibration the technique has been used selectively, typically with the individual document or signature as the hold-out unit. Our application in §III-K differs in two respects from the standard usage: (i) the hold-out unit is the *firm* (not the individual CPA or signature), so the analysis directly probes cross-firm reproducibility of the fitted mixture rather than within-firm sampling variance; and (ii) the held-out predictions are interpreted as a *composition-sensitivity band* on the candidate mixture boundary, not as a sufficiency claim for the deployed five-way operational classifier (§III-H.1; calibrated separately in §III-L). We treat LOOO drift as descriptive information about how the mixture characterisation moves when training composition changes, not as a pass/fail test for the operational classifier. Cross-validation methodology in the leave-one-out tradition has been developed extensively in statistics since Stone [42] and Geisser [43], and modern surveys including Vehtari et al. [44] discuss its application to mixture models. In document-forensics calibration the technique has been used selectively, typically with the individual document or signature as the hold-out unit. Our application in §III-M differs in two respects from the standard usage: (i) the hold-out unit is the *firm* (not the individual CPA or signature), so the analysis directly probes cross-firm reproducibility of the fitted mixture rather than within-firm sampling variance; and (ii) the held-out predictions are interpreted as a *composition-sensitivity band* on the candidate mixture boundary, not as a sufficiency claim for the deployed five-way operational classifier (§III-H.1; calibrated separately in §III-I). We treat LOOO drift as descriptive information about how the mixture characterisation moves when training composition changes, not as a pass/fail test for the operational classifier.
<!-- <!--
REFERENCES for Related Work (full list in the References section): REFERENCES for Related Work (full list in the References section):
[3] Bromley et al. 1993 — Siamese TDNN (NeurIPS) [3] Bromley et al. 1993 — Siamese TDNN (NeurIPS)
@@ -170,9 +177,9 @@ REFERENCES for Related Work (full list in the References section):
## A. Pipeline Overview ## A. Pipeline Overview
We propose a six-stage pipeline for large-scale non-hand-signed auditor signature detection in scanned financial documents. We propose a six-stage pipeline for large-scale screening of non-hand-signed auditor signatures in scanned financial documents.
Fig. 1 illustrates the overall architecture. Fig. 1 illustrates the overall architecture.
The pipeline takes as input a corpus of PDF audit reports and produces five-way operational screening labels (§III-H.1) whose behaviour is characterised by pixel-identity positive-anchor capture checks and inter-CPA coincidence-rate calibration (§III-L). The pipeline takes as input a corpus of PDF audit reports and produces five-way operational screening labels (§III-H.1) whose behaviour is characterised by pixel-identity positive-anchor capture checks and inter-CPA coincidence-rate calibration (§III-I).
Throughout this paper we use the term *non-hand-signed* rather than "digitally replicated" to denote any signature produced by reproducing a previously stored image of the partner's signature---whether by administrative stamping workflows (dominant in the early years of the sample) or firm-level electronic signing systems (dominant in the later years). Throughout this paper we use the term *non-hand-signed* rather than "digitally replicated" to denote any signature produced by reproducing a previously stored image of the partner's signature---whether by administrative stamping workflows (dominant in the early years of the sample) or firm-level electronic signing systems (dominant in the later years).
From the perspective of the output image the two workflows are equivalent: both can reproduce one or more stored signature images, producing same-CPA signatures that are identical or near-identical up to reproduction, scanning, compression, and template-variant noise. From the perspective of the output image the two workflows are equivalent: both can reproduce one or more stored signature images, producing same-CPA signatures that are identical or near-identical up to reproduction, scanning, compression, and template-variant noise.
@@ -277,13 +284,13 @@ Non-hand-signing is expected to yield extreme similarity under *both* descriptor
One working hypothesis is that some hand-signed repetitions may preserve coarse layout while varying in fine execution, producing relatively higher dHash similarity than cosine similarity within a same-CPA pair; the classifier does not require this hypothesis to hold for all CPAs, and the descriptor-level pattern is used only as input to the deployed rule, not as a within-CPA consistency claim. One working hypothesis is that some hand-signed repetitions may preserve coarse layout while varying in fine execution, producing relatively higher dHash similarity than cosine similarity within a same-CPA pair; the classifier does not require this hypothesis to hold for all CPAs, and the descriptor-level pattern is used only as input to the deployed rule, not as a within-CPA consistency claim.
Convergence of the two descriptors is therefore a natural robustness check; when they disagree, the case is flagged as borderline. Convergence of the two descriptors is therefore a natural robustness check; when they disagree, the case is flagged as borderline.
We do not use SSIM (Structural Similarity Index) [30] or pixel-level comparison as primary descriptors. SSIM was developed as a perceptual quality index for natural images and is by construction sensitive to the local-luminance and local-contrast perturbations routine in a print-scan cycle (JPEG block artefacts, scan-noise speckle, scanner-rule ghosts) — properties that penalise identically-reproduced signature crops at the very margins SSIM is designed to weight most heavily. Pixel-level distances ($L_1$, $L_2$, pixel-identity counting) are defined on geometrically aligned images at a common resolution and inflate under the sub-pixel offsets that scanner DPI, paper-handling alignment, and PDF-page rasterisation routinely introduce, so two scans of the same physical document cannot score near-identically. The supplementary materials contain the full design-level argument; pixel-identity counting is retained only as a threshold-free positive anchor (§III-K), because byte-identical pairs are necessarily produced by literal file reuse and so do not interact with the alignment-fragility argument. We do not use SSIM (Structural Similarity Index) [30] or pixel-level comparison as primary descriptors. SSIM was developed as a perceptual quality index for natural images and is by construction sensitive to the local-luminance and local-contrast perturbations routine in a print-scan cycle (JPEG block artefacts, scan-noise speckle, scanner-rule ghosts) — properties that penalise identically-reproduced signature crops at the very margins SSIM is designed to weight most heavily. Pixel-level distances ($L_1$, $L_2$, pixel-identity counting) are defined on geometrically aligned images at a common resolution and inflate under the sub-pixel offsets that scanner DPI, paper-handling alignment, and PDF-page rasterisation routinely introduce, so two scans of the same physical document cannot score near-identically. The supplementary materials contain the full design-level argument; pixel-identity counting is retained only as a threshold-free positive anchor (§III-M), because byte-identical pairs are necessarily produced by literal file reuse and so do not interact with the alignment-fragility argument.
Cosine similarity on L2-normalised deep embeddings and dHash both remain stable across the print-scan-rasterise cycle by design [14], [19], [21], [27]; together they constitute the dual descriptor used throughout the rest of this paper. Cosine similarity on L2-normalised deep embeddings and dHash both remain stable across the print-scan-rasterise cycle by design [14], [19], [21], [27]; together they constitute the dual descriptor used throughout the rest of this paper.
## G. Unit of Analysis and Scope ## G. Unit of Analysis and Scope
We analyse signatures at two **descriptor-summary** units of resolution. The **signature** — one signature image extracted from one report — is the operational unit of classification (§III-H.1) and of the signature-level analyses in §IV (notably §IV-J for the five-way per-signature category counts and the inter-CPA negative-anchor coincidence-rate analysis referenced in §IV-I). The **accountant** — one CPA aggregated over all of their signatures in the corpus — is the unit of mixture-model characterisation (§III-J), of per-CPA internal-consistency analysis (§III-K), and of the leave-one-firm-out reproducibility check (§III-K). At the accountant level we compute, for each CPA with $n_{\text{sig}} \geq 10$ signatures, the per-CPA mean of the per-signature best-match cosine ($\overline{\text{cos}}_a$) and the per-CPA mean of the independent-minimum dHash ($\overline{\text{dHash}}_a$). The minimum threshold of 10 signatures per CPA is required for the per-CPA mean to be a stable summary; CPAs below this threshold are excluded from the accountant-level analyses but remain in the per-signature analyses. §III-L additionally characterises the deployed rule's behaviour at three **operational reporting** units (per-comparison, per-signature, per-document), which are distinct from the descriptor-summary units defined here: the descriptor-summary units summarise input descriptors; the operational reporting units summarise rule outputs. We analyse signatures at two **descriptor-summary** units of resolution. The **signature** — one signature image extracted from one report — is the operational unit of classification (§III-H.1) and of the signature-level analyses in §IV (notably §IV-J for the five-way per-signature category counts and the inter-CPA negative-anchor coincidence-rate analysis referenced in §IV-I). The **accountant** — one CPA aggregated over all of their signatures in the corpus — is the unit of mixture-model characterisation (§III-L), of per-CPA internal-consistency analysis (§III-M), and of the leave-one-firm-out reproducibility check (§III-M). At the accountant level we compute, for each CPA with $n_{\text{sig}} \geq 10$ signatures, the per-CPA mean of the per-signature best-match cosine ($\overline{\text{cos}}_a$) and the per-CPA mean of the independent-minimum dHash ($\overline{\text{dHash}}_a$). The minimum threshold of 10 signatures per CPA is required for the per-CPA mean to be a stable summary; CPAs below this threshold are excluded from the accountant-level analyses but remain in the per-signature analyses. §III-I additionally characterises the deployed rule's behaviour at three **operational reporting** units (per-comparison, per-signature, per-document), which are distinct from the descriptor-summary units defined here: the descriptor-summary units summarise input descriptors; the operational reporting units summarise rule outputs.
We make no within-year or across-year uniformity assumption about CPA signing mechanisms. Per-signature labels are signature-level quantities throughout this paper; we do not translate them to per-report or per-partner mechanism assignments, and we abstain from partner-level frequency inferences (such as "X% of CPAs hand-sign") that would require such a translation. A CPA's per-CPA mean is a *summary statistic* of their observed signatures, not a claim that all of their signatures share a single mechanism. We make no within-year or across-year uniformity assumption about CPA signing mechanisms. Per-signature labels are signature-level quantities throughout this paper; we do not translate them to per-report or per-partner mechanism assignments, and we abstain from partner-level frequency inferences (such as "X% of CPAs hand-sign") that would require such a translation. A CPA's per-CPA mean is a *summary statistic* of their observed signatures, not a claim that all of their signatures share a single mechanism.
@@ -293,15 +300,15 @@ We adopt one stipulation about same-CPA pair detectability:
A1 is plausible for high-volume stamping or firm-level electronic signing workflows but is not guaranteed when (i) the corpus contains only one observed replicated report for a CPA, (ii) multiple template variants are used in parallel, or (iii) scan-stage noise pushes a replicated pair outside the detection regime. A1 is the only assumption the per-signature detector requires to be sensitive to replication. A1 is plausible for high-volume stamping or firm-level electronic signing workflows but is not guaranteed when (i) the corpus contains only one observed replicated report for a CPA, (ii) multiple template variants are used in parallel, or (iii) scan-stage noise pushes a replicated pair outside the detection regime. A1 is the only assumption the per-signature detector requires to be sensitive to replication.
**Scope: the Big-4 sub-corpus.** The primary analyses (§III-I, §III-J, §III-K, §III-L, and the corresponding §IV-D through §IV-J and §IV-M tables) are restricted to the four largest accounting firms in Taiwan, pseudonymously labelled Firm A through Firm D throughout the manuscript. §IV-A through §IV-C and §IV-L report the corpus-wide pipeline performance and feature-backbone ablation that support the descriptor choice of §III-F; §IV-K reports a deliberately narrow full-dataset cross-check at $n = 686$ CPAs. The Big-4 sub-corpus comprises 437 CPAs (171 / 112 / 102 / 52 across Firms A through D) with $n_{\text{sig}} \geq 10$ — the threshold for accountant-level analyses — totalling 150,442 Big-4 signatures with both pre-computed descriptors available. Restricting the primary analyses to Big-4 is a methodological choice driven by four considerations: **Scope: the Big-4 sub-corpus.** The primary analyses (§III-I through §III-M, and the corresponding §IV-D through §IV-J and §IV-M tables) are restricted to the four largest accounting firms in Taiwan, pseudonymously labelled Firm A through Firm D throughout the manuscript. §IV-A through §IV-C and §IV-L report the corpus-wide pipeline performance and feature-backbone ablation that support the descriptor choice of §III-F; §IV-K reports a deliberately narrow full-dataset cross-check at $n = 686$ CPAs. The Big-4 sub-corpus comprises 437 CPAs (171 / 112 / 102 / 52 across Firms A through D) with $n_{\text{sig}} \geq 10$ — the threshold for accountant-level analyses — totalling 150,442 Big-4 signatures with both pre-computed descriptors available. Restricting the primary analyses to Big-4 is a methodological choice driven by four considerations:
1. **Restricted generalisability claim and Big-4 institutional comparability.** The primary claims are scoped to the Big-4 audit-report context, where the four firms share comparable institutional scale, document-production infrastructure, and CPA-volume regime; we do not assert that the same descriptive mixture structure or operational alert behaviour extends to mid/small firms. The 249 non-Big-4 CPAs enter only (a) as an external reference population in §III-H.2's reverse-anchor internal-consistency check, (b) as a robustness comparison in §IV-K, and (c) as a corroborating-population check on the dHash discrete-mass-point artefact in §III-I.4. Generalisation beyond Big-4 is left as future work. 1. **Restricted generalisability claim and Big-4 institutional comparability.** The primary claims are scoped to the Big-4 audit-report context, where the four firms share comparable institutional scale, document-production infrastructure, and CPA-volume regime; we do not assert that the same descriptive mixture structure or operational alert behaviour extends to mid/small firms. The 249 non-Big-4 CPAs enter only (a) as an external reference population in §III-H.2's reverse-anchor internal-consistency check, (b) as a robustness comparison in §IV-K, and (c) as a corroborating-population check on the dHash discrete-mass-point artefact in §III-K.4. Generalisation beyond Big-4 is left as future work.
2. **Within-firm cross-CPA collision structure analysis.** §III-L.4 reports a Big-4 cross-firm hit-matrix analysis that quantifies the within-firm cross-CPA template-like collision pattern. The four-firm setting affords the cleanest signal for this analysis; replicating the same matrix structure on the heterogeneous mid/small-firm tail is left as future work. 2. **Within-firm cross-CPA collision structure analysis.** §III-J.1 reports a Big-4 cross-firm hit-matrix analysis that quantifies the within-firm cross-CPA template-like collision pattern. The four-firm setting affords the cleanest signal for this analysis; replicating the same matrix structure on the heterogeneous mid/small-firm tail is left as future work.
3. **Firm A as templated-end case study.** Firm A is empirically the firm whose CPAs are most concentrated in the high-cosine, low-dHash corner of the descriptor plane (§III-J K=3 component cross-tab; byte-level pair analysis referenced in §III-H.2). We retain Firm A within the Big-4 scope as a descriptive case study of the templated end rather than as the calibration anchor for thresholds. 3. **Firm A as the out-of-sample templated-end target.** Firm A is empirically the firm whose CPAs are most concentrated in the high-cosine, low-dHash corner of the descriptor plane (§III-L K=3 component cross-tab; byte-level pair analysis referenced in §III-H.2). It is held out of the calibration negative anchor and scored as an out-of-sample target against the normative Firms-B/C/D baseline (§III-I.0, §III-J), illustrating the templated end the screening surfaces rather than serving as a calibration anchor for thresholds.
4. **Leave-one-firm-out fold feasibility.** §III-K reports leave-one-firm-out (LOOO) cross-validation of the Big-4 K=3 fit. The Big-4 sub-corpus permits a four-fold LOOO at the firm level (one fold per Big-4 firm). No analogous firm-level fold is available outside Big-4 because mid/small firms have CPA counts of $O(1)$$O(30)$ per firm. 4. **Leave-one-firm-out fold feasibility.** §III-M reports leave-one-firm-out (LOOO) cross-validation of the Big-4 K=3 fit. The Big-4 sub-corpus permits a four-fold LOOO at the firm level (one fold per Big-4 firm). No analogous firm-level fold is available outside Big-4 because mid/small firms have CPA counts of $O(1)$$O(30)$ per firm.
**Sample-size reconciliation.** Two Big-4 signature counts appear in this section and §IV: $n = 150{,}442$ for analyses using the pre-computed per-signature descriptors $\text{cos}_s$ (`max_similarity_to_same_accountant`) and $\text{dHash}_s$ (`min_dhash_independent`), and $n = 150{,}453$ for analyses recomputing pair-level metrics directly from the stored feature and dHash byte vectors (Scripts 40b, 43, 44). The $11$-signature difference reflects descriptor-completion status: $11$ signatures have feature vectors and dHash byte vectors stored but lack the pre-computed extrema. The $11$ signatures are negligible at population scale and do not affect any reported coincidence rate within $0.01$ percentage point. The CPA counts $468$ (all Big-4 CPAs with both vectors stored) and $437$ (Big-4 CPAs with $n_{\text{sig}} \geq 10$ for accountant-level stability) likewise reflect a single uniform exclusion rule rather than analysis-specific subsetting. **Sample-size reconciliation.** Two Big-4 signature counts appear in this section and §IV: $n = 150{,}442$ for analyses using the pre-computed per-signature descriptors $\text{cos}_s$ (`max_similarity_to_same_accountant`) and $\text{dHash}_s$ (`min_dhash_independent`), and $n = 150{,}453$ for analyses recomputing pair-level metrics directly from the stored feature and dHash byte vectors (Scripts 40b, 43, 44). The $11$-signature difference reflects descriptor-completion status: $11$ signatures have feature vectors and dHash byte vectors stored but lack the pre-computed extrema. The $11$ signatures are negligible at population scale and do not affect any reported coincidence rate within $0.01$ percentage point. The CPA counts $468$ (all Big-4 CPAs with both vectors stored) and $437$ (Big-4 CPAs with $n_{\text{sig}} \geq 10$ for accountant-level stability) likewise reflect a single uniform exclusion rule rather than analysis-specific subsetting.
@@ -309,66 +316,134 @@ A1 is plausible for high-volume stamping or firm-level electronic signing workfl
### H.1. Deployed Operational Rule ### H.1. Deployed Operational Rule
Each Big-4 signature is assigned to one of five categories using the per-signature descriptor pair $(\text{cos}_s, \text{dHash}_s)$ where $\text{cos}_s$ is the maximum cosine similarity to another signature by the same CPA and $\text{dHash}_s$ is the minimum independent dHash to another signature by the same CPA. The five labels below name regions of the descriptor space and are operational rule outputs, not validated ground-truth classes; the label names reflect the screening hypothesis associated with each region and are subject to the unsupervised-setting caveats of §III-M: Each Big-4 signature is assigned to one of five categories using the per-signature descriptor pair $(\text{cos}_s, \text{dHash}_s)$ where $\text{cos}_s$ is the maximum cosine similarity to another signature by the same CPA and $\text{dHash}_s$ is the minimum independent dHash to another signature by the same CPA. The five labels below name regions of the descriptor space and are operational rule outputs, not validated ground-truth classes; the label names reflect the screening hypothesis associated with each region and are subject to the unsupervised-setting caveats of §III-N:
1. **High-confidence non-hand-signed (HC):** Cosine $> 0.95$ AND $\text{dHash}_{\text{indep}} \leq 5$. Both descriptors converge on image-similarity evidence consistent with replication; mechanism attribution remains subject to §III-M. 1. **High-confidence replication candidate (HC):** Cosine $> 0.95$ AND $\text{dHash}_{\text{indep}} \leq 5$. Both descriptors converge on image-similarity evidence consistent with replication; this is the highest-priority triage bin for human review, and mechanism attribution remains subject to §III-N.
2. **Moderate-confidence non-hand-signed (MC):** Cosine $> 0.95$ AND $5 < \text{dHash}_{\text{indep}} \leq 15$. Feature-level similarity is strong; structural similarity is present but below the high-confidence cutoff. 2. **Moderate-confidence advisory flag (MC):** Cosine $> 0.95$ AND $5 < \text{dHash}_{\text{indep}} \leq 15$. Feature-level similarity is strong but structural similarity is below the high-confidence cutoff; §III-I.3 shows this band carries low inter-CPA specificity even on the normative baseline, so it is a low-specificity advisory bin (review-workload-expanding) rather than a confident replication flag.
3. **High style consistency (HSC):** Cosine $> 0.95$ AND $\text{dHash}_{\text{indep}} > 15$. High feature-level similarity without structural corroboration; the descriptor signature is operationally distinguished from HC/MC, but the underlying mechanism (within-CPA signing style, lossy image reproduction with structural drift, or a hybrid) is not resolved by descriptor data alone. 3. **High style-consistency flag (HSC):** Cosine $> 0.95$ AND $\text{dHash}_{\text{indep}} > 15$. High feature-level similarity without structural corroboration; the descriptor position is operationally distinguished from HC/MC, but the underlying mechanism (within-CPA signing style, lossy image reproduction with structural drift, or a hybrid) is not resolved by descriptor data alone.
4. **Uncertain (UN):** Cosine between the all-pairs intra/inter KDE crossover ($0.837$) and $0.95$. 4. **Uncertain (UN):** Cosine between the all-pairs intra/inter KDE crossover ($0.837$) and $0.95$.
5. **Likely hand-signed (LH):** Cosine $\leq 0.837$. The "Likely hand-signed" name reflects the screening hypothesis that low maximum same-CPA cosine similarity is more consistent with hand-signing variation than with image replication; the label is operational, not a verified hand-signed classification, since cross-year handwriting drift, scanner-workflow change, or template variant rotation within a CPA's reports can also yield a low max-cosine within a same-CPA pool. 5. **Low replication-similarity (LH):** Cosine $\leq 0.837$. The name reflects the screening hypothesis that low maximum same-CPA cosine similarity is more consistent with hand-signing variation than with image replication; it is an operational low-priority bin, not a verified hand-signed classification, since cross-year handwriting drift, scanner-workflow change, or template variant rotation within a CPA's reports can also yield a low max-cosine within a same-CPA pool.
Document-level labels are aggregated via the worst-case rule: each audit report inherits the most-replication-consistent category among its certifying-CPA signatures (rank order HC > MC > HSC > UN > LH). The thresholds ($\text{cos} = 0.95$ as the cosine operating point, $\text{cos} = 0.837$ as the all-pairs KDE crossover, $\text{dHash} = 5$ and $15$ as structural-similarity sub-band cutoffs) retain their prior calibration provenance (see supplementary materials). These thresholds define the deployed screening rule; the present analysis does not re-derive them as optimal cutoffs but characterises their behaviour under inter-CPA coincidence anchors (developed in §III-L). Document-level labels are aggregated via the worst-case rule: each audit report inherits the most-replication-consistent category among its certifying-CPA signatures (rank order HC > MC > HSC > UN > LH). The thresholds ($\text{cos} = 0.95$ as the cosine operating point, $\text{cos} = 0.837$ as the all-pairs KDE crossover, $\text{dHash} = 5$ and $15$ as structural-similarity sub-band cutoffs) retain their prior calibration provenance (see supplementary materials). These thresholds define the deployed screening rule; the present analysis does not re-derive them as optimal cutoffs but characterises their behaviour under inter-CPA coincidence anchors (developed in §III-I).
The remainder of this section (§III-H.2) describes the reference populations used to calibrate and cross-check this rule. §III-I demonstrates that the descriptor distributions do not provide a within-population natural threshold; §III-J–§III-K develop the descriptive partition and internal-consistency cross-checks; §III-L develops the anchor-based threshold calibration; §III-M discloses the unsupervised-setting limits. The remainder of this section (§III-H.2) describes the reference populations used to calibrate and cross-check this rule. §III-I then establishes the normative baseline and its inter-CPA coincidence floor; §III-J reads each firm, and Firm A in particular, as a deviation from that floor; §III-K shows that the descriptor distributions provide no within-population natural threshold; §III-L–§III-M develop the descriptive mixture partition and internal-consistency cross-checks; §III-N discloses the unsupervised-setting limits.
### H.2. Reference Populations ### H.2. Reference Populations
The supporting diagnostics use two reference populations: Firm A as a within-Big-4 templated-end case study, and the 249 non-Big-4 CPAs as an out-of-target reference for internal-consistency checking. Neither population is the calibration anchor for the deployed threshold; both are descriptive references that inform the cross-checks in §III-K. Beyond the normative Firms-B/C/D baseline that anchors the calibration (§III-I), two further populations inform the analysis: Firm A, the **out-of-sample templated-end target** characterised in §III-J, and the 249 non-Big-4 CPAs, an out-of-target **reverse-anchor reference** for the internal-consistency checks of §III-M. Neither is the calibration negative anchor: Firm A is held out of it (§III-I.0), and the non-Big-4 reference informs the §III-M cross-checks (it also appears as a robustness scope in §III-I).
**Internal reference: Firm A as the templated-end case study.** Firm A is empirically the firm whose CPAs are most concentrated in the high-cosine, low-dHash corner of the Big-4 descriptor plane. In the Big-4 K=3 descriptive partition (§III-J; Scripts 35, 38), Firm A accounts for 0% of the C1 component (low-cos / high-dHash corner; cos $\approx 0.946$, dHash $\approx 9.17$, weight $\approx 0.143$), 17.5% of the C2 component (central region), and 82.5% of the C3 component (high-cos / low-dHash corner); the opposite pattern holds at Firm C (Script 35: 23.5% C1, 75.5% C2, 1.0% C3, hereafter referred to as "the Firm whose CPAs are most concentrated in C1"). Byte-level decomposition of these signatures (see supplementary materials) identifies 145 Firm A pixel-identical signatures, spanning 50 distinct Firm A partners of the 180 registered, with 35 byte-identical matches occurring across different fiscal years; the 145 are the Firm A portion of the 262 byte-identical Big-4 signatures. **The out-of-sample target: Firm A as the templated end.** Firm A is empirically the firm whose CPAs are most concentrated in the high-cosine, low-dHash corner of the Big-4 descriptor plane. In the Big-4 K=3 descriptive partition (§III-L; Scripts 35, 38), Firm A accounts for 0% of the C1 component (low-cos / high-dHash corner; cos $\approx 0.946$, dHash $\approx 9.17$, weight $\approx 0.143$), 17.5% of the C2 component (central region), and 82.5% of the C3 component (high-cos / low-dHash corner); the opposite pattern holds at Firm C (Script 35: 23.5% C1, 75.5% C2, 1.0% C3, hereafter referred to as "the Firm whose CPAs are most concentrated in C1"). Byte-level decomposition of these signatures (see supplementary materials) identifies 145 Firm A pixel-identical signatures, spanning 50 distinct Firm A partners of the 180 registered, with 35 byte-identical matches occurring across different fiscal years; the 145 are the Firm A portion of the 262 byte-identical Big-4 signatures.
Firm A is *not* the calibration anchor for the operational threshold. Firm A enters the Big-4 mixture on equal footing with Firms B through D; the K=3 components are derived from the joint Big-4 distribution (§III-J), not from Firm A alone. Firm A's role in the methodology is descriptive: it is the Big-4 firm whose CPAs are most concentrated in the high-cosine, low-dHash corner of the descriptor plane, and the byte-level pair evidence above provides the firm-level signature-reuse evidence that anchors §III-K's pixel-identity positive-anchor miss rate. Firm A is *not* the calibration anchor for the operational threshold. Firm A enters the Big-4 mixture on equal footing with Firms B through D; the K=3 components are derived from the joint Big-4 distribution (§III-L), not from Firm A alone. Firm A's role is as the out-of-sample templated-end target (§III-J): it is the Big-4 firm whose CPAs are most concentrated in the high-cosine, low-dHash corner of the descriptor plane, and the byte-level pair evidence above provides the firm-level signature-reuse evidence that anchors §III-M's pixel-identity positive-anchor miss rate.
**External reference: non-Big-4 as the reverse-anchor reference for internal-consistency checking.** The 249 non-Big-4 CPAs ($n_{\text{sig}} \geq 10$, drawn from $\sim$30 mid- and small-firms) constitute a population strictly outside the Big-4 target. Their per-CPA $(\overline{\text{cos}}_a, \overline{\text{dHash}}_a)$ distribution defines a 2D Gaussian reference (fit by Minimum Covariance Determinant with support fraction 0.85 for robustness; Script 38). This reference is used in §III-K's reverse-anchor internal-consistency check: each Big-4 CPA's location relative to the reference centre, measured as the marginal cosine cumulative-distribution-function value under the reference, is one of three feature-derived scores used as a cross-check on the per-signature classifier. The reverse-anchor reference is *not* a positive or negative anchor for threshold derivation — its role is to provide a strictly out-of-target benchmark against which the within-Big-4 mixture-derived ranking can be internally cross-checked. **External reference: non-Big-4 as the reverse-anchor reference for internal-consistency checking.** The 249 non-Big-4 CPAs ($n_{\text{sig}} \geq 10$, drawn from $\sim$30 mid- and small-firms) constitute a population strictly outside the Big-4 target. Their per-CPA $(\overline{\text{cos}}_a, \overline{\text{dHash}}_a)$ distribution defines a 2D Gaussian reference (fit by Minimum Covariance Determinant with support fraction 0.85 for robustness; Script 38). This reference is used in §III-M's reverse-anchor internal-consistency check: each Big-4 CPA's location relative to the reference centre, measured as the marginal cosine cumulative-distribution-function value under the reference, is one of three feature-derived scores used as a cross-check on the per-signature classifier. The reverse-anchor reference is *not* a positive or negative anchor for threshold derivation — its role is to provide a strictly out-of-target benchmark against which the within-Big-4 mixture-derived ranking can be internally cross-checked.
The reverse-anchor reference centre is at $\overline{\text{cos}} = 0.935$, $\overline{\text{dHash}} = 9.77$ (Script 38). The reference sits at a lower cosine and higher dHash than the Big-4 K=3 low-cos / high-dHash component (cos $= 0.946$, dHash $= 9.17$; §III-J); compared to the Big-4 high-cos / low-dHash component (cos $= 0.983$, dHash $= 2.41$; §III-J) the reference is markedly less replication-dominated. The reverse-anchor metric for a given Big-4 CPA is the percentile of $\overline{\text{cos}}_a$ within the reference marginal cosine distribution, sign-flipped so that lower percentile (further into the left tail of the reference) corresponds to a Big-4 CPA whose mean cosine sits further from the templated end of the descriptor plane. This is a "deviation in the less-replication-dominated descriptor-position direction" measure, not a "deviation toward the templated descriptor-position" measure; the reference is the less-replication-dominated population. The reverse-anchor reference centre is at $\overline{\text{cos}} = 0.935$, $\overline{\text{dHash}} = 9.77$ (Script 38). The reference sits at a lower cosine and higher dHash than the Big-4 K=3 low-cos / high-dHash component (cos $= 0.946$, dHash $= 9.17$; §III-L); compared to the Big-4 high-cos / low-dHash component (cos $= 0.983$, dHash $= 2.41$; §III-L) the reference is markedly less replication-dominated. The reverse-anchor metric for a given Big-4 CPA is the percentile of $\overline{\text{cos}}_a$ within the reference marginal cosine distribution, sign-flipped so that lower percentile (further into the left tail of the reference) corresponds to a Big-4 CPA whose mean cosine sits further from the templated end of the descriptor plane. This is a "deviation in the less-replication-dominated descriptor-position direction" measure, not a "deviation toward the templated descriptor-position" measure; the reference is the less-replication-dominated population.
## I. Distributional Diagnostics: Why the Composition Path Does Not Yield a Natural Threshold
This section characterises the joint distribution of accountant-level descriptor means $(\overline{\text{cos}}_a, \overline{\text{dHash}}_a)$ across the 437 Big-4 CPAs of §III-G and tests whether the distribution provides distributional support — in the form of within-population bimodality — for the deployed operational thresholds. We apply four diagnostic procedures in turn: a univariate unimodality test on each accountant-level marginal; a 2D Gaussian mixture fit (developed in §III-J); a density-smoothness diagnostic; and a composition decomposition that distinguishes within-population multimodality from between-firm location-shift artefacts. The four diagnostics jointly imply that the operational thresholds are *not* anchored by distributional bimodality: §III-L develops an anchor-based calibration framework that does not require this assumption. ## I. Normative Baseline and the Inter-CPA Coincidence Floor
**1. Hartigan dip test on each accountant-level marginal.** We apply the Hartigan & Hartigan dip test [37] to each of the two marginal distributions $\{\overline{\text{cos}}_a\}_{a=1}^{437}$ and $\{\overline{\text{dHash}}_a\}_{a=1}^{437}$, with bootstrap-based $p$-value estimation ($n_{\text{boot}} = 2000$). In both cases no bootstrap replicate exceeded the observed dip statistic, so the empirical $p$-value is bounded above by $5 \times 10^{-4}$; we report this in tables as $p < 5 \times 10^{-4}$ rather than $p = 0$ to reflect the bootstrap resolution (Script 34). For comparison, no rejection of unimodality holds in the comparison scopes tested in Script 32: Firm A pooled alone ($p_{\text{cos}} = 0.992$, $p_{\text{dHash}} = 0.924$, $n = 171$); Firms B + C + D pooled ($p_{\text{cos}} = 0.998$, $p_{\text{dHash}} = 0.906$, $n = 266$); all non-Firm-A CPAs pooled ($p_{\text{cos}} = 0.998$, $p_{\text{dHash}} = 0.907$, $n = 515$). Single-firm dip tests for Firms B, C, and D were not separately computed; the comparison scopes above sufficed to establish that no narrower-than-Big-4 *tested* scope at the accountant level rejected unimodality. The accountant-level Big-4 rejection is a descriptive observation; §III-I.4 below shows that the rejection is fully explained by between-firm location-shift effects rather than within-population bimodality. We calibrate the operational classifier of §III-H.1 by first establishing a *normative baseline* — a population of independent CPAs in which the deployed rule should fire only by chance — and then measuring the rate at which it fires there. This inter-CPA coincidence floor is the reference against which every firm, Firm A included, is read in §III-J. Because the descriptor distributions contain no within-population bimodal antimode that could anchor a threshold directly (§III-K), it is this empirically measured floor, rather than a distributional cut, that gives the deployed thresholds an interpretable specificity meaning. Throughout we report **inter-CPA coincidence rates (ICCR)** rather than "False Acceptance Rates", for the reasons given in §III-I.0. This section develops the calibration method and reports the headline floor at each unit of analysis; the full result tables are consolidated in §IV-M (Tables XXIXXIII).
**2. K=2 / K=3 Gaussian mixture fits (descriptive partition).** A 2-component 2D Gaussian Mixture Model (full covariance, $n_{\text{init}} = 15$, fixed seed 42; Script 34) recovers components at $(\overline{\text{cos}}, \overline{\text{dHash}}) = (0.954, 7.14)$, weight $0.689$, and $(0.983, 2.41)$, weight $0.311$. The marginal crossings of the K=2 fit are $\overline{\text{cos}}^* = 0.9755$ and $\overline{\text{dHash}}^* = 3.755$, with bootstrap 95% confidence intervals $[0.9742, 0.9772]$ and $[3.48, 3.97]$ over $n_{\text{boot}} = 500$ resamples. The 3-component fit (§III-J) is BIC-preferred — using the convention that lower BIC is preferred, $\text{BIC}(K{=}3) - \text{BIC}(K{=}2) = -3.48$ (Script 36). The $\Delta$BIC magnitude is small in absolute terms; we do not treat $\Delta\text{BIC} = 3.5$ alone as decisive evidence for K=3 as a population mixture. Following §III-I.4 we treat both K=2 and K=3 fits as *descriptive partitions* of the joint Big-4 distribution that reflect firm-composition structure (Firm A vs others; §III-J) rather than as inferential evidence for two or three latent population modes. ### I.0. Calibration methodology
**3. Burgstahler-Dichev / McCrary density-smoothness diagnostic.** We apply the discontinuity test of [38, 39] as a *density-smoothness diagnostic* (rather than as a threshold estimator) on each accountant-level marginal axis (cosine in bins of $0.002$, dHash in integer bins). At the Big-4 scope, the diagnostic identifies no significant transition on either marginal at $\alpha = 0.05$ (Script 34). Outside Big-4, the diagnostic does flag dHash transitions in some subsets (Script 32: `big4_non_A` dHash transition at $10.8$; `all_non_A` dHash transition at $6.6$; pre-2018 and post-2020 time-stratified variants also exhibit one or more dHash transitions), but no cosine transition is identified in any subset. The Big-4-scope null on both axes is consistent with §III-I.4 below: under the composition decomposition the Big-4 marginals are unimodal once between-firm and integer-tie confounds are removed, so a local-discontinuity test correctly fails to flag a within-population transition. **Choice of negative-anchor pool.** A negative anchor must approximate a population in which the rule should *not* fire — independent CPAs whose signatures coincide only by chance. §III-J.1 shows that under the deployed rule $98.8\%$ of Firm A's inter-CPA collisions fall on other Firm-A CPAs, and byte-level evidence (§IV-H, supplementary materials) confirms image-level reuse across $\sim 50$ Firm-A partners. Including Firm A in the negative-anchor pool would therefore load the "coincidence" rate with structured within-firm collisions rather than chance coincidence — a circularity, since that collision structure is the phenomenon the rule targets. We adopt **Firms B/C/D (BCD) as the normative negative-anchor baseline** and report the all-Big-4 (ABCD) pool only as a contamination-comparison scope; Firm A enters as an **out-of-sample target** (§III-J.1), not as a calibration input. A still-broader baseline adding the eligible non-Big-4 firms (BCD+non-Big-4) is reported as a robustness scope.
**4. Composition decomposition (Scripts 39b39e).** §III-I.1 establishes that the accountant-level marginals reject unimodality at the Big-4 sub-corpus. The remaining question is whether the rejection reflects (a) genuine within-population bimodality at the signature or accountant level, (b) between-firm location-shift artefacts (firms with different mean descriptor positions pool to a multi-peaked distribution), or (c) integer mass-point artefacts on the integer-valued dHash axis (the dHash dip statistic is sensitive to spikes at integer values). We apply four diagnostics that decompose the rejection into these candidate sources: We further restrict the calibration baseline temporally to **fiscal years 20132019**. Following the post-2020 acceleration of digital document workflows, Taiwan audit firms increasingly adopted electronic-signature and stamping systems for report assembly, with firm-specific timing; the pre-2020 BCD period is therefore the construct-clean hand-signing baseline, while the post-2020 period mixes genuine hand-signing with legitimate e-signing and is not a clean negative anchor. The data corroborate this: the BCD per-comparison HC floor rises from $0.000010$ (20132019) to $0.000036$ (20202023), and the per-signature floor from $0.0059$ to $0.0105$ — the gradual, non-stepped rise being consistent with staggered per-firm adoption. We therefore calibrate on BCD 20132019 and report BCD 20202023 only as a robustness scope. Firm A is scored across its full 20132023 record against this clean threshold.
*Within-firm signature-level dip (Scripts 39b, 39c).* Repeating the dip test at the signature level inside each individual Big-4 firm (Script 39b) and inside each individual non-Big-4 firm with $\geq 500$ signatures (Script 39c) yields a consistent picture. The cosine marginal *fails* to reject unimodality in every single firm tested — all four Big-4 firms ($p_{\text{cos}} \in \{0.176, 0.991, 0.551, 0.976\}$ for Firms A through D; Script 39b) and ten non-Big-4 firms with $\geq 500$ signatures ($p_{\text{cos}} \in [0.59, 0.99]$; Script 39c). The raw dHash marginal *does* reject unimodality in every firm tested ($p < 5 \times 10^{-4}$ in all $14$ firms), but the raw dHash values are integer-valued in $\{0, 1, \ldots, 64\}$, leaving open the possibility of an integer-tie artefact. **Calibration role.** The deployed thresholds of §III-H.1 preserve continuity with the existing literature and the supplementary calibration evidence. Because a recalibration cannot be anchored on distributional antimodes (no within-population bimodality exists, §III-K.4), §III-I.1 below characterises the cosine and structural ($\text{dHash} \leq 5$) thresholds' specificity-proxy behaviour at the inter-CPA pair level on the BCD baseline. The sub-band thresholds ($\text{dHash} = 15$, $\text{cos} = 0.837$) retain their supplementary calibration evidence; the present calibration does not provide independent rates for them. The cosine LH/UN crossover $\text{cos} = 0.837$ is a corpus-wide descriptor-space landmark (intra- vs inter-CPA cosine KDE crossover, §IV-C) robust to baseline choice — it moves by at most $0.012$ across the corpus-wide, BCD, and BCD+non-Big-4 scopes ($0.8367$, $0.8489$, $0.8302$) — so we retain the corpus-wide value.
*Integer-jitter robustness (Scripts 39d, 39e).* Adding independent uniform jitter $\sim \mathrm{U}[-0.5, +0.5]$ to break exact dHash ties and re-running the dip test on the perturbed signature cloud (5 seeds, $n_{\text{boot}} = 2000$; Script 39d) eliminates the dHash within-firm rejection in every Big-4 firm tested (Firm A jittered $p_{\text{median}} = 0.999$; B $0.996$; C $0.999$; D $0.9995$; $0$/$5$ seeds reject at $\alpha = 0.05$ in any firm). The pooled-Big-4 dHash dip *does* survive jitter alone ($p_{\text{median}} = 0$, $5$/$5$ seeds reject), but Firm A's mean dHash ($2.73$) is substantially below Firms B/C/D's ($6.46$, $7.39$, $7.21$) — a between-firm location shift. Script 39e applies a 2 \times 2 factorial correction (firm-mean centring $\times$ integer jitter) on the Big-4 pooled dHash: **Three units of analysis.** We report inter-CPA negative-anchor coincidence behaviour at three units, each answering a different operational question:
| Condition | Firm-mean centred | Integer jitter | Median dip $p$ | Reject at $\alpha = 0.05$ | - *Per comparison.* For a randomly drawn pair of signatures from different CPAs, what fraction satisfies the rule (cos $>$ cos\_threshold and / or dHash $\leq$ dHash\_threshold)? This is the conventional pairwise calibration unit in biometric verification, reported marginally and jointly (§III-I.1).
- *Per signature pool.* For a source signature $s$ with same-CPA pool of size $n_{\text{pool}}(s)$, what is the probability that the deployed rule fires *under the counterfactual* of replacing the source's same-CPA pool with $n_{\text{pool}}(s)$ random non-same-CPA candidates from the baseline pool? The deployed rule takes max-cosine and min-dHash over the pool, so its effective coincidence rate is $\approx 1 - (1 - p_{\text{pair}})^{n_{\text{pool}}}$ in the independence limit (§III-I.2).
- *Per document.* For an audit report aggregated via the worst-case rule, what fraction of documents have at least one signature whose pool-normalised rule fires under the same inter-CPA candidate-replacement counterfactual? This is the operational alarm-rate unit (§III-I.3).
**Any-pair vs same-pair semantics.** The deployed rule uses independent extrema: a signature satisfies the HC rule if $\max_{\text{pool}} \text{cos} > 0.95$ AND $\min_{\text{pool}} \text{dHash} \leq 5$, *not* if a single candidate satisfies both. We call this the **any-pair** rule, and report the stricter **same-pair** rule (one candidate satisfying both inequalities) as an alternative where useful (§III-I.2, §III-J.1).
**Terminological note on "FAR".** We adopt **inter-CPA coincidence rate (ICCR)** and *do not* use "FAR", for two reasons: (a) FAR has a specific biometric-verification meaning requiring ground-truth negative labels, which the corpus does not provide at the signature level; (b) the inter-CPA negative-anchor assumption — that inter-CPA pairs are negative — is partially violated by within-firm cross-CPA template-like collision structures, which is precisely why we move the anchor to the BCD baseline. Even on the BCD baseline, ICCR is a *specificity proxy* under an explicitly disclosed assumption, not a true biometric FAR.
### I.1. Per-comparison inter-CPA coincidence rate (Script 46)
We sample $5 \times 10^5$ inter-CPA pairs uniformly at random from the baseline pool, computing for each the cosine similarity and the Hamming distance between dHash byte vectors, with Wilson 95% confidence intervals (Script 46; Table XXI, §IV-M).
On the normative BCD baseline the joint per-comparison coincidence rate for the deployed HC rule (cos $> 0.95$ AND dHash $\leq 5$, any-pair) is $\mathbf{0.000010}$ $[0.000004, 0.000023]$ — roughly $8\times$ lower than the all-Big-4 rate ($0.000140$) and lower still when the non-Big-4 firms are added ($0.000004$). The all-Big-4 figure is inflated by Firm A's within-firm collision structure (§III-J.1): removing Firm A from the negative anchor strips out the structured reuse that an honest specificity proxy must exclude. The joint-rule hit count is small in absolute terms ($5$ of $5 \times 10^5$ pairs on the BCD pool), so we treat the per-comparison joint rate as an order-of-magnitude specificity proxy and let the well-powered per-signature and per-document units (§III-I.2, §III-I.3) carry the primary calibration weight. The all-Big-4 cos $> 0.95$ marginal ($0.00060$) is consistent with the corpus-wide per-comparison rate of §IV-I, and on the all-Big-4 sample the conditional rate ICCR(dHash $\leq 5\mid$ cos $> 0.95$) $= 0.234$ — the structural dimension adds substantial per-comparison specificity beyond the cosine gate.
The per-comparison rate does *not* directly translate to deployed-rule specificity at the per-signature classifier level, because the deployed classifier takes extrema over a same-CPA pool of size $n_{\text{pool}}$ (§III-I.2).
### I.2. Pool-normalised inter-CPA alert rate (Script 52)
For each source signature $s$ we simulate one realisation of an inter-CPA candidate pool of the same size $n_{\text{pool}}(s)$, drawn uniformly from non-same-CPA signatures *in the baseline pool*, compute the deployed extrema and rule indicator, and aggregate (Script 52, canonical retry-loop sampler matching Scripts 43/45; CPA-block bootstrap 95% CIs on $n_{\text{boot}} = 1000$ replicates; Table XXII, §IV-M).
On the normative BCD baseline the deployed HC rule's pool-normalised per-signature coincidence rate is $\mathbf{0.0059}$ $[0.0045, 0.0073]$ — an order of magnitude below the all-Big-4 figure of $0.1102$, which is dominated by Firm A. Once Firm A is removed from both the source set and the candidate pool, the residual per-signature coincidence among independent normative-baseline CPAs is $\approx 0.59\%$. **This is the specificity-proxy floor against which the deployed HC rule operates.** The rate rises with pool size (the rule takes extrema over $n_{\text{pool}}$ candidates), consistent with the $1 - (1 - p_{\text{pair}})^{n_{\text{pool}}}$ form expected under inter-CPA independence; the within-firm violation of that independence (§III-J.1) bounds how literally the closed form can be read. Stakeholders requiring a tighter specificity proxy can characterise alternative operating points (e.g., dHash $\leq 3$) by inverting the ICCR curve, under the unsupervised-setting caveats of §III-N.
### I.3. Document-level inter-CPA proxy alert rate (Script 52)
Each document is classified by the worst-case rule over its constituent signatures (§III-H.1) under the same inter-CPA candidate-pool counterfactual as §III-I.2 (Script 52, dominant-firm document assignment; Table XXIII, §IV-M).
**The HC and HC+MC bands behave very differently on a clean baseline, which sharpens the operating-point recommendation.** On the BCD baseline the per-document HC (dHash $\leq 5$) rate is $\mathbf{0.0117}$ ($\sim 8\times$ below the all-Big-4 $0.1797$): a clean inter-CPA baseline almost never produces an HC document, confirming HC as a high-specificity operating point. The HC+MC (dHash $\leq 15$) rate, by contrast, stays high on the clean baseline — $0.1753$ per document — and does *not* fall when Firm A is removed. Per-firm per-document HC+MC ICCR on the BCD baseline is Firm B $0.162$, Firm C $0.225$, Firm D $0.089$, slightly *higher* than under the all-Big-4 pool (B $0.160$, C $0.163$, D $0.088$), because removing Firm A's idiosyncratic template leaves a candidate pool whose members resemble one another more closely at the coarse dHash $\leq 15$ scale. **We therefore treat the HC sub-rule (dHash $\leq 5$) as the specificity-anchored operating point and reposition the MC band ($5 < \text{dHash} \leq 15$) as a low-specificity advisory tier, not a confident non-hand-signed screening label**: roughly one normative-baseline document in five would coincidentally carry an HC+MC flag under random inter-CPA candidate replacement. The positioning of the operational system as a **screening framework with human-in-the-loop review**, not an autonomous forensic classifier, follows directly (§III-N).
## J. Firm-Level Deviation from the Baseline
With the calibration anchored on the clean BCD floor (§III-I.2), every firm — and in particular Firm A — can be read as a deviation from that floor. Firm A is scored as a true out-of-sample target against the baseline.
### J.1. Firm A as an out-of-sample target; firm heterogeneity
Three complementary readings establish that Firm A is the extreme case while keeping the inferential limits explicit.
**(i) Observed deployed rate versus the clean floor.** The deployed HC rule fires on each firm's *actual* same-CPA pools at the following per-signature rates (observed, not counterfactual; Script 49), against the BCD specificity-proxy floor of $0.0059$ (§III-I.2):
| Firm | Observed per-signature HC rate | Multiple of BCD floor |
|---|---|---|
| Firm A | $0.817$ | $\sim 139\times$ |
| Firm B | $0.346$ | $\sim 59\times$ |
| Firm C | $0.238$ | $\sim 40\times$ |
| Firm D | $0.245$ | $\sim 42\times$ |
All four Big-4 firms fire the HC rule on their own pools far above the inter-CPA coincidence floor; Firm A is the extreme at $\sim 139\times$, roughly $2.4$$3.4\times$ the other Big-4 firms in absolute rate.
**(ii) Firm A against the clean baseline behaves like the floor — its signal is within-firm.** Scored as a true out-of-sample target (Firm A source signatures, candidate pool drawn from the clean BCD baseline, any-pair, Script 52), Firm A's per-signature HC coincidence rate is $0.0001$ — below even the BCD-internal floor of $0.0059$, i.e. Firm A's signatures essentially never resemble genuine 20132019 hand-signing from other firms. The entire elevation in Firm A's observed rate ($0.817$) therefore arises from matches against *other Firm-A* signatures, localising the repeatability signal to within-firm comparisons rather than cross-firm distinctiveness.
**(iii) Firm-effect regressions: Firm A singular, baseline homogeneous.** Two logistic regressions of the per-signature any-pair HC hit indicator on firm dummies and centred log pool size jointly establish that Firm A is the singular extreme while Firms B/C/D form an internally homogeneous baseline. On the full Big-4 pool with Firm A as reference (Script 44), the odds ratios are $0.053$ (B), $0.010$ (C), $0.027$ (D), with log-pool-size odds ratio $4.01$ — Firms B/C/D sit one to two orders of magnitude below Firm A after pool-size control. On the BCD baseline with Firm D as reference (Script 53; $n = 89{,}994$, hit rate $0.0059$), the residual firm spread collapses to within a factor of $\sim 3.5$: odds ratios $1.73$ (B), $0.49$ (C), log-pool-size odds ratio $3.29$. The normative-baseline firms are therefore comparable to one another, with Firm A the lone outlier — supporting treating B/C/D as a coherent calibration baseline and Firm A as an out-of-sample target. (We report odds ratios rather than $z$-scores because per-signature observations are clustered by CPA and firm; cluster-robust inference is left as a robustness check.)
**Cross-firm hit matrix: within-firm concentration is a universal Big-4 pattern.** Under the deployed any-pair rule, inter-CPA collisions concentrate within the source firm at every Big-4 firm. On the full Big-4 candidate pool, within-firm concentration is $98.8\%$ at Firm A and $76.7$$83.7\%$ at Firms B/C/D (same-pair $97.0$$99.96\%$; Table XXV). Restricting the candidate pool to the BCD baseline (Script 53) *raises* the within-firm concentration for B/C/D to $89.2$$97.2\%$ any-pair (Firm B $97.2\%$, Firm C $92.3\%$, Firm D $89.2\%$) and $98.5$$100\%$ same-pair — higher than on the full pool, because there some B/C/D collisions landed on Firm A's generically copy-like signatures; removing Firm A leaves each firm's collisions concentrated within itself. Within-firm collision concentration is therefore a universal Big-4 structural pattern, not a Firm-A peculiarity: Firm A is extreme in the *rate* at which the rule fires (reading (i)), but all four firms exhibit the same within-firm collision signature.
### J.2. Observed deployed alert rate on actual same-CPA pools
Reading (i) of §III-J.1 reported each firm's observed HC rate; reading (ii) used the inter-CPA candidate-replacement counterfactual. Here we report the pooled-Big-4 **observed deployed alert rate** — the rate at which the rule fires on each source's actual same-CPA pool across the real corpus — and its excess over the clean floor. For Big-4 it fires on $49.58\%$ of signatures and $62.28\%$ of documents (Script 46; Script 42 reproduces the per-signature rate). Read against the **normative BCD floor** rather than the contaminated all-Big-4 rate, the observed-deployed excess is large: per signature $0.4958$ vs $0.0059$ ($49.0$ pp, $\sim 84\times$); per document (HC) $0.6228$ vs $0.0117$ ($61.1$ pp, $\sim 53\times$). Anchoring the floor on the clean BCD baseline sharpens this contrast, since the all-Big-4 floor would understate it by absorbing Firm A's reuse.
**Interpretation and inferential limits.** The firm multiples of §III-J.1 and the observed-deployed excess above are *not* true-positive rates: the floor is an inter-CPA coincidence rate, whereas a CPA who hand-signs consistently can also produce same-pool repeatability above that floor. We therefore read the excess as an *observed same-CPA-pool excess over the normative inter-CPA floor* — a quantity far exceeding what random inter-CPA candidate replacement among normative firms would produce — whose mechanism is not identifiable from descriptor-only data (§III-N); we do not attribute it to within-CPA handwriting repeatability or to image replication without further evidence. Likewise, the within-firm collision concentration is consistent with — but not by itself diagnostic of — firm-specific template, stamp, or document-production reuse: common form templates, shared scanning workflows, and report-generation infrastructure could all produce visually similar signature crops across CPAs within a firm. Byte-level decomposition of Firm A's $145$ pixel-identical signatures across $\sim 50$ distinct certifying partners (§IV-H, supplementary materials) is direct evidence of image-level reuse among Firm A signatures; the milder within-firm patterns at Firms B/C/D may reflect template-like reuse, digitisation-pipeline homogeneity, or signing-style homogeneity, which descriptor-only data cannot separate (§V-H). We report "inter-CPA collision concentration is within-firm" as a descriptive observation about deployed-rule behaviour and refrain from inferring deliberate or systematic template sharing.
## K. Why the Descriptor Distribution Provides No Threshold
The baseline calibration of §III-I is necessary because the descriptor distribution itself supplies no within-population threshold. This section establishes that negative result: the joint distribution of accountant-level descriptor means $(\overline{\text{cos}}_a, \overline{\text{dHash}}_a)$ across the 437 Big-4 CPAs contains no within-population bimodal antimode that could anchor the deployed operational thresholds. We apply four diagnostics, decompose the one apparent rejection into its true source, and confirm that the deployed thresholds sit on a steep — not plateau-like — region of the alert-rate surface.
**1. Hartigan dip test on each accountant-level marginal.** The dip test [37] on each marginal $\{\overline{\text{cos}}_a\}$ and $\{\overline{\text{dHash}}_a\}$ (bootstrap $p$, $n_{\text{boot}} = 2000$) rejects unimodality at the Big-4 sub-corpus ($p < 5 \times 10^{-4}$ on both, Script 34). The rejection does *not* hold in narrower tested scopes (Script 32): Firm A alone ($p_{\text{cos}} = 0.992$, $p_{\text{dHash}} = 0.924$), Firms B+C+D pooled ($0.998$, $0.906$), and all non-Firm-A CPAs pooled ($0.998$, $0.907$). The Big-4 rejection is thus a descriptive observation that item 4 below attributes entirely to between-firm composition rather than within-population bimodality.
**2. K=2 / K=3 Gaussian mixture fits (descriptive partition).** A 2-component 2D GMM (Script 34) recovers components at $(0.954, 7.14)$, weight $0.689$, and $(0.983, 2.41)$, weight $0.311$, with marginal crossings $\overline{\text{cos}}^* = 0.9755$, $\overline{\text{dHash}}^* = 3.755$. The 3-component fit is mildly BIC-preferred ($\Delta\text{BIC} = -3.48$, not decisive). Following item 4 we treat both fits as *descriptive partitions* reflecting firm-composition structure (Firm A vs others), not evidence for latent population modes; they are developed in §III-L.
**3. Burgstahler-Dichev / McCrary density-smoothness diagnostic.** Applied as a density-smoothness diagnostic [38, 39] on each marginal, the test flags no significant transition at the Big-4 scope on either axis ($\alpha = 0.05$, Script 34). It does flag dHash transitions in some out-of-scope subsets (Script 32) but no cosine transition in any subset — consistent with item 4: once between-firm and integer-tie confounds are removed, the Big-4 marginals are unimodal, so a local-discontinuity test correctly finds no within-population transition.
**4. Composition decomposition (Scripts 39b39e).** The Big-4 accountant-level rejection (item 1) could reflect (a) genuine within-population bimodality, (b) between-firm location-shift artefacts, or (c) integer mass-point artefacts on the integer-valued dHash axis. Repeating the dip test at the signature level *inside* each firm shows the cosine marginal fails to reject unimodality in every firm tested — all four Big-4 firms ($p_{\text{cos}} \in \{0.176, 0.991, 0.551, 0.976\}$; Script 39b) and ten non-Big-4 firms with $\geq 500$ signatures ($p_{\text{cos}} \in [0.59, 0.99]$; Script 39c). The raw dHash marginal rejects in every firm, but the values are integer-valued; adding uniform jitter $\sim \mathrm{U}[-0.5, +0.5]$ to break exact ties (5 seeds; Script 39d) eliminates the within-firm dHash rejection in every Big-4 firm (jittered $p_{\text{median}} \geq 0.996$, $0/5$ seeds reject). The pooled-Big-4 dHash dip survives jitter alone, but Firm A's mean dHash ($2.73$) sits well below Firms B/C/D's ($6.46$, $7.39$, $7.21$) — a between-firm location shift. Script 39e applies a $2 \times 2$ factorial correction on the pooled dHash:
| Condition | Firm-mean centred | Integer jitter | Median dip $p$ | Reject at $\alpha = 0.05$ |
|---|---|---|---|---| |---|---|---|---|---|
| 1 raw | — | — | $< 5 \times 10^{-4}$ | $5/5$ | | 1 raw | — | — | $< 5 \times 10^{-4}$ | $5/5$ |
| 2 centred only | $\checkmark$ | — | $< 5 \times 10^{-4}$ | $5/5$ | | 2 centred only | $\checkmark$ | — | $< 5 \times 10^{-4}$ | $5/5$ |
| 3 jittered only | — | $\checkmark$ | $< 5 \times 10^{-4}$ | $5/5$ | | 3 jittered only | — | $\checkmark$ | $< 5 \times 10^{-4}$ | $5/5$ |
| 4 centred and jittered | $\checkmark$ | $\checkmark$ | $\mathbf{0.35}$ | $\mathbf{0/5}$ | | 4 centred and jittered | $\checkmark$ | $\checkmark$ | $\mathbf{0.35}$ | $\mathbf{0/5}$ |
Removing *both* the between-firm location shift *and* the integer mass points eliminates the Big-4 dHash rejection. The Big-4 pooled dHash multimodality is therefore fully attributable to firm-composition contrast (primarily Firm A's mean $\text{dHash} = 2.73$ versus Firms B/C/D $\approx 6.5$$7.4$) and integer-density artefacts, with no residual continuous within-firm bimodality. Removing *both* the between-firm location shift *and* the integer mass points eliminates the rejection ($p_{\text{median}} = 0.35$): the Big-4 pooled dHash multimodality is fully attributable to firm-composition contrast and integer-density artefacts, with no residual continuous within-firm bimodality. Consistently, within each Big-4 firm the dHash histogram on bins $0$$20$ exhibits no strict local minimum, and the pooled histogram shows only a shallow valley at $\text{dHash} = 4$ (relative depth $2.1\%$) — no antimode near the deployed $\text{dHash} = 5$ boundary in any firm.
*Cosine analogue.* The cosine axis follows the same pattern by construction: the within-firm signature-level cosine dip tests above (Scripts 39b, 39c) fail to reject in every Big-4 firm and in every eligible non-Big-4 firm, so any pooled cosine multimodality must arise from between-firm composition rather than from within-population bimodality. **5. Conclusion.** The descriptor distributions contain no within-population bimodal antimode that could anchor an operational threshold. The K=2 / K=3 mixtures (§III-L) are therefore descriptive firm-compositional partitions, not evidence for population modes, and the anchor-based calibration of §III-I does not require a distributional antimode.
*Integer-histogram valleys (Script 39d).* A genuine within-firm dHash antimode would appear as a strict local minimum in the count histogram with deep relative depth. Within each of the four Big-4 firms, the dHash histogram on bins $0$$20$ exhibits no strict local minimum; the Big-4 pooled histogram exhibits one shallow valley at $\text{dHash} = 4$ with relative depth $0.021$ (a $2.1\%$ count drop). No valley near the deployed $\text{dHash} = 5$ operational boundary appears within any individual firm. The hypothesised dHash antimode near $\text{dHash} \approx 5$ is not empirically supported by the histogram analysis. **6. Local sensitivity of the deployed thresholds (Script 46).** As a final confirmation that the deployed HC thresholds are not distributional features, we sweep each threshold against the *actual observed* Big-4 same-CPA pools and compare the local gradient at the deployed value to the median gradient across the sweep. At cos $> 0.95$ AND dHash $\leq 5$ the local gradient is substantially larger than the median (cosine ratio $\approx 25\times$; dHash ratio $\approx 3.8\times$): the HC threshold is *locally sensitive*, not plateau-stable (a $0.01$ cosine perturbation swings the rate $3.0$ pp; a single dHash integer step swings it $14.3$ pp). The MC/HSC boundary at dHash $= 15$, by contrast, lies in a low-gradient plateau (ratio $\approx 0.08\times$ median) — adding alert yield without inter-CPA specificity (§III-I.3), reinforcing the MC band's demotion to an advisory tier. We therefore read the deployed HC thresholds as **specificity-anchored operating points** (chosen for the specificity-vs-alert-yield tradeoff, §III-I.1), not as distributional antimodes; the gradient ratios are descriptive diagnostics, and the primary "no antimode" evidence comes from item 4 above.
**5. Conclusion: no natural threshold from the descriptor distribution.** §III-I.4 jointly establishes that (a) the Big-4 accountant-level dip rejection is fully attributable to between-firm composition and integer mass-point artefacts; (b) within the Big-4 firms, the descriptor marginals at the signature level are unimodal once integer ties are broken (Scripts 39b, 39d); (c) eligible non-Big-4 checks provide corroborating raw-axis evidence on the cosine dimension (Script 39c) and corroborate the integer-mass-point reading of raw dHash, but are not used as calibration evidence for the deployed thresholds; and (d) no integer-histogram valley near the deployed $\text{dHash} = 5$ operational boundary exists within any Big-4 firm. The descriptor distributions therefore do not contain a within-population bimodal antimode that could anchor an operational threshold. The K=2 / K=3 mixture fits of §III-I.2 and §III-J are retained as *descriptive partitions* that reflect firm-composition contrast, not as inferential evidence for two or three population modes. §III-L develops the anchor-based threshold calibration framework, which derives operational rates from inter-CPA pair-level negative-anchor coincidences rather than from a distributional antimode. ## L. K=3 as a Descriptive Partition of Firm-Composition Contrast
## J. K=3 as a Descriptive Partition of Firm-Composition Contrast This section develops the K=2 and K=3 Gaussian mixture fits and clarifies their role. **Both fits are descriptive partitions of the joint Big-4 distribution; they reflect firm-composition contrast — primarily Firm A versus Firms B, C, D — rather than within-population mechanism modes** (§III-K.4 shows the apparent multimodality is fully explained by between-firm location shifts and integer mass-point artefacts). Neither mixture assigns signature- or document-level labels in the primary analysis; the operational classifier of §III-H.1 is calibrated in §III-I via inter-CPA coincidence rates, not mixture-derived antimodes.
This section develops the K=2 and K=3 Gaussian mixture fits to the Big-4 accountant-level distribution and clarifies their role. **Both fits are descriptive partitions of the joint Big-4 distribution; they reflect firm-composition contrast — primarily Firm A versus Firms B, C, D — rather than within-population mechanism modes.** §III-I.4 demonstrates that the apparent multimodality of the accountant-level marginals is fully explained by between-firm location shifts and integer mass-point artefacts, leaving no residual evidence for two or three latent within-population mechanism classes. Neither mixture is used to assign signature-level or document-level labels in the primary analysis. The operational classifier of §III-H.1 is calibrated in §III-L via inter-CPA negative-anchor coincidence rates, not via mixture-derived antimodes. **K=2 fit.** Two components at $(\overline{\text{cos}}, \overline{\text{dHash}}) = (0.954, 7.14)$ (weight $0.689$) and $(0.983, 2.41)$ (weight $0.311$); marginal crossings $\overline{\text{cos}}^* = 0.9755$, $\overline{\text{dHash}}^* = 3.755$ (Script 34). We refer to components by index, since §III-K.4 establishes that the separation is firm-compositional, not mechanistic.
**K=2 fit.** Two components at $(\overline{\text{cos}}, \overline{\text{dHash}}) = (0.954, 7.14)$ (weight $0.689$) and $(0.983, 2.41)$ (weight $0.311$) (Script 34). $\text{BIC}(K{=}2) = -1108.45$. Marginal crossings: $\overline{\text{cos}}^* = 0.9755$, $\overline{\text{dHash}}^* = 3.755$. We refer to the components by index rather than by mechanism labels, since §III-I.4 establishes that the K=2 separation is firm-compositional rather than mechanistic.
**K=3 fit.** Three components, sorted by ascending cosine mean (Script 35; Script 38 reproduces): **K=3 fit.** Three components, sorted by ascending cosine mean (Script 35; Script 38 reproduces):
@@ -378,227 +453,35 @@ This section develops the K=2 and K=3 Gaussian mixture fits to the Big-4 account
| C2 | 0.9558 | 6.66 | 0.536 | central region | | C2 | 0.9558 | 6.66 | 0.536 | central region |
| C3 | 0.9826 | 2.41 | 0.321 | high-cos / low-dHash corner | | C3 | 0.9826 | 2.41 | 0.321 | high-cos / low-dHash corner |
$\text{BIC}(K{=}3) = -1111.93$, lower than $K{=}2$ by $3.48$ (mild numerical preference for K=3 under standard BIC interpretation, but not by itself decisive). The "descriptive position" column refrains from any mechanism interpretation: §III-I.4 establishes that the cosine and dHash axes both lack within-population bimodality, so component centres are best interpreted as locations in a continuous descriptor space rather than as latent mechanism modes. $\text{BIC}(K{=}3) = -1111.93$, below $K{=}2$ by $3.48$ (mild, not decisive). The component centres are locations in a continuous descriptor space, not latent mechanism modes.
**Per-firm component composition (Script 35 firm × cluster cross-tab).** The K=3 partition is dominated by firm membership: **The partition is dominated by firm membership (Script 35).** Firm A is $82.5\%$ C3 and accounts for $141$ of the $143$ C3-assigned CPAs; Firm C accounts for $24$ of the $40$ C1-assigned CPAs; Firms B and D sit predominantly in the central C2. The K=3 partition is therefore a firm-compositional decomposition: C3 is essentially "Firm A," C1 essentially "non-Firm-A CPAs in the low-cos / high-dHash corner." This same firm-compositional contrast reappears at the deployment level in the cross-firm hit matrix of §III-J.1.
- Firm A: $0\%$ C1, $17.5\%$ C2, $82.5\%$ C3 **Leave-one-firm-out stability (Scripts 36, 37).** K=2 is unstable across folds (holding Firm A out shifts the cosine crossing to $0.938$ vs $\sim 0.975$ for the other folds; max across-fold deviation $0.028$, $5.6\times$ the report's tolerance), confirming the K=2 boundary is essentially a Firm-A-versus-others separator. K=3 has a *reproducible component shape* (C1 cosine mean varies by $\leq 0.005$, dHash by $\leq 0.96$, weight by $\leq 0.012$ across folds) but composition-sensitive hard-posterior membership (held-out C1 rate $36.3\%$ vs baseline $23.5\%$ at Firm C — a $12.8$ pp difference; legend `P2_PARTIAL`). We therefore do not use K=3 hard-posterior membership as an operational label; the operational classifier is calibrated in §III-I, and cross-checks between the deployed rule and the K=3 partition appear in §III-M.
- Firm B: $8.9\%$ C1, $\sim 78\%$ C2, $\sim 13\%$ C3
- Firm C: $23.5\%$ C1, $75.5\%$ C2, $1.0\%$ C3
- Firm D: $11.5\%$ C1, $\sim 84\%$ C2, $\sim 4.5\%$ C3
Firm A accounts for $141$ of the $143$ C3-assigned CPAs; Firm C accounts for $24$ of the $40$ C1-assigned CPAs. The K=3 partition is therefore well-described as a firm-compositional decomposition: C3 is essentially "Firm A and any non-Firm-A CPA whose mean descriptors happen to land in the high-cos / low-dHash corner"; C1 is essentially "non-Firm-A CPAs whose mean descriptors land in the low-cos / high-dHash corner." The composition contrast that K=3 captures at the accountant level reappears at the deployment level in the cross-firm hit matrix of §III-L.4 (Script 44): under the deployed any-pair rule, within-firm collision concentration is $98.8\%$ at Firm A and $76.7$$83.7\%$ at Firms B/C/D (the stricter same-pair joint event saturates at $97.0$$99.96\%$ within-firm across all four firms). The K=3 partition and the cross-firm hit matrix therefore describe the same underlying firm-compositional structure at two different units of analysis. ## M. Convergent Internal-Consistency Checks
**Leave-one-firm-out stability (Scripts 36, 37).** Leave-one-firm-out cross-validation shows that K=2 is unstable across folds: holding Firm A out gives a fold rule cos $> 0.938$ AND dHash $\leq 8.79$, while holding any single non-Firm-A Big-4 firm out gives a fold rule near cos $> 0.975$ AND dHash $\leq 3.76$ (Script 36). The maximum absolute deviation of the four fold cosine crossings from their across-fold mean is $0.028$ (the corresponding pairwise across-fold range is $0.0376$, from $0.9380$ for the held-out-Firm-A fold to $0.9756$ for the held-out-Firm-D fold; Script 36 stability summary). The $0.028$ value is $5.6\times$ the report's $0.005$ across-fold stability tolerance. K=3 in contrast has a *reproducible component shape*: across the four folds the C1 cosine mean varies by at most $0.005$, the C1 dHash mean by at most $0.96$, and the C1 weight by at most $0.023$ (Script 37). K=3 hard-posterior membership for the held-out firm is composition-sensitive — for Firm C the held-out C1 rate is $36.3\%$ vs the full-Big-4 baseline of $23.5\%$, an absolute difference of $12.8$ pp; for Firm A the held-out C1 rate is $4.7\%$ vs baseline $0.0\%$; the report's own legend classifies this pattern as `P2_PARTIAL` ("the C1 cluster exists but membership is not well-predicted by the held-out fit"). We accordingly do not use K=3 hard-posterior membership as an operational label. The descriptive partition of §III-L is supported by three feature-derived per-CPA scores and a conservative hard-positive subset analysis. We caution at the outset that the three scores are **not statistically independent**: all three are deterministic functions of the same per-CPA descriptor means $(\overline{\text{cos}}_a, \overline{\text{dHash}}_a)$, so their high rank correlations are partly mechanical. The checks below document **internal consistency among feature-derived ranks**, not external validation against an independent hand-signed ground truth (which the corpus does not provide). Full result tables are in §IV-F (Tables IX, XI) and §IV-H (Table XIV).
We take the joint K=2 / K=3 LOOO evidence as supporting the following descriptive claims, all of which are used in §III-K and §V but none of which underwrites the operational classifier: **1. Three feature-derived per-CPA scores (Script 38).** For each Big-4 CPA we compute (i) the K=3 posterior $P(\text{C1})$ on the low-cos / high-dHash component (§III-L); (ii) a reverse-anchor cosine percentile of $\overline{\text{cos}}_a$ under the non-Big-4 reference Gaussian of §III-H.2; and (iii) the per-CPA fraction of signatures *not* satisfying the deployed HC box rule (cos $> 0.95$ AND dHash $\leq 5$). The three pairwise Spearman correlations are all $\rho \geq 0.879$ ($+0.9627$, $+0.8890$, $+0.8794$; $n = 437$; Table IX) — the strongest internal-consistency signal in the analysis: three summarisations of the same descriptor pair agree on the per-CPA ranking, all placing Firm A as the most replication-dominated descriptor position. They disagree only mildly at the less-replication-dominated end (Scores 1/3 place Firm C furthest from the templated end; the reverse-anchor places Firm D fractionally beyond Firm C). This is not external validation of any classifier; the deployed rule is calibrated separately (§III-I).
- The Big-4 K=2 marginal crossing $(0.975, 3.76)$ is essentially a firm-mass separator between Firm A and Firms B + C + D, not a within-Big-4 mechanism boundary. **2. Per-signature consistency (Script 39).** Refitting K=3 at the signature level (150,442 Big-4 points) and comparing binary labels gives Cohen $\kappa = 0.870$ between per-CPA-fit and per-signature-fit K=3 labels (Table XI), so per-CPA aggregation does not collapse the three-component ordering. The lower $\kappa = 0.56$$0.66$ between the binary box rule and either K=3 fit reflects different decision geometries (rectangular box vs Gaussian-mixture boundary).
- The Big-4 K=3 mixture exhibits a reproducible three-component component shape across LOOO folds at the descriptor-position level, with C1 reproducibly located at $\overline{\text{cos}} \approx 0.946$, $\overline{\text{dHash}} \approx 9.17$.
- Hard-posterior K=3 membership is composition-sensitive across folds (max absolute deviation $12.8$ pp); K=3 is therefore not used to assign operational labels to CPAs.
The operational signature-level classifier of §III-H.1 is calibrated in §III-L against inter-CPA pair-level negative-anchor coincidence rates, not against mixture-derived antimodes. Cross-checks between the deployed five-way box rule and the K=3 partition appear in §III-K. **3. Leave-one-firm-out reproducibility (Scripts 36, 37).** As developed in §III-L, firm-level LOOO shows K=2 unstable (a Firm-A-versus-others separator) while K=3 has a reproducible C1 component shape ($\leq 0.005$ cosine drift) but composition-sensitive hard membership (up to $12.8$ pp; `P2_PARTIAL`), which is why K=3 hard membership is not an operational label. Full LOOO tables are in §IV-G.
## K. Convergent Internal-Consistency Checks **4. Positive-anchor miss rate on byte-identical signatures (Script 40).** The corpus provides one conservative hard-positive subset: $n = 262$ Big-4 signatures whose nearest same-CPA match is byte-identical after crop and normalisation ($145 / 8 / 107 / 2$ across Firms AD). Independent hand-signing cannot produce pixel-identical images, so these are a conservative hard-positive subset for replication. All three candidate scores — the deployed HC box rule, the K=3 hard label, and the prevalence-calibrated reverse-anchor cut — assign every byte-identical signature to the replicated class ($0\%$ miss, Wilson $[0\%, 1.45\%]$; Table XIV, §IV-H). We caution that for the box rule this is close to tautological (byte-identical neighbours have cos $\approx 1$, dHash $\approx 0$), so it is a *necessary* check a failing classifier would not pass, not a sufficiency proof on the non-byte-identical replicated population. The corresponding inter-CPA negative-anchor evidence is in §III-I.1 (Big-4) and the corpus-wide version at §IV-I.
The descriptive partition of §III-J is supported by three feature-derived per-CPA scores and a conservative hard-positive subset analysis. We caution at the outset that the three scores are **not statistically independent measurements** — all three are deterministic functions of the same per-CPA descriptor means $(\overline{\text{cos}}_a, \overline{\text{dHash}}_a)$ — so their high pairwise rank correlations are partly a mechanical consequence of shared inputs. Per §III-I.4, none of the three scores has a within-population bimodality interpretation; they are firm-compositional position scores at the accountant level. The checks below therefore document **internal consistency among feature-derived ranks**, not external validation against an independent hand-signed ground truth (which the corpus does not provide). ## N. Unsupervised Diagnostic Strategy and Limits
**1. Three feature-derived per-CPA scores (Script 38).** For each Big-4 CPA we compute: The corpus lacks signature-level ground-truth replication labels: no signature is annotated as definitively hand-signed or definitively templated. The conservative positive anchor (pixel-identical same-CPA signatures; §III-M.4) is by construction near $\text{cos} = 1$ and $\text{dHash} = 0$, providing a tautological capture-check rather than a sensitivity estimate for the non-byte-identical replicated class. The corpus therefore does not admit standard supervised classifier validation: we cannot report False Rejection Rate, sensitivity, recall, Equal Error Rate, ROC-AUC, or precision against ground truth. Each diagnostic in this paper addresses one specific failure mode of an unsupervised screening classifier; the full diagnostic-to-failure-mode-to-assumption map is given in Appendix A Table A.II.
- **Score 1 (K=3 posterior on the low-cos / high-dHash component):** $P(\text{C1})$ from the K=3 fit of §III-J. Per §III-J this is a firm-compositional position score on the (cos, dHash) plane (not a probability of any latent "hand-signing mechanism") — a function of both descriptor means. **Limits.** We do not claim a validated forensic detector or an autonomous classification system, and we do not interpret the deployed-rate excess of §III-J.2 as a presumed true-positive rate. That interpretation would require assuming a CPA's genuine same-CPA hand-signing produces a collision rate no higher than random inter-CPA pairs — unsafe for two reasons: (a) a CPA who signs consistently can produce stylistically similar signatures across years that exceed inter-CPA cosine similarity; and (b) within-firm template-like reuse (§III-J.1; byte-level evidence of Firm A's pixel-identical signatures across partners) places a collision floor that itself reflects reuse rather than independent random matching. We describe the within-firm collision concentration of §III-J.1 as a descriptive observation and treat its mechanism as an open empirical question.
- **Score 2 (reverse-anchor cosine percentile):** the marginal cosine CDF value of $\overline{\text{cos}}_a$ under the non-Big-4 reference Gaussian of §III-H.2, sign-flipped so that lower percentile (further into the reference's left tail) corresponds to a Big-4 CPA whose mean cosine sits further from the templated end. This is a function of $\overline{\text{cos}}_a$ alone.
- **Score 3 (deployed binary high-confidence box rule rate):** the per-CPA fraction of signatures that do **not** satisfy the deployed binary high-confidence box rule (cos $> 0.95$ AND dHash $\leq 5$). This is a per-signature-aggregated function of the same descriptors.
Pairwise Spearman rank correlations among the three scores, $n = 437$ Big-4 CPAs (Script 38): **Scope and positioning.** The deployed rule is characterised at three units against the normative Firms-B/C/D inter-CPA negative anchor, with Firm A held out as an out-of-sample target (§III-I.0). The resulting rates (§III-I, §III-J) are specificity-proxy-anchored **alarm-yield** indicators, not true error rates: the HC rule has a very low BCD coincidence rate at every unit, the dHash $\leq 15$ MC band is a low-specificity advisory tier, and the per-firm heterogeneity is read against the clean floor (Firm A the rate-extreme, its signal within-firm). The framework is positioned as a **specificity-proxy-anchored screening tool with human-in-the-loop review**, not a validated forensic classifier.
| Pair | Spearman $\rho$ | $p$-value | **Specificity-alert-yield tradeoff.** Because sensitivity is unobservable, operators cannot derive an operating point by optimising a ROC criterion. Instead, tighter operating points (e.g., cos $> 0.98$ AND dHash $\leq 3$) further reduce both the per-comparison ICCR and the per-signature alert yield below the deployed-HC values of §III-I.1–§III-I.2, with an unknown effect on actual replication-detection recall — so tightening is not necessarily preferable. The deployment decision depends on the relative cost of manual review per alarm and missed-replication risk per false negative, neither directly observable from corpus data.
|---|---|---|
| Score 1 vs Score 3 | $+0.9627$ | $< 10^{-248}$ |
| Score 2 vs Score 3 | $+0.8890$ | $< 10^{-149}$ |
| Score 1 vs Score 2 | $+0.8794$ | $< 10^{-142}$ |
We read this as the strongest internal-consistency signal in the analysis: three different summarisations of the same descriptor pair agree on the per-CPA descriptor-position ranking with $\rho > 0.87$. The three scores agree on placing Firm A as the most replication-dominated descriptor position and the three non-Firm-A Big-4 firms further from the templated end, but they do not all rank the non-Firm-A firms identically: the K=3 posterior P(C1) and the box-rule less-replication-dominated rate (Scores 1 and 3) place Firm C at the less-replication-dominated end of Big-4 (mean P(C1) $= 0.311$; mean box-rule less-replication-dominated rate $= 0.790$), while the reverse-anchor cosine percentile (Score 2) places Firm D fractionally higher than Firm C (mean reverse-anchor score $-0.7125$ vs Firm C $-0.7672$, with higher value indicating deeper into the reference left tail). The mean values for Firms B and D sit between Firms A and C on Scores 1 and 3 (Script 38 per-firm summary). We do not claim this constitutes external validation of any operational classifier; the deployed box rule is calibrated separately (§III-L), and the convergence above shows that a mixture-derived score and a reverse-anchor score concur with the box rule's per-CPA-aggregated outputs on the directional ordering, with a modest disagreement at the less-replication-dominated end between the three non-A Big-4 firms. ## O. Data Source and Firm Anonymization
**2. Per-signature consistency (Script 39).** Per-CPA aggregation could in principle reflect averaging across within-CPA heterogeneity rather than coherent within-CPA behaviour. We test this by repeating the K=3 fit at the signature level — fitting a fresh K=3 GMM to the 150,442 Big-4 signature-level $(\text{cos}, \text{dHash}_{\text{indep}})$ points (Script 39) — and comparing labels. The per-CPA and per-signature K=3 fits recover a broadly similar three-component ordering; per-CPA C1 is at $\overline{\text{cos}} = 0.946$, $\overline{\text{dHash}} = 9.17$ vs per-signature C1 at $\overline{\text{cos}} = 0.928$, $\overline{\text{dHash}} = 9.75$ (an absolute cosine drift of $0.018$). Cohen $\kappa$ on the binary collapse (replication-dominated vs less-replication-dominated):
| Pair | Cohen $\kappa$ |
|---|---|
| Deployed binary high-confidence box rule vs per-CPA K=3 hard label | $0.662$ |
| Deployed binary high-confidence box rule vs per-signature K=3 hard label | $0.559$ |
| Per-CPA K=3 vs per-signature K=3 | $0.870$ |
The $\kappa = 0.870$ between per-CPA-fit and per-signature-fit K=3 binary labels indicates that per-CPA aggregation does not collapse the broad three-component ordering. The lower $\kappa = 0.56\text{}0.66$ between the binary box rule and either K=3 fit is consistent with two factors: different decision geometries (rectangular box vs Gaussian-mixture posterior boundary), and the fact that the binary box rule is a strict subset of the five-way rule. This comparison checks only the binary high-confidence rule (cos $> 0.95$ AND dHash $\leq 5$); §III-K does not directly check the five-way rule's `5 < \text{dHash} \leq 15` moderate-confidence band, whose calibration and capture-rate evidence is reported in the supplementary materials and not regenerated on the Big-4 subset.
**3. Leave-one-firm-out reproducibility (Scripts 36, 37).** Discussed in §III-J above. We summarise the joint result for cross-reference:
- *K=2 LOOO is unstable.* The maximum absolute deviation of the four fold cosine crossings from their across-fold mean is $0.028$, against the report's $0.005$ across-fold stability tolerance (Script 36; pairwise fold range $0.0376$, from $0.9380$ to $0.9756$). When Firm A is held out, the fold rule classifies $171/171$ of held-out Firm A CPAs as templated; when any non-Firm-A Big-4 firm is held out, the fold rule classifies $0$ of the held-out firm's CPAs as templated. This pattern indicates the K=2 boundary is essentially a Firm-A-vs-others separator rather than a within-Big-4 mechanism boundary.
- *K=3 LOOO is partially stable.* The C1 (low-cos / high-dHash) component shape is reproducible across folds: max deviation from the full-Big-4 baseline is $0.005$ in cosine, $0.96$ in dHash, and $0.023$ in mixture weight (Script 37). Hard-posterior membership remains composition-sensitive — observed absolute differences are $1.8$$12.8$ pp across the four folds, with the Firm C fold exceeding the report's $5$ pp viability bar; the report's own screening label is `P2_PARTIAL` ("K=3 is not predictively useful as an operational classifier"). We accordingly do not use K=3 hard-posterior membership as an operational label.
**4. Positive-anchor miss rate on byte-identical signatures (Script 40).** The corpus provides one conservative hard-positive subset: signatures whose nearest same-CPA match is byte-identical after crop and normalisation. Independent hand-signing cannot produce pixel-identical images, so byte-identical signatures are a conservative hard-positive subset for image replication. The Big-4 byte-identical subset comprises $n = 262$ signatures ($145 / 8 / 107 / 2$ across Firms A through D; Script 40).
We report each candidate check's *positive-anchor miss rate* — the fraction of byte-identical signatures classified as belonging to the less-replication-dominated descriptor positions. This is a one-sided check against a conservative positive subset, **not a paired specificity metric in the usual two-class sense**; we do not report a paired negative-anchor metric here because no signature-level hand-signed ground truth exists. The corresponding signature-level inter-CPA negative-anchor ICCR evidence is developed in §III-L.1 (Big-4 sample) and the corpus-wide version cited at §IV-I:
| Candidate check | Pixel-identity miss rate (Wilson 95% CI) |
|---|---|
| Deployed binary high-confidence box rule (cos $> 0.95$ AND dHash $\leq 5$) | $0\%$ $[0\%, 1.45\%]$ |
| K=3 per-CPA hard label (C3 high-cos / low-dHash corner; descriptive only) | $0\%$ $[0\%, 1.45\%]$ |
| Reverse-anchor with prevalence-calibrated cut | $0\%$ $[0\%, 1.45\%]$ |
All three candidate scores correctly assign every byte-identical signature to the replicated class. We caution that for the box rule this result is close to tautological: byte-identical nearest-neighbour signatures have cosine $\approx 1$ and dHash $\approx 0$ by construction, so any threshold strictly below cos $= 1$ and strictly above dHash $= 0$ will capture them. The positive-anchor miss rate is therefore a necessary check (a classifier that *failed* this check would be disqualified), not a sufficient validation of the classifier's behaviour on the non-byte-identical replicated population. The reverse-anchor cut here is chosen by prevalence calibration against the box rule's overall replicated rate ($49.58\%$ of Big-4 signatures); this is a documented limitation since no signature-level hand-signed ground truth exists to permit direct ROC optimisation.
## L. Anchor-Based Threshold Calibration
The operational classifier defined in §III-H.1 is calibrated by characterising the deployed thresholds' inter-CPA pair-level negative-anchor coincidence behaviour and their pool-normalised per-signature and per-document alert behaviour, at multiple units of analysis. §III-I.4 establishes that the descriptor distributions do not contain a within-population bimodal antimode that could anchor an operational threshold; the K=3 mixture of §III-J is a descriptive firm-compositional partition, not a mechanism-cluster model. Throughout this section we report **inter-CPA coincidence rates** rather than "False Acceptance Rates"; we explain the terminological choice in §III-L.0.
### L.0. Calibration methodology
**Calibration role of the present analysis.** The deployed thresholds of §III-H.1 preserve continuity with the existing literature and the supplementary calibration evidence. §III-I.4 establishes that a recalibration cannot be anchored on distributional antimodes (no within-population bimodality exists); §III-L.1 below characterises the cosine threshold's specificity-proxy behaviour at the inter-CPA pair level and the structural-dimension threshold $\text{dHash} \leq 5$'s pair-level coincidence behaviour. The sub-band thresholds ($\text{dHash} = 15$, $\text{cos} = 0.837$) retain their supplementary calibration evidence; the present calibration does not provide independent rates for those sub-bands.
**Three units of analysis.** We report inter-CPA negative-anchor coincidence behaviour at three units, each addressing a different operational question:
- *Per comparison.* For a randomly drawn pair of signatures from different CPAs, what fraction satisfies the rule (cos $>$ cos\_threshold and / or dHash $\leq$ dHash\_threshold)? This is the conventional pairwise calibration unit in biometric verification. We report it for both the cosine and dHash dimensions, marginally and jointly (§III-L.1).
- *Per signature pool.* For a Big-4 source signature $s$ with same-CPA pool of size $n_{\text{pool}}(s)$, what is the probability that the deployed rule fires *under the counterfactual* of replacing the source's same-CPA pool with $n_{\text{pool}}(s)$ random non-same-CPA candidates? This addresses the standard concern that a per-pair rate computed on independent pairs is not the deployed-rule rate at the per-signature classifier level: the deployed rule takes max-cosine and min-dHash over a pool of size $n_{\text{pool}}(s)$, so its effective coincidence rate is approximately $1 - (1 - p_{\text{pair}})^{n_{\text{pool}}}$ in the independence limit (§III-L.2).
- *Per document.* For an audit report aggregated via the worst-case rule, what fraction of documents have at least one signature whose deployed pool-normalised rule fires under the same inter-CPA candidate-replacement counterfactual? This is the operational alarm-rate unit (§III-L.3).
**Any-pair vs same-pair semantics.** The deployed rule uses independent extrema: a signature satisfies the HC rule if $\max_{\text{pool}} \text{cos} > 0.95$ AND $\min_{\text{pool}} \text{dHash} \leq 5$, *not* if a single candidate in the pool satisfies both. We refer to this as the **any-pair** rule. A stricter alternative — the **same-pair** rule — requires a single candidate to satisfy both inequalities; the deployed rule is any-pair, but we report same-pair as a stricter alternative classifier where useful (§III-L.2, §III-L.4).
**Terminological note on "FAR".** The biometric-verification literature speaks of "False Acceptance Rate" (FAR) for a per-pair rate computed on independent inter-CPA pairs. We adopt **inter-CPA coincidence rate (ICCR)** as the metric name and *do not* use "FAR" in the manuscript prose, for two reasons: (a) FAR has a specific biometric-verification meaning that requires ground-truth negative labels (which the corpus does not provide at the signature level); (b) §III-L.4 shows that the inter-CPA negative-anchor assumption — that inter-CPA pairs are negative — is partially violated by within-firm cross-CPA template-like collision structures. Reading "inter-CPA coincidence rate" as a *specificity proxy* under an explicitly disclosed assumption is faithful to the evidence; reading it as a true biometric FAR would overstate the evidence.
### L.1. Per-comparison inter-CPA coincidence rate (Script 40b)
We sample $5 \times 10^5$ inter-CPA pairs uniformly at random from Big-4 signatures, computing for each pair the cosine similarity (feature dot product) and Hamming distance between the dHash byte vectors. Marginal and joint rates at threshold $k$ are reported with Wilson 95% confidence intervals (Script 40b).
| Threshold | Per-comparison inter-CPA coincidence rate | 95% Wilson CI |
|---|---|---|
| Cosine $> 0.95$ | $0.00060$ | $[0.00053, 0.00067]$ |
| Cosine $> 0.945$ (alternative operating point from supplementary calibration evidence) | $0.00081$ | $[0.00073, 0.00089]$ |
| Cosine $> 0.97$ | $0.00024$ | $[0.00020, 0.00029]$ |
| Cosine $> 0.98$ | $0.00009$ | $[0.00007, 0.00012]$ |
| dHash $\leq 5$ | $0.00129$ | $[0.00120, 0.00140]$ |
| dHash $\leq 4$ | $0.00050$ | $[0.00044, 0.00057]$ |
| dHash $\leq 3$ | $0.00019$ | $[0.00015, 0.00023]$ |
| dHash $\leq 2$ | $0.00006$ | $[0.00004, 0.00008]$ |
| Joint: cos $> 0.95$ AND dHash $\leq 5$ (any-pair semantics) | $0.00014$ | $[0.00011, 0.00018]$ |
| Joint: cos $> 0.95$ AND dHash $\leq 4$ (any-pair) | $0.00011$ | $[0.00008, 0.00014]$ |
The cosine row at $\text{cos} > 0.95$ is consistent with the corpus-wide per-comparison rate of $0.0005$ reported in §IV-I on a similarly-sized inter-CPA sample; the present $5 \times 10^5$-pair sample yields $0.00060$, within that precision. The dHash row and joint row are reported here for the first time; the corpus-wide spike did not provide an inter-CPA pair-level coincidence rate for the structural dimension or the joint rule.
The all-firms-scope sample yields slightly lower per-comparison coincidence rates (cos $> 0.95$: $0.00031$; dHash $\leq 5$: $0.00073$; joint: $0.00007$); the all-firms sample weights small CPAs more heavily under CPA-uniform pair sampling, so we treat the Big-4 sample as the primary calibration scope and report all-firms as a corroborating-scope robustness check.
**Conditional inter-CPA coincidence rate.** A natural follow-up question is whether the dHash dimension provides marginal specificity beyond the cosine gate. For pairs with cos $> 0.95$, the conditional rate of dHash $\leq 5$ is $0.234$ (Wilson 95% CI $[0.190, 0.285]$; $70$ of $299$ pairs in the Big-4 sample). At cos $> 0.95$, dHash provides $\sim 4.3\times$ further per-comparison ICCR refinement (joint $0.00014$ vs cos-only $0.00060$).
The per-comparison rate is a useful *specificity-proxy calibration* for the deployed rule's pair-level behaviour. It does *not* directly translate to the deployed-rule specificity at the per-signature classifier level, because the deployed classifier takes extrema over a same-CPA pool of size $n_{\text{pool}}$. The pool-normalised inter-CPA alert rate is reported in §III-L.2.
### L.2. Pool-normalised inter-CPA alert rate (Script 43)
The deployed rule uses $\max_{\text{pool}} \text{cos}$ and $\min_{\text{pool}} \text{dHash}$ over the same-CPA pool of size $n_{\text{pool}}(s)$ for each signature $s$. A per-comparison rate is therefore not the rate at which the deployed classifier fires per signature. To compute the per-signature inter-CPA-equivalent rate, for each Big-4 source signature $s$ we simulate one realisation of an inter-CPA candidate pool of the same size $n_{\text{pool}}(s)$, drawn uniformly from non-same-CPA signatures across all firms, compute the deployed extrema and rule indicator, and aggregate (Script 43; $n_{\text{sig}} = 150{,}453$ vector-complete in this analysis; CPA-block bootstrap 95% CIs reported below).
**Headline rates (deployed any-pair rule, HC = cos $> 0.95$ AND dHash $\leq 5$).** Wilson 95% CIs on the point estimate, CPA-block bootstrap 95% CI on $n_{\text{boot}} = 1000$ replicates:
| Rule semantics | Per-signature ICCR | Wilson 95% CI | CPA-bootstrap 95% CI |
|---|---|---|---|
| Any-pair (deployed) | $0.1102$ | $[0.1086, 0.1118]$ | $[0.0908, 0.1330]$ |
| Same-pair (stricter alternative) | $0.0827$ | $[0.0813, 0.0841]$ | $[0.0668, 0.1021]$ |
Per-firm any-pair rates (no bootstrap; descriptive):
| Firm | $n_{\text{sig}}$ | Any-pair ICCR | Same-pair ICCR |
|---|---|---|---|
| Firm A | $60{,}450$ | $0.2594$ | $0.2018$ |
| Firm B | $34{,}254$ | $0.0147$ | $0.0023$ |
| Firm C | $38{,}616$ | $0.0053$ | $0.0019$ |
| Firm D | $17{,}133$ | $0.0110$ | $0.0051$ |
**Pool-size decile dependence.** The deployed rule's pool-normalised rate is monotonically (broadly) increasing in $n_{\text{pool}}$, consistent with the $1 - (1 - p_{\text{pair}})^{n_{\text{pool}}}$ form expected under inter-CPA independence (Script 43 decile table). This functional form is used as descriptive intuition for the broad monotone trend, not as an independence assumption used for estimation; the within-firm violation of inter-CPA independence (§III-L.4) bounds how literally the closed form can be read. Decile 1 (smallest pools, $n_{\text{pool}} \in [0, 201]$): any-pair ICCR $= 0.0249$. Decile 10 (largest, $n_{\text{pool}} \in [846, 1115]$): any-pair ICCR $= 0.1905$. The trend is broadly monotonic with two minor non-monotone reversals (decile 5 and decile 9 dip below their predecessors).
**Threshold sensitivity at per-signature unit.** Tightening the HC rule from $\text{dHash} \leq 5$ to $\text{dHash} \leq 3$ (same-pair) reduces the per-signature ICCR from $0.0827$ to $0.0449$ (Big-4 pooled); tightening to $\text{dHash} \leq 4$ gives $0.0639$ (same-pair). A stricter operating point of dHash $\leq 3$ same-pair would correspond to a per-signature ICCR of $\approx 0.05$; the deployed HC any-pair rule with $\text{dHash} \leq 5$ corresponds to $\approx 0.11$. Stakeholders requiring a tighter specificity proxy could consider the dHash $\leq 3$ same-pair variant, with the unsupervised-setting caveats of §III-M.
### L.3. Document-level inter-CPA proxy alert rate (Script 45)
The deployed worst-case aggregation classifies each document by the most-replication-consistent category among its constituent signatures (§III-H.1). Three operationally meaningful document-level alarm definitions are reported, each as the fraction of documents whose worst-case signature category falls in the alarm set under the same inter-CPA candidate-pool counterfactual as §III-L.2 (Script 45; $n_{\text{docs}} = 75{,}233$ Big-4 documents):
| Alarm definition | Alarm set | Document-level ICCR | Wilson 95% CI |
|---|---|---|---|
| D1 | HC only | $0.1797$ | $[0.1770, 0.1825]$ |
| D2 | HC + MC ("any non-hand-signed screening label") | $0.3375$ | $[0.3342, 0.3409]$ |
| D3 | HC + MC + HSC | $0.3384$ | $[0.3351, 0.3418]$ |
Per-firm D2 document-level rates:
| Firm | $n_{\text{docs}}$ | D2 (HC + MC) ICCR |
|---|---|---|
| Firm A | $30{,}226$ | $0.6201$ |
| Firm B | $17{,}127$ | $0.1600$ |
| Firm C | $19{,}501$ | $0.1635$ |
| Firm D | $8{,}379$ | $0.0863$ |
The document-level D2 rate of $33.75\%$ pooled over Big-4 is the most operationally relevant alarm-rate metric: it is the fraction of audit documents that would carry at least one signature flagged HC or MC under the counterfactual of inter-CPA candidate-pool replacement. The non-trivial per-document inter-CPA alarm rate (and its concentration in Firm A at $62\%$) motivates the positioning of the operational system as a **screening framework with human-in-the-loop review**, not as an autonomous forensic classifier (§III-M).
### L.4. Firm heterogeneity (Script 44)
§III-L.2 and §III-L.3 report large per-firm variation in the deployed rule's pool-normalised behaviour: Firm A's any-pair per-signature ICCR is $0.2594$, an order of magnitude larger than Firm B's $0.0147$, Firm C's $0.0053$, Firm D's $0.0110$. A natural alternative explanation is the pool-size confound: Firm A's median pool size ($\sim 285$) is larger than other firms', and pool size monotonically (broadly) increases the per-signature rate (§III-L.2 decile trend). We test the firm-vs-pool confound with a logistic regression of the per-signature hit indicator (any-pair HC) on firm dummies (Firm A = reference) and centred log pool size (Script 44):
| Term | Odds ratio (vs Firm A) | Direction | Magnitude |
|---|---|---|---|
| Firm B | $0.053$ | $< 1$ | $\sim 19\times$ lower odds than Firm A |
| Firm C | $0.010$ | $< 1$ | $\sim 100\times$ lower odds than Firm A |
| Firm D | $0.027$ | $< 1$ | $\sim 37\times$ lower odds than Firm A |
| log(pool size, centred) | $4.01$ | $> 1$ | $\sim 4\times$ higher odds per unit log pool size |
The Firm B/C/D odds ratios are very small after controlling for pool size, indicating that firm membership accounts for a large multiplicative effect on the per-signature rate that is *not* explained by pool size alone. (We report odds ratios rather than $z$-scores because per-signature observations are clustered by CPA and firm, and naive standard errors would be unreliable under within-cluster correlation; a cluster-robust standard error analysis is left as a robustness check.)
The per-decile per-firm breakdown (Script 44) confirms the pattern: within every pool-size decile, Firms B/C/D have rates of $0.0006$$0.0358$, while Firm A's rate ranges $0.0541$$0.5958$ across deciles. The firm gap is large within matched pool sizes, not driven by pool composition.
**Cross-firm hit matrix.** Among Big-4 source signatures whose any-pair rule fires under the inter-CPA candidate-pool counterfactual, the candidate firm of the max-cosine partner is distributed as follows (Script 44):
| Source firm | Firm A candidate | Firm B | Firm C | Firm D | non-Big-4 | hits |
|---|---|---|---|---|---|---|
| Firm A | $14{,}447$ | $95$ | $44$ | $19$ | $17$ | $14{,}622$ |
| Firm B | $92$ | $371$ | $8$ | $4$ | $9$ | $484$ |
| Firm C | $16$ | $7$ | $149$ | $5$ | $1$ | $178$ |
| Firm D | $22$ | $2$ | $6$ | $106$ | $1$ | $137$ |
For the same-pair joint event (a single candidate satisfying both $\text{cos} > 0.95$ and $\text{dHash} \leq 5$), the candidate firm is even more strongly concentrated within the source firm: Firm A source $\to$ Firm A candidate in $11{,}314$ of $11{,}319$ same-pair hits ($99.96\%$); Firm B source $\to$ Firm B candidate in $85$ of $87$ ($97.7\%$); Firm C source $\to$ Firm C candidate in $54$ of $55$ ($98.2\%$); Firm D source $\to$ Firm D candidate in $64$ of $66$ ($97.0\%$).
**Interpretation.** Under the deployed any-pair rule, the within-firm collision concentration is $98.8\%$ at Firm A and $76.7$$83.7\%$ at Firms B/C/D — Firm A's pattern is markedly more within-firm-concentrated than the other three firms', though every Big-4 firm still has more than three quarters of its any-pair collisions falling on candidates within the same firm. The stricter same-pair joint event — a single candidate satisfying both cos $> 0.95$ and dHash $\leq 5$ — saturates at $97.0$$99.96\%$ within-firm across all four firms. This pattern is consistent with — but not by itself diagnostic of — firm-specific template, stamp, or document-production reuse: within-firm scanning workflows, common form templates, and shared report-generation infrastructure could produce visually similar signature crops across different CPAs within the same firm. Byte-level decomposition of Firm A's $145$ pixel-identical signatures across $\sim 50$ distinct certifying partners (supplementary materials; §III-H.2) provides direct evidence of image-level reuse among Firm A signatures; the distribution across many partners is consistent with a firm-level template or production workflow, and the broader inter-CPA collision pattern in §III-L.4 is consistent with similar, milder within-firm collision patterns at Firms B/C/D, whose mechanisms may include template-like reuse, digitisation-pipeline homogeneity, or signing-style homogeneity (§V-H). We report this as "inter-CPA collision concentration is within-firm" — a descriptive observation about deployed-rule behaviour — and refrain from inferring that the within-firm hits constitute deliberate or systematic template sharing.
This connects back to §III-J: the K=3 firm-composition contrast at the accountant level (Firm A dominating C3; Firm C dominating C1) reappears at the deployment level in the cross-firm hit matrix, where the within-firm collision concentration is the dominant pattern at all four Big-4 firms — most strongly at Firm A ($98.8\%$ any-pair, $99.96\%$ same-pair) and at materially lower but still majority levels at Firms B/C/D ($76.7$$83.7\%$ any-pair; $97.0$$98.2\%$ same-pair).
### L.5. Alert-rate sensitivity around deployed thresholds (Script 46)
To test whether the deployed cosine threshold $0.95$ and dHash threshold $5$ coincide with a low-gradient (plateau-stable) region of the deployed-rule alert-rate surface — which would be weak distributional evidence that the deployed thresholds are stable operating points — we sweep each threshold across a range and report the per-signature alert rate on actual observed Big-4 same-CPA pools (not inter-CPA-replaced pools), comparing the local gradient at the deployed threshold to the median gradient across the sweep (Script 46).
At the deployed HC operating point cos $> 0.95$ AND dHash $\leq 5$, the local gradient of the per-signature alert rate is substantially larger than the median gradient across the sweep (cosine: ratio $\approx 25\times$ at the $0.95$ point relative to median; dHash: ratio $\approx 3.8\times$ at the $5$ point relative to median; both Script 46). Reading these ratios descriptively, the deployed HC threshold is *locally sensitive* rather than plateau-stable: small threshold perturbations materially change the deployed alert rate (cosine sweep at dHash $\leq 5$ yields rates of $0.5091$ at cos $> 0.945$ vs $0.4789$ at cos $> 0.955$, a $3.0$ pp swing across a $0.01$ cosine perturbation; dHash sweep at cos $> 0.95$ yields rates of $0.4207$ at dHash $\leq 4$ vs $0.5639$ at dHash $\leq 6$, a $14.3$ pp swing across a single integer step). The local-gradient-to-median-gradient ratios are descriptive diagnostics, not formal plateau tests; the primary evidence for "no within-population bimodal antimode at these thresholds" comes from §III-I.4's composition decomposition, not from §III-L.5.
The MC/HSC boundary at dHash $= 15$, by contrast, *is* in a low-gradient region (ratio $\approx 0.08$ to the median); the plateau-like behaviour around dHash $= 15$ is corroborating evidence that the high-end structural threshold lies in a regime where the rule's alert rate is approximately saturated, consistent with the high-dHash tail behaviour expected once near-identical pairs have been exhausted. The §III-L.5 non-plateau / local-sensitivity finding therefore applies specifically to the HC cutoff (cos $= 0.95$, dHash $= 5$); the MC/HSC sub-band boundary at dHash $= 15$ exhibits the opposite behaviour and is plateau-like.
We interpret the deployed HC thresholds as **specificity-anchored operating points** chosen for the specificity-vs-alert-yield tradeoff (§III-L.1), *not* as distributional antimodes. Alternative operating points on the tradeoff curve can be characterised by inverting the per-comparison or pool-normalised ICCR curves (§III-L.1, §III-L.2) at the preferred specificity target.
### L.6. Observed deployed alert rate on actual same-CPA pools
The pool-normalised inter-CPA rates of §III-L.2 and §III-L.3 use the counterfactual of replacing the source signature's same-CPA pool with random non-same-CPA candidates. The **observed deployed alert rate** uses the source's actual same-CPA pool, i.e., the rate at which the deployed rule fires on the real corpus. For Big-4, the deployed HC any-pair rule fires on $49.58\%$ of signatures and $62.28\%$ of documents (Script 46; Script 42 reproduces the per-signature rate at $49.58\%$).
The per-signature observed-deployed rate is $\sim 4.5\times$ the pool-normalised inter-CPA rate ($0.4958$ vs $0.1102$); the per-document observed-deployed rate is $\sim 3.5\times$ the pool-normalised inter-CPA D1 (HC) rate ($0.6228$ vs $0.1797$). We refer to this multiplicative gap as the **deployed-rate excess over the inter-CPA proxy**:
- Per-signature: $0.4958 - 0.1102 = 0.3856$ ($38.6$ pp excess)
- Per-document HC: $0.6228 - 0.1797 = 0.4431$ ($44.3$ pp excess)
We *do not* interpret the deployed-rate excess as a presumed true-positive rate; the inferential limits of this interpretation are developed in §III-M. The deployed-rate excess is best read as an *observed same-CPA-pool excess* — a quantity that exceeds what random inter-CPA candidate replacement would produce — whose mechanism is not identifiable from descriptor-only data (§III-M); we do not attribute it to within-CPA handwriting repeatability or to image replication without further evidence.
## M. Unsupervised Diagnostic Strategy and Limits
The corpus lacks signature-level ground-truth replication labels: no signature is annotated as definitively hand-signed or definitively templated. The conservative positive anchor (pixel-identical same-CPA signatures; §III-K.4) is by construction near $\text{cos} = 1$ and $\text{dHash} = 0$, providing a tautological capture-check rather than a sensitivity estimate for the non-byte-identical replicated class. The corpus therefore does not admit standard supervised classifier validation: we cannot report False Rejection Rate, sensitivity, recall, Equal Error Rate, ROC-AUC, or precision against ground truth.
Each diagnostic reported in this paper therefore addresses one specific failure mode of an unsupervised screening classifier; the full diagnostic-to-failure-mode-to-assumption map is given in Appendix A Table A.II. No single diagnostic provides ground-truth validation; together they define the limits of what can be supported in this corpus without signature-level ground truth.
**Limits of the present analysis.** We do not claim a validated forensic detector or an autonomous classification system. We do not report False Rejection Rate, sensitivity, recall, EER, ROC-AUC, precision, or positive predictive value against ground truth, because no ground truth exists at the signature level. We do not interpret the deployed-rate excess of §III-L.6 as a presumed true-positive rate: that interpretation would require assuming that the within-firm same-CPA pool's collision rate equals the inter-CPA proxy rate in the absence of replication (i.e., that genuine same-CPA hand-signing would produce a collision rate no higher than random inter-CPA pairs). Two factors make the assumption unsafe: (a) a CPA who signs consistently can produce stylistically similar signatures across years that exceed inter-CPA similarity at the cosine axis; (b) within-firm template sharing (§III-L.4 cross-firm hit matrix; byte-level evidence of Firm A's pixel-identical signatures across partners, supplementary materials) places a substantial inter-CPA collision floor that itself reflects template-like reuse rather than independent inter-CPA random matching. We do not infer that the within-firm collision concentration of §III-L.4 constitutes deliberate template sharing; we describe it as "inter-CPA collision concentration is within-firm" and treat the mechanism as an open empirical question.
**Scope of the present analysis.** The deployed signature-replication screening rule is characterised at three units of analysis (per-comparison, per-signature pool, per-document) against an inter-CPA negative-anchor coincidence-rate calibration. The per-comparison rates ($\leq 0.0006$ at cos $> 0.95$; $\leq 0.0013$ at dHash $\leq 5$; $\leq 0.00014$ jointly) are specificity-proxy-anchored operating points consistent with biometric-verification convention, with the proxy nature recorded in §III-L.0 and §III-M. The per-signature any-pair HC ICCR ($0.11$; Table XXII) and per-document HC+MC alarm-rate ICCR ($0.34$; Table XXIII) are operationally meaningful **alarm-yield** indicators rather than true error rates. Per-firm rates show substantial heterogeneity (Firm A's per-document HC + MC alarm at $0.62$ vs Firm B/C/D at $0.09$$0.16$), driven by firm-level rather than pool-size effects, and concentrated in within-firm cross-CPA candidate matching. The framework is positioned as a **specificity-proxy-anchored screening tool with human-in-the-loop review**, not as a validated forensic classifier.
**Specificity-alert-yield tradeoff.** Because sensitivity is unobservable, stakeholders cannot derive an operating point by optimising a ROC criterion. Instead, the specificity-proxy-anchored framework offers a *specificity-alert-yield tradeoff*: tighter operating points (e.g., cos $> 0.98$ AND dHash $\leq 3$) reduce both per-comparison ICCR (to $\approx 5 \times 10^{-5}$; §III-L.1 inversion) and per-signature alert yield (to $\approx 0.05$; §III-L.2), with an unknown effect on actual replication-detection recall. Tighter operating points are not necessarily preferable: any tightening reduces the alert rate but may also miss true replicated signatures whose noise has pushed them outside the tighter envelope. The deployment decision depends on the relative cost of manual review (per alarm) and missed-replication risk (per false negative) — neither directly observable from corpus data.
## N. Data Source and Firm Anonymization
**Audit-report corpus.** The 90,282 audit-report PDFs analyzed in this study were obtained from the Market Observation Post System (MOPS) operated by the Taiwan Stock Exchange Corporation. **Audit-report corpus.** The 90,282 audit-report PDFs analyzed in this study were obtained from the Market Observation Post System (MOPS) operated by the Taiwan Stock Exchange Corporation.
MOPS is the statutory public-disclosure platform for Taiwan-listed companies; every audit report filed on MOPS is already a publicly accessible regulatory document. MOPS is the statutory public-disclosure platform for Taiwan-listed companies; every audit report filed on MOPS is already a publicly accessible regulatory document.
@@ -609,9 +492,10 @@ The CPA registry used to map signatures to CPAs is a publicly available audit-fi
Readers with domain familiarity may still infer Firm A from contextual descriptors (Big-4 status, replication-dominated behavior); we disclose this residual identifiability explicitly and note that none of the paper's conclusions depend on the specific firm's name. Readers with domain familiarity may still infer Firm A from contextual descriptors (Big-4 status, replication-dominated behavior); we disclose this residual identifiability explicitly and note that none of the paper's conclusions depend on the specific firm's name.
# IV. Experiments and Results # IV. Experiments and Results
Section IV reports the empirical results that calibrate and characterise the operational classifier of §III-H.1 (calibration developed in §III-L). The primary analyses (§IV-D through §IV-J, and the anchor-based ICCR calibration consolidated in §IV-M) are scoped to the Big-4 sub-corpus (Firms AD, $n = 437$ CPAs with $n_{\text{sig}} \geq 10$, totalling 150,442 signatures with both descriptors available) per the methodology choice articulated in §III-G. §IV-K reports a full-dataset (686 CPAs) robustness check on the K=3 mixture and per-CPA score-rank convergence; §IV-A through §IV-C and §IV-L report the corpus-wide pipeline performance and feature-backbone ablation that support the descriptor choice of §III-F. Section IV reports the empirical results that calibrate and characterise the operational classifier of §III-H.1 (calibration developed in §III-I). The primary analyses (§IV-D through §IV-J, and the anchor-based ICCR calibration consolidated in §IV-M) are scoped to the Big-4 sub-corpus (Firms AD, $n = 437$ CPAs with $n_{\text{sig}} \geq 10$, totalling 150,442 signatures with both descriptors available) per the methodology choice articulated in §III-G. §IV-K reports a full-dataset (686 CPAs) robustness check on the K=3 mixture and per-CPA score-rank convergence; §IV-A through §IV-C and §IV-L report the corpus-wide pipeline performance and feature-backbone ablation that support the descriptor choice of §III-F.
## A. Experimental Setup ## A. Experimental Setup
@@ -659,7 +543,7 @@ Table IV summarizes the distributional statistics.
Both distributions are left-skewed and leptokurtic. Both distributions are left-skewed and leptokurtic.
Shapiro-Wilk and Kolmogorov-Smirnov tests rejected normality for both ($p < 0.001$), confirming that parametric thresholds based on normality assumptions would be inappropriate. Shapiro-Wilk and Kolmogorov-Smirnov tests rejected normality for both ($p < 0.001$), confirming that parametric thresholds based on normality assumptions would be inappropriate.
Distribution fitting identified the lognormal distribution as the best parametric fit (lowest AIC) for both classes, though we use this result only descriptively; the subsequent distributional diagnostics in Section IV-D are produced via the methods of Section III-I to avoid single-family distributional assumptions. Distribution fitting identified the lognormal distribution as the best parametric fit (lowest AIC) for both classes, though we use this result only descriptively; the subsequent distributional diagnostics in Section IV-D are produced via the methods of Section III-K to avoid single-family distributional assumptions.
The KDE crossover---where the two density functions intersect---was located at 0.837. The KDE crossover---where the two density functions intersect---was located at 0.837.
Under equal prior probabilities and equal misclassification costs, this crossover is a candidate decision boundary between the two classes; we adopt it only as the operational LH/UN boundary in §III-H.1, not as a natural distributional threshold. Under equal prior probabilities and equal misclassification costs, this crossover is a candidate decision boundary between the two classes; we adopt it only as the operational LH/UN boundary in §III-H.1, not as a natural distributional threshold.
@@ -671,13 +555,13 @@ A Cohen's $d$ of 0.669 indicates a medium effect size [29], confirming that the
## D. Big-4 Accountant-Level Distributional Characterisation ## D. Big-4 Accountant-Level Distributional Characterisation
This section reports the empirical evidence for §III-I's distributional diagnostics at the Big-4 accountant level. The accountant-level dip-test rejection reported in Table V is, per §III-I.4, fully attributable to between-firm location shifts and integer mass-point artefacts rather than to within-population bimodality; the composition-decomposition diagnostics that establish this finding are tabulated in §IV-M below alongside the anchor-based ICCR calibration. This section reports the empirical evidence for §III-K's distributional diagnostics at the Big-4 accountant level. The accountant-level dip-test rejection reported in Table V is, per §III-K.4, fully attributable to between-firm location shifts and integer mass-point artefacts rather than to within-population bimodality; the composition-decomposition diagnostics that establish this finding are tabulated in §IV-M below alongside the anchor-based ICCR calibration.
**Table V.** Hartigan dip-test results, accountant-level marginals (Big-4 primary; comparison scopes from Script 32). **Table V.** Hartigan dip-test results, accountant-level marginals (Big-4 primary; comparison scopes from Script 32).
| Population | $n$ CPAs | $p_{\text{cos}}$ | $p_{\text{dHash}}$ | Interpretation | | Population | $n$ CPAs | $p_{\text{cos}}$ | $p_{\text{dHash}}$ | Interpretation |
|---|---|---|---|---| |---|---|---|---|---|
| **Big-4 pooled (primary)** | 437 | $< 5 \times 10^{-4}$ | $< 5 \times 10^{-4}$ | reject unimodality on both axes | | **Big-4 pooled (analysis scope; not the calibration anchor)** | 437 | $< 5 \times 10^{-4}$ | $< 5 \times 10^{-4}$ | reject unimodality on both axes |
| Firm A pooled alone | 171 | 0.992 | 0.924 | unimodal | | Firm A pooled alone | 171 | 0.992 | 0.924 | unimodal |
| Firms B + C + D pooled | 266 | 0.998 | 0.906 | unimodal | | Firms B + C + D pooled | 266 | 0.998 | 0.906 | unimodal |
| All non-Firm-A pooled | 515 | 0.998 | 0.907 | unimodal | | All non-Firm-A pooled | 515 | 0.998 | 0.907 | unimodal |
@@ -699,7 +583,7 @@ The Big-4-scope null on both axes is consistent with the §IV-E mixture evidence
This section reports the K=2 and K=3 2D Gaussian mixture fits to the Big-4 accountant-level distribution and the bootstrap stability of their marginal crossings. This section reports the K=2 and K=3 2D Gaussian mixture fits to the Big-4 accountant-level distribution and the bootstrap stability of their marginal crossings.
**Table VII.** Big-4 K=2 mixture components (descriptive partition; not mechanism clusters per §III-J) and marginal-crossing bootstrap 95% confidence intervals. **Table VII.** Big-4 K=2 mixture components (descriptive partition; not mechanism clusters per §III-L) and marginal-crossing bootstrap 95% confidence intervals.
| K=2 component | $\overline{\text{cos}}$ | $\overline{\text{dHash}}$ | weight | | K=2 component | $\overline{\text{cos}}$ | $\overline{\text{dHash}}$ | weight |
|---|---|---|---| |---|---|---|---|
@@ -715,7 +599,7 @@ Marginal crossings (point + bootstrap 95% CI, $n_{\text{boot}} = 500$):
$\text{BIC}(K{=}2) = -1108.45$ (Script 34). $\text{BIC}(K{=}2) = -1108.45$ (Script 34).
**Table VIII.** Big-4 K=3 mixture components (descriptive firm-compositional partition per §III-J; not mechanism clusters). **Table VIII.** Big-4 K=3 mixture components (descriptive firm-compositional partition per §III-L; not mechanism clusters).
| K=3 component | $\overline{\text{cos}}$ | $\overline{\text{dHash}}$ | weight | descriptive position | | K=3 component | $\overline{\text{cos}}$ | $\overline{\text{dHash}}$ | weight | descriptive position |
|---|---|---|---|---| |---|---|---|---|---|
@@ -723,11 +607,11 @@ $\text{BIC}(K{=}2) = -1108.45$ (Script 34).
| C2 | 0.9558 | 6.66 | 0.536 | central region | | C2 | 0.9558 | 6.66 | 0.536 | central region |
| C3 | 0.9826 | 2.41 | 0.321 | high-cos / low-dHash corner | | C3 | 0.9826 | 2.41 | 0.321 | high-cos / low-dHash corner |
$\text{BIC}(K{=}3) = -1111.93$, lower than $K{=}2$ by $3.48$ (mild support; not by itself decisive). The full-fit K=3 baseline above is reproduced in Scripts 35, 37, and 38 with identical hyperparameters; Script 37 additionally fits K=3 on each leave-one-firm-out training set (those fold-specific components differ from the full-fit baseline by design and are reported separately in §IV-G Table XIII). Operational use of the K=2 / K=3 fits is governed by §III-J and §III-L; §IV-G reports the LOOO reproducibility evidence that motivates reporting both fits descriptively. $\text{BIC}(K{=}3) = -1111.93$, lower than $K{=}2$ by $3.48$ (mild support; not by itself decisive). The full-fit K=3 baseline above is reproduced in Scripts 35, 37, and 38 with identical hyperparameters; Script 37 additionally fits K=3 on each leave-one-firm-out training set (those fold-specific components differ from the full-fit baseline by design and are reported separately in §IV-G Table XIII). Operational use of the K=2 / K=3 fits is governed by §III-I and §III-L; §IV-G reports the LOOO reproducibility evidence that motivates reporting both fits descriptively.
## F. Convergent Internal-Consistency Checks ## F. Convergent Internal-Consistency Checks
This section reports the empirical evidence for §III-K's three-score internal-consistency analysis. We re-emphasise the §III-K caveat: the three scores are deterministic functions of the same per-CPA descriptor pair $(\overline{\text{cos}}_a, \overline{\text{dHash}}_a)$ and are *not statistically independent measurements*. The pairwise correlations document internal consistency among feature-derived ranks rather than external validation against an independent ground truth. This section reports the empirical evidence for §III-M's three-score internal-consistency analysis. We re-emphasise the §III-M caveat: the three scores are deterministic functions of the same per-CPA descriptor pair $(\overline{\text{cos}}_a, \overline{\text{dHash}}_a)$ and are *not statistically independent measurements*. The pairwise correlations document internal consistency among feature-derived ranks rather than external validation against an independent ground truth.
**Table IX.** Per-CPA Spearman rank correlations among three feature-derived scores, Big-4, $n = 437$. **Table IX.** Per-CPA Spearman rank correlations among three feature-derived scores, Big-4, $n = 437$.
@@ -764,7 +648,7 @@ The three scores agree on placing Firm A as the most replication-dominated and t
## G. Leave-One-Firm-Out Reproducibility ## G. Leave-One-Firm-Out Reproducibility
This section reports the firm-level cross-validation evidence motivating §III-J's "K=3 descriptive, not operational" framing. This section reports the firm-level cross-validation evidence motivating §III-L's "K=3 descriptive, not operational" framing.
**Table XII.** K=2 leave-one-firm-out across the four Big-4 folds. **Table XII.** K=2 leave-one-firm-out across the four Big-4 folds.
@@ -787,11 +671,11 @@ This section reports the firm-level cross-validation evidence motivating §III-J
| Firm C held out | 0.9504 | 8.41 | 0.126 | $36.27\%$ | $23.53\%$ | $12.77$ pp | | Firm C held out | 0.9504 | 8.41 | 0.126 | $36.27\%$ | $23.53\%$ | $12.77$ pp |
| Firm D held out | 0.9439 | 9.29 | 0.120 | $17.31\%$ | $11.54\%$ | $5.81$ pp | | Firm D held out | 0.9439 | 9.29 | 0.120 | $17.31\%$ | $11.54\%$ | $5.81$ pp |
(Source: Script 37; screening label `P2_PARTIAL`.) Component shape is reproducible across folds: max deviation of C1 cosine = $0.005$, C1 dHash = $0.96$, C1 weight = $0.023$. Hard-posterior membership for the held-out firm varies: max absolute difference from the full-Big-4 baseline is $12.77$ pp at the Firm C held-out fold, exceeding the report's $5$ pp viability bar. We accordingly do not use K=3 hard-posterior membership as an operational classifier label (§III-J, §III-L). (Source: Script 37; screening label `P2_PARTIAL`.) Component shape is reproducible across folds: max deviation of C1 cosine = $0.005$, C1 dHash = $0.96$, C1 weight = $0.012$. Hard-posterior membership for the held-out firm varies: max absolute difference from the full-Big-4 baseline is $12.77$ pp at the Firm C held-out fold, exceeding the report's $5$ pp viability bar. We accordingly do not use K=3 hard-posterior membership as an operational classifier label (§III-I, §III-L).
## H. Pixel-Identity Positive-Anchor Miss Rate ## H. Pixel-Identity Positive-Anchor Miss Rate
This section reports the only conservative hard-positive subset analysis available in the corpus: the positive-anchor miss rate against $n = 262$ Big-4 signatures whose nearest same-CPA match is byte-identical after crop and normalisation. Independent hand-signing cannot produce pixel-identical images, so byte-identical signatures are a conservative hard-positive subset for image replication. The analysis is one-sided (positive-anchor only); a paired false-alarm rate against a hand-signed negative anchor is not available because no signature-level hand-signed ground truth exists in the corpus (§III-K item 4). This section reports the only conservative hard-positive subset analysis available in the corpus: the positive-anchor miss rate against $n = 262$ Big-4 signatures whose nearest same-CPA match is byte-identical after crop and normalisation. Independent hand-signing cannot produce pixel-identical images, so byte-identical signatures are a conservative hard-positive subset for image replication. The analysis is one-sided (positive-anchor only); a paired false-alarm rate against a hand-signed negative anchor is not available because no signature-level hand-signed ground truth exists in the corpus (§III-M item 4).
**Table XIV.** Positive-anchor miss rate, $n = 262$ Big-4 byte-identical signatures. **Table XIV.** Positive-anchor miss rate, $n = 262$ Big-4 byte-identical signatures.
@@ -807,25 +691,25 @@ We caution that for the deployed box rule this result is close to tautological (
## I. Inter-CPA Pair-Level Coincidence Rate ## I. Inter-CPA Pair-Level Coincidence Rate
The metric reported here is the inter-CPA pair-level coincidence rate (ICCR). It is the per-pair rate at which two signatures from different CPAs satisfy the deployed rule. We do not label it as a False Acceptance Rate because (a) FAR has a biometric-verification meaning that requires ground-truth negative labels, and (b) the inter-CPA negative-anchor assumption is partially violated by within-firm cross-CPA template-like collision structures (§III-L.4 cross-firm hit matrix). The metric reported here is the inter-CPA pair-level coincidence rate (ICCR). It is the per-pair rate at which two signatures from different CPAs satisfy the deployed rule. We do not label it as a False Acceptance Rate because (a) FAR has a biometric-verification meaning that requires ground-truth negative labels, and (b) the inter-CPA negative-anchor assumption is partially violated by within-firm cross-CPA template-like collision structures (§III-J.1 cross-firm hit matrix).
A corpus-wide spike on $\sim 50{,}000$ inter-CPA pairs gives a per-comparison rate of $0.0005$ (Wilson 95% CI $[0.0003, 0.0007]$) at the cosine cut $0.95$. The Big-4-scope spike at higher sample size ($5 \times 10^5$ inter-CPA pairs) replicates this number, adds the structural dimension (dHash), and adds joint-rule rates; the §III-L.1 numbers are referenced rather than duplicated here, and the consolidated ICCR calibration appears in §IV-M Tables XXIXXVI. A corpus-wide spike on $\sim 50{,}000$ inter-CPA pairs gives a per-comparison rate of $0.0005$ (Wilson 95% CI $[0.0003, 0.0007]$) at the cosine cut $0.95$. The Big-4-scope spike at higher sample size ($5 \times 10^5$ inter-CPA pairs) replicates this number, adds the structural dimension (dHash), and adds joint-rule rates; the §III-I.1 numbers are referenced rather than duplicated here, and the consolidated ICCR calibration appears in §IV-M Tables XXIXXVI.
## J. Five-Way Per-Signature + Document-Level Classification Output ## J. Five-Way Per-Signature + Document-Level Classification Output
This section reports the five-way per-signature + document-level worst-case classifier output on the Big-4 sub-corpus. See §III-H.1 for the five-way category definitions and the cosine and dHash cuts; calibration is in §III-L. This section reports the five-way per-signature + document-level worst-case classifier output on the Big-4 sub-corpus. See §III-H.1 for the five-way category definitions and the cosine and dHash cuts; calibration is in §III-I.
**Table XV.** Five-way per-signature category counts, Big-4 sub-corpus, $n = 150{,}442$ classified. **Table XV.** Five-way per-signature category counts, Big-4 sub-corpus, $n = 150{,}442$ classified.
| Category | Long name | $n$ signatures | % of classified | | Category | Long name | $n$ signatures | % of classified |
|---|---|---|---| |---|---|---|---|
| HC | High-confidence non-hand-signed | 74,593 | 49.58% | | HC | High-confidence replication candidate | 74,593 | 49.58% |
| MC | Moderate-confidence non-hand-signed | 39,817 | 26.47% | | MC | Moderate-confidence advisory flag | 39,817 | 26.47% |
| HSC | High style consistency | 314 | 0.21% | | HSC | High style-consistency flag | 314 | 0.21% |
| UN | Uncertain | 35,480 | 23.58% | | UN | Uncertain | 35,480 | 23.58% |
| LH | Likely hand-signed | 238 | 0.16% | | LH | Low replication-similarity | 238 | 0.16% |
(Source: Script 42; 11 of 150,453 loaded Big-4 signatures lacked one or both descriptors and were excluded. The $150{,}442$ vs $150{,}453$ distinction — descriptor-complete vs vector-complete — recurs across §IV: descriptor-complete analyses (§IV-D through §IV-J, all using accountant-level aggregates or per-signature category counts derived from the same 150,442-signature substrate) use $n = 150{,}442$; vector- or pair-recomputed analyses (§IV-M.2 Table XXI, §IV-M.3 Table XXII, §IV-M.5 Tables XXIVXXV; Scripts 40b, 43, 44) use $n = 150{,}453$ because their pair- or pool-level computations load all vector-complete signatures including those failing the descriptor-complete filter. See §III-G for the sample-size reconciliation.) (Source: Script 42; 11 of 150,453 loaded Big-4 signatures lacked one or both descriptors and were excluded. The $150{,}442$ vs $150{,}453$ distinction — descriptor-complete vs vector-complete — recurs across §IV: descriptor-complete analyses (§IV-D through §IV-J, all using accountant-level aggregates or per-signature category counts derived from the same 150,442-signature substrate) use $n = 150{,}442$; vector- or pair-recomputed analyses (§IV-M.2 Table XXI, §IV-M.3 Table XXII, §IV-M.5 Tables XXIVXXV; Scripts 46, 52, 44, 53) use $n = 150{,}453$ because their pair- or pool-level computations load all vector-complete signatures including those failing the descriptor-complete filter. See §III-G for the sample-size reconciliation.)
**Per-firm five-way breakdown (% within firm).** **Per-firm five-way breakdown (% within firm).**
@@ -844,11 +728,11 @@ This section reports the five-way per-signature + document-level worst-case clas
| Category | Long name | $n$ documents | % | | Category | Long name | $n$ documents | % |
|---|---|---|---| |---|---|---|---|
| HC | High-confidence non-hand-signed | 46,857 | 62.28% | | HC | High-confidence replication candidate | 46,857 | 62.28% |
| MC | Moderate-confidence non-hand-signed | 19,667 | 26.14% | | MC | Moderate-confidence advisory flag | 19,667 | 26.14% |
| HSC | High style consistency | 167 | 0.22% | | HSC | High style-consistency flag | 167 | 0.22% |
| UN | Uncertain | 8,524 | 11.33% | | UN | Uncertain | 8,524 | 11.33% |
| LH | Likely hand-signed | 18 | 0.02% | | LH | Low replication-similarity | 18 | 0.02% |
(Source: Script 42 document-level table; 379 of 75,233 PDFs carried signatures from more than one Big-4 firm and are reported in the single-firm-PDF per-firm breakdown of the script CSV but pooled into the overall counts here.) (Source: Script 42 document-level table; 379 of 75,233 PDFs carried signatures from more than one Big-4 firm and are reported in the single-firm-PDF per-firm breakdown of the script CSV but pooled into the overall counts here.)
@@ -863,7 +747,7 @@ This section reports the five-way per-signature + document-level worst-case clas
(Source: Script 42; mixed-firm PDFs $n = 379$ excluded from the per-firm rows but included in the overall counts above.) (Source: Script 42; mixed-firm PDFs $n = 379$ excluded from the per-firm rows but included in the overall counts above.)
The five-way **moderate-confidence non-hand-signed** band (cos $> 0.95$ AND $5 < \text{dHash} \leq 15$) retains its prior calibration (supplementary materials); it is **not separately re-characterised by Scripts 3840**, which checked only the binary high-confidence rule (cos $> 0.95$ AND dHash $\leq 5$). The moderate-band cuts are not re-derived on the Big-4 subset; we report the Table XV per-firm MC proportions (10.76% / 35.88% / 41.44% / 29.33% across Firms A through D) descriptively. The capture-rate calibration evidence for the moderate band is reported in the supplementary materials and not regenerated on the Big-4 subset. We do not claim that the MC-band per-firm ordering above is a separate validation of the §III-K Spearman convergence, since MC occupancy is not a monotone function of the per-CPA less-replication-dominated ranking (e.g., Firm D's MC fraction is lower than Firm B's while Firm D's reverse-anchor score ranks it as less replication-dominated than Firm B). The five-way **moderate-confidence advisory** band (cos $> 0.95$ AND $5 < \text{dHash} \leq 15$) retains the threshold provenance of its prior calibration (supplementary materials), but §III-I.3 **supersedes its claim strength**: on the normative BCD baseline this band carries a $\sim 0.175$ per-document inter-CPA coincidence rate, so it is a low-specificity advisory (review-workload-expanding) bin, not calibrated evidence of replication. It is **not separately re-characterised by Scripts 3840**, which checked only the binary high-confidence rule (cos $> 0.95$ AND dHash $\leq 5$). The moderate-band cuts are not re-derived on the Big-4 subset; we report the Table XV per-firm MC proportions (10.76% / 35.88% / 41.44% / 29.33% across Firms A through D) descriptively only. We do not claim that the MC-band per-firm ordering above is a separate validation of the §III-M Spearman convergence, since MC occupancy is not a monotone function of the per-CPA less-replication-dominated ranking (e.g., Firm D's MC fraction is lower than Firm B's while Firm D's reverse-anchor score ranks it as less replication-dominated than Firm B).
**Table XVII.** Firm × K=3 cluster cross-tabulation, Big-4 sub-corpus. **Table XVII.** Firm × K=3 cluster cross-tabulation, Big-4 sub-corpus.
@@ -874,7 +758,7 @@ The five-way **moderate-confidence non-hand-signed** band (cos $> 0.95$ AND $5 <
| Firm C | 102 | 24 | 77 | 1 | $23.53\%$ | $0.98\%$ | | Firm C | 102 | 24 | 77 | 1 | $23.53\%$ | $0.98\%$ |
| Firm D | 52 | 6 | 45 | 1 | $11.54\%$ | $1.92\%$ | | Firm D | 52 | 6 | 45 | 1 | $11.54\%$ | $1.92\%$ |
(Source: Script 35.) The cross-tab is the accountant-level descriptive output of the K=3 mixture (§III-J / §IV-E). It is reported here as a complement to the five-way per-signature classifier (Table XV), not as an operational classifier output. Reading: Firm A's CPAs are concentrated in the C3 (high-cos / low-dHash) component (no Firm A CPAs in C1); Firm C has the highest C1 (low-cos / high-dHash) concentration of the Big-4 (C1 fraction $23.5\%$); Firms B and D sit between A and C on the K=3 hard-label ordering, broadly consistent with the per-firm Spearman ordering of Table X (with the within-Big-4-non-A reverse-anchor disagreement noted there). (Source: Script 35.) The cross-tab is the accountant-level descriptive output of the K=3 mixture (§III-L / §IV-E). It is reported here as a complement to the five-way per-signature screening rule (Table XV), not as an operational classifier output. Reading: Firm A's CPAs are concentrated in the C3 (high-cos / low-dHash) component (no Firm A CPAs in C1); Firm C has the highest C1 (low-cos / high-dHash) concentration of the Big-4 (C1 fraction $23.5\%$); Firms B and D sit between A and C on the K=3 hard-label ordering, broadly consistent with the per-firm Spearman ordering of Table X (with the within-Big-4-non-A reverse-anchor disagreement noted there).
**Document-level worst-case aggregation outputs are reported in Table XVI above.** **Document-level worst-case aggregation outputs are reported in Table XVI above.**
@@ -902,7 +786,7 @@ This section reports the reproducibility cross-check at the full accountant scop
(Source: Script 41.) (Source: Script 41.)
**Reading.** The K=3 component ordering and the strong Spearman convergence between K=3 P(C1) and the deployed box-rule less-replication-dominated rate are preserved at the full scope. Component centres shift modestly: C3 (high-cos / low-dHash) is essentially unchanged in centre but loses weight $0.117$ as the full population includes more non-templated CPAs (mid/small firms); C1 (low-cos / high-dHash) gains weight $0.141$ and shifts to lower cosine and higher dHash (centre $(0.928, 11.17)$ vs Big-4 $(0.946, 9.17)$) as the broader population includes mid/small-firm CPAs landing toward the low-cos / high-dHash region that the Big-4-primary scope deliberately excludes. We read this as evidence that the Big-4-primary K=3 + deployed-rule convergence is not a Big-4-specific artefact; we do **not** read it as an endorsement of using full-dataset K=3 component centres or operational thresholds in place of the Big-4-primary analysis. Mid/small-firm composition shifts the component centres meaningfully and the primary methodology is restricted to Big-4 by design (§III-G item 4). **Reading.** The K=3 component ordering and the strong Spearman convergence between K=3 P(C1) and the deployed box-rule less-replication-dominated rate are preserved at the full scope. Component centres shift modestly: C3 (high-cos / low-dHash) is essentially unchanged in centre but loses weight $0.117$ as the full population includes more CPAs in the low-cos / high-dHash descriptor region (mid/small firms); C1 (low-cos / high-dHash) gains weight $0.141$ and shifts to lower cosine and higher dHash (centre $(0.928, 11.17)$ vs Big-4 $(0.946, 9.17)$) as the broader population includes mid/small-firm CPAs landing toward the low-cos / high-dHash region that the Big-4-primary scope deliberately excludes. We read this as evidence that the Big-4-primary K=3 + deployed-rule convergence is not a Big-4-specific artefact; we do **not** read it as an endorsement of using full-dataset K=3 component centres or operational thresholds in place of the Big-4-primary analysis. Mid/small-firm composition shifts the component centres meaningfully and the primary methodology is restricted to Big-4 by design (§III-G item 4).
## L. Ablation Study: Feature Backbone Comparison ## L. Ablation Study: Feature Backbone Comparison
@@ -941,7 +825,7 @@ ResNet-50 provides the best overall balance:
## M. Anchor-Based ICCR Calibration Results ## M. Anchor-Based ICCR Calibration Results
This section consolidates the empirical results that support the §III-L anchor-based threshold calibration framework. This section consolidates the empirical results that support the §III-I anchor-based threshold calibration framework.
### M.1 Composition decomposition (Scripts 39b39e) ### M.1 Composition decomposition (Scripts 39b39e)
@@ -957,54 +841,40 @@ This section consolidates the empirical results that support the §III-L anchor-
(Source: Scripts 39b, 39c, 39d, 39e; bootstrap $n_{\text{boot}} = 2000$; jitter $\sim \mathrm{U}[-0.5, +0.5]$.) (Source: Scripts 39b, 39c, 39d, 39e; bootstrap $n_{\text{boot}} = 2000$; jitter $\sim \mathrm{U}[-0.5, +0.5]$.)
### M.2 Anchor-based inter-CPA pair-level ICCR (Script 40b) ### M.2 Anchor-based inter-CPA pair-level ICCR (Script 46)
**Table XXI.** Big-4 inter-CPA per-comparison ICCR sweep, $n = 5 \times 10^5$ pairs (Big-4 scope). **Table XXI.** Inter-CPA per-comparison ICCR by negative-anchor pool, $n = 5 \times 10^5$ pairs each.
| Threshold | Per-comparison ICCR | 95% Wilson CI | | Threshold | BCD (primary) | All-Big-4 (contamination comparison) | BCD+non-Big-4 |
|---|---|---|---|
| cos $> 0.95$ | $0.00026$ | $0.00060$ | $0.00014$ |
| dHash $\leq 5$ | $0.00037$ | $0.00129$ | $0.00034$ |
| Joint: cos $> 0.95$ AND dHash $\leq 5$ (any-pair) | $\mathbf{0.000010}$ | $0.000140$ | $0.000004$ |
BCD joint Wilson 95% $[0.000004, 0.000023]$ ($5$ of $5 \times 10^5$ pairs); all-Big-4 joint $[0.000111, 0.000177]$; BCD+non-Big-4 joint $[0.000001, 0.000015]$. Removing Firm A from the negative anchor lowers the joint HC coincidence rate by $\sim 8\times$, confirming that the all-Big-4 rate is inflated by Firm A's within-firm template reuse (§III-J.1). On the all-Big-4 sample, conditional ICCR(dHash $\leq 5$ | cos $> 0.95$) $= 0.234$; the all-Big-4 cos $> 0.95$ row is consistent with the corpus-wide spike of §IV-I ($0.0005$).
### M.3 Pool-normalised per-signature ICCR (Script 52)
**Table XXII.** Pool-normalised per-signature ICCR under the deployed any-pair HC rule (cos $> 0.95$ AND dHash $\leq 5$) by negative-anchor pool; canonical retry-loop sampler; CPA-block bootstrap $n_{\text{boot}} = 1000$.
| Baseline pool | Per-signature HC ICCR | CPA-bootstrap 95% CI |
|---|---|---| |---|---|---|
| cos $> 0.945$ (alternative operating point from supplementary calibration evidence) | $0.00081$ | $[0.00073, 0.00089]$ | | BCD (primary) | $\mathbf{0.0059}$ | $[0.0045, 0.0073]$ |
| cos $> 0.95$ (deployed operating point) | $0.00060$ | $[0.00053, 0.00067]$ | | All-Big-4 (contamination comparison) | $0.1102$ | $[0.0908, 0.1330]$ |
| cos $> 0.97$ | $0.00024$ | $[0.00020, 0.00029]$ | | BCD+non-Big-4 | $0.0083$ | $[0.0066, 0.0099]$ |
| cos $> 0.98$ | $0.00009$ | $[0.00007, 0.00012]$ |
| dHash $\leq 5$ (deployed operating point) | $0.00129$ | $[0.00120, 0.00140]$ |
| dHash $\leq 4$ | $0.00050$ | $[0.00044, 0.00057]$ |
| dHash $\leq 3$ | $0.00019$ | $[0.00015, 0.00023]$ |
| Joint: cos $> 0.95$ AND dHash $\leq 5$ (any-pair semantics) | $0.00014$ | $[0.00011, 0.00018]$ |
| Joint: cos $> 0.95$ AND dHash $\leq 4$ (any-pair) | $0.00011$ | $[0.00008, 0.00014]$ |
Conditional ICCR(dHash $\leq 5$ | cos $> 0.95$) $= 0.234$ (Wilson 95% $[0.190, 0.285]$; $70$ of $299$ pairs). The BCD floor is an order of magnitude below the all-Big-4 figure, which is dominated by Firm A's within-firm coincidences. The per-signature rate increases with pool size (the deployed rule takes extrema over $n_{\text{pool}}$ candidates); the per-document HC+MC band on the clean baseline (Table XXIII) does not show the same collapse, because the dHash $\leq 15$ band carries little inter-CPA specificity even among normative firms.
The cos $> 0.95$ row is consistent with the corpus-wide spike of §IV-I (per-comparison rate $0.0005$). The dHash row and joint row are reported here for the first time on this corpus. ### M.4 Document-level ICCR by alarm definition and pool (Script 52)
### M.3 Pool-normalised per-signature ICCR (Script 43) **Table XXIII.** Document-level inter-CPA ICCR by alarm definition and negative-anchor pool (dominant-firm document assignment).
**Table XXII.** Pool-normalised per-signature ICCR under the deployed any-pair HC rule (cos $> 0.95$ AND dHash $\leq 5$); $n_{\text{sig}} = 150{,}453$ (vector-complete Big-4); CPA-block bootstrap $n_{\text{boot}} = 1000$. | Alarm definition | BCD (primary) | All-Big-4 | BCD+non-Big-4 |
| Scope | Per-signature ICCR | Wilson 95% CI | CPA-bootstrap 95% CI |
|---|---|---|---| |---|---|---|---|
| Big-4 pooled (any-pair, deployed) | $0.1102$ | $[0.1086, 0.1118]$ | $[0.0908, 0.1330]$ | | HC (dHash $\leq 5$) | $\mathbf{0.0117}$ | $0.1797$ | $0.0163$ |
| Big-4 pooled (same-pair, stricter alternative) | $0.0827$ | $[0.0813, 0.0841]$ | $[0.0668, 0.1021]$ | | HC + MC (dHash $\leq 15$) | $0.1753$ | $0.3375$ | $0.1467$ |
| Firm A (any-pair) | $0.2594$ | — | — |
| Firm B (any-pair) | $0.0147$ | — | — |
| Firm C (any-pair) | $0.0053$ | — | — |
| Firm D (any-pair) | $0.0110$ | — | — |
| Pool-size decile 1 (smallest pools) any-pair | $0.0249$ | — | — |
| Pool-size decile 10 (largest pools) any-pair | $0.1905$ | — | — |
Decile trend is broadly monotone in pool size with two minor reversals (decile 5 and decile 9 dip below their predecessors). Stricter operating point cos $> 0.95$ AND dHash $\leq 3$ (same-pair) gives per-signature ICCR $0.0449$. Per-firm per-document HC+MC ICCR on the BCD baseline is Firm B $0.162$, Firm C $0.225$, Firm D $0.089$ (all-Big-4 pool: Firm A $0.620$, Firm B $0.160$, Firm C $0.163$, Firm D $0.088$). The HC band collapses by $\sim 8\times$ when Firm A is removed from the anchor (high specificity), whereas the HC+MC band is essentially unchanged — slightly higher for B/C/D — confirming that dHash $\leq 15$ adds alert yield without inter-CPA specificity and motivating the MC band's repositioning as an advisory tier (§III-I.3).
### M.4 Document-level ICCR under three alarm definitions (Script 45)
**Table XXIII.** Document-level inter-CPA ICCR by alarm definition; $n_{\text{docs}} = 75{,}233$.
| Alarm definition | Alarm set | Document-level ICCR | Wilson 95% CI |
|---|---|---|---|
| D1 | HC only | $0.1797$ | $[0.1770, 0.1825]$ |
| D2 (operational) | HC + MC | $0.3375$ | $[0.3342, 0.3409]$ |
| D3 | HC + MC + HSC | $0.3384$ | $[0.3351, 0.3418]$ |
Per-firm D2 document-level ICCR: Firm A $0.6201$ ($n = 30{,}226$); Firm B $0.1600$ ($n = 17{,}127$); Firm C $0.1635$ ($n = 19{,}501$); Firm D $0.0863$ ($n = 8{,}379$). The Firm C denominator $n = 19{,}501$ exceeds Table XVI's single-firm Firm C count of $19{,}122$ by exactly the $379$ mixed-firm PDFs (all $379$ are $1{:}1$ Firm C / Firm D documents that an alphabetically-ordered tie-break assigns to Firm C; full implementation detail in the supplementary materials). The four per-firm denominators here therefore sum to the full $75{,}233$, whereas Table XVI's per-firm rows sum to $74{,}854 = 75{,}233 - 379$.
### M.5 Firm heterogeneity logistic regression and cross-firm hit matrix (Script 44) ### M.5 Firm heterogeneity logistic regression and cross-firm hit matrix (Script 44)
@@ -1017,6 +887,8 @@ Per-firm D2 document-level ICCR: Firm A $0.6201$ ($n = 30{,}226$); Firm B $0.160
| Firm D | $0.027$ | $\sim 37\times$ lower odds than Firm A | | Firm D | $0.027$ | $\sim 37\times$ lower odds than Firm A |
| log(pool size, centred) | $4.01$ | $\sim 4\times$ higher odds per log unit pool size | | log(pool size, centred) | $4.01$ | $\sim 4\times$ higher odds per log unit pool size |
On the BCD baseline with Firm D as reference (Script 53; $n = 89{,}994$, hit rate $0.0059$), the residual firm spread collapses to within $\sim 3.5\times$ — odds ratios $1.73$ (Firm B), $0.49$ (Firm C), log-pool-size $3.29$ — confirming that Firm A is the singular outlier while Firms B/C/D form an internally homogeneous baseline (§III-J.1).
Per-decile per-firm rates (Table not duplicated here; Script 44 decile table available in the supplementary report): within every pool-size decile, Firms B/C/D show rates of $0.0006$$0.0358$ while Firm A ranges $0.0541$$0.5958$. The firm gap survives within matched pool sizes. Per-decile per-firm rates (Table not duplicated here; Script 44 decile table available in the supplementary report): within every pool-size decile, Firms B/C/D show rates of $0.0006$$0.0358$ while Firm A ranges $0.0541$$0.5958$. The firm gap survives within matched pool sizes.
**Table XXV.** Cross-firm hit matrix among Big-4 source signatures with any-pair HC hit; max-cosine partner firm (counts). **Table XXV.** Cross-firm hit matrix among Big-4 source signatures with any-pair HC hit; max-cosine partner firm (counts).
@@ -1028,7 +900,7 @@ Per-decile per-firm rates (Table not duplicated here; Script 44 decile table ava
| Firm C | $16$ | $7$ | $149$ | $5$ | $1$ | $178$ | | Firm C | $16$ | $7$ | $149$ | $5$ | $1$ | $178$ |
| Firm D | $22$ | $2$ | $6$ | $106$ | $1$ | $137$ | | Firm D | $22$ | $2$ | $6$ | $106$ | $1$ | $137$ |
Same-pair joint hits (single candidate satisfying both cos $> 0.95$ AND dHash $\leq 5$) are within-firm at rates $99.96\%$ / $97.7\%$ / $98.2\%$ / $97.0\%$ for Firms A/B/C/D respectively. Same-pair joint hits (single candidate satisfying both cos $> 0.95$ AND dHash $\leq 5$) are within-firm at rates $99.96\%$ / $97.7\%$ / $98.2\%$ / $97.0\%$ for Firms A/B/C/D respectively. Restricting the candidate pool to the BCD baseline (Script 53) raises Firms B/C/D within-firm any-pair concentration to $97.2\%$ / $92.3\%$ / $89.2\%$ (same-pair $100\%$ / $100\%$ / $98.5\%$): within-firm concentration is a universal Big-4 pattern, not a Firm-A peculiarity (§III-J.1).
### M.6 Alert-rate sensitivity around deployed HC threshold (Script 46) ### M.6 Alert-rate sensitivity around deployed HC threshold (Script 46)
@@ -1040,7 +912,7 @@ Same-pair joint hits (single candidate satisfying both cos $> 0.95$ AND dHash $\
| dHash $= 5$ (HC) | $\approx 3.8\times$ | locally sensitive (not plateau-stable) | | dHash $= 5$ (HC) | $\approx 3.8\times$ | locally sensitive (not plateau-stable) |
| dHash $= 15$ (MC/HSC boundary) | $\approx 0.08$ | plateau-like (saturating tail) | | dHash $= 15$ (MC/HSC boundary) | $\approx 0.08$ | plateau-like (saturating tail) |
Big-4 observed deployed alert rate on actual same-CPA pools: per-signature HC $= 0.4958$; per-document HC $= 0.6228$. The deployed-rate excess over the inter-CPA proxy is $0.3856$ ($38.6$ pp) per-signature and $0.4431$ ($44.3$ pp) per-document; this excess is reported as an observed same-CPA-pool excess under §III-M caveats, not as a presumed true-positive rate and not attributed to within-CPA handwriting repeatability. Big-4 observed deployed alert rate on actual same-CPA pools: per-signature HC $= 0.4958$; per-document HC $= 0.6228$. Against the normative BCD floor (per-signature $0.0059$; per-document HC $0.0117$), the observed same-CPA-pool excess is $0.4899$ ($49.0$ pp, $\sim 84\times$) per-signature and $0.6111$ ($61.1$ pp, $\sim 53\times$) per-document; this excess is reported under §III-N caveats, not as a presumed true-positive rate and not attributed to within-CPA handwriting repeatability.
# V. Discussion # V. Discussion
@@ -1051,33 +923,29 @@ Non-hand-signing differs from forgery in that the questioned signature is produc
## B. Per-Signature Similarity is a Continuous Quality Spectrum; the Accountant-Level Multimodality is Composition-Driven ## B. Per-Signature Similarity is a Continuous Quality Spectrum; the Accountant-Level Multimodality is Composition-Driven
The Big-4 accountant-level descriptor distribution rejects unimodality on both marginals at $p < 5 \times 10^{-4}$ (§IV-D Table V). The composition decomposition of §III-I.4 shows that this rejection is fully attributable to two non-mechanistic sources: (a) between-firm location-shift effects on both axes — Firm A's mean dHash of $2.73$ versus Firms B/C/D's $6.46$, $7.39$, $7.21$ creates a multi-peaked pooled distribution that any single firm's distribution lacks — and (b) integer mass-point artefacts on the integer-valued dHash axis, which inflate the dip statistic against a continuous-density null. A 2×2 factorial diagnostic applied to the Big-4 pooled dHash (firm-mean centring × uniform integer jitter $[-0.5, +0.5]$, 5 jitter seeds) shows that the dip test fails to reject ($p_{\text{median}} = 0.35$, 0/5 seeds reject) when *both* corrections are applied; either correction alone leaves the rejection in place. Within the Big-4 firms, the descriptor marginals at the signature level are unimodal once integer ties are broken (Scripts 39b, 39d); eligible non-Big-4 firms provide corroborating raw-axis evidence on the cosine dimension (Script 39c) but are not used as calibration evidence (§III-I.4). The descriptor distributions therefore lack a within-population bimodal antimode that could anchor an operational threshold. The K=2 / K=3 mixture fits are retained in §III-J as descriptive partitions of the joint Big-4 distribution that reflect firm-compositional structure, not as inferential evidence for two or three latent mechanism modes. The Big-4 accountant-level distribution rejects unimodality on both marginals (§IV-D), but §III-K.4 shows this is fully attributable to between-firm location shifts and integer mass-point artefacts, not within-population structure: under joint firm-mean centring and integer-tie jitter the dip test no longer rejects ($p_{\text{median}} = 0.35$), and within each Big-4 firm the signature-level marginals are unimodal once integer ties are broken. The distributions therefore contain no within-population bimodal antimode to anchor a threshold, and per-signature similarity is best read as a continuous quality spectrum rather than two discrete populations. The K=2 / K=3 fits are descriptive firm-compositional partitions (§III-L), not latent mechanism classes.
## C. Firm A as the Templated End of Big-4 (Case Study, Not Calibration Anchor) ## C. Firm A as the Templated End of Big-4 (Out-of-Sample Target, Not Calibration Anchor)
Firm A is empirically the firm whose CPAs are most concentrated in the high-cosine, low-dHash corner of the Big-4 descriptor plane. In the Big-4 K=3 hard-posterior assignment (now interpreted as a firm-compositional position assignment; §III-J), Firm A accounts for $0\%$ of C1 (low-cos / high-dHash position) and $82.5\%$ of C3 (high-cos / low-dHash position); the opposite pattern holds at Firm C, which has the highest C1 concentration at $23.5\%$. Firm A also accounts for 145 of the 262 byte-identical signatures in the Big-4 byte-identical anchor of §IV-H (with Firm B 8, Firm C 107, Firm D 2). Byte-level decomposition of the 145 Firm A pixel-identical signatures (see supplementary materials) shows they span 50 distinct Firm A partners (of 180 registered), with 35 byte-identical matches occurring across different fiscal years. Firm A is empirically the firm whose CPAs are most concentrated in the high-cosine, low-dHash corner of the Big-4 descriptor plane. In the Big-4 K=3 hard-posterior assignment (now interpreted as a firm-compositional position assignment; §III-L), Firm A accounts for $0\%$ of C1 (low-cos / high-dHash position) and $82.5\%$ of C3 (high-cos / low-dHash position); the opposite pattern holds at Firm C, which has the highest C1 concentration at $23.5\%$. Firm A also accounts for 145 of the 262 byte-identical signatures in the Big-4 byte-identical anchor of §IV-H (with Firm B 8, Firm C 107, Firm D 2). Byte-level decomposition of the 145 Firm A pixel-identical signatures (see supplementary materials) shows they span 50 distinct Firm A partners (of 180 registered), with 35 byte-identical matches occurring across different fiscal years.
We treat Firm A as a *templated-end case study within the Big-4 sub-corpus* rather than as the calibration anchor for the operational threshold. Firm A enters the Big-4 anchor-based ICCR calibration on equal footing with the other three Big-4 firms (§III-L). The cross-firm hit matrix of §III-L.4 strengthens this framing: under the deployed any-pair rule, within-firm collision concentration is $98.8\%$ at Firm A and $76.7$$83.7\%$ at Firms B/C/D (the stricter same-pair joint event saturates at $97.0$$99.96\%$ within-firm across all four firms). Firm A's per-document D2 inter-CPA proxy ICCR of $0.6201$ (versus Firms B/C/D's $0.09$$0.16$) — the counterfactual rate at which Firm A documents would fire HC$+$MC if same-CPA pools were replaced by random inter-CPA candidates — reflects high inter-CPA collision concentration under the deployed rule, consistent with firm-specific template, stamp, or document-production reuse. (The corresponding observed rate on real same-CPA pools, from Table XVI, is substantially higher: $97.5\%$ HC$+$MC for Firm A; the proxy and observed rates measure different quantities and are not directly comparable.) The inter-CPA-anchor analysis alone is not diagnostic of deliberate template sharing. The byte-level evidence above (Firm A's 145 pixel-identical signatures across $\sim 50$ distinct partners) provides direct evidence of image-level reuse among Firm A signatures; the distribution across many partners is consistent with a firm-level template or production workflow, and the within-firm collision pattern at all four Big-4 firms is consistent with similar, milder within-firm collision patterns at Firms B/C/D, whose mechanisms may include template-like reuse, digitisation-pipeline homogeneity, or signing-style homogeneity (§V-H). We treat Firm A as the **out-of-sample templated-end target**: held out of the calibration negative anchor and scored against the normative Firms-B/C/D baseline (§III-I.0) rather than used as a calibration input. Three readings (§III-J.1) make Firm A's status precise. First, scored against the clean BCD baseline, Firm A's signatures coincide essentially never ($0.0001$, below the BCD floor of $0.0059$) — so Firm A is unremarkable, indeed sub-baseline, *cross-firm*; its signal is entirely within-firm. Second, on its own same-CPA pools the deployed HC rule fires on $0.82$ of Firm A signatures, $\sim 139\times$ the clean floor, versus $\sim 40$$59\times$ for Firms B/C/D — Firm A is the rate-extreme, but every Big-4 firm sits far above the floor. Third, within-firm collision concentration is universal: $98.8\%$ at Firm A and, on the clean BCD pool, $89$$97\%$ at Firms B/C/D, with same-pair concentration $97$$100\%$ across all four firms. The firm contrast is sharpest and most defensible in the high-confidence bin (the observed per-signature HC rates above); the per-document HC+MC proxy ICCR of $0.62$ at Firm A versus $0.09$$0.16$ at Firms B/C/D is reported only as advisory review burden, since the MC band carries low inter-CPA specificity even on the normative baseline (§III-I.3). None of this is by itself diagnostic of deliberate template sharing. The byte-level evidence above (Firm A's 145 pixel-identical signatures across $\sim 50$ distinct partners) provides direct evidence of image-level reuse among Firm A signatures, consistent with a firm-level template or production workflow; the milder within-firm patterns at Firms B/C/D may reflect template-like reuse, digitisation-pipeline homogeneity, or signing-style homogeneity, which descriptor-only data cannot separate (§V-H). We present Firm A as a *demonstration that the screening surfaces a known templated end at scale* — corroborated by the byte-identical capture check (§IV-H) — not as a forensic determination about the firm. Whether firm-level signing patterns bear on audit quality is a question for a dedicated companion study (§VI), beyond what descriptor-only screening can establish.
## D. K=2 / K=3 as Descriptive Firm-Compositional Partitions ## D. K=2 / K=3 as Descriptive Firm-Compositional Partitions
Leave-one-firm-out cross-validation of the Big-4 mixture fit reveals a sharp contrast between K=2 and K=3 behaviour. K=2 is unstable: across-fold cosine-crossing deviation is $0.028$, and holding Firm A out gives a fold rule (cos $> 0.938$, dHash $\leq 8.79$) that classifies $100\%$ of held-out Firm A in the upper component, while holding any non-Firm-A Big-4 firm out gives a fold rule near (cos $> 0.975$, dHash $\leq 3.76$) that classifies $0\%$ of the held-out firm in the upper component. The K=2 boundary is essentially a Firm-A-vs-others separator — direct evidence that the K=2 partition reflects firm-compositional rather than mechanistic structure. Leave-one-firm-out cross-validation (§III-L) sharply separates the two fits. K=2 is unstable — its boundary is essentially a Firm-A-versus-others separator (holding Firm A out gives a markedly looser fold rule than holding any other firm out), direct evidence that it reflects firm composition, not mechanism. K=3, by contrast, has a reproducible component shape across folds (the C1 cosine mean varies by $\leq 0.005$), though hard-posterior membership remains composition-sensitive. We therefore read K=3 as a reproducible three-region descriptor partition reflecting how firm-compositional weight is distributed across the descriptor plane, not a three-mechanism latent structure, and use it only as an accountant-level descriptive summary — never as operational classifier output.
K=3 in contrast has a *reproducible component shape* at the descriptor-position level: across the four folds the C1 (low-cos / high-dHash) component cosine mean varies by at most $0.005$, the dHash mean by at most $0.96$, and the weight by at most $0.023$. Hard-posterior membership for the held-out firm is composition-sensitive (absolute differences $1.8$$12.8$ pp across folds). Together with the §III-I.4 composition decomposition (no within-population bimodal antimode), the K=3 stability supports a descriptive reading: the Big-4 descriptor plane has a reproducible three-region partition that reflects how firm-compositional weight is distributed across the descriptor space, *not* a three-mechanism latent-class structure. We accordingly do not use K=3 hard-posterior membership as an operational classifier; we use it as the accountant-level descriptive summary that complements the deployed signature-level five-way classifier of §III-H.1.
## E. Three-Score Convergent Internal-Consistency ## E. Three-Score Convergent Internal-Consistency
Three feature-derived scores agree on the per-CPA descriptor-position ranking at Spearman $\rho \geq 0.879$: the K=3 mixture posterior (a firm-compositional position score, not a mechanism cluster posterior); the reverse-anchor cosine percentile under a non-Big-4 reference distribution; and the deployed box-rule less-replication-dominated rate. The three scores are *not* statistically independent measurements — they are deterministic functions of the same per-CPA descriptor pair — so the convergence is documented as internal consistency rather than external validation against an independent ground truth (which the corpus does not provide for the hand-signed class). The strength of the convergence (all pairwise $|\rho| > 0.87$) and its persistence at the signature level (Cohen $\kappa = 0.87$ between per-CPA-fit and per-signature-fit K=3 binary labels) are nevertheless informative: per-CPA aggregation does not collapse the broad three-region ordering, and three different summarisations of the descriptor space produce broadly concordant per-CPA rankings, with a residual non-Firm-A disagreement (the reverse-anchor cosine percentile ranks Firm D fractionally above Firm C, while the mixture posterior and the deployed box-rule rate rank Firm C highest among non-Firm-A firms). Three feature-derived per-CPA scores — the K=3 firm-compositional position, the reverse-anchor cosine percentile against a non-Big-4 reference, and the deployed box-rule rate — agree on the per-CPA ranking at Spearman $\rho \geq 0.879$, with agreement persisting at the signature level (Cohen $\kappa = 0.87$). Because the three are deterministic functions of the same descriptor pair, we report this as internal consistency, not external validation against an independent ground truth (which the corpus does not provide for the hand-signed class). The only material disagreement is a Firm C / Firm D swap among the non-Firm-A firms.
## F. Anchor-Based Multi-Level Calibration ## F. Anchor-Based Multi-Level Calibration
The operational specificity-proxy behaviour of the deployed HC sub-rule and document-level HC$+$MC alarm derived from the five-way classifier is characterised at three units of analysis (§III-L), all against the same inter-CPA negative-anchor coincidence-rate proxy. The per-comparison ICCR is consistent with the corpus-wide rate reported in §IV-I (cos$>0.95 \to 0.00060$) and extends it to the structural dimension (dHash$\leq 5 \to 0.00129$; joint $\to 0.00014$). The pool-normalised per-signature ICCR captures the deployed rule's effective per-signature rate under inter-CPA candidate-pool replacement ($0.1102$ pooled Big-4 any-pair HC), exposing that the per-comparison rate is not the deployed-rule rate at the per-signature classifier level: the deployed classifier takes max-cosine and min-dHash over a same-CPA pool of size $n_{\text{pool}}$, so the inter-CPA-equivalent rate scales approximately as $1 - (1 - p_{\text{pair}})^{n_{\text{pool}}}$ in the independence limit. The per-document ICCR aggregates to operational alarm-rate units: HC alone $0.18$, the operational HC$+$MC alarm $0.34$. The deployed HC sub-rule's specificity-proxy behaviour is characterised at three units against the normative BCD baseline (§III-I), with the all-Big-4 pool shown only as a contamination comparison. At every unit the HC inter-CPA coincidence rate is an order of magnitude below the all-Big-4 figure — the gap being Firm A's extreme within-firm collision structure (§III-J.1) — confirming HC as a high-specificity-proxy operating point. Because the deployed rule takes pool extrema, the per-comparison rate understates the per-signature rate (the $1 - (1 - p_{\text{pair}})^{n_{\text{pool}}}$ pool effect). The HC threshold is locally sensitive rather than plateau-stable (§III-K.6), so it is a specificity-anchored operating *choice*, not a distributional antimode; operators can select alternative points by inverting the ICCR curves (§III-I.2). The dHash$\leq 15$ MC band stays a low-specificity advisory tier even on the clean baseline (§III-I.3).
Two additional findings refine the calibration story. First, the per-pair conditional ICCR for dHash$\leq 5$ given cos$>0.95$ is $0.234$ (Wilson 95% $[0.190, 0.285]$): given the cosine gate, the structural dimension provides further per-comparison specificity at $\sim 4.3\times$ refinement. Second, the alert-rate sensitivity analysis (§III-L.5) shows the deployed HC threshold is locally sensitive rather than plateau-stable (local gradient $\approx 25\times$ the median for cosine, $\approx 3.8\times$ for dHash); alternative operating points can be characterised by inverting the ICCR curves (e.g., a tighter rule cos$>0.95$ AND dHash$\leq 3$ on the same-pair joint corresponds to per-signature ICCR $\approx 0.045$). The MC/HSC sub-band boundary at dHash$=15$, by contrast, *is* plateau-like (local-to-median ratio $\approx 0.08$), consistent with high-dHash-tail saturation.
## G. Pixel-Identity Positive Anchor and Inter-CPA Coincidence-Rate Negative Anchor ## G. Pixel-Identity Positive Anchor and Inter-CPA Coincidence-Rate Negative Anchor
The only conservative hard-positive subset in the corpus is pixel-identical signatures: those whose nearest same-CPA match is byte-identical after crop and normalisation. Independent hand-signing cannot produce byte-identical images, so these signatures are a conservative hard-positive subset for image replication. On the Big-4 subset ($n = 262$ pixel-identical signatures), all three candidate checks — the deployed box rule, the K=3 hard label, and the reverse-anchor metric with a prevalence-calibrated cut — achieve $0\%$ positive-anchor miss rate (Wilson 95% upper bound $1.45\%$). We caution that this result is necessary but not sufficient: for the deployed box rule it is close to tautological, because byte-identical neighbours have cosine $\approx 1$ and dHash $\approx 0$, well inside the rule's high-confidence region. The corresponding signature-level *negative* anchor evidence is developed in §III-L.1 above (per-comparison ICCR $= 0.00060$ at cos$>0.95$, consistent with the corpus-wide rate of $0.0005$ reported in §IV-I). We frame the per-comparison rate as a specificity proxy under the assumption that inter-CPA pairs constitute a clean negative anchor, and we document in §III-L.4 that this assumption is partially violated by within-firm cross-CPA template-like collision structures. The only conservative hard-positive subset is pixel-identical (byte-identical) signatures, which independent hand-signing cannot produce. All three candidate checks achieve $0\%$ positive-anchor miss on the 262 Big-4 byte-identical signatures (§IV-H) — a necessary check, though close to tautological for the box rule (byte-identical $\Rightarrow$ cosine $\approx 1$, dHash $\approx 0$, well inside the HC region). The complementary negative anchor is the §III-I.1 per-comparison ICCR on the normative BCD baseline ($0.000010$); we frame it as a specificity proxy, and because the inter-CPA-as-negative assumption is violated by within-firm collisions concentrated at Firm A, we anchor on Firms B/C/D with Firm A held out as an out-of-sample target (§III-I.0).
## H. Limitations ## H. Limitations
@@ -1085,9 +953,9 @@ Several limitations should be transparent. We group them into primary methodolog
**Primary methodological limitations.** **Primary methodological limitations.**
*No signature-level ground truth; no true error rates reportable.* The corpus does not contain labelled hand-signed or replicated classes at the signature level. We therefore cannot report False Rejection Rate, sensitivity, recall, Equal Error Rate, ROC-AUC, precision, or positive predictive value against ground truth. All quantitative rates reported in §III-L are inter-CPA negative-anchor coincidence rates (ICCRs) under the assumption that inter-CPA pairs constitute a clean negative anchor; this is a specificity proxy, not a calibrated specificity (§III-M). *No signature-level ground truth; no true error rates reportable.* The corpus does not contain labelled hand-signed or replicated classes at the signature level. We therefore cannot report False Rejection Rate, sensitivity, recall, Equal Error Rate, ROC-AUC, precision, or positive predictive value against ground truth. All quantitative rates reported in §III-I are inter-CPA negative-anchor coincidence rates (ICCRs) under the assumption that inter-CPA pairs constitute a clean negative anchor; this is a specificity proxy, not a calibrated specificity (§III-N).
*Inter-CPA negative-anchor assumption is partially violated and the violation is firm-dependent.* The cross-firm hit matrix of §III-L.4 shows that under the deployed any-pair rule, within-firm collision concentration is $98.8\%$ at Firm A and $76.7$$83.7\%$ at Firms B/C/D (the stricter same-pair joint event saturates at $97.0$$99.96\%$ within-firm across all four firms), consistent with firm-specific template, stamp, or document-production reuse. The inter-CPA-as-negative assumption is therefore not exactly satisfied — some inter-CPA pairs may share firm-level templates rather than being independent random matches. Our reported per-comparison ICCRs are best read as specificity-proxy rates under a partially-violated assumption, not as calibrated FARs. Because the violation is firm-dependent, Firm A's per-firm ICCR is more contaminated by within-firm sharing than Firms B/C/D's; the per-firm B/C/D rates of $0.09$$0.16$ may therefore be less contaminated than the pooled rate, and the Firm A vs Firms B/C/D contrast reflects both genuine firm heterogeneity and a firm-dependent proxy-contamination gradient. *Inter-CPA negative-anchor assumption, and why we anchor on the BCD baseline.* The cross-firm hit matrix of §III-J.1 shows that under the deployed rule, within-firm collision concentration is $98.8\%$ at Firm A and $76.7$$97.2\%$ at Firms B/C/D, consistent with firm-specific template, stamp, or document-production reuse. An all-Big-4 inter-CPA pool is therefore not a clean negative anchor — some inter-CPA pairs share firm-level templates rather than being independent random matches, and the contamination is dominated by Firm A. We address this directly by anchoring the calibration on the Firms-B/C/D baseline and holding Firm A out as an out-of-sample target (§III-I.0); on this baseline the per-comparison HC rate falls from $0.00014$ to $0.000010$ and the per-signature HC rate from $0.1102$ to $0.0059$. A residual caveat survives even on the clean baseline: the BCD floor is an *inter-CPA coincidence* rate, not an *intra-CPA genuine-hand-signing* rate, so the observed-versus-floor excess (§III-J.2) cannot be read as a true-positive rate — a consistently hand-signing CPA can exceed the inter-CPA floor. All reported ICCRs are therefore specificity proxies, not calibrated FARs or specificities.
*Mechanism attribution for the firm-level heterogeneity is not identifiable from descriptor-only data.* The observed firm-level contrast (Firm A's per-document HC$+$MC ICCR of $0.62$ versus $0.09$$0.16$ at Firms B/C/D; within-firm collision concentration $77$$99\%$ under the deployed any-pair rule; byte-identical evidence of §IV-H) is consistent with at least three non-mutually-exclusive firm-level mechanisms: (i) template, stamp, or e-signature production reuse; (ii) digitisation-pipeline homogeneity — shared scanners, common PDF generation infrastructure, identical compression and form-template settings — that systematically inflates image-descriptor similarity without signature replication; and (iii) signing-style or training homogeneity that produces correlated handwritten signatures within a firm. The descriptor pair (cosine, dHash) operates at the image-similarity level and is, by construction, indifferent to which mechanism generated a given near-identical pair. We therefore report the firm contrast as a methodological observation — the framework discriminates at firm-level resolution — rather than as a mechanism finding. The byte-identical Firm A signatures across $\sim 50$ distinct partners (§IV-H, §V-C) provide direct evidence for (i) at Firm A specifically, but do not exclude additive contribution from (ii) or (iii); the milder within-firm collision patterns at Firms B/C/D are individually consistent with all three mechanisms. Image-acquisition metadata (scanner identifiers, PDF generator fingerprints, compression-codec markers), partner-level intent records, or controlled hand-signed baselines would be needed to attribute the contrast across (i), (ii), and (iii). *Mechanism attribution for the firm-level heterogeneity is not identifiable from descriptor-only data.* The observed firm-level contrast (Firm A's per-document HC$+$MC ICCR of $0.62$ versus $0.09$$0.16$ at Firms B/C/D; within-firm collision concentration $77$$99\%$ under the deployed any-pair rule; byte-identical evidence of §IV-H) is consistent with at least three non-mutually-exclusive firm-level mechanisms: (i) template, stamp, or e-signature production reuse; (ii) digitisation-pipeline homogeneity — shared scanners, common PDF generation infrastructure, identical compression and form-template settings — that systematically inflates image-descriptor similarity without signature replication; and (iii) signing-style or training homogeneity that produces correlated handwritten signatures within a firm. The descriptor pair (cosine, dHash) operates at the image-similarity level and is, by construction, indifferent to which mechanism generated a given near-identical pair. We therefore report the firm contrast as a methodological observation — the framework discriminates at firm-level resolution — rather than as a mechanism finding. The byte-identical Firm A signatures across $\sim 50$ distinct partners (§IV-H, §V-C) provide direct evidence for (i) at Firm A specifically, but do not exclude additive contribution from (ii) or (iii); the milder within-firm collision patterns at Firms B/C/D are individually consistent with all three mechanisms. Image-acquisition metadata (scanner identifiers, PDF generator fingerprints, compression-codec markers), partner-level intent records, or controlled hand-signed baselines would be needed to attribute the contrast across (i), (ii), and (iii).
@@ -1097,9 +965,9 @@ Several limitations should be transparent. We group them into primary methodolog
*Pixel-identity is a conservative subset.* Byte-identical pairs are the easiest replicated cases, and for the deployed box rule the positive-anchor miss rate against byte-identical pairs is close to tautological (byte-identical $\Rightarrow$ cosine $\approx 1$, dHash $\approx 0$, well inside the high-confidence box). A score that fails the pixel-identity check would be disqualified, but passing the check does not guarantee correct behaviour on the broader replicated population (e.g., re-stamped or noisy-template-variant signatures). *Pixel-identity is a conservative subset.* Byte-identical pairs are the easiest replicated cases, and for the deployed box rule the positive-anchor miss rate against byte-identical pairs is close to tautological (byte-identical $\Rightarrow$ cosine $\approx 1$, dHash $\approx 0$, well inside the high-confidence box). A score that fails the pixel-identity check would be disqualified, but passing the check does not guarantee correct behaviour on the broader replicated population (e.g., re-stamped or noisy-template-variant signatures).
*Rule components not separately re-characterised by the present diagnostic battery.* The five-way classifier's moderate-confidence band (cos $> 0.95$ AND $5 < \text{dHash} \leq 15$), the style-consistency band ($\text{dHash} > 15$), and the document-level worst-case aggregation rule retain their prior calibration and capture-rate evidence (supplementary materials); the anchor-based ICCR calibration covers the binary high-confidence sub-rule (and its tightening alternatives such as dHash$\leq 3$), and the alert-rate sensitivity analysis (§III-L.5) characterises only the HC threshold. The MC and HSC sub-band boundaries are not separately re-characterised by the present diagnostic battery. *Rule components not separately re-characterised by the present diagnostic battery.* The five-way classifier's moderate-confidence advisory band (cos $> 0.95$ AND $5 < \text{dHash} \leq 15$), the style-consistency band ($\text{dHash} > 15$), and the document-level worst-case aggregation rule retain the threshold provenance of their prior calibration (supplementary materials); however, §III-I.3 supersedes the MC band's *claim strength* — its $\sim 0.175$ per-document inter-CPA coincidence on the normative baseline makes it a low-specificity advisory bin, not calibrated evidence of replication. The anchor-based ICCR calibration covers the binary high-confidence sub-rule (and its tightening alternatives such as dHash$\leq 3$), and the alert-rate sensitivity analysis (§III-K.6) characterises only the HC threshold. The MC and HSC sub-band boundaries are not separately re-characterised by the present diagnostic battery.
*Deployed-rate excess is not a presumed true-positive rate.* The $\sim 44$-pp per-document gap between the observed deployed alert rate (HC: $0.62$ on real same-CPA pools) and the inter-CPA proxy rate (HC: $0.18$) cannot be interpreted as a presumed true-positive rate without additional assumptions that §III-M shows are unsafe (consistent within-CPA signing can exceed inter-CPA similarity at the cosine axis; within-firm template sharing inflates the inter-CPA proxy baseline). The gap is best read as a same-CPA repeatability signal. *Deployed-rate excess is not a presumed true-positive rate.* The per-document gap between the observed deployed alert rate (HC: $0.62$ on real same-CPA pools) and the normative inter-CPA proxy floor (HC: $0.012$ on the BCD baseline) — $\sim 60$ pp — cannot be interpreted as a presumed true-positive rate without additional assumptions that §III-N shows are unsafe (consistent within-CPA signing can exceed inter-CPA similarity at the cosine axis; the inter-CPA floor is not an intra-CPA genuine-hand-signing rate). The gap is best read as an observed same-CPA-pool repeatability signal.
*A1 pair-detectability stipulation.* The per-signature detector requires at least one same-CPA pair to be near-identical when a CPA uses image replication. A1 is plausible for high-volume stamping or firm-level electronic signing but not guaranteed when a corpus contains only one observed replicated report for a CPA, multiple template variants used in parallel, or scan-stage noise that pushes a replicated pair outside the detection regime. *A1 pair-detectability stipulation.* The per-signature detector requires at least one same-CPA pair to be near-identical when a CPA uses image replication. A1 is plausible for high-volume stamping or firm-level electronic signing but not guaranteed when a corpus contains only one observed replicated report for a CPA, multiple template variants used in parallel, or scan-stage noise that pushes a replicated pair outside the detection regime.
@@ -1107,7 +975,7 @@ Several limitations should be transparent. We group them into primary methodolog
*K=3 hard-posterior membership is composition-sensitive.* The K=3 hard-posterior membership for any single firm varies by up to $12.8$ pp across LOOO folds. This is documented as a composition-sensitivity band rather than failure, but it means K=3 hard labels are not used as operational classifier output; they are reported only as accountant-level descriptive characterisation. *K=3 hard-posterior membership is composition-sensitive.* The K=3 hard-posterior membership for any single firm varies by up to $12.8$ pp across LOOO folds. This is documented as a composition-sensitivity band rather than failure, but it means K=3 hard labels are not used as operational classifier output; they are reported only as accountant-level descriptive characterisation.
*No partner-level mechanism attribution.* The analysis reports population-level patterns; it does not perform partner-level mechanism attribution or report-level claims of intent. The signature-level outputs are signature-level quantities throughout. The within-firm cross-CPA collision concentration of §III-L.4 is consistent with template-like reuse but is not by itself diagnostic of deliberate sharing. *No partner-level mechanism attribution.* The analysis reports population-level patterns; it does not perform partner-level mechanism attribution or report-level claims of intent. The signature-level outputs are signature-level quantities throughout. The within-firm cross-CPA collision concentration of §III-J.1 is consistent with template-like reuse but is not by itself diagnostic of deliberate sharing.
**Engineering-level caveats of the pipeline.** **Engineering-level caveats of the pipeline.**
@@ -1124,18 +992,18 @@ Several limitations should be transparent. We group them into primary methodolog
# VI. Conclusion and Future Work # VI. Conclusion and Future Work
We present a fully automated pipeline for screening non-hand-signed CPA signatures in Taiwan-listed financial audit reports, together with an anchor-calibrated screening framework that characterises the pipeline's operational behaviour at the Big-4 sub-corpus scope under explicit unsupervised assumptions. The pipeline processes raw PDFs through VLM-based page identification, YOLO-based signature detection, ResNet-50 feature extraction, and dual-descriptor (cosine + independent-minimum dHash) similarity computation. The operational output is the deployed five-way per-signature classifier with worst-case document-level aggregation (§III-H.1; calibrated in §III-L). Applied to 90,282 audit reports filed between 2013 and 2023, the pipeline extracts 182,328 signatures from 758 CPAs, with the Big-4 sub-corpus (437 CPAs at accountant level; 150,442150,453 signatures at signature level) as the primary analytical population. We present a fully automated pipeline for screening non-hand-signed CPA signatures in Taiwan-listed financial audit reports, together with an anchor-calibrated screening framework that characterises the pipeline's operational behaviour at the Big-4 sub-corpus scope under explicit unsupervised assumptions. The pipeline processes raw PDFs through VLM-based page identification, YOLO-based signature detection, ResNet-50 feature extraction, and dual-descriptor (cosine + independent-minimum dHash) similarity computation. The operational output is the deployed five-way per-signature screening rule with worst-case document-level aggregation (§III-H.1; calibrated in §III-I). Applied to 90,282 audit reports filed between 2013 and 2023, the pipeline extracts 182,328 signatures from 758 CPAs, with the Big-4 sub-corpus (437 CPAs at accountant level; 150,442150,453 signatures at signature level) as the primary analytical population. We emphasise that the operating thresholds are operator-tunable and that the system performs semi-automated triage — surfacing replication candidates from hundreds of thousands of signatures for human adjudication — rather than autonomous forensic classification; its central deliverable is the label-free calibration methodology by which an operator selects and characterises a screening operating point.
Our central methodological contributions are: (1) a composition decomposition that establishes the absence of a within-population bimodal antimode in the Big-4 descriptor distribution: the apparent multimodality dissolves under joint firm-mean centring and integer-tie jitter ($p_{\text{median}} = 0.35$), so distributional "natural-threshold" framings of the deployed operating points are not empirically supported; (2) an anchor-based inter-CPA coincidence-rate (ICCR) calibration at three units of analysis — per-comparison ($0.0006$ at cos$>0.95$; $0.0013$ at dHash$\leq 5$; $0.00014$ jointly), pool-normalised per-signature ($0.11$ for the deployed any-pair HC rule), and per-document ($0.34$ for the operational HC$+$MC alarm) — with explicit terminological replacement of "FAR" by "ICCR" given the unsupervised setting; (3) firm-level heterogeneity surfaced by the framework: logistic regression with pool-size adjustment gives odds ratios $0.053$, $0.010$, $0.027$ for Firms B/C/D relative to Firm A reference, a contrast that pool-size differences do not explain and that we report as a framework-discriminative observation rather than a mechanism finding (§V-H); (4) cross-firm hit matrix evidence that under the deployed any-pair rule, within-firm collision concentration is $98.8\%$ at Firm A and $76.7$$83.7\%$ at Firms B/C/D (the stricter same-pair joint event saturates at $97.0$$99.96\%$ within-firm across all four firms), consistent with but not independently establishing firm-level template-like reuse, digitisation-pipeline homogeneity, or signing-style similarity, which descriptor-only data cannot separate (§V-H); (5) K=3 mixture demoted from "three mechanism clusters" to a descriptive firm-compositional partition; (6) three feature-derived scores converging on the per-CPA descriptor-position ranking at Spearman $\rho \geq 0.879$, reported as internal consistency rather than external validation; (7) $0\%$ positive-anchor miss rate on 262 byte-identical Big-4 signatures with the conservative-subset caveat; and (8) explicit disclosure of each diagnostic's untested assumption (Appendix A Table A.II), positioning the system as an anchor-calibrated screening framework with human-in-the-loop review rather than as a validated forensic detector. Our central methodological contributions are: (1) a composition decomposition that establishes the absence of a within-population bimodal antimode in the Big-4 descriptor distribution: the apparent multimodality dissolves under joint firm-mean centring and integer-tie jitter ($p_{\text{median}} = 0.35$), so distributional "natural-threshold" framings of the deployed operating points are not empirically supported; (2) an anchor-based inter-CPA coincidence-rate (ICCR) calibration on a normative non-Firm-A baseline (Firms B/C/D, with Firm A held out as an out-of-sample target to avoid circularity): on this clean baseline the deployed HC rule yields per-comparison ICCR $0.000010$, per-signature $0.0059$, and per-document $0.012$ — roughly an order of magnitude below the contaminated all-Big-4 figures ($0.00014$, $0.11$, $0.18$) — while the dHash$\leq 15$ moderate-confidence band, which retains a $\sim 0.175$ per-document coincidence rate even on the clean baseline, is repositioned as a low-specificity advisory tier; with explicit terminological replacement of "FAR" by "ICCR" given the unsupervised setting; (3) firm-level heterogeneity surfaced by the framework: against the clean BCD floor the deployed rule fires on each firm's own pools at $\sim 139\times$ (Firm A) and $\sim 40$$59\times$ (Firms B/C/D), while Firm A scored cross-firm against the clean 20132019 baseline coincides essentially never cross-firm ($0.0001$); two logistic regressions (full-Big-4 Firm-A-reference odds ratios $0.053$/$0.010$/$0.027$; BCD-only Firm-D-reference residual spread within $\sim 3.5\times$) show Firm A is the singular outlier and Firms B/C/D an internally homogeneous baseline — reported as a framework-discriminative observation rather than a mechanism finding (§V-H); (4) cross-firm hit matrix evidence that within-firm collision concentration is a universal Big-4 pattern — $98.8\%$ at Firm A and $89$$97\%$ at Firms B/C/D on the clean BCD pool (same-pair $97$$100\%$ across all four firms) consistent with, but not independently establishing, firm-level template-like reuse, digitisation-pipeline homogeneity, or signing-style similarity, which descriptor-only data cannot separate (§V-H); (5) K=3 mixture demoted from "three mechanism clusters" to a descriptive firm-compositional partition; (6) three feature-derived scores converging on the per-CPA descriptor-position ranking at Spearman $\rho \geq 0.879$, reported as internal consistency rather than external validation; (7) $0\%$ positive-anchor miss rate on 262 byte-identical Big-4 signatures with the conservative-subset caveat; and (8) explicit disclosure of each diagnostic's untested assumption (Appendix A Table A.II), positioning the system as an anchor-calibrated screening framework with human-in-the-loop review rather than as a validated forensic detector.
Future work falls in four directions. *First*, a small-scale human-rated labelled set would enable direct ROC optimisation and provide the signature-level ground truth that the present analysis fundamentally lacks; without such ground truth, no true error rates can be reported. *Second*, the within-firm collision concentration documented in §III-L.4 (any-pair $76.7$$98.8\%$ across Big-4; same-pair joint $97.0$$99.96\%$) invites a separate study to distinguish deliberate template sharing from passive firm-level production artefacts (shared scanners, common form templates, identical report-generation infrastructure) — a question the inter-CPA-anchor analysis alone cannot resolve. *Third*, the descriptive Firm A versus Firms B/C/D contrast (per-document HC$+$MC alarm $0.62$ vs $0.09$$0.16$) — together with the byte-level evidence of 145 pixel-identical signatures across $\sim 50$ distinct Firm A partners — invites a companion analysis examining whether such firm-level signing patterns correlate with established audit-quality measures. *Fourth*, generalisation to mid- and small-firm contexts requires extending the anchor-based ICCR framework to scopes where firm-level LOOO folds are not available; the §III-I.4 composition diagnostics already document that the absence of within-population bimodality holds across the tested eligible scopes, so the calibration approach in principle generalises, but a full extension with cluster-robust uncertainty quantification is left as future work. Future work falls in four directions. *First*, a small-scale human-rated labelled set would enable direct ROC optimisation and provide the signature-level ground truth that the present analysis fundamentally lacks; without such ground truth, no true error rates can be reported. *Second*, the within-firm collision concentration documented in §III-J.1 (any-pair $76.7$$98.8\%$ across Big-4; same-pair joint $97.0$$99.96\%$) invites a separate study to distinguish deliberate template sharing from passive firm-level production artefacts (shared scanners, common form templates, identical report-generation infrastructure) — a question the inter-CPA-anchor analysis alone cannot resolve. *Third*, the descriptive Firm A versus Firms B/C/D contrast (observed per-signature high-confidence rate $0.82$ vs $0.24$$0.35$, $\sim 139\times$ vs $\sim 40$$59\times$ the clean BCD floor) — together with the byte-level evidence of 145 pixel-identical signatures across $\sim 50$ distinct Firm A partners — invites a companion analysis examining whether such firm-level signing patterns correlate with established audit-quality measures. *Fourth*, generalisation to mid- and small-firm contexts requires extending the anchor-based ICCR framework to scopes where firm-level LOOO folds are not available; the §III-K.4 composition diagnostics already document that the absence of within-population bimodality holds across the tested eligible scopes, so the calibration approach in principle generalises, but a full extension with cluster-robust uncertainty quantification is left as future work.
# Appendix A. Supplementary Diagnostic Detail # Appendix A. Supplementary Diagnostic Detail
## A.1. BD/McCrary Bin-Width Sensitivity (Signature Level) ## A.1. BD/McCrary Bin-Width Sensitivity (Signature Level)
The main text (Section III-I, Section IV-D Table VI) treats the Burgstahler-Dichev / McCrary discontinuity procedure [38], [39] as a *density-smoothness diagnostic* rather than as a threshold estimator. The main text (Section III-K, Section IV-D Table VI) treats the Burgstahler-Dichev / McCrary discontinuity procedure [38], [39] as a *density-smoothness diagnostic* rather than as a threshold estimator.
This subsection documents the empirical basis for that framing by sweeping the bin width across four (variant, bin-width) panels: Firm A and full-sample, each in the cosine and $\text{dHash}_\text{indep}$ direction. This subsection documents the empirical basis for that framing by sweeping the bin width across four (variant, bin-width) panels: Firm A and full-sample, each in the cosine and $\text{dHash}_\text{indep}$ direction.
**Table A.I.** BD/McCrary Bin-Width Sensitivity (two-sided $\alpha = 0.05$, $|Z| > 1.96$). **Table A.I.** BD/McCrary Bin-Width Sensitivity (two-sided $\alpha = 0.05$, $|Z| > 1.96$).
@@ -1164,29 +1032,29 @@ Both features are characteristic of a histogram-resolution artifact rather than
Second, the candidate transitions all locate *inside* the high-similarity region (cosine $\geq 0.975$, dHash $\leq 10$) rather than at a between-mode boundary, which is the location pattern we would expect of a clean within-population antimode. Second, the candidate transitions all locate *inside* the high-similarity region (cosine $\geq 0.975$, dHash $\leq 10$) rather than at a between-mode boundary, which is the location pattern we would expect of a clean within-population antimode.
Taken together, Table A.I shows that the signature-level BD/McCrary transitions are not a threshold in the usual sense---they are histogram-resolution-dependent local density anomalies located *inside* the non-hand-signed mode rather than between modes. Taken together, Table A.I shows that the signature-level BD/McCrary transitions are not a threshold in the usual sense---they are histogram-resolution-dependent local density anomalies located *inside* the high-similarity descriptor region rather than between modes.
This observation supports the main-text decision to use BD/McCrary as a density-smoothness diagnostic rather than as a threshold estimator and reinforces the joint reading of Section IV-D that the descriptor distributions do not contain a within-population bimodal antimode that could anchor an operational threshold. This observation supports the main-text decision to use BD/McCrary as a density-smoothness diagnostic rather than as a threshold estimator and reinforces the joint reading of Section IV-D that the descriptor distributions do not contain a within-population bimodal antimode that could anchor an operational threshold.
Raw per-bin $Z$ sequences and $p$-values for every (variant, bin-width) panel are available in the supplementary materials. Raw per-bin $Z$ sequences and $p$-values for every (variant, bin-width) panel are available in the supplementary materials.
## A.2. Diagnostic Summary ## A.2. Diagnostic Summary
Section III-M positions the unsupervised-diagnostic strategy as a set of complementary checks, each addressing one specific failure mode of an unsupervised screening classifier with an explicitly disclosed untested assumption. Table A.II maps each diagnostic to the failure mode it addresses and to the untested assumption it relies on. Section III-N positions the unsupervised-diagnostic strategy as a set of complementary checks, each addressing one specific failure mode of an unsupervised screening classifier with an explicitly disclosed untested assumption. Table A.II maps each diagnostic to the failure mode it addresses and to the untested assumption it relies on.
**Table A.II.** Diagnostics, failure mode addressed, and disclosed untested assumption. **Table A.II.** Diagnostics, failure mode addressed, and disclosed untested assumption.
| Diagnostic | Failure mode addressed | Disclosed untested assumption | | Diagnostic | Failure mode addressed | Disclosed untested assumption |
|---|---|---| |---|---|---|
| Composition decomposition (§III-I.4; Scripts 39b39e) | Whether descriptor multimodality is within-population (mechanism) or between-group (composition + integer artefact); $p_{\text{median}} = 0.35$ under joint firm-mean centring + integer-tie jitter | Integer-tie jitter and firm-mean centring are unbiased over the descriptor support; corroborated by Big-4 per-firm jitter (Script 39d; per-firm dHash rejection disappears under jitter at every Big-4 firm) and Big-4 pooled centred + jittered ($n_{\text{seeds}} = 5$; Script 39e) | | Composition decomposition (§III-K.4; Scripts 39b39e) | Whether descriptor multimodality is within-population (mechanism) or between-group (composition + integer artefact); $p_{\text{median}} = 0.35$ under joint firm-mean centring + integer-tie jitter | Integer-tie jitter and firm-mean centring are unbiased over the descriptor support; corroborated by Big-4 per-firm jitter (Script 39d; per-firm dHash rejection disappears under jitter at every Big-4 firm) and Big-4 pooled centred + jittered ($n_{\text{seeds}} = 5$; Script 39e) |
| Per-comparison inter-CPA coincidence rate (§III-L.1; Script 40b) | Pair-level specificity proxy under a random-pair negative anchor | Inter-CPA pairs are negative (i.e., not template-related); partially violated by within-firm sharing (§III-L.4) | | Per-comparison inter-CPA coincidence rate (§III-I.1; Script 46) | Pair-level specificity proxy under a random-pair negative anchor, on the normative BCD baseline | Inter-CPA pairs are negative (i.e., not template-related); addressed by anchoring on Firms B/C/D and holding Firm A out (§III-I.0) |
| Pool-normalised per-signature ICCR (§III-L.2; Script 43) | Deployed-rule specificity proxy at per-signature unit, accounting for pool size | Same as above + that pool replacement preserves the negative-anchor property | | Pool-normalised per-signature ICCR (§III-I.2; Script 52) | Deployed-rule specificity proxy at per-signature unit, accounting for pool size, on the BCD baseline | Same as above + that pool replacement preserves the negative-anchor property |
| Document-level ICCR (§III-L.3; Script 45) | Operational alarm rate proxy at per-document unit under three alarm definitions | Same as above | | Document-level ICCR (§III-I.3; Script 52) | Operational alarm-rate proxy at per-document unit (HC and HC+MC), on the BCD baseline | Same as above |
| Firm-heterogeneity logistic regression (§III-L.4; Script 44) | Multiplicative effect of firm membership on per-signature rate, controlling for pool size | Per-signature observations are clustered by CPA/firm; naïve standard errors unreliable; cluster-robust analysis is a future check | | Firm-heterogeneity logistic regression (§III-J.1; Script 44) | Multiplicative effect of firm membership on per-signature rate, controlling for pool size | Per-signature observations are clustered by CPA/firm; naïve standard errors unreliable; cluster-robust analysis is a future check |
| Cross-firm hit matrix (§III-L.4; Script 44) | Concentration of inter-CPA collisions within source firm | Concentration depends on deployed-rule semantics (the stricter same-pair joint event yields $97.0$$99.96\%$ within-firm at all four firms versus $76.7$$98.8\%$ under any-pair; §III-L.4); per-document per-firm assignment uses Script 45's mode-of-firms tie-break (§IV-M.4) | | Cross-firm hit matrix (§III-J.1; Scripts 44, 53) | Concentration of inter-CPA collisions within source firm (all-Big-4 and BCD-pool variants) | Concentration depends on deployed-rule semantics (the stricter same-pair joint event yields $97.0$$99.96\%$ within-firm at all four firms versus $76.7$$98.8\%$ under any-pair; §III-J.1); per-document per-firm assignment uses Script 52's dominant-firm rule (§IV-M.4) |
| Alert-rate sensitivity sweep (§III-L.5; Script 46) | Local sensitivity of deployed rule to threshold perturbation | Gradient comparison is descriptive, not a formal plateau test | | Alert-rate sensitivity sweep (§III-K.6; Script 46) | Local sensitivity of deployed rule to threshold perturbation | Gradient comparison is descriptive, not a formal plateau test |
| Convergent score Spearman ranking (§III-K.1; Script 38) | Internal-consistency of three feature-derived per-CPA scores | Scores share underlying inputs and are not statistically independent | | Convergent score Spearman ranking (§III-M.1; Script 38) | Internal-consistency of three feature-derived per-CPA scores | Scores share underlying inputs and are not statistically independent |
| Pixel-identical conservative positive capture (§III-K.4; Script 40) | Trivial sanity check on the conservative positive anchor | Anchor is tautologically captured by any reasonable threshold | | Pixel-identical conservative positive capture (§III-M.4; Script 40) | Trivial sanity check on the conservative positive anchor | Anchor is tautologically captured by any reasonable threshold |
| LOOO firm-level reproducibility (§III-K.3; Scripts 36, 37) | Algorithmic stability of K=2 / K=3 partition across firm folds | Stability is necessary but not sufficient for classification validity | | LOOO firm-level reproducibility (§III-M.3; Scripts 36, 37) | Algorithmic stability of K=2 / K=3 partition across firm folds | Stability is necessary but not sufficient for classification validity |
# Appendix B. Reproducibility Materials # Appendix B. Reproducibility Materials
@@ -1,361 +0,0 @@
# Review Handoff: Abstract and Introduction
Date: 2026-05-15
Target manuscript: `paper/paper_a_v4_combined.md`
Scope reviewed: Abstract and Introduction only
## Overall Assessment
The Abstract and Introduction are substantively strong and defensible. The current argument is clear:
- Regulations require CPA attestation, but digitized PDF workflows make stored-signature reuse operationally easy.
- The problem is not signature forgery; identity is not in dispute. The target is detecting possible image-level reproduction by the legitimate signer or firm workflow.
- The paper avoids claiming validated forensic detection and instead frames the system as an anchor-calibrated screening framework under unsupervised constraints.
- The strongest methodological move is replacing unsupported distributional "natural threshold" logic with anchor-based inter-CPA coincidence-rate (ICCR) calibration.
Recommended disposition: Minor Revision for prose and narrative complexity, not for core empirical weakness.
## Main Reviewer Concern
The Introduction currently explains the methodology shift too explicitly as a research-process or version-history pivot. This is useful internally, but in the submitted paper it may increase complexity and invite reviewers to focus on why earlier versions used a different framing.
The final manuscript should explain the final methodological choice, not the internal research journey.
Keep:
- The descriptor distribution does not support a stable within-population bimodal antimode.
- Apparent multimodality is explained by firm composition and integer mass-point artefacts.
- Mixture fits are descriptive, not threshold-generating.
- Operational rules are characterized using anchor-based ICCR at multiple units.
Reduce or remove:
- "Earlier work in this lineage..."
- "v4.0 contribution..."
- "overturns this reading..."
- "inherited Paper A v3.x..."
- Internal script-heavy provenance in the Introduction.
Detailed provenance belongs in Methodology, Results, Appendix, or reproducibility notes, not in the opening narrative.
## Suggested Rewrite Direction for Introduction Pivot Paragraph
Current issue location: around `paper/paper_a_v4_combined.md`, Introduction paragraph beginning with "The methodological reframing relative to earlier versions..."
Recommended replacement direction:
```text
A key empirical finding is that the descriptor distributions do not support a within-population natural threshold. The apparent multimodality in the Big-4 accountant-level distribution is explained by between-firm location shifts and integer mass-point artefacts on the dHash axis. After firm-mean centring and integer-tie jitter, the pooled dHash dip-test rejection disappears. Within-firm diagnostics likewise do not reveal a stable bimodal antimode. We therefore treat mixture fits as descriptive summaries of firm-compositional structure rather than threshold-generating mechanisms, and calibrate the deployed operating rules using inter-CPA coincidence-rate anchors.
```
This preserves the methodological defense while removing the internal v3-to-v4 story.
## Abstract-Specific Comments
The Abstract is strong but very dense. It is currently optimized for technical reviewers rather than broad readability. That may be acceptable for IEEE Access, but the first sentence has a small grammar/style issue.
Suggested edit:
```text
Regulations require Certified Public Accountants (CPAs) to attest each audit report with a signature, but digitization makes it feasible to reuse a stored signature image across reports -- through administrative stamping or firm-level electronic signing -- thereby undermining individualized attestation.
```
Reason:
- Current wording: "digitization makes reusing ... undermining ..." is grammatically awkward.
- The suggested version makes the causal relation explicit.
No need to remove the final limitation sentence. The sentence "not as a validated forensic detector; no calibrated error rates..." is important and should remain.
## Introduction-Specific Comments
### 1. Keep the legal framing but avoid legal overclaiming
The sentence saying non-hand-signed workflows "may fall within the literal statutory requirement" is acceptable because it is cautious. Do not strengthen it into a legal conclusion.
Preferred style:
- "may fall within"
- "raises substantive concerns"
- "may not represent meaningful individual attestation"
Avoid:
- "violates"
- "illegal"
- "non-compliant"
- "fraudulent"
### 2. Preserve the forgery distinction
The distinction between non-hand-signing detection and signature forgery detection is one of the strongest conceptual contributions. Keep it prominent.
Key idea to preserve:
- Forgery detection asks whether the signer is genuine.
- This paper asks whether the signing act was repeated for each document or a stored image was reused.
### 3. Reduce script/provenance detail in the Introduction
Current paragraph references scripts such as Script 39c and Script 39d. This makes the Introduction read like an internal review memo.
Recommendation:
- Remove or simplify script references from Introduction.
- Keep exact script provenance in Methodology, Results, Appendix B, or supplementary material.
Specific risk:
- The current parenthetical "10 firms tested in Script 39c" is imprecise for jittered-dHash. Script 39c raw dHash tests reject unimodality; the non-Big-4 jittered-dHash no-rejection statement depends on a codex-verified read-only spike on the same substrate.
Safer Introduction wording:
```text
Within-firm diagnostics likewise fail to reveal stable bimodal structure after accounting for integer ties, including in eligible mid/small-firm checks.
```
If provenance must remain:
```text
Within-firm signature-level cosine checks fail to reject in eligible firms, and corresponding jittered-dHash checks fail to reject in Big-4 firms and in a read-only spike on the same mid/small-firm substrate.
```
### 4. Avoid presenting the Introduction as a Results section
The Introduction currently contains many detailed numbers. Some are necessary because the paper is methodological, but the v4 pivot paragraphs are numerically heavy.
Keep headline numbers:
- Dataset size: 90,282 reports, 182,328 signatures, 758 CPAs.
- Big-4 scope: 437 CPAs, 150,442 signatures.
- Key ICCR levels: per-comparison, per-signature, per-document.
- Firm heterogeneity: Firm A 0.62 vs Firms B/C/D 0.09-0.16.
Consider moving or reducing:
- Full script-specific details.
- Too many parenthetical rule semantics in the Introduction.
- Repeated mentions of inherited/v3/v4 framing.
## Recommended Minimum Patch List
1. Fix Abstract first sentence grammar:
```text
digitization makes it feasible to reuse...
```
2. Rewrite the Introduction paragraph that begins with "The methodological reframing relative to earlier versions..." so it describes the final methodological rationale rather than v3-to-v4 revision history.
3. Remove or narrow `Script 39c` provenance in the Introduction because the raw vs jittered dHash distinction is subtle and currently risky.
4. Replace internal-version language across the Introduction:
- Replace "v4.0 adopts..." with "We adopt..."
- Replace "Earlier work in this lineage..." with "A distributional-threshold approach would be inappropriate here because..."
- Replace "inherited Paper A v3.x five-way box rule" with "the deployed five-way box rule" unless historical provenance is essential.
5. Preserve limitation language:
- The paper should continue to say it is not a validated forensic detector.
- The paper should continue to say calibrated error rates cannot be reported without signature-level ground truth.
## Reviewer Bottom Line
The paper should not hide that the distributional threshold path failed; that is actually a methodological strength. But it should present this as a final empirical finding and design rationale, not as a visible research-history correction.
Recommended framing:
```text
Because the observed distribution does not provide a defensible natural threshold, we use ICCR calibration to characterize the deployed operating rules under explicit unsupervised assumptions.
```
This is cleaner, less complex, and more reviewer-facing than the current v3-to-v4 narrative.
## Additional Framing Issue: Are We Giving Thresholds or Not?
A likely reviewer confusion point is whether the paper provides a concrete classifier threshold or merely explains why no defensible threshold can be derived.
The intended answer should be explicit:
- The paper does provide a concrete, reproducible operational classifier.
- The paper does not claim that this classifier is ground-truth-optimal.
- The paper does not claim that the operating thresholds are natural antimodes in the descriptor distribution.
- The paper's calibration contribution is to characterize the deployed rule's inter-CPA coincidence behavior under unsupervised assumptions.
Recommended high-level framing:
```text
We use a fixed, pre-specified five-way operating rule. The present calibration does not derive an optimal threshold; instead, it quantifies the rule's inter-CPA coincidence behavior at per-comparison, per-signature, and per-document units under explicit unsupervised assumptions.
```
Chinese interpretation:
```text
我們有一組明確、可重現的五分類操作規則;本文不是宣稱這組門檻是最佳門檻或自然分界點,而是在沒有 signature-level ground truth 的情況下,用 ICCR 量化這組規則的 specificity-proxy 行為。
```
## Concrete Threshold Language to Make Visible
The manuscript should not bury the actual operating thresholds. Somewhere early in Methodology, and preferably summarized in Introduction, make the rule explicit:
```text
High-confidence non-hand-signed: cosine > 0.95 AND dHash <= 5.
Moderate-confidence non-hand-signed: cosine > 0.95 AND 5 < dHash <= 15.
Other outcomes follow the fixed five-way box rule.
```
If space allows, add a compact sentence:
```text
Thus, the system has explicit decision rules; what remains uncalibrated in the absence of signature-level labels is their true false-positive and false-negative error rate.
```
This directly answers the reviewer question: "Do the authors actually have a classifier?"
## Rewrite Style Recommendation
Avoid language that sounds like the authors are unable to provide thresholds:
- Avoid: "No threshold can be derived."
- Avoid: "The distribution does not support classification."
- Avoid: "We cannot determine a threshold."
Use language that distinguishes operational thresholds from statistically natural or supervised-optimal thresholds:
- Prefer: "The deployed thresholds are operational rules rather than natural antimodes."
- Prefer: "We characterize these rules with ICCR rather than claiming supervised error rates."
- Prefer: "The absence of a distributional antimode motivates anchor-based calibration, not threshold-free analysis."
- Prefer: "The system is a concrete screening classifier with explicit unsupervised calibration limits."
## Reviewer-Facing Answer to the Threshold Question
If the manuscript needs one sentence that resolves the ambiguity, use:
```text
The system therefore uses explicit operating thresholds, but the evidentiary claim attached to those thresholds is limited: they define a reproducible screening rule whose coincidence behavior can be estimated under inter-CPA anchors, not a validated forensic decision boundary with calibrated error rates.
```
This should be the guiding style for Abstract, Introduction, and the start of Methodology.
## Readability Risk: Too Many Diagnostics Can Look Like Methodological Overbuilding
The manuscript's multi-method statistical design increases rigor, but it also creates a readability risk. In the current form, some sections may feel like a defensive accumulation of diagnostics rather than a clean research design.
Reviewer risk:
- The reader may ask: "Are the authors using many methods because the core classifier is unclear?"
- The reader may miss the simple main claim because the paper introduces too many caveats and validation tools early.
- The paper may look like "we used many methods, therefore credible" instead of "each method answers one necessary question."
Recommended main-thread sentence:
```text
We deploy a fixed five-way screening rule and characterize its unsupervised reliability limits using ICCR, after showing that the descriptor distribution does not support a natural threshold.
```
Chinese interpretation:
```text
我們有明確五分類篩檢規則;先證明不能用自然分布切點來當門檻,再用 ICCR 描述這組規則在無標註資料中的可靠性邊界。
```
All methods and diagnostics should serve this main thread.
## Core vs Supporting Diagnostics
Treat the following as core and keep them prominent:
- End-to-end pipeline: VLM -> YOLO -> ResNet -> cosine/dHash.
- Explicit five-way operating rule.
- Composition decomposition showing why the descriptor distribution does not yield a natural threshold.
- ICCR calibration at three units: per-comparison, per-signature, per-document.
- Firm heterogeneity and within-firm collision concentration.
- Ground-truth limitation and no true error-rate claim.
Treat the following as supporting diagnostics and avoid letting them dominate the main narrative:
- K=2 / K=3 mixture fits.
- Three-score Spearman convergence.
- Leave-one-firm-out reproducibility.
- BD/McCrary sensitivity.
- Ten-tool validation table.
- Pixel-identity positive anchor, especially because it is close to tautological for the high-confidence rule.
These supporting diagnostics can stay, but they should be framed as robustness checks, assumption checks, or supplementary evidence, not as independent central contributions.
## Suggested Manuscript Structure for Clarity
Recommended structure for the Methodology / Results narrative:
1. Core Method
Describe the pipeline, descriptor construction, and five-way rule.
2. Why the Threshold Is Operational Rather Than Natural
Use the composition decomposition only. Avoid over-explaining K=3, BD/McCrary, or historical mixture logic here.
3. How the Rule Is Calibrated Without Ground Truth
Explain ICCR and the three reporting units: per-comparison, per-signature, per-document.
4. What the Calibration Reveals
Report firm heterogeneity and within-firm collision concentration.
5. Supporting Diagnostics
Place K=3, Spearman convergence, LOOO, BD/McCrary, and pixel-identity checks here as supporting evidence.
## Rewrite Style for Multi-Method Sections
Avoid:
```text
We apply a multi-tool validation framework consisting of ten diagnostics...
```
This can sound like methodological stacking.
Prefer:
```text
Each supporting diagnostic addresses a specific failure mode: composition artefacts, inter-CPA coincidence, pool-size effects, firm heterogeneity, or positive-anchor capture.
```
Avoid:
```text
The conjunction of ten tools constitutes validation...
```
Prefer:
```text
Together, these diagnostics define the limits of what can be supported without signature-level ground truth.
```
Avoid presenting auxiliary diagnostics before the reader understands the classifier.
Preferred order:
```text
Rule first. Then why not natural threshold. Then ICCR calibration. Then robustness.
```
## Reviewer-Facing Principle
The paper should not read as:
```text
We used many methods, so the result is credible.
```
It should read as:
```text
We use one explicit screening rule. Each statistical diagnostic answers one necessary question about how that rule should be interpreted under unsupervised constraints.
```
This distinction is important for readability and reviewer trust.
-397
View File
@@ -1,397 +0,0 @@
# Review Handoff: Methodology, Results, Discussion, Conclusion
Date: 2026-05-15
Target manuscript: `paper/paper_a_v4_combined.md`
Scope reviewed: §III Methodology, §IV Experiments and Results, §V Discussion, §VI Conclusion
Companion review: `paper/review_handoff_abstract_intro_20260515.md` (Abstract + Introduction)
This handoff continues the same framing principle established for Abstract + Introduction:
> *"One explicit screening rule. Each statistical diagnostic answers one necessary question about how that rule should be interpreted under unsupervised constraints."*
If only the Abstract and Introduction are revised, the manuscript will exhibit tonal mismatch when the reader drops into the body sections, which currently retain internal-version language and a defensive-accumulation framing for the supporting diagnostics. The body must be brought into the same register.
## Overall Assessment
The body sections are substantively defensible. The core empirical results — composition decomposition, anchor-based ICCR at three units, firm heterogeneity logistic, cross-firm hit matrix, alert-rate sensitivity — are presented in adequate quantitative detail with explicit unsupervised-validation caveats. The Discussion correctly distinguishes positive and negative anchors. The Conclusion lists eight methodological contributions that map onto the v4 contribution set.
The recurring weakness across §III / §IV / §V / §VI is *not* empirical. It is two intertwined narrative tendencies:
1. The body is still written as a *revision history* relative to v3.x in many paragraphs — "v4.0 strengthens", "v4.0 retroactively reframes", "v4.0 adopts", "inherited from v3.x", "the v3.x role of Firm A". This is internally honest but, in a submitted paper, signals to the reviewer that the authors are arguing with themselves.
2. The supporting diagnostics are repeatedly presented as a *collection* ("multi-tool framework", "ten-tool unsupervised-validation collection", "Table XXVII"). This collection framing is precisely the readability risk identified in the Abstract / Introduction handoff under "Readability Risk: Too Many Diagnostics Can Look Like Methodological Overbuilding." It currently appears unmodified in §III-M.
Recommended disposition: Minor Revision for narrative voice and structural emphasis, not for empirical weakness.
## Main Reviewer Concerns
### 1. The v3-to-v4 revision narrative is pervasive in the body and must be removed
The Abstract / Introduction handoff identified "v4.0 adopts", "Earlier work in this lineage", and "inherited Paper A v3.x five-way box rule" as patterns to strip. The same patterns occur throughout the body sections. Representative instances (not exhaustive):
- §III-G: "We earlier (v4.0 first draft) listed 'statistical multimodality at the accountant level' among the scope justifications..."
- §III-H opening: "v4.0 distinguishes two reference populations in its calibration, replacing v3.x's single-anchor framing."
- §III-I.5 closing sentence: "§III-L develops the v4.0 anchor-based threshold calibration framework..."
- §III-L.0 "Why retained without v4.0 recalibration" subsection title.
- §III-L.7 closing: "The operational classifier of §III-L.0 is the inherited v3.x five-way box rule..."
- §IV opening paragraph: "The v4.0 primary analyses (§IV-D through §IV-J) are scoped to..." and "§IV-A through §IV-C report inherited corpus-wide v3.x material; §IV-L (feature backbone ablation) is also inherited. §IV-M consolidates the v4-new anchor-based ICCR calibration tables."
- §IV-I: "v4.0 retroactively reframes the metric as inter-CPA pair-level coincidence rate (ICCR) rather than 'False Acceptance Rate'..."
- §IV-J: "v4.0 does not change this aggregation rule; only the population over which it is computed changes (Big-4 subset)."
- §IV-M opening: "v4-new empirical results that support..."
- §V-B: "A central empirical finding of v3.x was that per-signature similarity does not admit a clean two-mechanism mixture... v4.0 strengthens and extends this signature-level reading."
- §V-C: "In v4.0 we treat Firm A as a templated-end case study rather than as the calibration anchor for the operational threshold."
- §V-H opening: "The first nine are v4.0-specific; the last five are inherited from v3.20.0 §V-G and still apply to the v4.0 pipeline."
The remediation principle is the same as for the Introduction pivot paragraph. The final manuscript should describe the *final methodological state* and its rationale, not the trajectory by which that state was reached. Internal provenance — "this analysis is reproduced from v3.x §IV-F.1 / Script 28" — belongs in an Appendix B reproducibility table or supplementary material, not in the main narrative arc.
A safe rewriting heuristic: every sentence that begins with "v4.0", "v3.x", "v4-new", "inherited", or "earlier work" should be candidated for either deletion or rewriting in the present tense without version labels.
### 2. The "Ten-Tool Unsupervised-Validation Collection" frame must be retired
§III-M Table XXVII is the canonical instance of the readability risk that the Abstract / Introduction handoff flagged. The current frame is:
> "v4.0 adopts a multi-tool collection of partial-evidence diagnostics (Table XXVII), each with an explicitly disclosed assumption..."
> "No single tool in this collection provides ground-truth validation. Their conjunction constitutes the unsupervised validation ceiling that the v4.0 corpus admits."
This is exactly the language the Abstract / Introduction handoff identified as risky ("We used many methods, so the result is credible"). It reappears verbatim in the §VI Conclusion as "a multi-tool framework for characterising and disclosing its operational behaviour at the Big-4 sub-corpus scope" and "(8) a ten-tool unsupervised-validation collection (§III-M Table XXVII) that explicitly discloses each tool's untested assumption."
The recommended reframe is:
```text
The corpus does not admit standard supervised classifier validation: no signature-level
ground truth exists for hand-signed versus replicated classes, so False Rejection Rate,
sensitivity, recall, EER, ROC-AUC, precision, and positive predictive value are not
reportable. Each diagnostic in this section therefore addresses one specific
failure mode of an unsupervised screening classifier: composition artefacts,
inter-CPA coincidence, pool-size confounding, firm heterogeneity, threshold
sensitivity, or positive-anchor capture. Together they characterise the limits of
what can be claimed without signature-level ground truth.
```
Keep Table XXVII as a reference table if useful, but retitle it as "Diagnostic — failure mode addressed — disclosed assumption" rather than "Ten-tool collection". The word "ten" should not appear in the manuscript.
### 3. The §V-H Limitations list is correct but defensively ordered
§V-H lists fourteen limitations. The first one — "No signature-level ground truth; no true error rates reportable" — is the load-bearing limitation that everything else in v4.0 hinges on. The next two — "Inter-CPA negative-anchor assumption is partially violated" and "Scope" — are also major. The other eleven are real but secondary. The current presentation gives every item roughly equal visual weight as a flat list.
Recommended reorganisation:
- *Primary limitations (3 items):* (a) no signature-level ground truth, (b) inter-CPA negative-anchor assumption partially violated and firm-dependent, (c) Big-4 scope (full-dataset robustness is light).
- *Secondary limitations (4 items):* pixel-identity conservative subset; inherited rule components not separately v4-validated; deployed-rate excess not a true-positive rate; A1 pair-detectability stipulation.
- *Documented features rather than limitations (2 items):* K=3 hard-posterior composition sensitivity; no partner-level mechanism attribution.
- *Inherited engineering limitations (5 items):* ImageNet features, red-stamp HSV preprocessing, longitudinal scan / PDF / compression, source-exemplar misattribution, legal interpretation.
This preserves the disclosures but signals to the reviewer which limitations carry the methodological weight and which are routine engineering caveats.
### 4. §III-F SSIM and pixel-comparison justification is too long for Methodology
§III-F currently dedicates roughly 15 lines (lines 112127 in `paper_a_methodology_v3.md`) to justifying *why* SSIM and pixel-level comparison are not used as primary descriptors. The argument is correct (design-level mismatch between SSIM's natural-image quality factors and signature-crop artefacts; sub-pixel alignment fragility of pixel L1/L2), but in its current form it reads as a defensive response to an anticipated reviewer objection rather than as forward Methodology exposition.
Recommended reduction: collapse the argument to one short paragraph (34 sentences) and move the full design-level discussion to Appendix B. The Methodology body should state the choice (cosine on deep features + dHash) and briefly justify it (both stable across print-scan cycles by design), with the SSIM / pixel-comparison rebuttal in an appendix or a single citation footnote.
### 5. §IV's section opener still encodes provenance not appropriate to a Results section opener
The current §IV opener:
> "The v4.0 primary analyses (§IV-D through §IV-J) are scoped to the Big-4 sub-corpus (Firms AD, n = 437 CPAs with n_sig ≥ 10, totalling 150,442 signatures with both descriptors available) per the methodology choice articulated in §III-G. The §IV-K Full-Dataset Robustness section reports the full-dataset (686 CPAs) variant of the K=3 mixture + Paper A box-rule Spearman analysis as a cross-scope robustness check. §IV-A through §IV-C report inherited corpus-wide v3.x material; §IV-L (feature backbone ablation) is also inherited. §IV-M consolidates the v4-new anchor-based ICCR calibration tables."
Recommended replacement direction:
```text
Section IV reports the empirical results that calibrate and characterise the
operational classifier of §III-L. The primary analyses (§IV-D through §IV-J,
§IV-M) are scoped to the Big-4 sub-corpus (Firms AD, 437 CPAs, 150,442
signatures); §IV-K reports a full-dataset (686 CPAs) robustness check on the K=3
mixture and per-CPA score-rank convergence; §IV-A through §IV-C and §IV-L
report the corpus-wide pipeline performance and feature-backbone ablation that
support the descriptor choice of §III-F.
```
This preserves the scope information while removing the v3-to-v4 inheritance labels and the "v4-new" prefix on §IV-M.
## Section-by-Section Comments
### §III-A Pipeline Overview
The pipeline diagram caption (lines 1220) describes the classifier as "Firm A P7.5-anchored", which is residual v3 language that conflicts with the v4 reframe. v4 explicitly abandons Firm A as the calibration anchor in favour of inter-CPA ICCR (§III-H, §III-L). The figure caption should be updated to read "Anchor-Calibrated Five-Way Classifier" or similar, consistent with the §III-L title "Anchor-Based Threshold Calibration and Operational Classifier".
The §III-A second paragraph ("Throughout this paper we use the term non-hand-signed rather than 'digitally replicated'...") is well-positioned and should be kept.
### §III-B Data Collection
No issues identified.
### §III-C Signature Page Identification
No issues identified. The 98.8% VLM-YOLO agreement footnote is appropriately scoped ("we do not attempt to attribute the residual").
### §III-D Signature Detection
No issues identified.
### §III-E Feature Extraction
No issues identified.
### §III-F Dual-Method Similarity Descriptors
As noted in Main Concern 4: shorten the SSIM and pixel-comparison rebuttal to ~34 sentences and move full design-level argument to Appendix B.
### §III-G Unit of Analysis and Scope
This section is currently long and contains the "We earlier (v4.0 first draft) listed..." paragraph that explicitly walks through the methodological revision. That paragraph (currently at the end of §III-G, before the sample-size reconciliation) should be deleted. The four-item scope rationale list above it is good and should be kept.
The sample-size reconciliation paragraph (n=150,442 vs n=150,453) is technically necessary but is repeated almost verbatim in §IV-J as a parenthetical. Consider centralising it in §III-G with a forward reference, or in an Appendix B reproducibility note.
### §III-H Reference Populations
Replace the opening sentence:
> "v4.0 distinguishes two reference populations in its calibration, replacing v3.x's single-anchor framing."
with:
```text
The calibration distinguishes two reference populations: Firm A as a within-Big-4
templated-end case study, and the 249 non-Big-4 CPAs as an out-of-target reference
for internal-consistency checking.
```
The remainder of §III-H is well-written; the descriptive content is fine. The "v3.x's single-anchor framing" phrase is the only internal-version language that needs removal.
### §III-I Distributional Diagnostics
This is the strongest single section in the body. The four sub-diagnostics (dip test, mixture, BD/McCrary, composition decomposition) are tightly organised around one claim: the descriptor distribution does not provide a within-population bimodal antimode. The 2x2 factorial table at §III-I.4 is the empirical centrepiece of the v4 reframe.
One small narrative issue: §III-I.5 ("Conclusion") closes with "§III-L develops the v4.0 anchor-based threshold calibration framework, which derives operational rates from inter-CPA pair-level negative-anchor coincidences rather than from a distributional antimode." Remove "v4.0" — write "§III-L develops the anchor-based threshold calibration framework..."
### §III-J K=3 as a Descriptive Partition of Firm-Composition Contrast
The section header is clear and the framing ("Both fits are descriptive partitions... not within-population mechanism modes") is correct.
The current closing paragraph references "§III-K" for cross-checks between the box rule and K=3, but §III-K is the next subsection — this is a within-Methodology forward reference and reads slightly oddly. Consider rephrasing as "Cross-checks between the inherited five-way box rule and the K=3 partition appear in §III-K below."
### §III-K Convergent Internal-Consistency Checks
This section is well-handled. The opening caveat — "the three scores are not statistically independent measurements... so their high pairwise rank correlations are partly a mechanical consequence of shared inputs" — is exactly the methodological honesty the v4 reframe needs.
One narrative issue: §III-K.4 (positive-anchor miss rate) and §III-K.3 (LOOO reproducibility) are *summarised* in §III-K but also reported in detail in §III-J and §IV-G respectively. Consider whether the §III-K subsections add narrative value beyond cross-referencing — if not, §III-K could shrink to just the three-score Spearman block (§III-K.1) and a one-line cross-reference to LOOO and pixel-identity, with the detail living in §III-J and §IV-G / §IV-H.
### §III-L Anchor-Based Threshold Calibration and Operational Classifier
This section has the operating-rule text that the Abstract / Introduction handoff explicitly asked for ("Cosine > 0.95 AND dHash ≤ 5" etc., §III-L.0 item 1). Good.
The "Terminological note on FAR" at the end of §III-L.0 is explicit and reviewer-facing. Keep it.
Issues:
- "Why retained without v4.0 recalibration" — replace subsection title and contents to remove v4 references. The argument ("the inherited thresholds preserve continuity with prior reporting; §III-I.4 establishes that recalibration cannot be anchored on distributional antimodes; §III-L.1 confirms the cosine threshold's specificity at the inter-CPA pair level is reproducible") is intact without the v4 label.
- §III-L.7 ("K=3 not used as classifier") restates content already in §III-J. Consider deleting §III-L.7 and adding a one-line note inside §III-L.0 ("The K=3 mixture of §III-J is used as an accountant-level descriptive summary alongside the per-signature five-way classifier; K=3 hard-posterior membership is not used to assign signature-level or document-level labels in any result table").
### §III-M Validation Strategy and Limitations under Unsupervised Setting
Replace the framing as described in Main Concern 2. Keep the underlying disclosure content. Consider whether Table XXVII is best presented as a numbered methodological table or as an Appendix B reproducibility-and-assumption summary; in either case retitle and reframe so that "ten" does not appear and the unifying principle is "each diagnostic addresses one specific unsupervised failure mode."
The "What v4.0 does not claim" and "What v4.0 does claim" subsections at the end of §III-M are strong but the framing tag "v4.0 does not claim" / "v4.0 does claim" is the problematic version-language pattern. Replace with "Limits of the present analysis" and "Scope of the present analysis."
### §III-N Data Source and Firm Anonymization
No issues. The residual-identifiability disclosure is appropriately framed.
### §IV-A Experimental Setup
No issues identified.
### §IV-B Signature Detection Performance
No issues identified.
### §IV-C All-Pairs Intra-vs-Inter Class Distribution Analysis
The pairwise-non-independence caveat ("we therefore rely primarily on Cohen's d... A Cohen's d of 0.669 indicates a medium effect size, confirming that the distributional difference is practically meaningful, not merely an artifact of the large sample count") is well-positioned. Keep.
### §IV-D Big-4 Accountant-Level Distributional Characterisation
The Table V dip-test row labels are clear. The "v4-new composition-decomposition diagnostics that establish this finding are tabulated in §IV-M below alongside the anchor-based ICCR calibration" should drop the "v4-new" — just write "...are tabulated in §IV-M below alongside the anchor-based ICCR calibration."
### §IV-E Big-4 K=2 / K=3 Mixture Fits
The "descriptive partition; not mechanism clusters per §III-J" labels in Tables VII and VIII are consistent with the v4 reframe. Keep. Drop "(v3.x role)" anywhere it appears.
### §IV-F Convergent Internal-Consistency Checks
This is duplicate Results-side reporting of §III-K. Consider whether the duplication adds value or is redundant. If both sections must remain, then §III-K should describe the *method* (three scores, why they are not independent) and §IV-F should report the *numbers*; currently §III-K reports both the method and the numbers, leaving §IV-F as a near-duplicate. Recommendation: trim §IV-F to just the per-firm summary table and the Cohen-kappa block, with the method description living in §III-K.
### §IV-G Leave-One-Firm-Out Reproducibility
Tables XII and XIII are well-organised. The interpretation paragraph following Table XIII correctly identifies the K=2 vs K=3 contrast (K=2 unstable; K=3 component shape reproducible but hard-posterior membership composition-sensitive). Keep.
### §IV-H Pixel-Identity Positive-Anchor Miss Rate
The "close to tautological" caveat is appropriately positioned. Keep. The reverse-anchor cut by prevalence calibration disclosure is also appropriate.
### §IV-I Inter-CPA Pair-Level Coincidence Rate
Replace:
> "v4.0 retroactively reframes the metric as inter-CPA pair-level coincidence rate (ICCR) rather than 'False Acceptance Rate' because..."
with:
```text
The metric reported here is the inter-CPA pair-level coincidence rate (ICCR). It
is the per-pair rate at which two signatures from different CPAs satisfy the
deployed rule. We do not label it as a False Acceptance Rate because (a) FAR has
a biometric-verification meaning that requires ground-truth negative labels, and
(b) the inter-CPA negative-anchor assumption is partially violated by within-firm
cross-CPA template-like collision structures (§III-L.4 cross-firm hit matrix).
```
### §IV-J Five-Way Per-Signature + Document-Level Classification Output
The sample-size reconciliation parenthetical ("11 of 150,453 loaded Big-4 signatures lacked one or both descriptors and were excluded") is repeated from §III-G. Centralise once and forward-reference.
"v4.0 does not change this aggregation rule; only the population over which it is computed changes" should be "The aggregation rule is the inherited worst-case rule (HC > MC > HSC > UN > LH); we apply it to the Big-4 sub-corpus."
The MC band capture-rate inheritance disclosure is appropriately framed but should drop the "v4.0 does not re-derive" phrasing; rewrite as "The moderate-confidence band's calibration and capture-rate evidence is reported in [Appendix B / v3.20.0 Tables IX, XI, XII, XII-B] and is not regenerated on the Big-4 subset."
### §IV-K Full-Dataset Robustness
The scope-of-§IV-K paragraph ("The scope of §IV-K is deliberately narrow: we re-run only the K=3 mixture + Paper A operational-rule per-CPA less-replication-dominated rate analysis...") is defensively framed but the substance is correct. Consider shortening the "what we do not do" enumeration and emphasising the "what we do show" finding (K=3 + Paper A box-rule Spearman convergence preserved at full scope; ρ drift = 0.007).
### §IV-L Feature Backbone Comparison
This is inherited v3.x content. The "inherited unchanged from the v3.20.0 backbone-ablation table" framing is acceptable here because it is a methodological choice (do not re-run the ablation at the Big-4 scope) rather than a narrative pivot. Keep.
### §IV-M v4-New Anchor-Based ICCR Calibration Results
Drop the "v4-new" from the section heading. Recommended replacement heading: "Anchor-Based ICCR Calibration Results".
The section is empirically dense and methodologically sound. Tables XXIXXVI cover the four units (per-comparison, per-signature, per-document, firm logistic + hit matrix) and the alert-rate sensitivity. Keep all tables. Drop "v4 new" / "v4-new" wherever it appears as a row qualifier or section subheading.
### §V-A Non-Hand-Signing Detection as a Distinct Problem
Keep. This section preserves the forgery distinction (Main concern #2 in the Abstract / Introduction handoff).
### §V-B Per-Signature Similarity is a Continuous Quality Spectrum
Replace the v3-to-v4 opening:
> "A central empirical finding of v3.x was that per-signature similarity does not admit a clean two-mechanism mixture: dip-test fails to reject unimodality at the signature level for Firm A, BIC prefers a 3-component fit, and BD/McCrary candidate transitions lie inside the high-similarity mode rather than between modes. v4.0 strengthens and extends this signature-level reading."
with:
```text
The Big-4 accountant-level descriptor distribution rejects unimodality on both
marginals at p < 5 × 10⁻⁴ (§IV-D Table V). The composition decomposition of
§III-I.4 (Scripts 39b39e) shows this rejection is fully attributable to two
non-mechanistic sources...
```
This preserves the §V-B content while removing the v3.x lineage statement.
### §V-C Firm A as the Templated End of Big-4
Replace "In v4.0 we treat Firm A as a templated-end case study rather than as the calibration anchor for the operational threshold" with "We treat Firm A as a templated-end case study within the Big-4 sub-corpus rather than as the calibration anchor for the operational threshold."
Drop the "the v3.x role of Firm A" historical sub-clause that appears in §III-G item 2.
The Firm A byte-level pixel-identity reference (145 signatures across ~50 distinct partners; 35 byte-identical matches across fiscal years) is inherited from v3.x §IV-F.1 / Script 28 — this byte-level granularity is the strongest single piece of v3.x evidence that *should* survive into v4 because it directly supports the §V-C templated-end characterisation. Keep the reference but recast as "Byte-level decomposition of these 145 signatures (Appendix B) shows..." rather than the current "The additional v3.x finding... is inherited from v3.20.0 §IV-F.1 / Script 28..."
### §V-D K=2 / K=3 as Descriptive Firm-Compositional Partitions
Keep. The contrast between K=2 instability and K=3 reproducible-component-shape-but-composition-sensitive-membership is one of the cleanest narrative arcs in the paper.
### §V-E Three-Score Convergent Internal-Consistency
Keep. The "not statistically independent" caveat is correctly positioned. The within-Big-4 non-Firm-A disagreement between Score 2 and Scores 1/3 is correctly disclosed.
### §V-F Anchor-Based Multi-Level Calibration
Keep. This is the v4 contribution. Drop any residual "v4" labels.
### §V-G Pixel-Identity as a Hard Positive Anchor; Inherited Inter-CPA Negative Anchor
Keep. The "positive necessary but not sufficient" caveat and the "specificity proxy under a partially-violated assumption" framing are exactly right.
Drop "Inherited" from the §V-G section heading — the heading currently reads "Pixel-Identity as a Hard Positive Anchor; Inherited Inter-CPA Negative Anchor Reframed as Coincidence Rate", which encodes the v3-to-v4 history in the section title itself. Recommended: "Pixel-Identity Positive Anchor and Inter-CPA Coincidence-Rate Negative Anchor".
### §V-H Limitations
Reorganise as described in Main Concern 3: primary (3) / secondary (4) / documented features (2) / inherited engineering (5).
Drop "inherited from v3.20.0 §V-G" qualifiers — the limitation either applies to the pipeline or it does not; the version source is reproducibility metadata that belongs in Appendix B.
### §VI Conclusion
Replace the opening framing:
> "We present a fully automated pipeline for detecting non-hand-signed CPA signatures in Taiwan-listed financial audit reports and a multi-tool framework for characterising and disclosing its operational behaviour at the Big-4 sub-corpus scope."
with:
```text
We present a fully automated pipeline for detecting non-hand-signed CPA
signatures in Taiwan-listed financial audit reports, together with an
anchor-calibrated screening framework that characterises the pipeline's
operational behaviour at the Big-4 sub-corpus scope under explicit unsupervised
assumptions.
```
The eight numbered contributions are content-correct but presented in flat-list form. Consider grouping into three thematic clusters:
- *Why the descriptor distribution does not anchor a natural threshold* (contributions 1, 5).
- *How the deployed rule is calibrated under unsupervised constraints* (contributions 2, 6, 7).
- *What the calibration reveals about firm heterogeneity* (contributions 3, 4).
- *Methodological positioning* (contribution 8 — but reframe per Main Concern 2).
The Future Work block (four items) is fine; consider trimming the second item ("a separate study to distinguish deliberate template sharing from passive firm-level production artefacts") which is the only item that involves additional fieldwork rather than methodological extension.
## Recommended Minimum Patch List
1. Strip v3-to-v4 revision language throughout §III, §IV, §V, §VI. Mechanical pass on "v4.0", "v3.x", "v4-new", "inherited", "earlier work in this lineage". Replace with present-tense descriptions of the final methodological choice and forward references to Appendix B for reproducibility provenance.
2. Retire the "ten-tool unsupervised-validation collection" framing in §III-M and the "multi-tool framework" phrase in §VI Conclusion. Replace with "each diagnostic addresses one specific unsupervised failure mode" framing. Retitle Table XXVII so that "ten" does not appear.
3. Reorganise §V-H Limitations into primary / secondary / documented-features / inherited-engineering groupings.
4. Shorten §III-F SSIM and pixel-comparison rebuttal to ~34 sentences; move design-level discussion to Appendix B.
5. Update Figure 1 caption (currently in §III-A commented HTML) to remove "Firm A P7.5-anchored" residual v3 language.
6. Rewrite the §IV opener paragraph to remove the inherited-vs-v4-new section labels.
7. Rewrite the §IV-I opening paragraph to remove "v4.0 retroactively reframes the metric...".
8. Drop "v4-new" from the §IV-M section heading; replace with "Anchor-Based ICCR Calibration Results".
9. Centralise the n=150,442 vs n=150,453 sample-size reconciliation in §III-G; remove the duplicate parenthetical from §IV-J.
10. Consider trimming §IV-F to numbers-only (per-firm summary table + Cohen kappa), with the method description living in §III-K.
11. Consider deleting §III-L.7 (duplicate of §III-J K=3-not-used-as-classifier claim) and adding a one-line note in §III-L.0.
## Reviewer Bottom Line
The body sections of v4 are empirically defensible and methodologically internally consistent. The required revisions are stylistic and structural rather than substantive:
- Remove the v3-to-v4 revision narrative from the present-tense exposition.
- Reframe the supporting diagnostics from "ten-tool collection" to "each diagnostic addresses one unsupervised failure mode."
- Reorganise the limitations list so that the load-bearing limitations are visibly more prominent than the routine engineering caveats.
- Move provenance and reproducibility detail to Appendix B / supplementary material.
These changes preserve every quantitative claim and every disclosure currently in the manuscript. They tighten the narrative voice so that the reader experiences the v4 methodological choices as the final state of the design rather than as an ongoing argument with an earlier version. Combined with the Abstract / Introduction patches in the companion handoff, the manuscript should read as a single coherent submission rather than as a layered revision document.
## Additional Cross-Cutting Observation: Script Provenance in Tables
Across §III, §IV, §V, and the Conclusion, tables are annotated with `(Source: Script 32 / 34 / 35 / 38 / 40b / 43 / 44 / 45 / 46)` parentheticals. This is appropriate for reproducibility but heavy at the visual level — every table footer in §IV-D through §IV-M carries one of these annotations.
Recommended consolidation: move the script-to-table mapping to a single Appendix B reproducibility table ("Table B-1. Script-to-table provenance map"), and replace the inline annotations with a single one-line note at the start of §IV ("Script-to-table provenance is summarised in Appendix B Table B-1; raw outputs are available in the supplementary repository").
This is a minor change but it materially reduces the visual signal that the paper is built on a large number of separate scripts.
## Closing Note
This review covers the body sections only. The Abstract / Introduction handoff (`paper/review_handoff_abstract_intro_20260515.md`) covers the front matter. The two handoffs should be applied together; applying only one of them will produce tonal mismatch as the reader moves from the front matter into the body.
The References and the Appendix have not been reviewed and may benefit from a separate handoff if the Appendix is to absorb the SSIM / pixel-comparison material and the reproducibility-provenance table recommended above.
@@ -0,0 +1,95 @@
# Canonical number set — Paper A v13 rev9.1 (verified 2026-06-30)
Source of truth: `signature_analysis.db` (`/Volumes/NV2/PDF-Processing/signature-analysis/`).
Verified against scripts in `paper/v13_build/scripts/`. All firm-level signature counts and
within-accountant HC rates below are DB-reproduced to 2 decimals.
## ROOT CAUSE of the "Firm C/D two-snapshot" inconsistency
It is **NOT** a stale snapshot. It is **two live firm-assignment keys** used inconsistently:
| Key | Definition | C | D | total |
|---|---|---|---|---|
| **assigned** (canonical) | `assigned_accountant → accountants.firm` (registry firm) | 38,613 | 17,133 | **150,442** |
| excel | `excel_firm` column (source Excel metadata) | 38,993 | 16,752 | 150,441 |
Difference = **379 signatures with excel_firm=資誠(C) but registry firm=安永(D)** (one/few
cross-labeled accountants). A and B are identical under both keys. Because the headline
contrast pools B/C/D, the swap is invisible to it (FE/LOYO/bootstrap reproduce exactly under
either key); only **per-firm-separated tables** (IV, II-b, II-c, VI) are affected.
DECISION: standardize on the **assigned** key — it is what headline Table IV/II-b already use.
## "Analyzable signatures" definition (reproduces 150,442 exactly)
Analyzable = signature whose CPA has **≥2 signatures** (singleton CPAs have no same-accountant
partner). Per-firm singletons (A:2, B:6, C:3, D:0) exactly equal rawSet A.
## Canonical signature counts (assigned key)
| Firm | Full 201323 | 201319 | 202023 |
|---|---|---|---|
| A | 60,448 | 36,550 | 23,898 |
| B | 34,248 | 19,677 | 14,571 |
| C | 38,613 | 22,449 | 16,164 |
| D | 17,133 | 9,945 | 7,188 |
| Big-4 | **150,442** | 88,621 | 61,821 |
Every row sums exactly. (excel-key alternatives, do NOT use for per-firm tables:
C 202023 = 16,485, D 202023 = 6,866 — these are what the stale Table II-c rows show.)
## Five-way breakdown (HC | MC | HSC | UN | LH | n), low cut = 0.8547
FULL 20132023 (Table IV):
- A: 81.70 | 10.76 | 0.05 | 7.35 | 0.14 | 60,448
- B: 34.56 | 35.88 | 0.29 | 28.95 | 0.32 | 34,248
- C: 23.75 | 41.44 | 0.38 | 33.97 | 0.47 | 38,613
- D: 24.51 | 29.33 | 0.22 | 45.28 | 0.66 | 17,133
- Overall: 49.58 | 26.47 | 0.21 | 23.42 | 0.32 | 150,442
20132019 (Table II-b):
- B: 29.04 | 39.31 | 0.39 | 30.91 | 0.35 | 19,677
- C: 21.59 | 42.09 | 0.37 | 35.53 | 0.43 | 22,449
- D: 22.01 | 29.67 | 0.20 | 47.35 | 0.76 | 9,945
20202023 (Table II-c) — **C/D are the fix**:
- A: 83.84 | 9.13 | 0.04 | 6.88 | 0.11 | 23,898
- B: 42.01 | 31.24 | 0.16 | 26.31 | 0.28 | 14,571
- C: **26.74 | 40.55 | 0.40 | 31.80 | 0.51 | 16,164** (manuscript stale: 26.53/.../16,485)
- D: **27.98 | 28.85 | 0.24 | 42.42 | 0.51 | 7,188** (manuscript stale: 28.53/.../6,866)
Per-firm period HC rates (§IV-C text / Fig 5 — already CORRECT in manuscript):
A 80.3→83.8, B 29.0→42.0, C 21.6→26.7, D 22.0→28.0.
## Table VI (any-pair vs same-pair HC) under assigned key
| firm | n | any-pair% | same-pair% |
|---|---|---|---|
| A | 60,448 | 81.7 | 57.3 |
| B | 34,248 | 34.6 | 9.0 |
| C | 38,613 | 23.7 | 5.3 |
| D | 17,133 | 24.5 | 7.7 |
| all | 150,442 | 49.6 | 27.3 |
(Manuscript currently shows excel-key: C 38,993, D 16,752, all 150,441, D any-pair 24.7.)
## Accountant counts (R2) — reviewer's "179 > 171 impossible" is a FALSE POSITIVE
Different keys, not a contradiction:
- Bootstrap/FE (`accountant_id`, is_valid): **A=179** (reproduces exactly), BCD=281 (manuscript 280).
- Table III / accountant-level partition (171/112/102/52 = 437): RESOLVED 2026-06-30 — this is the
Big-4 accountants with **≥10 signatures** (registry key), reproduces EXACTLY on current DB.
GMM recipe: accountant point = (mean max_similarity_to_same_accountant, mean min_dhash_independent);
sklearn GaussianMixture(n_components=3, covariance_type='full', random_state=42, n_init=10);
templated cluster = highest-cosine component (cos 0.983 / dHash 2.4). Shares reproduce to the digit:
A=82.5% (141/171), B=0.0% (0/112), C=1.0% (1/102), D=1.9% (1/52). Script: scratchpad/gmm.py.
- Analyzable accountant count (registry name key, ≥2 sig) = 457 (A=178, B=119, C=107, D=53) — owns
the 150,442 signatures; now stated in Table I and the §III-B prose.
THREE DISTINCT, ALL-REPRODUCIBLE accountant universes (the reviewer collapsed them → false "179>171"):
457 (≥2 sig, owns 150,442) | 437 (≥10 sig, Table III GMM) | 459 = 179/280 (accountant_id bootstrap).
Manuscript edits applied 2026-06-30: Table I + §III-B prose → 457; §III-B prose + Table III caption
note the 437/≥10-sig subset. Bootstrap 179/280 stays (correct, key-invariant).
## F5 robustness (re-validated EXACTLY on current DB, key-invariant)
Firm+Year FE ORs: B=0.116, C=0.061, D=0.070. LOYO gap range [53.1, 54.9]pp, full-sample 53.7pp.
Binary file not shown.

After

Width:  |  Height:  |  Size: 55 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 48 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 69 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 96 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 96 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 109 KiB

+499
View File
@@ -0,0 +1,499 @@
# Anchor-Calibrated, Label-Free Screening of Non-Hand-Signed Signatures in Large-Scale Audit Reports
*(Authors removed for double-blind review)*
## Abstract
An audit report must carry each certifying accountant's signature as the mark of an individual act of endorsement, yet in digital workflows a saved image can instead be pasted onto many reports — by stamping or by an automated signing system — producing what we term non-hand-signed signatures. The signer is genuine; the question is whether signing occurred for each report, and at archive scale this carries no labels. We present a label-free screening system and apply it to 86,071 Taiwanese statutory audit reports (20132023), within which the four largest firms contribute 150,442 analyzable signatures. The system finds the signature page, detects signatures, extracts deep features, and computes two similarities to the same accountant's other signatures — a style cosine and a perceptual-hash (dHash) structural distance — on the logic that a consistent hand keeps style high while structure varies, whereas a reused image keeps both extreme. With no labels and no natural gap in the data (a unimodality test gives median p = 0.35 once firm effects and the hash's integer steps are removed), no cutoff can be learned; instead we calibrate a five-way rule by how often it fires by chance between unrelated accountants in a clean reference group (non-Firm-A firms, 20132019), where the strict rule fires on about 1.2% of reports and a looser advisory band on about 17.5%. Held out as a known-positive benchmark — one firm independently described by interviews as a stamping firm (a confirmatory check, not a blind test) — it fires the strict rule on 82% of its own signatures against 2435% elsewhere, with its cross-firm rate at the clean floor, so the signal is entirely within-firm; the contrast survives pool-size stratification and accountant-level resampling, and 262 byte-identical signatures are direct evidence of reuse. The screen thus locates where reuse concentrates and confines human review to exceptions. We report a between-accountant specificity proxy — not a within-accountant error rate, nor a bound on one — and we neither separate signing practice from a firm's imaging pipeline nor label any single signature. Calibrated on a large Chinese-signature corpus with script-agnostic descriptors, it serves as an operator-set reference point for comparable pipelines.
**Keywords:** signature analysis, document forensics, perceptual hashing, deep features, unsupervised calibration, audit reports, anchor-based screening.
## I. Introduction
An audit report is one of the main ways a company is held accountable to investors, and the certifying accountant's signature is the visible sign that a named professional takes responsibility for it. In Taiwan, the Certified Public Accountant Act and the attestation rules of the Financial Supervisory Commission require certifying CPAs to put their signature or seal on each audit report [1]. The law accepts either a handwritten signature or a seal, but the point of the requirement is the same in both cases: the mark on each report should stand for a deliberate, individual act of endorsement for that particular engagement [2].
Going digital makes that harder to guarantee. Because reports are now created, sent, and stored as electronic files, it is easy to copy an accountant's saved signature image onto many reports instead of signing each one. This can happen in two ways: a staff member can overlay a scanned signature onto the finished report (a stamping workflow), or a firm-wide electronic-signing system can do the same step automatically. We call signatures produced either way non-hand-signed. To fix the term operationally before any method is introduced: a signature is *non-hand-signed* when the mark on the report is a reproduction of a stored signature image rather than a fresh signing act for that engagement. This spans manual overlay (stamping), automated firm-wide e-signing that pastes a saved image, and proxy application of a stored image by another person. It excludes a freshly handwritten signature or a hand-applied seal made for that specific report (the in-scope "hand-signed" case), and it is distinct from a cryptographic digital signature, which binds a document mathematically rather than reproducing an image. The criterion is therefore the visible outcome — image reuse, the same stored image recurring across reports — not the intent, the actor, or the legal status, and it is this outcome that our two measures and five categories track. The worry is not about legality; it is about meaning. A single image pasted onto hundreds of reports may not carry the individual endorsement the rule assumes — a concern the literature on signatures connects to behavior, and, in auditing specifically, to rules that name and identify the engagement partner [31], [32], [33]. This is also why the problem is not forgery: a non-hand-signed signature reuses the real signer's own image, and at scale no reader can see the difference.
That difference matters for the method too. Almost all work on offline signature analysis is about forgery — deciding whether a questioned signature was really written by the person it claims to be [3][8]. In our setting the identity is not in doubt; the accountant is genuine. What we want to know is whether the person actually signed each report, or whether one signing was copied as an image. This removes the need to model clever forgers, but it adds a new difficulty: we must separate a person who signs consistently from a reused image. Someone who signs in a very steady hand will produce signatures that look alike year after year; a process that reuses one stored file will produce signatures that are structurally identical. The method has to tell these two cases apart.
Two facts make the obvious approach — pick a similarity cutoff and call everything above it a copy — unworkable, and they shape our design. First, archives like ours have no labels at the level of individual signatures: no signature is marked as "definitely hand-signed" or "definitely reused." Without such labels, any cutoff we choose has unknown error rates; we cannot measure how often it would wrongly flag a genuine signature or miss a reused one. Second, even setting labels aside, the data themselves do not contain a natural cutoff. As we show in Section V, the raw numbers look at first as if they split into two groups, but that appearance comes from differences between firms and from the fact that the hash takes only whole-number values; once we remove those two effects, the distribution is a single smooth spread, not two clusters. You cannot read a dividing line off a distribution that has no gap, and you cannot test a line against labels that do not exist. So the method must get its cutoff some other way.
Our two similarity measures are chosen precisely to expose the distinction the problem turns on. For each signature we compute two numbers against the same accountant's other signatures: a cosine similarity on deep ResNet-50 features, and an independent perceptual hash (dHash) distance. They carry different information. Cosine similarity measures overall style, and it is high both when an image is reused and when a person signs consistently. The dHash distance measures structure almost pixel by pixel, and a very small distance is the sign most specific to a reused image. But neither measure is enough on its own. Cosine alone over-flags a steady hand, because consistent signing also keeps it high. dHash alone has the opposite weakness: it is brittle to how an image is captured — a reused signature that has been re-scaled, re-cropped, or re-compressed can show a larger dHash distance and slip past a structure-only test — and a small dHash distance carries no meaning between two signatures whose styles do not match in the first place. The two are complementary precisely because they fail in different directions: cosine first establishes that the styles match, which catches reuse even when the image has been mildly altered, and dHash then asks whether the match is also near-identical in structure, which is what separates a reused image from a merely steady hand. A single similarity number blurs these two cases; two measures keep them apart. The implication between them runs one way only: a near-identical structure (a tiny dHash) forces a high cosine, but a high cosine in no way implies a near-identical structure — which is why the two-measure plane cannot be collapsed onto either single axis. This complementarity also shapes the rule (Section III-D): because a small dHash distance is only meaningful once cosine is already high, the structural cut subdivides the high-cosine cases rather than the low-cosine ones. This is the heart of the design.
On this basis we build and study a complete screening system. The pipeline takes raw PDF reports through four steps — find the signature page, detect each signature, turn it into features, and compute the two similarities — and sorts each signature into one of five categories. Because there is no natural cutoff to read off the data and no labels to learn one from, we instead measure how often the rule fires by chance between unrelated accountants in a clean reference group. That chance rate is a *between-accountant* coincidence rate, which we treat as a proxy for the rule's specificity: it gives us a principled way to choose an operating point, and — just as important — it tells us what each category's flag is worth among unrelated accountants. It is not the within-accountant false-positive rate (how often a genuine consistent hand-signer would fire the rule), which the reuse question would ideally use but which no labels let us estimate (Section III-E).
What is the screen for? Two things. Run over a large archive, it discovers where reuse concentrates — which firms, which periods — without being told where to look. And it keeps human review at the scale of exceptions. In a reuse-dominated population (a stamping firm, a firm with an electronic-signing system), the high-confidence tier routes most signatures directly to a high-specificity candidate list, and the small residual goes through a defined review protocol (specified in Section IV-B) — side-by-side overlay inspection, secondary image-artifact checks, and bounded per-accountant sampling — that also accumulates labels for later calibration. In a mixed population, where hand-signing and informal stamping coexist, the ambiguous middle is larger, and the same disposition machinery delivers the same promise one level up, at the accountant: the low-specificity advisory band is demoted rather than worked, accountant-level scores concentrate attention on the few high-ranked or mixed cases, and byte-identity hits supply proof where proof exists, confirming that an accountant's stored image is in circulation. What the screen does not deliver there — and we say so plainly when we report the category proportions (Section IV-B) — is a per-signature verdict for the ambiguous middle. In every case the output is bounded triage, not a verdict on any single signature.
The Taiwan setting suits this study well. The Market Observation Post System offers a large, standardized, public collection of statutory audit reports, each with the same two-signature format, which makes large-scale extraction practical. In addition, anonymized interviews with certifying partners and signing-system staff at all four firms give us institutional facts about how each firm signs and about when each firm adopted a formal electronic-signing system — adoptions that were staggered from 2020 onward. This gives the study a natural before-and-after structure in time, and outside information against which to read the firm-level results (Section III-A).
We make four contributions:
1. An end-to-end screening pipeline that turns raw audit-report PDFs into operational risk strata for hundreds of thousands of signatures.
2. A dual descriptor that separates style consistency from image reproduction — a distinction a single similarity measure blurs.
3. The methodological core: a label-free way to *construct and characterize* a screening operating point when no signature-level labels exist — the question this paper is really organized around. With neither a natural cutoff in the data nor labels to learn one from, we set a tunable rule by measuring how often it fires by chance in a clean reference group, and we say plainly what that measure can and cannot support. This is the part we expect to transfer beyond the present setting; we demonstrate and stress-test it at scale on audit signatures rather than claiming it as a finished, fully general framework. Concretely the result is not only a calibration method but a concrete operating point — the high-confidence rule and its measured specificity proxy — that practitioners working with comparable Chinese-signature image pipelines can use as a starting reference (not transplant unchanged, since the proxy is conditional on a similar preprocessing and reference-group setup), together with a defined disposition path for the ambiguous middle (calibrated demotion of the low-specificity band, aggregation to the accountant level, byte-identity escalation, and a bounded manual protocol) that keeps human review at the scale of exceptions.
4. A demonstration on Chinese signatures, a structurally complex and comparatively under-served script for signature analysis. Because our descriptors work on the image rather than on script-specific strokes, the approach does not depend on Latin-script assumptions and is a candidate for other scripts.
The paper is organized to move from the problem to the evidence. Section II reviews related work and states the gap. Section III describes the study design — the data split, the pipeline, the five-way rule, and the calibration logic — and explains why each piece is built the way it is. Section IV reports the results: the calibration baseline, which category needs human review, and the held-out benchmark on Firm A. Section V collects supporting analyses, including the diagnostic showing that no natural cutoff exists. Section VI concludes.
## II. Related Work and Research Gap
Why reproduction matters: signatures carry symbolic weight. A signature is valuable mainly as a symbol — it stands for the signer's identity and intent. Recent experiments show that this symbolism does not survive a change in how one signs. In studies that take the reader's point of view, Chou [41] finds that electronic signatures give a weaker sense of the signer's presence than handwritten ones, and that readers therefore judge an e-signed document as less valid and expect more non-compliance; across five kinds of e-signature (a checked box, a PIN, an avatar, a typed name, and a software-generated signature), the software-generated kind felt the most "present" of the electronic options but still less than a handwritten signature. In studies that take the signer's point of view, Chou [42] finds that electronic signatures give a weaker sense of self-presence — the signer's felt attachment to the mark — and that this, in turn, makes people more willing to cheat; the work singles out signing by proxy (an autopen) as cutting the tie between the document and the signer. These results matter for us because the practice we detect — a stored signature image laid onto a report by staff or by software — is, in this scheme, one of the lowest-presence modes: it looks like a software-generated signature and is executed like a proxy signature, because the accountant performs no signing act for the report. These effects are robust rather than one-off: in a pre-registered, multi-study replication with meta-analysis, Tzelios and Williams [43] reproduce Chou's reader-side result — an avatar e-signature lowers the sense of the signer's presence and raises the expectation that the contract will be breached. In their general discussion the same authors point to accounting as a next setting — noting the spread of online tax filing and asking how digital signatures affect an evaluator's assessment of the legitimacy of claims, while cautioning that accounting documents may prove less sensitive to signature form than legal ones. We read that call precisely: their "auditors" are the readers of digitally signed filings — those who evaluate the claims — not the certifying accountants who sign. The signer-side question in auditing — what it means when the certifying professional's own signature is reproduced rather than performed — is not addressed in that literature. Both questions, reader-side and signer-side, presuppose the same missing capability: a way to measure non-hand-signing at scale. The lesson we draw is not that non-hand-signing harms audit quality — that is a separate question we leave to a companion study (Section VI) — but that whether it matters is a real question, and one nobody can study without first being able to measure non-hand-signing at scale.
Signature analysis to date is about forgery, not reuse. The obvious toolkit for that measurement is signature analysis, but its main concern is the wrong one for us. Bromley et al. [3] introduced the Siamese network that still anchors the field; SigNet [4] extended it to compare writers it had never seen; Kao and Wen [5] worked from a single genuine sample; TransOSV [6] brought in a Vision Transformer; and meta-learning has been used to cut the effort of enrolling new signers [16]. All of this targets imitation by another hand, so it learns to tell different people apart. Our task is the opposite: spotting reuse of the genuine signer's own image, which lives in the most-similar tail of one person's signatures. The closest idea uses reference examples to set a sensible cutoff [8], but on benchmark data with known genuine references — whereas our archive has no signature-level labels at all. This body of work is also overwhelmingly built on Western, Latin-script signatures; non-Latin scripts such as Chinese are comparatively under-served, and reported accuracies for them are lower [44]. Chinese signatures are structurally distinctive — many strokes, with wide variation between writers — and the forensic literature on them is thin; the closest precedent, Chen [45], analyzes Chinese signatures with a maximum-similarity-to-same-class statistic that directly parallels our use of the maximum cosine to the same accountant. Our descriptors, however, work on the image rather than on script-specific strokes, so the method itself does not depend on the script.
Image-duplication and document forensics: useful parts, different setting. A second line of work looks directly at duplicated images. Copy-move detection finds regions copied within an image [11], and Abramova and Böhme [10] adapted it to scanned documents, noting that ordinary repeated characters confuse the standard methods. Self-supervised copy detection on everyday photos [13] shows that pretrained CNN features with cosine similarity make a strong baseline for spotting near-duplicates. Closest in pipeline terms, Woodruff et al. [9] pull signatures from corporate filings for anti-money-laundering work — but to group signatures by who signed them, not to detect one signer's image being reused across documents. The building blocks exist; the specific setting — one signer's image reused across many scanned financial reports — does not seem to have been addressed.
Deep features and perceptual hashing as ready-made parts. Features from a pretrained CNN transfer well to document images without any retraining [20], [21], and perceptual hashes are built to survive the printscanrasterize cycle [27]. Jakhar and Borah [12] show that combining a perceptual hash with deep features beats either one alone for near-duplicate detection — a direct precedent for our two-measure design, though they work on natural images rather than signatures.
The recurring obstacle is the missing label. None of these lines solves the problem we face, because real archives carry no signature-level ground truth, and a similarity screen without it falls back on a hand-chosen cutoff whose error behavior is unknown. (The statistical tools we use to test for a natural cutoff and to describe the rule once we find none are introduced where they are used, in Section III and Section V, since they are part of our method rather than prior work on this problem.)
The gap, and our contribution. Two gaps follow. First, large-scale screening for non-hand-signed auditor signatures has not been done, even though there is good reason (above) to think it matters. Second, and more broadly, similarity-based screening has no principled way to set and describe an operating point when labels are missing. Our contribution sits exactly here: a label-free calibration that replaces both the arbitrary cutoff and the unavailable labeled validation with a chance-rate measured in a clean reference group, together with the pipeline and dual descriptor that make the screening possible (contributions listed in Section I).
It is worth being explicit about a design choice this implies, because it is easily mistaken for a missing component. A natural reflex would be to learn the discriminator — to fine-tune a Siamese or contrastive network to separate reused from hand-signed signatures. We deliberately do not, and the reason is not expedience but the defining constraint of the setting: supervised metric learning requires labeled pairs (genuine-vs-reused), which is exactly the ground truth the archive does not contain. Training such a network would require either fabricating labels or importing them from a different distribution (e.g., forgery datasets), reintroducing the unverifiable assumptions our calibration is designed to avoid; the resulting boundary would again have unknown error behavior on the real archive. Label-free operation is therefore not a weaker version of a supervised method but the only honest option when no labels exist, and the contribution is correspondingly methodological — a way to set and *characterize* an operating point by measured chance behavior — rather than a new network architecture. Off-the-shelf pretrained features are used precisely because they introduce no task-specific supervision; supervised fine-tuning is the right tool once a labeled sample exists, which is why we frame the review protocol's first run (Section IV-B, Section V) as the route to that sample and to any future supervised validation.
## III. Research Background and Study Design
This section explains how the study is built and why. We report no computed numbers here; all results appear in Section IV.
### A. Institutional Background
To pin down the signing practices that we need in order to interpret the results, we held semi-structured interviews with certifying partners and signing-system staff at all four firms in the study.¹ Three points do real work later. First, all four firms allow handwritten signing but none require it. Second, formal firm-wide electronic signing or sealing systems were adopted on staggered dates from 2020 onward. Third, one firm — which we call Firm A throughout — has used scanned-image overlay stamping as its usual practice since at least 2013. We use these facts only as background, not as labels for individual signatures: they guide how we split the data below and how we read the firm-level results in Section IV-C, but they do not tell us the status of any single signature. A further caution applies to how the interviews are used as corroboration. They are self-reported, anonymized, and not independently reproducible, so when the screen's firm-level output agrees with them (Section IV-C) that agreement is evidence of consistency with domain knowledge, not a measurement of the screen's accuracy or recall — quantifying those would require signature-level labels, which the archive does not provide. To be unambiguous about their role: the interviews are used only to *contextualize* the firm-level findings and are not treated as validation. They are corroborative, not confirmatory, and not independently reproducible; the empirical claims of this paper rest on the calibration and the byte-identical evidence, which stand without them. Their one load-bearing use is to motivate why Firm A is read as a known-positive benchmark rather than a blinded test (Section IV-C) — a framing that, if anything, lowers the evidentiary status we claim for that firm. The practical implication is that the years before the formal systems (before 2020) are the right "normal" period to use for calibration.
> ¹ Footnote — institutional detail. The interviews were conducted under institutional research-ethics approval and are reported in anonymized, aggregated form; firms are labeled AD and no individual can be identified. The formal systems were reported to have been adopted at roughly one firm in early 2020, one in 2021, and one in late 2022 (exact firm-level dates are withheld for anonymity; see supplementary materials). Interviewees attributed this timing partly to the COVID-19 pandemic, which forced remote review and signing, and to firm-wide paperless and environmental (ESG) initiatives — both of which accelerated the move to formal electronic signing at Firms B/C/D. For Firm A, the reported workflow is that the certifying accountant approves the finished report electronically, after which the print room overlays the accountant's stored seal or signature image onto the PDF and prints it; the stored image is rarely changed, and although handwritten signing is allowed it is reported to be very rare, and rarer over time. Before the formal systems, the other firms' practice varied: some used informal scan- or photocopy-based stamping alongside handwritten signing, and at least one reported mostly handwritten signing before its system. The property the calibration relies on (Section III-E) is that, in the pre-2020 baseline firms, different accountants did not share a common template — not that every signature was handwritten.
### B. Data and Analysis Design
The corpus is all retrievable Taiwan statutory audit reports for fiscal years 20132023; the four largest firms (AD) form the primary analysis sample, and non-Big-4 firms enter only in the crossover-scope robustness check (Section V-C), never in the calibration or the headline rates. Signatures are extracted as described in Section III-C. To be precise about the headline denominator, since it recurs throughout: "150,442 analyzable signatures" means exactly those Big-4 signatures that are valid and have both similarity measures computed, assigned by each accountant's registered firm (Firm A 60,448, Firm B 34,248, Firm C 38,613, Firm D 17,133). We then split the Big-4 corpus by firm and by period, giving each part a distinct job (Fig. 1):
- Calibration (the clean reference group): Firms B/C/D, 20132019.
- Held-out benchmark 1: Firm A, 20132023 (a known positive, not a blinded test).
- Held-out test 2 (secondary): Firms B/C/D, 20202023.
We explain the reason for each part in Section III-E. The key idea is simple: we calibrate only on the clean cell — the non-Firm-A firms in the years before formal systems — and test everything else against it. No numbers appear here; the calibration results start in Section IV-A.
![](figures/fig1.png)
*Figure 1. The data split. Rows are Firms AD; columns are 20132019 and 20202023. The B/C/D × 20132019 cells are the clean calibration group; Firm A (both periods) is held-out benchmark 1 (a known positive); B/C/D × 20202023 is the secondary held-out test. We calibrate only on the clean cell and test everything else against it.*
### C. Pipeline
The pipeline turns a raw PDF report into labeled signatures in five steps (Fig. 2).
Finding the signature page. A vision-language model [24], [35] scans only the first quarter of each document — where the auditor's report page reliably sits — and stops as soon as it finds the page.
Detecting signatures. A YOLOv11n detector [25], [34], trained on 500 hand-labeled signature pages (425 for training, 75 for validation; 100 epochs; started from COCO weights), draws a box around each signature. A region counts as a signature if it holds handwritten content that belongs to a personal signature, even where it overlaps an official stamp. A red-stamp removal step (filtering in HSV color space) then strips away overlapping red seals, leaving the handwritten part.
Turning signatures into features. Each detected signature is passed through an ImageNet-pretrained ResNet-50 [26] used as a fixed feature extractor — we take the 2,048-number output of its global-average-pooling layer and drop the classification head. We resize each image to 224×224 while keeping its aspect ratio (padding with white), apply the standard ImageNet normalization, and scale the feature vector to unit length, so that cosine similarity is just the dot product. We use these off-the-shelf features rather than fine-tuning the network, for three reasons: the task is comparing similarity, not classifying; ImageNet features are known to transfer well to document images [20], [21]; and not fine-tuning avoids the risk of learning quirks of our particular dataset. The backbone choice is checked in Section V-C.
Assigning each signature to an accountant. Each signature is matched to a registered accountant by its position on the page (first or second) against the official registry. Signatures we cannot match are left out of the same-accountant comparisons, because the "most similar signature by the same accountant" measure has no meaning without an assigned accountant.
(Detection accuracy, signature counts, match rates, and the resulting analysis sample are reported in Section IV-A.)
![](figures/fig2.png)
*Figure 2. The screening pipeline. A raw PDF passes through page-finding (a vision-language model), signature detection (YOLOv11) with red-stamp removal, feature extraction (ResNet-50), the two per-signature similarities (cosine for style; the smallest dHash to the same accountant for structure), and a five-way label.*
### D. The Two Similarity Measures and the Five-Way Rule
For each signature we compute two numbers, both against the same accountant's other signatures: cos, its highest cosine similarity to another of that accountant's signatures, and dHash, its smallest perceptual-hash distance to another of them. As explained in Section I, the point of using two measures is to separate two things that one measure blurs. A high cos means the signatures look alike in style, which happens both when an image is reused and when a person signs consistently. A small dHash means the signatures are alike almost pixel for pixel, which is the sign most specific to a reused image. Together they are far more telling than either alone: a steady hand gives a high cos but a dHash that still varies, while a reused image gives a high cos and a tiny dHash.
The rule places each signature in one of five categories, with cosine acting as the primary gate and the structural (dHash) distance refining only the cases where cosine is already high. Each name states the screening hypothesis its region suggests — a candidate reading, not a confirmed determination:
- HC — high-confidence reuse candidate: cosine above the high cut and structure at or below the near-identical cut. Both measures point to a reused image.
- MC — moderate-confidence, advisory: cosine above the high cut and structure between the two structural cuts. Style is very similar, but structure is below the strict bar.
- HSC — high style-consistency: cosine above the high cut and structure above the upper structural cut. Style is similar with no structural support.
- UN — uncertain: cosine between the low cut (the same-vs-different-accountant crossover) and the high cut.
- LH — low reuse-similarity: cosine at or below the low cut.
A report takes the strongest label among its signatures (HC > MC > HSC > UN > LH). Table I-a summarizes the five categories, the thresholds that define them, and the notation used throughout; the high cut is cosine 0.95, the low cut is 0.8547 (the same-vs-different-accountant crossover; Section IV-A), and the two structural cuts are dHash 5 and 15.
**Table I-a — Category definitions, thresholds, and notation.**
| Label | Name | Condition (cosine *c*, structure dHash *d*) | Role |
|---|---|---|---|
| HC | high-confidence reuse candidate | *c* > 0.95 and *d* ≤ 5 | self-certifying flag |
| MC | moderate-confidence | *c* > 0.95 and 5 < *d* ≤ 15 | advisory |
| HSC | high style-consistency | *c* > 0.95 and *d* > 15 | no structural support; no weight |
| UN | uncertain | 0.8547 < *c* ≤ 0.95 | ambiguous middle |
| LH | low reuse-similarity | *c* ≤ 0.8547 | likely hand-signed |
Other abbreviations used throughout: ICCR — inter-CPA coincidence rate, the between-accountant chance-firing rate that calibrates the rule (Section III-E); *c* — cosine similarity to the same accountant's other signatures (style); *d* — smallest dHash distance (structure).
Why the partition has this shape (five categories, not nine). As explained in Section I, a near-identical structure is decision-relevant only once the styles already match, so the two cosine cuts come first — splitting signatures into three style bands (low, uncertain, high) — and the two structural cuts subdivide only the high band. Three facts pin this shape down. First, structure carries little standalone decision weight in the two lower bands: between signatures whose styles do not clearly match, a moderate structural distance is hash noise, not evidence of reproduction — and even the near-identical structural matches that do appear below the style cut (quantified next) are not assigned HC; their structural information re-enters only through accountant-level aggregation and byte-identity review (Section IV-B), not through a separate cell. Second, the cells of the full 3×3 grid that pair a lower style band with a near-identical structure are sparsely populated rather than ignored — and the empirical reading is more precise than a simple "they are empty." An explicit count makes this exact: of the 150,442 Big-4 signatures, 7,681 (5.1%) combine a near-identical structural match (dHash ≤ 5) with a sub-0.95 cosine, so the one-way implication of Section I (a tiny dHash forces a high cosine) holds approximately, not strictly. But the residents' mass sits immediately below the high-cosine cut — 7,311 of them (95.2%) fall in cosine 0.900.95, and only 370 signatures (0.25% of the corpus) reach the genuinely low-cosine bands, of which just 38 lie below the LH/UN crossover (cosine ≤ 0.8547). These residents are not degenerate crops: their image size (mean 33k px) and detection confidence (0.875) match the rest of the corpus (28k px, 0.877). Under the coherent same-pair definition — style and structure satisfied on the same partner signature — the count falls further to 874 (0.58%). The point is therefore not that these cells are empty but that subdividing the lower style bands by structure changes no disposition: because cosine is the primary gate, a near-identical structural match beneath the style cut is already handled as UN, and the residual structural information re-enters through the accountant-level aggregation and byte-identity escalation of Section IV-B rather than through a separate cell. Third, a partition should cut only where the resulting actions differ: subdividing the two lower bands by structure would create cells whose dispositions (Section IV-B) are identical — all demoted or aggregated the same way — adding calibration burden without operational consequence, whereas the three structural cells inside the high band exist precisely because their dispositions differ. (Count from the deployed-rule descriptor columns; any-pair definition, full Big-4 corpus.)
The cuts are operator-tunable operating points, not learned boundaries: there is no natural gap to read off the data (Section V-A) and no signature-level labels to learn one from, so the cuts are chosen and their specificity is measured, not learned. The four cut values, and where each one comes from — two are read directly from this study's data — are given in Section IV-A, alongside the chance-rate calibration that characterizes them and the figure of the two-measure plane (Fig. 3).
Any-pair versus same-pair: how the two extrema combine. One construction detail deserves to be explicit, because a careful reader will ask. The two per-signature values are independent extrema over the same accountant's other signatures — the highest cosine and the smallest dHash, each taken on its own — so the two values may come from different partner signatures. We call this the any-pair rule, and the choice is deliberate, for three reasons. First, the two descriptors have different invariances: cosine survives re-scaling and re-compression; dHash does not. For a genuinely reused image that crossed different scan or compression pipelines, the style-nearest copy and the pixel-nearest copy can therefore legitimately be different reports — forcing both extrema onto one pair would miss exactly that most realistic positive case. Second, dHash takes whole-number values and ties are massive in duplicate-heavy pools: which tied copy wins the minimum is essentially arbitrary, so whether the two extrema land on the same file is largely tie-breaking noise — both point into the same duplicate cluster. Third, the chance-rate calibration of Section IV-A applies the same any-pair rule to the clean reference group, so the high-specificity claim rests on the absolute clean-group rate (the HC rule fires by chance on only ~1.2% of clean-group reports), not on any firm-versus-floor ratio; the same rule is applied to every firm and to the reference group alike. The stricter same-pair variant, in which a single partner signature must satisfy both inequalities at once, is reported as a robustness check (Section V-C) and leaves every conclusion unchanged — the within-firm concentration of cross-accountant matches is in fact *higher* under same-pair (97.099.96% across the four firms) than under the deployed any-pair rule (76.798.8%) — because in the high-confidence region the two rules nearly coincide: a partner within the near-identical structural cut is pixel-near-identical and therefore clears the high style cut by itself.
Limitations, stated up front. Three follow directly from the design. (i) Because the cutoffs are chosen rather than learned, the system has a tunable operating point, not an optimal one. The dial moves in only one direction: a reviewer who wants more conservatism can tighten it for higher specificity, but cannot trade in the other direction toward higher recall, because recall is unobservable without labels — there is no precisionrecall frontier to navigate (Section V). (ii) The chance rate we report is a *between-accountant* coincidence rate — a proxy for specificity, not a true false-acceptance rate — because we have no labeled negatives; it speaks to how often unrelated accountants collide, not to how often a genuinely consistent hand-signer would fire the rule, which is the quantity the reuse question needs and which we cannot estimate (Section III-E). (iii) For any single signature, the two measures cannot tell us why it is so similar to another: reuse of an image, a shared scanning pipeline, and a very uniform house style all push the numbers the same way, and we do not try to choose between them at the level of one signature. These limits apply to every claim that follows.
### E. The Clean Reference Group and the Chance Rate
With no labeled negatives to learn from, the calibration uses a stand-in: a group in which the rule should fire only by chance — unrelated accountants whose signatures happen to look alike now and then. Choosing this group well is the central design decision, and two requirements force the choice.
Why not all four firms. As Section IV-C will show, almost all of one firm's between-accountant matches fall on other accountants of the same firm, and we have byte-level proof of image reuse across about fifty of that firm's partners. If we put Firm A into the reference group, we would be filling the "by chance" rate with exactly the within-firm matches the rule is supposed to catch — a circular calibration. So we use Firms B/C/D as the clean reference group and keep Firm A as a test case; we report the all-four-firm number only to show how much Firm A contaminates it.
Why 20132019. We further limit the reference group to the years before formal firm-wide electronic-signing systems (adopted from 2020 onward; Section III-A). What this buys us is the absence of a shared template across accountants — not a guarantee that every signature was handwritten. The interviews say some baseline firms used informal individual stamping before 2020, but each accountant's stored image was their own, so different accountants' signatures still match only by chance; the chance rate is about matches between accountants, which individual stamping does not inflate. One further channel deserves to be named, because it is not the template and we cannot fully exclude it: accountants at the same firm pass through a shared imaging pipeline — common scanners, PDF-assembly software, and the red-stamp-removal step (Section III-C, Section V-B) — and a shared pipeline can imprint correlated artifacts on otherwise-unrelated signatures, which would lift the inter-CPA rate above true chance. The pipeline audit of Section V-B confirms that such shared production paths exist and change over time. This is a reason to read the ICCR as a *specificity proxy* rather than a literal coincidence rate; its bias, like reference contamination, runs toward a higher floor, which makes the Firm-A contrast more conservative rather than less. After 2020, formal systems standardize how reports are assembled, so that period is not a clean reference — and indeed the chance rate rises after 2020 (Section V-B). We therefore calibrate on the Firms-B/C/D 20132019 cell and score every held-out cell against it.
We report the rule's chance rate at three levels, because the rule takes the best match over a pool and so the per-signature rate is not the same as the per-pair rate: per comparison (sampled pairs of different accountants), per signature, and per report, each with a confidence interval. We call this the inter-CPA coincidence rate (ICCR) rather than a "false-acceptance rate," which we reserve for settings that have labeled negatives. The ICCR is a *between-accountant* coincidence rate: how often the rule fires on the signatures of two *different* accountants. It is therefore at best a proxy for specificity, and only under the stated assumption (no shared template across accountants). It is important to be exact about what it is not. The quantity the reuse question actually needs is the *within-accountant* false-positive rate — how often the rule would fire on a genuinely consistent hand-signer's own signatures — and that rate is not estimable here, because no accountant in the corpus is labeled as a known hand-signer. We considered benchmarking it against an external corpus of genuine repeated signatures (a public signature dataset supplies many authentic samples per writer), but such corpora are a different population and script acquired under a different pipeline, so the resulting rate would not transfer to this setting; importing it would reintroduce exactly the kind of unverifiable cross-distribution assumption our label-free calibration is built to avoid. We therefore report the limitation rather than a misleading proxy. The ICCR is not even a bound on it: a uniform individual hand keeps cosine high by design, so a true hand-signer's within-accountant fire rate can sit far *above* the between-accountant coincidence rate. Any statement that divides a firm's within-accountant fire rate by this between-accountant floor (an "X× the floor" comparison) therefore overstates the gap — the bias runs in the anti-conservative direction — and we do not report such ratios as effect sizes. Read as a between-accountant specificity proxy under the stated assumption, the ICCR is faithful to the evidence; read as a true error rate for the reuse question, it would claim more than we can show.
One further assumption deserves to be stated rather than buried, because it concerns how the clean group was chosen. The floor is *conditional on the reference group actually being clean* — it is a coincidence rate among accountants we take to be independent hand-signers, and the group (non-Firm-A firms, pre-2020) was selected partly because its rates are low and its practices, by the interviews, are not stamping-dominated. That selection is mild but not innocent: if some baseline accountants in fact reuse images undetected, the reference is contaminated. The direction of that error, however, is reassuring for the Firm-A contrast. Undetected reuse inside the baseline would only *raise* the between-accountant coincidence floor, which makes Firm A's gap above it *smaller*, not larger — so contamination of the clean group biases the headline contrast conservatively, against our conclusion rather than toward it. Two pieces of evidence bound the concern empirically. First, the three baseline firms are mutually consistent and uniformly low (Firms B and C within about 3.5× of each other, none close to Firm A; Section IV-A), so the floor does not hinge on any single firm and a leave-one-baseline-firm-out reading does not move it materially. Second, the one data-derived threshold, the low cosine cut, is stable when the group composition is changed — 0.8547 on the calibration cell, 0.8302 with the non-Big-4 firms folded in, a shift of at most 0.025 (Section V-C) — so widening or narrowing the reference at its boundary does not move the operating point. We therefore treat the clean-group assumption as a stated limitation with a known-safe error direction, not as a hidden premise.
### F. What HC Means and Does Not Mean
One sentence prevents the most common misreading of everything that follows. *HC is not a reuse label.* HC denotes an extreme *within-accountant repetition pattern* — a signature whose closest match among the same accountant's own signatures is both stylistically near-identical (cosine > 0.95) and structurally near-identical (dHash ≤ 5) — that is *statistically rare between unrelated accountants*, by the ICCR calibration of Section III-E. That is the whole of what the rule, on its own, establishes. Reuse of a stored image is one interpretation of an HC pattern, and the most economical one, but the rule does not imply it: a very steady hand, a fixed scanning-and-assembly pipeline, or a uniform house style can each raise within-accountant repetition (Section V-A, Section V-B). Where we go further than "extreme repetition" — as we do for Firm A — the additional weight comes from outside the rule: byte-identical signatures, which independent hand-signing cannot produce, and the institutional context, neither of which is implied by HC alone. For Firms B/C/D we make no reuse claim at all; their HC signatures are reported as a within-accountant repetition rate, not as detected reuse. Read this way, HC is a calibrated, reproducible screening category, and "reuse" is a conclusion that has to be earned separately — firm by firm, or signature by signature — rather than read off the label.
## IV. Findings
This section reports the numbers. It starts with the calibration baseline (Firms B/C/D, 20132019), then says which category needs human review, then presents the held-out benchmark on Firm A.
### A. Detection Sample (Whole Corpus) and the Calibration Baseline (Firms B/C/D, 20132019)
Detection and the analysis sample (whole corpus). Two scopes appear in this section and must not be confused: detection and the analysis sample here are computed on the whole corpus, whereas both data-derived calibration quantities — the chance-rate ICCR and the low cosine cut (Section IV-C) — are computed only on the clean Firms-B/C/D 20132019 cell. Of the 90,282 reports, the page-finder flagged 86,084 as having a signature page (the other 4,198, or 4.6%, had none); 13 of those 86,084 could not be rendered, leaving 86,071 documents processed. On the validation set, the YOLOv11n detector reached precision 0.970.98, recall 0.950.98, mAP@0.50 0.980.99, and mAP@0.50:0.95 0.850.90. Across the corpus it extracted 182,328 signatures — 2.14 per document with detections, where two certifying accountants per report implies 2.00. The ≈6.7% excess is explained by extra detections rather than missed accountants: of the 13,573 detections (7.4%) that could not be matched to a registered accountant and were excluded, 8,901 (66%) are third-or-later detections on a page — boxes beyond the two certifying signatures — and the unmatched set as a whole carries lower detection confidence than the matched set (mean 0.826 vs 0.874), consistent with these being extra boxes and low-confidence noise; the remaining 4,672 are first/second-position detections that failed registry matching. Throughput was 43.1 documents per second, and the detector agreed with the vision-language model on 98.8% of documents. Matching by position assigned 92.6% of signatures (168,755 of 182,328) to a registered accountant; of these, 168,740 have both similarity measures computed (the 15-signature difference is accountants with a single signature in the corpus, for whom no same-accountant comparison exists, so the full-corpus distributional statistics in the Appendix are reported on 168,740). The four-firm analysis sample is 150,442 signatures with both measures computed, from 457 accountants (Table I); the accountant-level partition (Table III, Section V-C) is fit on the 437 of these with at least ten signatures (171/112/102/52 across Firms AD).
**Table I — Detection and extraction summary.**
| Quantity | Value |
|---|---|
| Documents with a signature page | 86,071 |
| Detector precision / recall | 0.970.98 / 0.950.98 |
| Detector mAP@0.50 / mAP@0.50:0.95 | 0.980.99 / 0.850.90 |
| Signatures extracted | 182,328 (2.14 per document) |
| VLMdetector agreement | 98.8% |
| Signatures matched to an accountant | 168,755 (92.6%) |
| Four-firm analysis sample | 457 accountants; 150,442 signatures |
The calibrated operating point: the four cut values and their bases. The five-way rule of Section III-D uses four cut values; we state them here because two are read directly from this study's data. The low cosine cut, 0.8547, is the crossover of the same-accountant and different-accountant cosine distributions computed on the calibration cell alone (Firms B/C/D, 20132019, closed-world: both the source signatures and their comparison set drawn from that cell; Section IV-C). We use this closed-world value as the primary cut rather than the corpus-wide crossover, so that the one data-derived threshold in the rule is estimated only on the calibration-only Firms-B/C/D 20132019 cell, held out from Firm A and from post-2020 scoring. The cut is stable across scopes — 0.8547 (calibration closed-world), 0.8367 corpus-wide, 0.8489 on the all-period baseline firms, 0.8302 with the non-Big-4 firms added; it moves by at most 0.025 across all four scopes (0.018 from the corpus-wide value), so the choice of scope is immaterial and the broader-scope values stand as robustness checks (Section V-C). The high cosine cut, 0.95, is the high-similarity operating point: it sits in the region where genuine reuse concentrates — the byte-identical anchor (Section IV-C) lies at cosine 1 — and a recalibration cannot move it onto a distributional antimode because none exists (no within-population bimodality, Section V-A). The near-identical structural cut, dHash ≤ 5, is the perceptual-hash distance below which two rasters are pixel-equivalent up to mild recompression, and dHash ≤ 15 bounds the looser "structurally similar" band; both follow the standard 64-bit dHash distance scale [27]. We therefore do not re-derive these three as optimal cutoffs but characterize their chance-of-firing behavior directly (the full prior-calibration provenance is in the supplementary materials), and we make them operator-tunable in one direction: their specificity proxy at these values is read off the chance-rate calibration below, and an operator can tighten the floor by inverting the ICCR curve (for example, dHash ≤ 3). This is a conservativeness dial, not a precisionrecall control: tightening raises the specificity proxy and lowers the flag count, but there is no observable recall to trade back, so loosening cannot be calibrated against a known cost. We deliver these as a concrete, calibrated operating point — in particular the high-confidence (HC) rule, cosine > 0.95 and dHash ≤ 5 — whose between-accountant coincidence behavior the calibration below makes explicit. Because the rule is calibrated on a large Chinese-signature corpus, the HC values double as a practical starting reference for practitioners working with comparable Chinese-signature image pipelines, rather than a setting to transplant unchanged.
![](figures/fig3.png)
*Figure 3. The two measures and the five regions, drawn as the real 2D density of all Big-4 signatures (n = 150,442; log color scale, integer dHash bins). The cosine axis is split at the low cut 0.8547 (the calibration-cell same-vs-different-accountant crossover) and the high cut 0.95; within the high-cosine band the dHash axis is split at 5 and 15. The mass concentrates in the bottom-right HC corner — high cosine with near-identical structure — and thins out as a single continuum toward lower cosine and higher dHash, with no gap separating a "reuse" cluster from a "hand-signed" one (Section V-A); note also that essentially all signatures sit above cosine ≈ 0.85, the compressed high-similarity range discussed in Section V-A.*
The calibration sample itself (Firms B/C/D, 20132019). The chance-rate calibration that follows is computed on the clean cell only, and the reader should be able to see the calibration base directly rather than infer it from the full-period totals above. The Firms-B/C/D 20132019 cell contains 226 accountants, 52,071 signatures with both measures computed, and 26,042 reports; the per-comparison ICCR below is estimated from 5×10⁵ inter-CPA signature pairs sampled uniformly from this cell. Every ICCR source signature is restricted to this cell — the headline per-signature and per-document rates reproduce on the 52,071-signature 20132019 cell, not on the full-period BCD record (~90,000 signatures), which is used only where a robustness figure is explicitly quoted — so no post-2020 or Firm-A signature enters the calibration.
How often the strict rule fires by chance (pooled). In the Firms-B/C/D 20132019 group, the strict (HC) rule fires by chance very rarely at every level (Table II): about 1 in 100,000 per comparison (Wilson 95% CI [4×10⁻⁶, 2.3×10⁻⁵]), 0.59% per signature ([0.45%, 0.73%]), and 1.2% per report. These are roughly ten times lower than the contaminated all-four-firm figures (1.4×10⁻⁴, 11.0%, 18.0%); the difference is exactly the within-firm matching that the clean group leaves out. So a clean group of unrelated accountants almost never produces an HC report, which makes HC a high-specificity operating point. (The per-comparison figure rests on a small number of chance hits — 5 of 5×10⁵ pairs — and is best read as an order-of-magnitude value; the per-signature and per-report figures, which are well powered, carry the weight.) A low rate is not a small number at archive scale, and we state the absolute consequence plainly: applied blindly across all 150,442 analyzable Big-4 signatures, the clean per-signature rate alone would be expected to yield about 888 HC flags by chance (95% CI [677, 1,098]), scaling further if the screen is run over the full archive. This is exactly why a single HC flag is never read in isolation: the evidential weight is carried by the firm-level contrast (Section IV-C) and accountant-level aggregation (Section IV-B), not by a raw archive-wide HC count.
**Table II — Chance-firing rates (ICCR) by level and group: the strict HC rule (top two rows), with the looser MC band's per-report rate shown for contrast (bottom row).**
| Group / rule | Per comparison | Per signature | Per report |
|---|---|---|---|
| HC — B/C/D 20132019 (calibration) | 1.0×10⁻⁵ [4×10⁻⁶, 2.3×10⁻⁵] | 0.59% [0.45%, 0.73%] | 1.2% |
| HC — all four firms (contaminated) | 1.4×10⁻⁴ | 11.0% | 18.0% |
| MC band (HC+MC) — B/C/D 20132019 | — | — | ≈17.5% |
Each baseline firm on its own (B, C, D). Reported separately, the three baseline firms are alike and uniformly low. A logistic regression of the per-signature HC flag on firm (with Firm D as the reference) over the baseline cell puts Firms B and C within about 3.5× of each other (odds ratios 1.73 and 0.49), and none of them comes close to the high rates we see for Firm A in Section IV-C. The 20132019 five-way breakdown for each of Firms B/C/D (counts and within-firm percentages) is reported in Table II-b; the full-period (20132023) breakdown is in Table IV for reference.
**Table II-b — Five-way breakdown for each baseline firm, calibration period (B/C/D, 20132019).**
| Firm | HC | MC | HSC | UN | LH | signatures |
|---|---|---|---|---|---|---|
| Firm B | 29.04% | 39.31% | 0.39% | 30.91% | 0.35% | 19,677 |
| Firm C | 21.59% | 42.09% | 0.37% | 35.53% | 0.43% | 22,449 |
| Firm D | 22.01% | 29.67% | 0.20% | 47.35% | 0.76% | 9,945 |
One point in Table II-b needs to be made explicit, because at first glance it looks like a contradiction: the within-firm HC percentages here (Firm B 29.0%, Firm C 21.6%, Firm D 22.0%) are an order of magnitude above the 0.59% chance rate of Table II, even though both are computed on the same clean calibration cell. They are not in tension, because they measure different things. The 0.59% is a *between-accountant* rate — how often the HC rule fires on the signatures of two *different* accountants — and that is the quantity the calibration uses and that stays tiny. The 2129% figures are *within-accountant* rates — how often an accountant's own signatures fire the rule against each other — and a substantial within-accountant rate is exactly what one expects from anyone with a consistent hand or a uniform house style, before any reuse is invoked; at these firms it also carries a genuine but smaller component of image reuse that grows after 2020 (Section V-B). "Clean," in this paper, means the between-accountant coincidence is rare, not that within-accountant similarity is low. This is also why the within-accountant rate cannot be read as a false-positive rate (Section III-E), and why the contrast that isolates Firm A in Section IV-C is not "HC fires at all" but that Firm A's within-accountant rate (82%) stands far above the 2129% of three otherwise-alike firms.
### B. From Categories to Actions: Review as Exception Management
The proportions first, stated plainly. Before saying what to do with each category, we show how much of the data falls into each (Table IV, full corpus): HC 49.6%, MC 26.5%, UN 23.4%, HSC 0.2%, LH 0.3%. The ambiguous middle (MC + UN) is therefore not a fringe: about half of all four-firm signatures, and 6576% at Firms B/C/D individually, against 18.1% at Firm A. Read against the institutional background (Section III-A), this is exactly the expected shape. Firm A behaves in the screen as a reuse-dominated population — a reading consistent with the interviews and with the byte-identical evidence, though it rests on those rather than on per-signature ground truth — and the screen settles most of its signatures outright; Firms B/C/D in this period are mixed populations in which hand-signing and informal individual stamping coexist, so per-signature similarity is genuinely ambiguous there. The right response to a large middle is not to hide it but to give it a disposition path that does not require a per-signature verdict. Four moves do this. To be clear about what is established versus proposed here: the category proportions above, the per-band chance rates, and the byte-identity counts are empirical results, whereas the four moves are a *designed* operating procedure derived from the calibration — they are an argument that the workload is tractable, not a validated workflow. The protocol's end-to-end first run on a bounded, human-labeled sample, which is what would actually measure its discriminating behavior, is left to future work (Section V); we therefore present the moves as the intended use of the calibrated rule, not as evidence in their own right.
Move 1 — calibrate each band's evidential weight, and demote what fails. The calibration tells us what each flag is worth. The HC band fires by chance on only about 1.2% of reports in the clean reference group, so an HC flag is close to self-certifying: it needs essentially no verification effort, and it goes straight onto the action list — findings to count, report, or investigate — rather than onto a list of flags still to be checked. The MC band fires by chance on about 17.5% of reports in the clean reference group — roughly one clean-group report in six — and, unlike HC, this rate does not drop when Firm A's accountants are excluded from the cross-accountant comparison pool (it edges up, because removing Firm A's distinctive template leaves a pool whose members resemble one another a little more at the coarse dHash ≤ 15 scale); the boundary at dHash = 15 also sits in a flat region of the sensitivity sweep, adding flagged cases without adding specificity (Section V-C). An MC flag on its own therefore carries almost no information and does not justify verification effort; it matters only in combination with other evidence. The UN band is ambiguous in the same spirit and is treated alongside MC; on the clean baseline the UN cosine band is reached by chance about 88% of the time per signature (98.2% per report), confirming that a UN flag is essentially uninformative about reuse on its own, whereas the HSC band is reached by chance only about 0.13% of the time per signature (0.25% per report) and in any case points away from reuse (style match without structural support). The HSC band is tiny (0.2%), so it warrants only a light spot-check. The LH band needs no action. Demotion, however, only says what an MC or UN flag is not — standalone evidence; what becomes of these signatures is the business of the next three moves: their information flows into the accountant-level scores (Move 2), which byte-identity hits then sharpen by proving that an accountant's stored image is in circulation (Move 3); the residual's data needs are named rather than guessed at (Move 4); and where a human does look at individual cases, the bounded protocol specified below applies.
Move 2 — lift the unit of decision from the signature to the accountant. The middle categories rarely need to be resolved one signature at a time, because the operational question is almost always about an accountant or a firm, and the ambiguous signatures still carry information at that level. Three accountant-level scores — a mixture-model position score on the two-measure plane, a percentile relative to an external non-Big-4 reference population, and the accountant's own rate of replication-consistent labels — rank the 437 accountants in close agreement (Spearman ρ ≥ 0.879; reported as internal consistency among scores built on the same descriptors, not as external validation). A signature that is individually undecidable still moves its accountant's position; several hundred per-signature questions collapse into one per-accountant judgment.
Move 3 — anchor with byte-identity, the one check that yields certainty. An exact byte-level comparison costs little, and what it finds is proof rather than evidence: independent hand-signing cannot produce byte-identical images, so every byte-identical pair is confirmed reuse with no human judgment required (the corpus contains 262 such signatures; Section IV-C). To be precise about where this bites: a byte-identical pair has cosine 1 and dHash 0, so these signatures sit in HC by construction — byte-identity rescues no case from the ambiguous middle. Its role is twofold. Within HC, it upgrades a subset from high-confidence candidate to logical certainty, removing even the pipeline-and-house-style caveat of Section III-D for those cases — the difference between a statistical screen and an exhibit one can act on without qualification. And at the accountant level, a byte-identical hit proves that a stored image of that accountant is in circulation, which raises the prior on the rest of that accountant's near-identical cluster — including its MC and UN members — and thereby sharpens the per-accountant judgment of Move 2. (A byte-identical pair has cosine = 1 and dHash = 0, so it falls in HC by construction; that the rule "captures" the whole byte-identical set is therefore tautological, and we do not read it as a recall measure.)
Move 4 — state what the residual needs, instead of classifying it anyway. After the three moves, a residual middle remains whose mechanism the two measures genuinely cannot identify: reuse through a noisy pipeline, a very steady hand, and a homogeneous scanning infrastructure can occupy the same spot on the plane. We name the data that would resolve it — a proposed resolution path, not one executed in this study. Image-acquisition metadata is machine-readable provenance that could be extracted automatically rather than judged by eye: scanner identifiers and PDF-generator strings recorded in the files themselves, and compression markers such as JPEG quantization tables, which encode the processing history an image has been through. This adds the axis the two similarity measures lack — two near-identical images that arrived through different production pipelines are hard to explain except by reuse, while two that shared one pipeline may owe their similarity to the pipeline itself. (Whether this provenance survives the upload platform is itself an empirical question, and we checked: we verified across a stratified sample of MOPS reports (all four firms, 20142022) that producer/creator strings, PDF versions, and image encodings are heterogeneous report-to-report — distinct scanner models (Fuji Xerox D125, ApeosPort-III/IV/V), born-digital producers (Microsoft Word, Adobe, Acrobat Distiller), and a mix of CCITT-grayscale and JPEG-RGB encodings at differing resolutions — so the platform does not flatten uploads to a uniform template and the acquisition history is recoverable here; firms' own internal archives would retain at least as much.) A small labeled set of known hand-signed examples — certified by the firms, or accumulated case by case as a by-product of the review protocol below — would turn the chance-rate calibration into directly estimated error rates. Naming these is the honest alternative to pretending the residual can be classified from similarity alone.
Where a human does look, the review follows a defined and bounded protocol. We specify the protocol here as a design deliverable of the method: the discriminating behaviors stated below are design expectations, following from the artifact properties of reused versus independently signed images, and the protocol's first execution, on a bounded sample, is listed as future work (Section VI). (1) Side-by-side overlay inspection: the reviewer is shown the flagged signature next to the same-accountant signature(s) that produced its score, with a pixel-difference overlay and an edge-aligned superposition; a reused image is expected to overlay almost exactly, whereas two independent signings show natural variation in pressure, ink, and baseline. (2) Secondary artifact checks not used by the rule — exact registration, JPEG and scan-noise fingerprints (the compression and anti-aliasing traces a reused raster carries with it), and scaling traces — are designed to separate a reused raster from a re-scanned genuine signature at low cost. (3) Document and time context: the reviewer checks whether the matched signatures come from reports of different dates or engagements (reuse across time is more telling than within a single filing) and whether the surrounding layout shows a standard template or stamp. (4) Bounded per-accountant sampling: because the operational question is usually at the accountant or firm level, the reviewer judges a bounded random sample per accountant rather than every flagged signature, keeping the effort proportional to the number of accountants, not the number of signatures. (5) Feedback into calibration: each adjudicated case yields a label — reuse, hand-signed, or undetermined — and these accumulate into the small ground-truth set the setting otherwise lacks, which can later tighten the operating point or support supervised validation. The protocol's relation to Move 4 is one of scale: steps 13 apply per-case versions of the same artifact evidence that Move 4 would collect corpus-wide, step 4 bounds how many cases a human ever sees, and step 5 accumulates the labeled set Move 4 asks for. What the protocol cannot do — and is not claimed to do — is resolve the residual at scale; that is exactly what the corpus-wide metadata collection of Move 4 would add.
Why this is exception management rather than caseload. Where a firm's output is dominated by reuse, the high-confidence tier settles most signatures directly (82% at Firm A), and the four moves reduce the remaining 18% to per-accountant judgments and a review queue bounded by the number of accountants rather than the number of signatures — exception management at the signature level. In a mixed population the same machinery delivers the same promise one level up, at the accountant. Move 1 removes the bulk of the apparent caseload outright: an MC flag alone does not justify verification, which at Firms B/C/D takes 2941% of signatures off the worklist before anyone is assigned to anything (the UN band carries no flag in the first place, so the demotion bites on MC alone). Move 2 positions every accountant on the replication-dominance spectrum, so attention concentrates on the few high-ranked or mixed cases rather than on tens of thousands of signatures. Move 3 supplies proof where proof exists: 117 of the 262 byte-identical signatures sit at Firms B/C/D, demonstrating that stored-image reuse is a real practice at the mixed firms too, and anchoring the accountant-level judgments there. And the staggered post-2020 adoption of formal systems gives the mixed firms a readable time axis (Section V-B). What is not delivered in a mixed population is a per-signature verdict for the ambiguous middle — a limit of identification, not of workload. Exception management therefore holds in both settings; what changes is only the level at which exceptions are defined — the signature where reuse dominates, the accountant where practices are mixed. Because the cutoffs are tunable, a reviewer who wants higher specificity can tighten them (for example, cosine > 0.98 and dHash ≤ 3), trading a lighter caseload against the risk of missing noisier reused signatures — a trade-off we cannot tune against recall, since recall is unobservable here.
### C. Held-Out Benchmark: Firm A (a Known Positive)
Firm A — described by the interviews as a mainly-stamping firm, and kept out of the calibration — is our main benchmark. Because the interviews already identify it as a stamping firm, it is best read as a *quasi-positive institutional benchmark*: held out from calibration, but a known positive rather than a blinded out-of-sample test. What it can confirm is that the screen's measures move as expected on a firm independently believed to reuse images; what it cannot do is stand in for a blinded evaluation against ground-truth labels, which the corpus does not provide.
(1) Firm A's two measures against the baseline. Comparing Firm A's within-accountant similarities to those of Firms B/C/D (full record, 20132023²), Firm A's cos values are shifted toward 1.0 and its dHash distances toward 0 — the direction we would expect if a stored image is reused rather than re-signed. Concretely, Firm A's within-accountant cosine is centered at a median of 0.986 (mean 0.980) versus 0.959 (mean 0.954) for Firms B/C/D, and its smallest-dHash distance at a median of 2 (mean 2.7) versus 7 (mean 7.0); both shifts are in the reuse direction and overwhelmingly significant (MannWhitney U, p < 10⁻³⁰⁰ for each; two-sample KolmogorovSmirnov D = 0.60 for cosine and 0.57 for dHash). The decisive number is this: scored as a held-out (but not blinded) case — Firm A's signatures matched against unrelated accountants drawn from the clean 20132019 group — Firm A's per-signature cross-firm HC rate is 0.42% (154/36,552; Wilson 95% CI [0.36%, 0.49%]), at or below the clean reference ICCR of 0.59%. In other words, Firm A's cross-firm match rate sits at the level a clean inter-CPA comparison produces by chance — it is not elevated relative to the reference, and it is negligible beside the within-firm rate below — so the entire rise in Firm A's rate comes from matches with other Firm-A signatures, not from resemblance to other firms. The signal is inside the firm, not across firms. (Against the full-period BCD pool the same across-firm rate is 1.0%; the small difference reflects the post-2020 rise in baseline similarity of Section V-B. Both lie at the clean floor, two orders of magnitude below the within-firm rate that follows.)
> ² Restricting both groups to 20132019 gives essentially the same picture (Firm A cosine median 0.986, dHash 2; Firms B/C/D 0.957 and 7; MannWhitney p < 10⁻³⁰⁰ for each), confirming the contrast is not a post-2020 artifact.
Firm A's within-firm repeatability, against the other firms. On their own signatures, the HC rule fires on 82% of Firm A's, versus 2435% for Firms B/C/D. We deliberately report these as raw within-accountant fire rates and do not divide them by the between-accountant clean floor: as Section III-E explains, that floor is the wrong null for a within-accountant question, so an "X× the floor" multiplier would overstate the gap. The firm-to-firm contrast in raw rates is what carries the result. A logistic regression of the per-signature HC flag on firm and pool size, with Firm A as the reference, gives odds ratios of 0.053, 0.010, and 0.027 for Firms B/C/D — one to two orders of magnitude lower (the odds ratio for log pool size is 4.01). Firm A stands alone, against a baseline of three firms that look alike.
Four further checks confirm the contrast is not an artifact of how the comparison pools are built, of the imaging-pipeline trend, or of any single year. First, pool size. Stratifying accountants by how many signatures they contribute and comparing within each stratum, Firm A's HC rate exceeds the other firms' at every level — 66% versus 20% for the smallest pools (under 50 signatures), rising to 7684% versus 2129% for larger pools. Even Firm-A accountants with few signatures to match against fire the rule far more often than B/C/D accountants with the same pool size; pool size raises the rate within every firm (the log-pool-size odds ratio of 4.01), but the firm gap dwarfs it and survives at fixed pool size, which rules out the "more signatures, more chances for an extreme match" explanation. Second, dependence among an accountant's own signatures. Re-estimating the gap with the bootstrap resampled at the accountant level (179 Firm-A accountants, 280 at Firms B/C/D) rather than treating signatures as independent, the Firm-A-minus-B/C/D difference in HC rate is 53.7 percentage points with a 95% interval of [49.5, 57.5] — accountant-level clustering widens the intervals the per-signature Wilson bounds give, but leaves the contrast far too large to be explained away. Third, the time trend and pipeline shift (Section V-B). Adding year fixed effects to the logistic regression — so the firm effect is identified within year, net of the 20202021 imaging-pipeline transition — leaves Firms B/C/D at 0.060.12 times Firm A's odds of an HC flag (odds ratios 0.116, 0.061, 0.070), still an order of magnitude lower once the common time trend is absorbed. Fourth, single-year dependence. Leaving out each calendar year in turn and recomputing, the Firm-A-minus-B/C/D gap stays within 53.154.9 percentage points (full-sample 53.7), so neither the high-reuse digital-native years (20222023) nor any earlier year drives it.
![](figures/fig4.png)
*Figure 4. Within-accountant similarities, Firm A vs Firms B/C/D: (a) cosine, (b) dHash. Firm A's mass sits near cosine = 1 and dHash = 0 (medians 0.986 / 2) against Firms B/C/D's 0.959 / 7; dashed lines mark the cuts (cosine 0.95; dHash 5), the dotted line the LH/UN crossover (0.8547). The held-out cross-firm HC rate (0.42%) sits at/below the clean reference ICCR (0.59%), while the within-Firm-A HC rate is 82% — the signal is inside the firm (annotation below panels).*
(2) Ranking accountants by similarity, in each period. Ranking every accountant in Firms AD by a single within-accountant similarity score, separately for 20132019 and for 20202023, Firm A's accountants sit at the high-similarity (templated) end. A descriptive three-group summary of the two-measure space tells the same story: its high-cosine/low-dHash group holds 82.5% of Firm A's accountants and almost none of the others' (Table III). The period split confirms the expected pattern: Firm A's per-signature HC rate is at the top in both periods (80.3% in 20132019, 83.8% in 20202023), while Firms B/C/D move upward after 2020 as the formal systems came in — Firm B from 29.0% to 42.0%, Firm C from 21.6% to 26.7%, Firm D from 22.0% to 28.0% (see Section V-B).
**Table III — Firm by descriptive-group membership (whole corpus). The "high-cosine/low-dHash group" is the templated-end cluster of the three-group (K = 3) descriptive Gaussian-mixture partition of the accountant-level two-measure plane (Section V-C); membership is the cluster of maximum posterior probability for each accountant with at least ten signatures (437 accountants: 171/112/102/52 across Firms AD). The groups are used for description only, never as operational labels.**
| Firm | Accountants | Share in the high-cosine/low-dHash group |
|---|---|---|
| Firm A | 171 | 82.5% |
| Firm B | 112 | 0.0% |
| Firm C | 102 | 1.0% |
| Firm D | 52 | 1.9% |
![](figures/fig5.png)
*Figure 5. Per-accountant HC rate, ranked, one panel per period (20132019; 20202023), points colored by firm (accountants with ≥ 5 signatures in the period). Firm A (red) occupies the templated top of the ranking in both periods; Firms B/C/D rise after 2020 (HC rate B 29.0→42.0%, C 21.6→26.7%, D 22.0→28.0%; Firm A 80.3→83.8%), consistent with staggered formal-system adoption (Section V-B).*
(3) Applying the calibrated rule to Firm A, 20132023. Taking the operating point calibrated on Firms B/C/D in 20132019 and applying it across Firm A's full record, 81.70% of Firm A's signatures (82% rounded) land in HC (per signature; the full five-way breakdown is in Table IV). Read together with the interview fact that Firm A mainly uses overlay stamping, the system's firm-level output matches the practice the firm itself describes. We say this carefully: it is a match at the firm level, not a label on any single signature. We do not classify the individual signatures as non-hand-signed, because for any one signature the two measures cannot separate reuse from a shared scanning pipeline or a uniform house style (Section III-D).
**Table IV — Five-way breakdown by firm (whole corpus, 20132023; for reference; n = 150,442).**
| Firm | HC | MC | HSC | UN | LH | signatures |
|---|---|---|---|---|---|---|
| Firm A | 81.70% | 10.76% | 0.05% | 7.35% | 0.14% | 60,448 |
| Firm B | 34.56% | 35.88% | 0.29% | 28.95% | 0.32% | 34,248 |
| Firm C | 23.75% | 41.44% | 0.38% | 33.97% | 0.47% | 38,613 |
| Firm D | 24.51% | 29.33% | 0.22% | 45.28% | 0.66% | 17,133 |
| Overall | 49.58% | 26.47% | 0.21% | 23.42% | 0.32% | 150,442 |
Reading the five-way mix across firms. Table IV is also the quantitative basis for the positioning in Section IV-B. At Firm A the ambiguous middle (MC + UN) is 18.1% — the screen reads this population almost cleanly, with four signatures in five settled outright. At Firms B/C/D the middle is 6576% — the signature of a mixed population in which hand-signing and informal stamping coexist (Section III-A), where per-signature similarity is genuinely ambiguous. There the screen's deliverables move up one level (Section IV-B): the MC share (2941% of these firms' signatures, against the 26.5% corpus-wide MC share) is demoted off the worklist, the accountant-level scores rank these firms' accountants alongside everyone else's, and the byte-identical signatures at these firms (117 of the 262) are threshold-free proof that reuse occurs there too. The per-signature mix stays ambiguous; the disposition does not.
Byte-identical signatures: direct evidence of reuse. Beyond the screening numbers, 262 signatures across the four firms are byte-for-byte identical to another signature — 145 of them at Firm A, spread across about fifty partners. Identical files cannot come from independent hand-signing, so their existence is direct, hard evidence that image reuse happens and that it concentrates at Firm A. These pairs are not a bookkeeping artifact: every one of the 262 matches a signature in a *different* report PDF (none is the same file double-counted), and 170 of the 262 fall in different filing months, so duplicate filings or corrected re-submissions of one report cannot explain them. One caveat belongs with this count, developed in Section V-B: most of the 262 (232) occur in the post-2020 digital-native era, where exact reuse is both easier and perfectly preserved, so the raw count is not a clean prevalence trend; the pipeline-independent core is the 30 in the pre-2021 pure-scan era (18 at Firm A), which scanning noise alone cannot produce. Because a byte-identical pair has cosine = 1 and dHash = 0, it lands in HC by definition; the rule's "100% capture" of this set is therefore tautological, and we do not read it as a sanity check or a lower bound on recall. We use byte-identity only for what it can show directly — that reuse occurs and where it concentrates — as a prevalence signal, not a measure of detector performance.
## V. Other Analyses
This section gathers analyses that support the design and test its robustness: (a) the diagnostic showing the data contain no natural cutoff — the premise the whole calibration rests on; (b) how the baseline behaves after 2020; and (c) sensitivity checks.
### A. Why the Data Contain No Natural Cutoff
This diagnostic backs the design choice announced in Section III-D and Section III-E: that no cutoff can be read off the data, so the operating point has to be set from an outside reference. The Hartigan dip test [37] rejects a single-peak shape for both measures at the Big-4-pooled accountant level (p < 5×10⁻⁴), which might look like a clean split into two groups. But that rejection comes from two side-effects. Once we remove the differences between firms (by centering each firm on its own mean) and the effect of the hash taking only whole-number values (by adding a small jitter to dHash), the single-peak shape comes back (median p = 0.35 over jitter seeds). Tested firm by firm, each Big-4 firm is already unimodal on both axes (Firm A p_cos = 0.99, p_dHash = 0.92; B/C/D pooled p_cos = 0.998, p_dHash = 0.91), so the pooled rejection is a between-firm location-shift artifact, not within-population bimodality. A density-smoothness test in the BurgstahlerDichev / McCrary style [38], [39] finds no real break in either measure at the Big-4 scope (Appendix A.1 shows the apparent signature-level breaks drift with histogram bin width and sit inside the high-similarity region — a resolution artifact, not an antimode). So the data hold no real gap; per-signature similarity is best read as one continuous spread of quality, not two separate classes. This is exactly why the operating point is set from an outside reference (Section III-E) rather than read off the data, and why the three groups used for description in Section IV-C are treated as a summary of composition, not as real mechanisms.
A property of the cosine measure reinforces this and explains why the rule never leans on cosine alone. On these fixed-size, white-padded, ImageNet-normalized crops the within-accountant cosine is compressed into a narrow band at the top of its range: 97.7% of signatures score above 0.90, the median is 0.969, and only 0.3% fall below 0.85 (Appendix). Two signatures of the same accountant are highly cosine-similar whether the hand is steady or the image is reused, because the shared crop geometry and normalization contribute a common-structure baseline before any signature content is compared. The high cosine cut (0.95) therefore sits *inside* this saturated region — about three-quarters of signatures lie above it — so cosine on its own separates almost nothing; the structural dHash measure does the discriminating, which is why HC requires both and the cosine-only HSC band carries no evidential weight (Section III-D). We do not try to decompose this cosine baseline into its preprocessing and genuine-style parts here: doing so cleanly would mean re-extracting features with the padding and normalization ablated, which we flag as the way to quantify the preprocessing contribution and as a construct-validity check for future work.
### B. Time Trend and the FirmPipeline Confound (Secondary)
Looking only at Firms B/C/D, the strict rule's chance rate rises after 2020 (per comparison from 1.0×10⁻⁵ to 3.6×10⁻⁵; per signature from 0.59% to 1.05%), and the deployed HC rate rises in parallel (Firm B 29.0→42.0%, Firm C 21.6→26.7%, Firm D 22.0→28.0% across the two periods, Section IV-C). The rise is heterogeneous in timing rather than a common step. Tracing the yearly HC rate, Firm C's increase is concentrated in 2022 (about 18% through 2021, then ~30% in 2022 and ~40% in 2023) and Firm B's mainly in 2023 (about 33% in 2022, ~54% in 2023), while Firm D rises gradually with no visible step; Firm A, by contrast, is already high throughout the decade (80.3→83.8%) with no adoption-like jump — consistent with the interviews' account of long-standing stamping. This firm-by-firm staggering is what one would expect from progressive, independent adoption of formal signing systems (Section III-A), and it is why we limit the calibration to the pre-2020 years. Table II-c gives the full five-way breakdown by firm for the 20202023 deployment period, as a companion to the calibration-period Table II-b and for direct cross-checking against the proportions quoted here and in Section IV-C.
**Table II-c — Five-way breakdown by firm, deployment period (Firms AD, 20202023).**
| Firm | HC | MC | HSC | UN | LH | signatures |
|---|---|---|---|---|---|---|
| Firm A | 83.84% | 9.13% | 0.04% | 6.88% | 0.11% | 23,898 |
| Firm B | 42.01% | 31.24% | 0.16% | 26.31% | 0.28% | 14,571 |
| Firm C | 26.74% | 40.55% | 0.40% | 31.80% | 0.51% | 16,164 |
| Firm D | 27.98% | 28.85% | 0.24% | 42.42% | 0.51% | 7,188 |
We deliberately stop short of reading this as a *detected* e-signing effect, because of a confound these data cannot break: firm identity — and period within a firm — bundles signing practice together with the entire imaging pipeline, and that pipeline demonstrably changes across the decade. We audited the production provenance of a stratified sample of 880 report PDFs (20 per firm-year) from their embedded metadata and page structure. The shift is stark (Table V): through 2020, reports are overwhelmingly plain scanned rasters — 7085% in the early years carry no text layer at all, and their PDF metadata names the scanning hardware directly (for example "Fuji Xerox D125" and "ApeosPort-IV 7080") — whereas from 2021 plain scans collapse to about 12% as firms move to OCR'd and digital-native production. The two similarity measures are therefore computed on a substrate that itself transforms around 20202021, exactly when the baseline firms' similarity rises; firms also differ from one another in this respect (Firm A adopts digital-native output earliest, Firm C latest), though the cross-firm gap is much smaller than the temporal one. A post-2020 rise in similarity could thus come from this coincident pipeline change just as easily as from a change in how signatures are applied (Section III-D), and with no labels and no externally-dated adoption events the two are not separable here.
**Table V — Imaging-pipeline audit: production type by year (stratified sample, 880 PDFs, 20 per firm-year). "Scanned" = no extractable text layer; "digital-native" = text-based PDF with embedded image objects; the remainder are scanned-then-OCR'd.**
| Year | Scanned % | Digital-native % | Year | Scanned % | Digital-native % |
|---|---|---|---|---|---|
| 2013 | 82 | 0 | 2019 | 56 | 0 |
| 2014 | 76 | 0 | 2020 | 52 | 0 |
| 2015 | 85 | 0 | 2021 | 1 | 7 |
| 2016 | 70 | 2 | 2022 | 2 | 16 |
| 2017 | 50 | 0 | 2023 | 2 | 30 |
| 2018 | 55 | 0 | | | |
This same transition qualifies the byte-identity evidence (Section IV-C), which we flag rather than let the raw count mislead. Of the 262 byte-identical signatures, 232 fall in the digital-native era (20212023), where embedding a discrete signature image makes exact reuse both easy to do and perfectly preserved — so the post-2020 surge in byte-identical pairs is inflated by detectability and should not be read as a purely behavioral increase. The pipeline-robust core is the 30 byte-identical signatures in the pre-2021 pure-scan era, 18 of them at Firm A: two independently hand-signed pages, separately scanned, cannot yield byte-identical crops, so these are direct evidence of digital image reuse that predates the digital-native transition and concentrates at Firm A. This is also why Firm A's elevation, present throughout the scanned years, cannot be an artifact of digital-native embedding.
The clean way to separate them would be an event study that aligns each firm to its own externally-documented e-signing adoption date and absorbs static firm differences and common-year shocks with firm and year fixed effects; a within-firm jump locked to each firm's own adoption month would be evidence for signing practice over static pipeline. We do not possess those adoption dates — and inferring them from the very HC series we would then test would be circular (Section III-E) — so we flag this event study as the natural next step rather than a result we can claim here. For this paper the trend serves only its narrower purpose: it justifies the pre-2020 calibration window and stands as a robustness check, not as a causal finding.
### C. Sensitivity and Robustness
We summarize the robustness checks here; full detail is in the supplementary materials.
How sensitive the operating point is. Right around the HC cutoff the per-signature firing rate changes quickly — its local slope is about 25× the median across a cosine sweep and about 3.8× across a dHash sweep — which confirms that the HC point is a chosen, specificity-anchored operating point rather than a natural gap.
A single slope understates how the rule behaves, so we map the full surface rather than defend one cut. Figure 6 plots, over the entire (cosine cut × dHash cut) plane, the clean-group flag rate (panel a) and the Firm A B/C/D flag-rate contrast (panel b), and neither view favors the chosen cut by construction. First, the surfaces are smooth: there is no cliff at (0.95, dHash ≤ 5), so the operating point is a readable choice on a continuous trade-off rather than a discovered boundary (Section V-A), and an operator who wants a tighter floor can move toward higher cosine and lower dHash and read the consequence off the surface. Second, the firm contrast is not an artifact of the threshold: it exceeds 45 percentage points across a broad region of low-dHash, high-cosine cuts and in fact grows as the cut tightens (for example 58 pp at cosine 0.97, dHash ≤ 3), so the deliberately looser HC point trades a few points of contrast for catching more reuse, not the reverse. The same surface makes the weakness of the cosine-only direction explicit: extending the structural cut to the MC bound (dHash ≤ 15) roughly halves the contrast (to about 27 pp) while sharply inflating the clean-group flag rate. That is precisely why the MC band is only advisory and the cosine-only HSC band carries no weight (Section III-D): the partition is not drawn to flatter the narrative, and the surface shows directly where each band earns its keep and where it does not.
![](figures/fig6.png)
*Figure 6. Sensitivity surface of the deployed rule over the two-measure threshold plane (Big-4, n = 150,442). (a) Clean-group (B/C/D) flag rate at each (cosine cut, dHash cut); the chosen HC operating point (star) sits in a low-rate, high-specificity region with no cliff. (b) Firm A minus B/C/D flag-rate contrast (percentage points); the contrast exceeds 45 pp across a broad low-dHash, high-cosine band and weakens toward the MC bound (dHash ≤ 15, dotted), so the operating point is not a cherry-picked threshold and the MC band is visibly the less discriminating region.* The MC/HSC boundary at dHash = 15 sits in a flat (saturating) region, where moving the line adds flagged cases without adding specificity; this is a further reason to treat the MC band as advisory (Section IV-B).
Leaving out one firm at a time. A two-group fit is unstable across firms — its boundary is basically a "Firm A versus the rest" divider — while a three-group fit keeps a stable shape (its low-cosine/high-dHash group drifts by at most 0.005 in cosine) but a membership that shifts with the mix of firms (by up to 12.8 percentage points). So we use the groups only as descriptions, never as operational labels.
Crossover scope. The low cosine cut is the same-vs-different-accountant cosine crossover; recomputing it across scopes moves it by at most 0.025 — 0.8547 on the calibration cell (the primary value; Section IV-A), 0.8367 corpus-wide, 0.8489 on the all-period baseline firms, 0.8302 with the non-Big-4 firms added — and because the cut affects only the UN/LH boundary, switching among these scopes changes no HC/MC/HSC result and shifts the UN/LH split by at most 0.4 percentage points per firm. We use the calibration-cell value as primary for held-out discipline and report the others as robustness.
The same-pair variant. A reader may worry that the deployed rule is a *derived* statistic rather than an observation: the cosine maximum and the dHash minimum are each taken over the accountant's pool and can originate from different partner signatures, so the high-confidence region might in principle be assembled from two unrelated extrema. We therefore recompute the rule under the strict *same-pair* construction, where a single partner signature must satisfy both inequalities at once (Section III-D), and report it in the main text rather than the supplement. Two views agree. First, the within-firm concentration of cross-accountant matches is higher under same-pair (97.099.96% across the four firms) than under the deployed any-pair rule (76.798.8%). Second, and more directly, the per-signature HC flag rate — the quantity the any-pair concern targets — behaves the same way (Table VI): requiring one partner to satisfy both inequalities lowers every firm's rate, as expected, but it *widens* the firm gap rather than narrowing it. Firm A still fires on a majority of its own signatures (57.3%) while the baseline firms fall to 59%, so the Firm-A-to-baseline ratio rises from about 2.43.4× under any-pair to about 6.410.8× under same-pair. The high-confidence region is therefore not an artifact of combining extrema from different partner signatures; pushed to the stricter event, the structure gets stronger.
**Table VI — HC flag rate by firm under the deployed any-pair rule and the strict same-pair rule.**
| Firm | Signatures | Any-pair HC | Same-pair HC |
|---|---|---|---|
| Firm A | 60,448 | 81.7% | 57.3% |
| Firm B | 34,248 | 34.6% | 9.0% |
| Firm C | 38,613 | 23.7% | 5.3% |
| Firm D | 17,133 | 24.5% | 7.7% |
| All Big-4 | 150,442 | 49.6% | 27.3% |
Each gate adds specificity. On the all-four-firm pool the cosine gate alone fires per comparison at 6.0×10⁻⁴; adding the structural gate multiplies this by 0.234 (the conditional ICCR of dHash ≤ 5 given cos > 0.95), giving the joint 1.4×10⁻⁴. Each axis contributes specificity beyond the other — quantitative support for the two-gate design over either measure alone (Section I, Section III-D).
Which network we use. We compare ResNet-50 against VGG-16 and EfficientNet-B0 under the same preprocessing and L2 normalization (Appendix A; supplementary backbone-ablation table). EfficientNet-B0 gives the largest intra/inter separation (Cohen's d = 0.707) but also the widest descriptor spread (intra std 0.123 vs ResNet-50's 0.098); VGG-16 is worst on every key metric despite its larger 4096-dim features. ResNet-50 is the best overall balance: its Cohen's d (0.669) is competitive, its tighter distributions give more stable per-signature behavior, it yields the highest Firm A all-pairs 1st-percentile similarity (0.543), and its 2048-dim features are a practical compromise for processing 182K+ signatures. The comparison supports ResNet-50.
### D. Threats to Validity
For the reader's convenience we collect the main threats to validity in one place, each with a pointer to where it is treated and, where relevant, the direction of its bias. They are consequences of working without labels, and we state them as limitations rather than dissolve them.
1. *No signature-level ground truth.* The archive labels no signature as hand-signed or reused, so we report no recall, precision, ROC-AUC, or false-rejection rate, and every rate is a chance rate, not an error rate (Section III-D, Section VI).
2. *Wrong null for the reuse question.* The ICCR is a between-accountant coincidence rate; the within-accountant false-positive rate the question needs is not estimable and the ICCR is not even a bound on it, so "X× the floor" comparisons are avoided as anti-conservative (Section III-E, Section IV-C).
3. *Reference-group contamination / circular selection.* The clean floor is conditional on the reference group truly being clean; undetected reuse there would only raise the floor, biasing the Firm-A contrast conservatively, and the floor does not hinge on any single baseline firm (Section III-E).
4. *Pool-size and extremal dependence.* The rule takes a maximum over a pool, so larger pools mechanically raise fire rates; the firm contrast nonetheless holds within every pool-size stratum and under accountant-clustered resampling (Section IV-C).
5. *Firmpipeline confound.* Firm identity bundles signing practice with the imaging pipeline (crop geometry and reuse rates differ by firm), and internal timing cannot separate the two without externally-dated adoption events; a fixed-effects event study is the natural next step (Section V-B).
6. *Preprocessing and construct validity.* Padding and ImageNet normalization compress cosine into a narrow high band, so cosine alone discriminates little and the rule relies on the structural measure; a padding/normalization ablation is needed to quantify the preprocessing contribution (Section V-A).
7. *Generalizability.* Calibration is on a Chinese-signature corpus from one jurisdiction with a specific pipeline; the operating point is a starting reference for comparable pipelines, not a transplantable constant, and requires recalibration elsewhere (Section III-D, Section VI).
8. *Non-reproducible corroboration and an unrun protocol.* The interviews are self-reported and not reproducible, so agreement with them shows consistency with domain knowledge, not measured accuracy (Section III-A); and the review protocol of Section IV-B is a designed procedure whose validating first run remains future work.
## VI. Conclusion
We have presented a label-free, anchor-calibrated way to screen for non-hand-signed signatures in large numbers of audit reports. It has three working parts — a pipeline that takes raw PDFs through page-finding, detection, feature extraction, and a two-measure similarity step; a pair of measures that separate style consistency from image reproduction; and, in place of a natural cutoff we do not have and labeled data we cannot get, a calibration based on how often the rule fires by chance in a clean reference group. That calibration yields both a between-accountant specificity proxy and a concrete operating point: the high-confidence rule almost never fires by chance on the clean group, so it is a usable, highly specific screen, with a defined, bounded human-review protocol (Section IV-B) for the advisory and uncertain cases. Operationally the screen earns its keep in two ways: run over an archive, it discovers where reuse concentrates; and it keeps human review at the scale of exceptions in both kinds of population — settling most signatures directly where reuse dominates, and, where practices are mixed, demoting the low-specificity band, ranking accountants, and confirming the byte-identical cases, withholding only the per-signature verdict for the ambiguous middle. We report the category proportions that make that distinction concrete. Because it is calibrated on a large Chinese-signature corpus and uses script-agnostic image descriptors, the rule offers a practical starting reference for comparable Chinese-signature pipelines and, in principle, an approach portable to other scripts — subject in each case to recalibration on the new setting. Held out as a known-positive benchmark, one firm stands alone in how alike its own signatures are, its output matches the stamping practice the firm itself describes, and byte-identical signatures give direct evidence that reuse happens and concentrates there.
The limits are built into working without labels, and we have stated them alongside the design. There is no signature-level ground truth, so we report no false-rejection rate, recall, ROC-AUC, or precision; every rate we give is a between-accountant chance rate read as a proxy for specificity, not a true false-acceptance rate, and not even a bound on the within-accountant false-positive rate the reuse question would need (Section III-E). The contrast between firms is something the method can see, not a finding about why the signatures look alike: for any single signature, the two measures cannot separate reuse from a shared scanning pipeline or a uniform house style, and for Firms B/C/D we make no claim about firm practice at all. Whether firm-level signing patterns matter for audit quality is a question for a dedicated companion study — one this screening points toward, together with the low-presence character of proxy-executed stamping shown in the behavioral literature, but one that similarity alone cannot settle.
Four directions follow. First, a set-level reading of each accountant: judging the shape of an accountant's whole signature set — a tight cluster that recurs near-identically across reports and years (the signature of a stored image) versus a dispersed cloud (the signature of a hand) — instead of per-signature extrema. This would collapse much of the remaining middle into a few per-accountant cluster decisions, and it is the natural tool for separating the mixed signers of the baseline firms, whose sets may contain both a tight recurring sub-cluster and a dispersed remainder if both practices are present. We view this as the highest-value methodological extension, while noting honestly that it narrows but does not remove the fundamental ambiguity: a very steady hand and a noisy reused image can still meet in the middle of any set-level statistic. A first-pass probe on the calibration cell is consistent with this caution — across the 206 of the 226 Firms-B/C/D 20132019 accountants with enough signatures for a set-level shape to be estimated, the within-accountant similarity forms a continuum that piles up just below the high-similarity cut rather than splitting into a tight reused cluster and a dispersed hand-signed cloud (no accountant shows a tight-versus-remainder cosine gap above 0.10), so the no-natural-cutoff structure of Section V-A recurs at the accountant level; we therefore treat set-level adjudication as a research direction rather than a ready robustness result. Second, executing the review protocol of Section IV-B on a bounded sample — its first run — would both test the protocol's expected discriminating behavior and accumulate the small human-labeled set that permits supervised validation and direct error rates. Third, image-acquisition metadata (scanner identifiers, PDF-generator fingerprints, compression markers) adds a provenance axis that could help resolve the pipeline-versus-reuse ambiguity similarity alone cannot; we confirmed this metadata survives in the present corpus rather than being flattened by the platform, though its discriminative power remains to be validated (Section IV-B, Move 4). Fourth, the audit-quality question itself: whether firm-level signing patterns correlate with audit outcomes, for which this screening supplies the measurement layer.
## Appendix A. Supplementary Diagnostic Detail
### A.1. BD/McCrary Bin-Width Sensitivity (Signature Level)
The main text (Section III-D, Section V-A) treats the BurgstahlerDichev / McCrary discontinuity procedure [38], [39] as a density-smoothness diagnostic rather than as a threshold estimator. This subsection documents the empirical basis for that framing by sweeping the bin width across four (variant, bin-width) panels: Firm A and full-sample, each in the cosine and dHash direction.
**Table A.I. BD/McCrary bin-width sensitivity (two-sided α = 0.05, |Z| > 1.96).**
| Variant | n | Bin width | Best transition | z_below | z_above |
|---|---|---|---|---|---|
| Firm A cosine (sig-level) | 60,448 | 0.003 | 0.9870 | 2.81 | +9.42 |
| Firm A cosine (sig-level) | 60,448 | 0.005 | 0.9850 | 9.57 | +19.07 |
| Firm A cosine (sig-level) | 60,448 | 0.010 | 0.9800 | 54.64 | +69.96 |
| Firm A cosine (sig-level) | 60,448 | 0.015 | 0.9750 | 85.86 | +106.17 |
| Firm A dHash (sig-level) | 60,448 | 1 | 2.0 | 4.69 | +10.01 |
| Firm A dHash (sig-level) | 60,448 | 2 | no transition | — | — |
| Firm A dHash (sig-level) | 60,448 | 3 | no transition | — | — |
| Full-sample cosine (sig-level) | 168,740 | 0.003 | 0.9870 | 3.21 | +8.17 |
| Full-sample cosine (sig-level) | 168,740 | 0.005 | 0.9850 | 8.80 | +14.32 |
| Full-sample cosine (sig-level) | 168,740 | 0.010 | 0.9800 | 29.69 | +44.91 |
| Full-sample cosine (sig-level) | 168,740 | 0.015 | 0.9450 | 11.35 | +14.85 |
| Full-sample dHash (sig-level) | 168,740 | 1 | 2.0 | 6.22 | +4.89 |
| Full-sample dHash (sig-level) | 168,740 | 2 | 10.0 | 7.35 | +3.83 |
| Full-sample dHash (sig-level) | 168,740 | 3 | 9.0 | 11.05 | +45.39 |
Two patterns are visible. First, the procedure consistently identifies a "transition" under every bin width, but the location drifts monotonically with bin width (Firm A cosine: 0.987 → 0.985 → 0.980 → 0.975 as bin width grows from 0.003 to 0.015; full-sample dHash: 2 → 10 → 9 as bin width grows from 1 to 3), and the Z statistics inflate superlinearly with bin width because wider bins aggregate more mass and shrink the per-bin standard error on a very large sample. Both features are characteristic of a histogram-resolution artifact rather than a genuine density discontinuity. Second, the candidate transitions all locate inside the high-similarity region (cosine ≥ 0.975, dHash ≤ 10) rather than at a between-mode boundary. Taken together, the signature-level BD/McCrary transitions are not a threshold in the usual sense — they are histogram-resolution-dependent local density anomalies inside the high-similarity descriptor region rather than between modes — which supports using BD/McCrary as a density-smoothness diagnostic, not a threshold estimator (Section V-A).
### A.2. Diagnostic Summary
The unsupervised-diagnostic strategy is a set of complementary checks, each addressing one specific failure mode of an unsupervised screening classifier under an explicitly disclosed untested assumption.
**Table A.II. Diagnostics, failure mode addressed, and disclosed untested assumption (abridged).**
| Diagnostic | Failure mode addressed | Disclosed untested assumption |
|---|---|---|
| Composition decomposition (Section V-A) | Whether descriptor multimodality is within-population (mechanism) or between-group (composition + integer artifact); p_median = 0.35 under joint firm-mean centering + integer-tie jitter | Integer-tie jitter and firm-mean centering are unbiased over the descriptor support |
| Per-comparison ICCR (Section IV-A) | Pair-level specificity proxy under a random-pair negative anchor, on the BCD baseline | Inter-CPA pairs are negative; addressed by anchoring on B/C/D and holding Firm A out |
| Pool-normalised per-signature ICCR (Section IV-A) | Deployed-rule specificity proxy at per-signature unit, accounting for pool size | As above + pool replacement preserves the negative-anchor property |
| Document-level ICCR (Section IV-A) | Operational alarm-rate proxy at per-document unit (HC and HC+MC) | As above |
| Firm-heterogeneity logistic regression (Section IV-C) | Multiplicative effect of firm membership on per-signature rate, controlling for pool size | Observations clustered by CPA/firm; cluster-robust SEs are a future check |
| Cross-firm hit matrix (Section IV-C, Section V-C) | Concentration of inter-CPA collisions within source firm | Concentration depends on deployed-rule semantics (same-pair 97.099.96% vs any-pair 76.798.8%) |
| Alert-rate sensitivity sweep (Section V-C) | Local sensitivity of the deployed rule to threshold perturbation | Gradient comparison is descriptive, not a formal plateau test |
| Convergent score Spearman ranking (Section IV-B) | Internal consistency of three feature-derived per-CPA scores | Scores share inputs; not statistically independent |
| Pixel-identical positive capture (Section IV-C) | Prevalence evidence that reuse occurs and where it concentrates | Anchor is tautologically captured by any reasonable threshold; not read as a recall or performance measure |
## Appendix B. Reproducibility Materials
The full table-to-script provenance mapping, script source code, and report artifacts for every numerical table and figure in this paper are provided in the supplementary materials. Scripts run deterministically under fixed random seeds documented there (the inter-CPA candidate sampler uses seed 42 and a retry-loop matching the canonical samplers; CPA-block bootstraps use 1,000 replicates); reviewer reproduction should re-emit artifacts from the listed scripts rather than rely on any local path layout. The calibration baseline (BCD 20132019), the contamination-comparison scope (all-Big-4), the Firm-A out-of-sample scoring, and the five-way classification are all emitted by the same canonical pipeline so that the headline numbers in Tables I, II, II-b, and IV reproduce bit-for-bit.
## References
*References follow IEEE numeric style; entries [41][45] are the behavioral-science and Chinese-script works added in this draft.*
[1] Taiwan Certified Public Accountant Act (會計師法), Art. 4; FSC Attestation Regulations (查核簽證核准準則), Art. 6.
[2] S.-H. Yen, Y.-S. Chang, and H.-L. Chen, "Does the signature of a CPA matter? Evidence from Taiwan," *Res. Account. Regul.*, vol. 25, no. 2, pp. 230235, 2013.
[3] J. Bromley et al., "Signature verification using a Siamese time delay neural network," in *Proc. NeurIPS*, 1993.
[4] S. Dey et al., "SigNet: Convolutional Siamese network for writer independent offline signature verification," arXiv:1707.02131, 2017.
[5] H.-H. Kao and C.-Y. Wen, "An offline signature verification and forgery detection method based on a single known sample and an explainable deep learning approach," *Appl. Sci.*, vol. 10, no. 11, p. 3716, 2020.
[6] H. Li et al., "TransOSV: Offline signature verification with transformers," *Pattern Recognit.*, vol. 145, p. 109882, 2024.
[7] S. Tehsin et al., "Enhancing signature verification using triplet Siamese similarity networks in digital documents," *Mathematics*, vol. 12, no. 17, p. 2757, 2024.
[8] P. Brimoh and C. C. Olisah, "Consensus-threshold criterion for offline signature verification using CNN learned representations," arXiv:2401.03085, 2024.
[9] N. Woodruff et al., "Fully-automatic pipeline for document signature analysis to detect money laundering activities," arXiv:2107.14091, 2021.
[10] S. Abramova and R. Böhme, "Detecting copy-move forgeries in scanned text documents," in *Proc. Electronic Imaging*, 2016.
[11] Y. Li et al., "Copy-move forgery detection in digital image forensics: A survey," *Multimedia Tools Appl.*, 2024.
[12] Y. Jakhar and M. D. Borah, "Effective near-duplicate image detection using perceptual hashing and deep learning," *Inf. Process. Manage.*, p. 104086, 2025.
[13] E. Pizzi et al., "A self-supervised descriptor for image copy detection," in *Proc. CVPR*, 2022.
[14] L. G. Hafemann, R. Sabourin, and L. S. Oliveira, "Learning features for offline handwritten signature verification using deep convolutional neural networks," *Pattern Recognit.*, vol. 70, pp. 163176, 2017.
[15] E. N. Zois, D. Tsourounis, and D. Kalivas, "Similarity distance learning on SPD manifold for writer independent offline signature verification," *IEEE Trans. Inf. Forensics Security*, vol. 19, pp. 13421356, 2024.
[16] L. G. Hafemann, R. Sabourin, and L. S. Oliveira, "Meta-learning for fast classifier adaptation to new users of signature verification systems," *IEEE Trans. Inf. Forensics Security*, vol. 15, pp. 17351745, 2020.
[17] H. Farid, "Image forgery detection," *IEEE Signal Process. Mag.*, vol. 26, no. 2, pp. 1625, 2009.
[18] F. Z. Mehrjardi, A. M. Latif, M. S. Zarchi, and R. Sheikhpour, "A survey on deep learning-based image forgery detection," *Pattern Recognit.*, vol. 144, art. 109778, 2023.
[19] J. Luo et al., "A survey of perceptual hashing for multimedia," *ACM Trans. Multimedia Comput. Commun. Appl.*, vol. 21, no. 7, 2025.
[20] D. Engin et al., "Offline signature verification on real-world documents," in *Proc. CVPRW*, 2020.
[21] D. Tsourounis et al., "From text to signatures: Knowledge transfer for efficient deep feature learning in offline signature verification," *Expert Syst. Appl.*, vol. 189, art. 116136, 2022.
[22] B. Chamakh and O. Bounouh, "A unified ResNet18-based approach for offline signature classification and verification across multilingual datasets," *Procedia Comput. Sci.*, vol. 270, pp. 40244033, 2025.
[23] A. Babenko, A. Slesarev, A. Chigorin, and V. Lempitsky, "Neural codes for image retrieval," in *Proc. ECCV*, 2014, pp. 584599.
[24] S. Bai et al., "Qwen2.5-VL technical report," arXiv:2502.13923, 2025.
[25] Ultralytics, "YOLO11 documentation," 2024. [Online]. Available: https://docs.ultralytics.com
[26] K. He, X. Zhang, S. Ren, and J. Sun, "Deep residual learning for image recognition," in *Proc. CVPR*, 2016.
[27] N. Krawetz, "Kind of like that," The Hacker Factor Blog, Jan. 21, 2013. [Online]. Available: https://www.hackerfactor.com/blog/index.php?/archives/529-Kind-of-Like-That.html
[28] B. W. Silverman, *Density Estimation for Statistics and Data Analysis*. London: Chapman & Hall, 1986.
[29] J. Cohen, *Statistical Power Analysis for the Behavioral Sciences*, 2nd ed. Hillsdale, NJ: Lawrence Erlbaum, 1988.
[30] Z. Wang, A. C. Bovik, H. R. Sheikh, and E. P. Simoncelli, "Image quality assessment: From error visibility to structural similarity," *IEEE Trans. Image Process.*, vol. 13, no. 4, pp. 600612, 2004.
[31] J. V. Carcello and C. Li, "Costs and benefits of requiring an engagement partner signature: Recent experience in the United Kingdom," *The Accounting Review*, vol. 88, no. 5, pp. 15111546, 2013.
[32] A. D. Blay, M. Notbohm, C. Schelleman, and A. Valencia, "Audit quality effects of an individual audit engagement partner signature mandate," *Int. J. Auditing*, vol. 18, no. 3, pp. 172192, 2014.
[33] W. Chi, H. Huang, Y. Liao, and H. Xie, "Mandatory audit partner rotation, audit quality, and market perception: Evidence from Taiwan," *Contemp. Account. Res.*, vol. 26, no. 2, pp. 359391, 2009.
[34] J. Redmon, S. Divvala, R. Girshick, and A. Farhadi, "You only look once: Unified, real-time object detection," in *Proc. CVPR*, 2016, pp. 779788.
[35] J. Zhang, J. Huang, S. Jin, and S. Lu, "Vision-language models for vision tasks: A survey," *IEEE Trans. Pattern Anal. Mach. Intell.*, vol. 46, no. 8, pp. 56255644, 2024.
[36] H. B. Mann and D. R. Whitney, "On a test of whether one of two random variables is stochastically larger than the other," *Ann. Math. Statist.*, vol. 18, no. 1, pp. 5060, 1947.
[37] J. A. Hartigan and P. M. Hartigan, "The dip test of unimodality," *Ann. Statist.*, vol. 13, no. 1, pp. 7084, 1985.
[38] D. Burgstahler and I. Dichev, "Earnings management to avoid earnings decreases and losses," *J. Account. Econ.*, vol. 24, no. 1, pp. 99126, 1997.
[39] J. McCrary, "Manipulation of the running variable in the regression discontinuity design: A density test," *J. Econometrics*, vol. 142, no. 2, pp. 698714, 2008.
[40] A. P. Dempster, N. M. Laird, and D. B. Rubin, "Maximum likelihood from incomplete data via the EM algorithm," *J. R. Statist. Soc. B*, vol. 39, no. 1, pp. 138, 1977.
[41] E. Y. Chou, "Paperless and soulless: E-signatures diminish the signer's presence and decrease acceptance," *Social Psychological and Personality Science*, vol. 6, no. 3, pp. 343351, 2015.
[42] E. Y. Chou, "What's in a name? The toll e-signatures take on individual honesty," *Journal of Experimental Social Psychology*, vol. 61, pp. 8495, 2015.
[43] K. Tzelios and L. A. Williams, "The psychological impact of digital signatures: A multistudy replication," *Technology, Mind, and Behavior*, vol. 1, no. 2, 2020.
[44] S. Pal, M. Blumenstein, and U. Pal, "Non-English and non-Latin signature verification systems: A survey," in *Proc. 1st Int. Workshop on Automated Forensic Handwriting Analysis (AFHA)*, 2011, pp. 15.
[45] X. Chen, "Extraction and analysis of the width, gray scale and radian in Chinese signature handwriting," *Forensic Science International*, vol. 255, pp. 123132, 2015.
## Declarations
**Conflict of interest.** The authors declare no conflict of interest with Firm A, Firm B, Firm C, or Firm D, or with any other entity referenced in this work.
**Data availability.** All audit reports analyzed in this study were obtained from the Market Observation Post System (MOPS) operated by the Taiwan Stock Exchange Corporation, a publicly accessible regulatory disclosure platform. The CPA registry used to map signatures to certifying CPAs is publicly available. The reproducibility scripts and trained model weights are provided in the supplementary materials; signature-image release is subject to the firm-anonymization constraints of Section III-A (a de-identified subset and the per-table provenance mapping are included, with the full image set available to reviewers under the platform's public-data terms).
Binary file not shown.
+79
View File
@@ -0,0 +1,79 @@
import sqlite3, numpy as np
from collections import defaultdict
from scipy.stats import gaussian_kde
DB='/Volumes/NV2/PDF-Processing/signature-analysis/signature_analysis.db'
FIRM_A='勤業眾信聯合'; BIG4=('勤業眾信聯合','安侯建業聯合','資誠聯合','安永聯合')
SEED=42; POP=np.array([bin(i).count('1') for i in range(256)],dtype=np.uint8)
def load():
c=sqlite3.connect(f'file:{DB}?mode=ro',uri=True)
r=c.execute("""SELECT s.assigned_accountant,a.firm,s.source_pdf,s.feature_vector,s.dhash_vector,
CAST(substr(s.year_month,1,4) AS INT) FROM signatures s JOIN accountants a ON s.assigned_accountant=a.name
WHERE s.assigned_accountant IS NOT NULL AND a.firm IS NOT NULL AND s.feature_vector IS NOT NULL AND s.dhash_vector IS NOT NULL""").fetchall()
c.close(); return r
def crossover(keep,label):
feats=np.stack([np.frombuffer(r[3],np.float32) for r in keep]).astype(np.float32)
feats/=np.clip(np.linalg.norm(feats,axis=1,keepdims=True),1e-9,None)
cpas=np.array([r[0] for r in keep]); by=defaultdict(list)
for i,c in enumerate(cpas): by[c].append(i)
by={c:np.array(v) for c,v in by.items() if len(v)>=3}; accts=list(by.keys())
pw=np.array([len(by[c])*(len(by[c])-1)/2 for c in accts],float); pw/=pw.sum()
rng=np.random.default_rng(SEED); M=100_000
intra=np.empty(M,np.float32); ci=rng.choice(len(accts),M,p=pw)
for t in range(M):
a,b=rng.choice(by[accts[ci[t]]],2,replace=False); intra[t]=feats[a]@feats[b]
inter=np.empty(M,np.float32)
for t in range(M):
i,j=rng.choice(len(accts),2,replace=False); inter[t]=feats[rng.choice(by[accts[i]])]@feats[rng.choice(by[accts[j]])]
xs=np.linspace(0.3,1.0,10000); diff=gaussian_kde(intra)(xs)-gaussian_kde(inter)(xs)
cr=[float(x) for x in xs[np.where(np.diff(np.sign(diff)))[0]] if 0.6<x<0.99]
print(f' [{label}] crossover {[f"{x:.4f}" for x in cr]} (n={len(keep)}, accts>=3={len(accts)})')
def percomp_bands(keep,label,M=500_000):
feats=np.stack([np.frombuffer(r[3],np.float32) for r in keep]).astype(np.float32)
feats/=np.clip(np.linalg.norm(feats,axis=1,keepdims=True),1e-9,None)
dh=np.stack([np.frombuffer(r[4],np.uint8) for r in keep]); cpas=np.array([r[0] for r in keep])
by=defaultdict(list)
for i,c in enumerate(cpas): by[c].append(i)
accts=[c for c,v in by.items() if len(v)>=1]; rng=np.random.default_rng(SEED)
n=len(keep); ii=rng.integers(0,n,M*2); jj=rng.integers(0,n,M*2)
keepm=cpas[ii]!=cpas[jj]; ii=ii[keepm][:M]; jj=jj[keepm][:M]
cos=np.einsum('ij,ij->i',feats[ii],feats[jj]); d=POP[dh[ii]^dh[jj]].sum(1)
hc=(cos>0.95)&(d<=5); mc=(cos>0.95)&(d>5)&(d<=15); hsc=(cos>0.95)&(d>15)
un=(cos>0.837)&(cos<=0.95); lh=cos<=0.837
print(f' [{label}] per-COMPARISON ICCR (M={len(ii)}): HC {hc.mean():.6f} MC {mc.mean():.6f} HSC {hsc.mean():.6f} UN {un.mean():.4f} LH {lh.mean():.4f}')
def persig_perdoc_bands(keep,label):
n=len(keep); feats=np.stack([np.frombuffer(r[3],np.float32) for r in keep]).astype(np.float32)
feats/=np.clip(np.linalg.norm(feats,axis=1,keepdims=True),1e-9,None)
dh=np.stack([np.frombuffer(r[4],np.uint8) for r in keep]); cpas=np.array([r[0] for r in keep]); docs=np.array([r[2] for r in keep])
ci=defaultdict(list)
for i,c in enumerate(cpas): ci[c].append(i)
ci={c:np.array(v) for c,v in ci.items()}; ps={c:len(v)-1 for c,v in ci.items()}
allidx=np.arange(n); rng=np.random.default_rng(SEED); mc=np.zeros(n,np.float32); md=np.full(n,64,np.int32)
for si in range(n):
p=ps[cpas[si]]
if p<=0: continue
same=ci[cpas[si]]; need=p; cand=[]; att=0
while need>0 and att<10:
dr=rng.choice(n,size=need*2,replace=True); ok=dr[~np.isin(dr,same)]; cand.extend(ok[:need].tolist()); need-=len(ok[:need]); att+=1
cand=np.array(cand[:p],dtype=np.int64)
mc[si]=(feats[cand]@feats[si]).max(); md[si]=int(POP[dh[cand]^dh[si]].sum(1).min())
un=(mc>0.837)&(mc<=0.95); hsc=(mc>0.95)&(md>15)
# per-doc: any signature in band
dd=defaultdict(list)
for i in range(n): dd[docs[i]].append(i)
docs_un=np.mean([un[v].any() for v in dd.values()]); docs_hsc=np.mean([hsc[v].any() for v in dd.values()])
print(f' [{label}] per-SIGNATURE ICCR: UN {un.mean():.4f} HSC {hsc.mean():.6f}')
print(f' [{label}] per-REPORT ICCR: UN {docs_un:.4f} HSC {docs_hsc:.6f} (n_doc={len(dd)})')
rows=load()
bcd_all=[r for r in rows if r[1] in BIG4 and r[1]!=FIRM_A]
bcd_19=[r for r in bcd_all if 2013<=r[5]<=2019]
print("=== ITEM 11: KDE crossover (verify corpus 0.837 / BCD-all 0.8489, then closed-world 2013-2019) ===")
crossover(rows,'corpus-wide (verify ~0.8367)')
crossover(bcd_all,'BCD-only ALL period (verify 0.8489)')
crossover(bcd_19,'BCD 2013-2019 CLOSED-WORLD (NEW primary candidate)')
print("\n=== ITEM 3: UN / HSC full ICCR on BCD 2013-2019 ===")
percomp_bands(bcd_19,'BCD 2013-2019')
persig_perdoc_bands(bcd_19,'BCD 2013-2019')
print("\n=== ITEM 12: n reconciliation ===")
print(f" BCD full-period (2013-2023) signatures = {len(bcd_all)} <- Script53 logged n=89,994")
print(f" BCD 2013-2019 signatures = {len(bcd_19)} <- headline ICCR base (reproduces 0.0059)")
+63
View File
@@ -0,0 +1,63 @@
"""F5 robustness: firm+year fixed-effects logistic regression and leave-one-year-out.
Complements the pool-size stratification and accountant-clustered bootstrap (Section IV-C).
Uses numpy+scipy only (no statsmodels). Reproduces from signature_analysis.db.
"""
import sqlite3, numpy as np
from scipy.optimize import minimize
DB = "/Volumes/NV2/PDF-Processing/signature-analysis/signature_analysis.db"
BIG4 = ('勤業眾信聯合', '資誠聯合', '安侯建業聯合', '安永聯合')
FM = {'勤業眾信聯合': 'A', '安侯建業聯合': 'B', '資誠聯合': 'C', '安永聯合': 'D'}
con = sqlite3.connect(DB); cur = con.cursor()
cur.execute(f"""
SELECT s.excel_firm, CAST(substr(s.year_month,1,4) AS INT) yr,
(CASE WHEN s.max_similarity_to_same_accountant>0.95 AND s.min_dhash_independent<=5 THEN 1 ELSE 0 END) hc,
p.psize
FROM signatures s
JOIN (SELECT accountant_id, COUNT(*) psize FROM signatures
WHERE is_valid=1 AND excel_firm IN ({','.join('?'*4)})
AND max_similarity_to_same_accountant IS NOT NULL AND min_dhash_independent IS NOT NULL
GROUP BY accountant_id) p ON s.accountant_id=p.accountant_id
WHERE s.is_valid=1 AND s.excel_firm IN ({','.join('?'*4)})
AND s.max_similarity_to_same_accountant IS NOT NULL AND s.min_dhash_independent IS NOT NULL
AND s.year_month GLOB '2[0-9][0-9][0-9][0-9][0-9]'
""", BIG4 + BIG4)
rows = cur.fetchall(); con.close()
firm = np.array([FM[r[0]] for r in rows]); yr = np.array([r[1] for r in rows])
hc = np.array([r[2] for r in rows], float); pool = np.array([r[3] for r in rows], float)
n = len(hc); years = sorted(set(yr.tolist()))
# --- firm + year FE logistic (Firm A & first year = reference) ---
cols = [np.ones(n)]; names = ['const']
for f in ['B', 'C', 'D']:
cols.append((firm == f).astype(float)); names.append(f'firm_{f}')
for y in years[1:]:
cols.append((yr == y).astype(float)); names.append(f'yr_{y}')
lp = np.log(pool); lp = (lp - lp.mean()) / lp.std()
cols.append(lp); names.append('logpool_z')
X = np.column_stack(cols)
def nll(b):
z = X @ b
return -np.sum(hc * z - np.logaddexp(0, z)) + 1e-6 * np.sum(b * b)
def grad(b):
p = 1 / (1 + np.exp(-(X @ b)))
return -X.T @ (hc - p) + 2e-6 * b
b = minimize(nll, np.zeros(X.shape[1]), jac=grad, method='L-BFGS-B').x
print("Firm+Year FE logistic (Firm A & first year = ref):")
for nm, bi in zip(names, b):
if nm.startswith('firm') or nm == 'logpool_z':
print(f" {nm:11} coef={bi:7.3f} OR={np.exp(bi):.4f}")
# --- leave-one-year-out firm contrast ---
grp = np.where(firm == 'A', 'A', 'BCD')
def rate(mask, g):
m = mask & (grp == g); return 100 * hc[m].mean()
print("\nLeave-one-year-out (Firm A minus B/C/D HC gap):")
gaps = []
for y in years:
keep = (yr != y); a = rate(keep, 'A'); bb = rate(keep, 'BCD'); gaps.append(a - bb)
print(f" drop {y}: A={a:.1f}% BCD={bb:.1f}% gap={a-bb:.1f}pp")
print(f" full-sample gap={rate(np.ones(n, bool),'A')-rate(np.ones(n, bool),'BCD'):.1f}pp; "
f"LOYO range=[{min(gaps):.1f}, {max(gaps):.1f}]pp")
+70
View File
@@ -0,0 +1,70 @@
import sqlite3
from collections import defaultdict, Counter
import numpy as np
DB='/Volumes/NV2/PDF-Processing/signature-analysis/signature_analysis.db'
FIRM_A='勤業眾信聯合'; BIG4=('勤業眾信聯合','安侯建業聯合','資誠聯合','安永聯合')
ALIAS={'勤業眾信聯合':'A','安侯建業聯合':'B','資誠聯合':'C','安永聯合':'D'}
SEED=42; POP=np.array([bin(i).count('1') for i in range(256)],dtype=np.uint8)
def wilson(k,n,z=1.96):
if n==0: return (None,None)
p=k/n; d=1+z*z/n; c=(p+z*z/(2*n))/d; h=z*np.sqrt(p*(1-p)/n+z*z/(4*n*n))/d
return (max(0,c-h),min(1,c+h))
def load():
c=sqlite3.connect(f'file:{DB}?mode=ro',uri=True); cur=c.cursor()
cur.execute("""SELECT s.assigned_accountant,a.firm,s.source_pdf,s.feature_vector,s.dhash_vector,
CAST(substr(s.year_month,1,4) AS INT) FROM signatures s JOIN accountants a ON s.assigned_accountant=a.name
WHERE s.assigned_accountant IS NOT NULL AND a.firm IS NOT NULL AND s.feature_vector IS NOT NULL AND s.dhash_vector IS NOT NULL""")
r=cur.fetchall(); c.close(); return r
def canonical_sampler(rng,n,n_pool,same_cpa,all_idx):
need=n_pool; cand=[]; att=0
while need>0 and att<10:
draw=rng.choice(n,size=need*2,replace=True); ok=draw[~np.isin(draw,same_cpa)]
cand.extend(ok[:need].tolist()); need-=len(ok[:need]); att+=1
if need>0:
pm=np.ones(n,bool); pm[same_cpa]=False
cand.extend(rng.choice(all_idx[pm],size=need,replace=False).tolist())
return np.array(cand[:n_pool],dtype=np.int64)
def simulate(keep):
n=len(keep); feats=np.stack([np.frombuffer(r[3],np.float32) for r in keep]).astype(np.float32)
nr=np.linalg.norm(feats,axis=1,keepdims=True); nr[nr==0]=1; feats=feats/nr
dh=np.stack([np.frombuffer(r[4],np.uint8) for r in keep]); cpas=np.array([r[0] for r in keep])
cpa_idx=defaultdict(list)
for i,c in enumerate(cpas): cpa_idx[c].append(i)
cpa_idx={c:np.array(v) for c,v in cpa_idx.items()}; ps={c:len(v)-1 for c,v in cpa_idx.items()}
all_idx=np.arange(n); rng=np.random.default_rng(SEED)
mc=np.zeros(n,np.float32); md=np.full(n,64,np.int32)
for si in range(n):
p=ps[cpas[si]]
if p<=0: continue
cand=canonical_sampler(rng,n,p,cpa_idx[cpas[si]],all_idx)
mc[si]=(feats[cand]@feats[si]).max(); md[si]=int(POP[dh[cand]^dh[si]].sum(axis=1).min())
return mc,md
def iccr(keep,label):
mc,md=simulate(keep); n=len(keep)
hc=(mc>0.95)&(md<=5); d2=(mc>0.95)&(md<=15)
un=(mc>0.837)&(mc<=0.95); hsc=(mc>0.95)&(md>15)
print(f"\n== {label} (n_sig={n:,}) ==")
for nm,a in [('HC',hc),('HC+MC',d2),('UN-band',un),('HSC-band',hsc)]:
k=int(a.sum()); lo,hi=wilson(k,n); print(f" ICCR per-sig {nm}: {k/n:.6f} ({k}/{n}) [{lo:.5f},{hi:.5f}]")
def a_oos(rows,label):
A=[r for r in rows if r[1]==FIRM_A]; BCD=[r for r in rows if r[1] in BIG4 and r[1]!=FIRM_A]
bf=np.stack([np.frombuffer(r[3],np.float32) for r in BCD]).astype(np.float32)
bn=np.linalg.norm(bf,axis=1,keepdims=True); bn[bn==0]=1; bf=bf/bn
bdh=np.stack([np.frombuffer(r[4],np.uint8) for r in BCD]); nb=bf.shape[0]
ac=defaultdict(list)
for i,r in enumerate(A): ac[r[0]].append(i)
ps={c:len(v)-1 for c,v in ac.items()}; rng=np.random.default_rng(SEED); hc=np.zeros(len(A),bool)
for i,r in enumerate(A):
p=ps[r[0]]
if p<=0: continue
cand=rng.choice(nb,size=p,replace=True); sf=np.frombuffer(r[3],np.float32).astype(np.float32); sf=sf/max(np.linalg.norm(sf),1e-9)
mc=(bf[cand]@sf).max(); mdv=int(POP[bdh[cand]^np.frombuffer(r[4],np.uint8)].sum(axis=1).min())
hc[i]=(mc>0.95)and(mdv<=5)
k=int(hc.sum()); n=len(A); lo,hi=wilson(k,n)
print(f"\n== Firm A OOS vs {label} BCD pool == per-sig HC: {k/n:.6f} ({k}/{n}) [{lo:.6f},{hi:.6f}]")
rows=load()
bcd_all=[r for r in rows if r[1] in BIG4 and r[1]!=FIRM_A]
bcd_19=[r for r in bcd_all if 2013<=r[5]<=2019]
iccr(bcd_19,'BCD 2013-2019 (verify per-sig HC~0.0059)')
a_oos([r for r in rows if 2013<=r[5]<=2019],'2013-2019')
a_oos(rows,'full-period')
@@ -0,0 +1,84 @@
"""Figure 3 (real data version): 2D density of the two measures over the five-region scheme.
Replaces the earlier schematic with the actual distribution, with axis ticks and the rule cuts.
Reproduces from signature_analysis.db; Big-4, is_valid=1, both measures present."""
import matplotlib
matplotlib.use('Agg')
import matplotlib.pyplot as plt
from matplotlib.colors import LogNorm
from matplotlib.patches import Rectangle
import numpy as np
import sqlite3
DB = "/Volumes/NV2/PDF-Processing/signature-analysis/signature_analysis.db"
BIG4 = ('勤業眾信聯合', '資誠聯合', '安侯建業聯合', '安永聯合')
con = sqlite3.connect(DB)
cur = con.cursor()
cur.execute(f"""
SELECT s.max_similarity_to_same_accountant, s.min_dhash_independent
FROM signatures s JOIN accountants a ON s.assigned_accountant=a.name
WHERE s.max_similarity_to_same_accountant IS NOT NULL
AND s.min_dhash_independent IS NOT NULL
AND a.firm IN ({','.join(['?']*4)})
""", BIG4)
rows = cur.fetchall()
con.close()
cos = np.array([r[0] for r in rows], dtype=float)
dh = np.array([r[1] for r in rows], dtype=float)
n = len(cos)
LO, HI = 0.8547, 0.95
DH1, DH2 = 5, 15
xmin, xmax = 0.70, 1.002
ymin, ymax = -0.5, 30
ycap = 30 # display cap; values above are piled into the top row for visibility
dh_disp = np.minimum(dh, ycap - 0.5)
fig, ax = plt.subplots(figsize=(5.6, 4.4))
# faint region tint behind the density
ax.add_patch(Rectangle((xmin, ymin), LO - xmin, ymax - ymin, facecolor='#bdc3c7', alpha=0.12, zorder=0))
ax.add_patch(Rectangle((LO, ymin), HI - LO, ymax - ymin, facecolor='#f7dc6f', alpha=0.12, zorder=0))
ax.add_patch(Rectangle((HI, ymin), xmax - HI, DH1 - ymin, facecolor='#cb4335', alpha=0.14, zorder=0))
ax.add_patch(Rectangle((HI, DH1), xmax - HI, DH2 - DH1, facecolor='#eb984e', alpha=0.14, zorder=0))
ax.add_patch(Rectangle((HI, DH2), xmax - HI, ymax - DH2, facecolor='#aed6f1', alpha=0.14, zorder=0))
# real 2D density (log counts)
xedges = np.linspace(xmin, xmax, 90)
yedges = np.arange(-0.5, ycap + 0.5, 1.0) # integer dHash bins
H, xe, ye = np.histogram2d(cos, dh_disp, bins=[xedges, yedges])
pcm = ax.pcolormesh(xe, ye, H.T, norm=LogNorm(vmin=1, vmax=H.max()),
cmap='viridis', zorder=1, shading='flat')
cb = fig.colorbar(pcm, ax=ax, pad=0.02)
cb.set_label('signatures per cell (log scale)', fontsize=8)
cb.ax.tick_params(labelsize=7)
# cut lines
ax.axvline(LO, color='gray', ls=':', lw=1.1, zorder=3)
ax.axvline(HI, color='black', ls='--', lw=1.1, zorder=3)
ax.plot([HI, xmax], [DH1, DH1], 'k--', lw=0.9, zorder=3)
ax.plot([HI, xmax], [DH2, DH2], 'k--', lw=0.9, zorder=3)
# region labels
ax.text((xmin + LO) / 2, 24, 'LH', ha='center', fontsize=10, weight='bold', color='#34495e', zorder=4)
ax.text((LO + HI) / 2, 24, 'UN', ha='center', fontsize=10, weight='bold', color='#7d6608', zorder=4)
ax.text((HI + xmax) / 2, 2.2, 'HC', ha='center', fontsize=10, weight='bold', color='#cb4335', zorder=4)
ax.text((HI + xmax) / 2, 9.7, 'MC', ha='center', fontsize=10, weight='bold', color='#a04000', zorder=4)
ax.text((HI + xmax) / 2, 24, 'HSC', ha='center', fontsize=9, weight='bold', color='#21618c', zorder=4)
ax.set_xlim(xmin, xmax)
ax.set_ylim(ymin, ymax)
ax.set_xticks([0.70, 0.75, 0.80, 0.8547, 0.90, 0.95, 1.00])
ax.set_xticklabels(['0.70', '0.75', '0.80', '0.855', '0.90', '0.95', '1.00'], fontsize=7.5)
ax.set_yticks([0, 5, 10, 15, 20, 25, 30])
ax.set_yticklabels(['0', '5', '10', '15', '20', '25', '≥30'], fontsize=7.5)
ax.set_xlabel('cosine similarity to same accountant (style)', fontsize=9)
ax.set_ylabel('min dHash distance (structure)', fontsize=9)
ax.set_title(f'Figure 3. Two-measure plane: real density over the five regions (Big-4, n={n:,})',
fontsize=8.5)
fig.tight_layout()
out = '/Volumes/NV2/pdf_recognize/paper/v13_build/figures/fig3.png'
fig.savefig(out, dpi=200, bbox_inches='tight')
plt.close(fig)
print(f'fig3 density OK: n={n:,}, dHash>=30 piled: {(dh>=ycap).sum()}, written {out}')
@@ -0,0 +1,62 @@
"""Figure 6: two-measure sensitivity surface over the (cosine cut x dHash cut) plane.
Panel A: clean-group (B/C/D) flag rate -- how permissive the operating point is.
Panel B: Firm A minus B/C/D flag-rate contrast (pp) -- discrimination across the plane.
Shows the chosen HC point (0.95, dHash<=5) is not a cherry-picked threshold and exposes
the weaker MC band (dHash<=15). Reproduces from signature_analysis.db (DB columns only).
"""
import matplotlib
matplotlib.use('Agg')
import matplotlib.pyplot as plt
import numpy as np
import sqlite3
DB = "/Volumes/NV2/PDF-Processing/signature-analysis/signature_analysis.db"
BIG4 = ('勤業眾信聯合', '資誠聯合', '安侯建業聯合', '安永聯合')
con = sqlite3.connect(DB); cur = con.cursor()
cur.execute(f"""SELECT CASE WHEN a.firm='勤業眾信聯合' THEN 1 ELSE 0 END isA,
s.max_similarity_to_same_accountant c, s.min_dhash_independent d
FROM signatures s JOIN accountants a ON s.assigned_accountant=a.name
WHERE a.firm IN ({','.join('?'*4)})
AND s.max_similarity_to_same_accountant IS NOT NULL AND s.min_dhash_independent IS NOT NULL""", BIG4)
rows = cur.fetchall(); con.close()
isA = np.array([r[0] for r in rows], bool)
c = np.array([r[1] for r in rows]); d = np.array([r[2] for r in rows])
cA, dA = c[isA], d[isA]; cB, dB = c[~isA], d[~isA]
cos_cuts = np.arange(0.85, 0.9901, 0.0025)
dh_cuts = np.arange(0, 21, 1)
A = np.zeros((len(dh_cuts), len(cos_cuts)))
B = np.zeros_like(A)
for j, cc in enumerate(cos_cuts):
for i, dd in enumerate(dh_cuts):
A[i, j] = 100 * np.mean((cA > cc) & (dA <= dd))
B[i, j] = 100 * np.mean((cB > cc) & (dB <= dd))
contrast = A - B
extent = [cos_cuts[0], cos_cuts[-1], dh_cuts[0], dh_cuts[-1]]
fig, axes = plt.subplots(1, 2, figsize=(10.5, 4.3))
for ax, Z, title, cmap, lab in [
(axes[0], B, '(a) Clean group (B/C/D) flag rate', 'viridis', 'flag rate (%)'),
(axes[1], contrast, '(b) Firm A B/C/D contrast', 'magma', 'contrast (pp)')]:
im = ax.imshow(Z, origin='lower', aspect='auto', extent=extent, cmap=cmap)
cb = fig.colorbar(im, ax=ax, pad=0.02); cb.set_label(lab, fontsize=8); cb.ax.tick_params(labelsize=7)
# operating points
ax.scatter([0.95], [5], marker='*', s=180, color='white', edgecolor='black', zorder=5,
label='HC operating point (0.95, dHash≤5)')
ax.axhline(15, color='white', ls=':', lw=1.0)
ax.text(0.853, 15.4, 'MC upper bound (dHash≤15)', color='white', fontsize=6.5, va='bottom')
ax.set_xlabel('cosine cut', fontsize=9)
ax.set_ylabel('dHash cut (≤)', fontsize=9)
ax.set_title(title, fontsize=9)
ax.tick_params(labelsize=7.5)
ax.legend(loc='lower left', fontsize=6.5, framealpha=0.85)
fig.suptitle('Figure 6. Sensitivity surface of the deployed rule over the two-measure threshold plane (Big-4, n=%d).' % len(c),
fontsize=9, y=1.02)
fig.tight_layout()
out = '/Volumes/NV2/pdf_recognize/paper/v13_build/figures/fig6.png'
fig.savefig(out, dpi=200, bbox_inches='tight')
plt.close(fig)
print(f"fig6 OK n={len(c)}; HC(0.95,5) contrast={contrast[5, np.argmin(abs(cos_cuts-0.95))]:.1f}pp; written {out}")
+58
View File
@@ -0,0 +1,58 @@
import sqlite3, numpy as np
import matplotlib
matplotlib.use('Agg')
import matplotlib.pyplot as plt
DB='/Volumes/NV2/PDF-Processing/signature-analysis/signature_analysis.db'
ALIAS={'勤業眾信聯合':'A','安侯建業聯合':'B','資誠聯合':'C','安永聯合':'D'}
COL={'A':'#c0392b','B':'#2980b9','C':'#27ae60','D':'#8e44ad'}
c=sqlite3.connect(f'file:{DB}?mode=ro',uri=True)
rows=c.execute("""SELECT a.firm, s.max_similarity_to_same_accountant, s.min_dhash_independent,
s.assigned_accountant, CAST(substr(s.year_month,1,4) AS INT)
FROM signatures s JOIN accountants a ON s.assigned_accountant=a.name
WHERE s.max_similarity_to_same_accountant IS NOT NULL AND s.min_dhash_independent IS NOT NULL
AND a.firm IN ('勤業眾信聯合','安侯建業聯合','資誠聯合','安永聯合')""").fetchall()
firm=np.array([ALIAS[r[0]] for r in rows]); cos=np.array([r[1] for r in rows],float)
dh=np.array([r[2] for r in rows],float); acc=np.array([r[3] for r in rows]); yr=np.array([r[4] for r in rows])
A=firm=='A'; BCD=np.isin(firm,['B','C','D'])
# ---- Figure 4: two panels, Firm A vs BCD ----
fig,ax=plt.subplots(1,2,figsize=(9,3.4))
ax[0].hist(cos[A],bins=np.linspace(0.7,1.0,60),density=True,alpha=0.6,color='#c0392b',label='Firm A')
ax[0].hist(cos[BCD],bins=np.linspace(0.7,1.0,60),density=True,alpha=0.5,color='#34495e',label='Firms B/C/D')
ax[0].axvline(0.95,ls='--',c='k',lw=0.8); ax[0].axvline(0.8547,ls=':',c='gray',lw=0.8)
ax[0].set_title('(a) Within-accountant cosine',fontsize=10)
ax[0].set_xlabel('max cosine to same accountant'); ax[0].set_ylabel('density')
ax[0].text(0.952,ax[0].get_ylim()[1]*0.9,'0.95',fontsize=7); ax[0].legend(fontsize=8,frameon=False)
ax[0].annotate('A median 0.986',(0.986,0),(0.80,ax[0].get_ylim()[1]*0.55),fontsize=7,color='#c0392b',arrowprops=dict(arrowstyle='->',color='#c0392b',lw=0.7))
ax[0].annotate('B/C/D median 0.959',(0.959,0),(0.72,ax[0].get_ylim()[1]*0.35),fontsize=7,color='#34495e',arrowprops=dict(arrowstyle='->',color='#34495e',lw=0.7))
bins=np.arange(0,21)-0.5
ax[1].hist(np.clip(dh[A],0,20),bins=bins,density=True,alpha=0.6,color='#c0392b',label='Firm A')
ax[1].hist(np.clip(dh[BCD],0,20),bins=bins,density=True,alpha=0.5,color='#34495e',label='Firms B/C/D')
ax[1].axvline(5,ls='--',c='k',lw=0.8)
ax[1].set_title('(b) Within-accountant dHash',fontsize=10)
ax[1].set_xlabel('min dHash to same accountant'); ax[1].set_ylabel('density')
ax[1].text(5.1,ax[1].get_ylim()[1]*0.9,'5',fontsize=7); ax[1].legend(fontsize=8,frameon=False)
ax[1].text(0.50,0.62,'A median 2 / B,C,D median 7',transform=ax[1].transAxes,fontsize=7)
fig.text(0.5,-0.02,'Cross-firm held-out HC rate 0.42% sits at/below the clean reference ICCR 0.59%; within-Firm-A HC rate is 82%.',ha='center',fontsize=7,style='italic')
fig.tight_layout(); fig.savefig('/tmp/fig4.png',dpi=200,bbox_inches='tight'); plt.close(fig)
# ---- Figure 5: per-accountant HC rate, ranked, per period ----
def hc_by_acc(mask):
out={}
a=acc[mask]; h=((cos[mask]>0.95)&(dh[mask]<=5)).astype(float); f=firm[mask]
for ai in np.unique(a):
m=a==ai
if m.sum()>=5: out[ai]=(h[m].mean(),f[m][0])
return out
fig,ax=plt.subplots(1,2,figsize=(9,3.4),sharey=True)
for j,(lo,hi,ttl) in enumerate([(2013,2019,'(a) 20132019'),(2020,2023,'(b) 20202023')]):
d=hc_by_acc(BCD|A if False else ((yr>=lo)&(yr<=hi)))
items=sorted(d.items(),key=lambda kv:-kv[1][0])
xs=np.arange(len(items)); ys=[v[0]*100 for _,v in items]; cs=[COL[v[1]] for _,v in items]
ax[j].scatter(xs,ys,c=cs,s=10)
ax[j].set_title(ttl,fontsize=10); ax[j].set_xlabel('accountant rank');
if j==0: ax[j].set_ylabel('per-accountant HC rate (%)')
from matplotlib.lines import Line2D
ax[1].legend([Line2D([0],[0],marker='o',ls='',color=COL[k]) for k in 'ABCD'],['Firm A','Firm B','Firm C','Firm D'],fontsize=7,frameon=False,loc='upper right')
fig.tight_layout(); fig.savefig('/tmp/fig5.png',dpi=200,bbox_inches='tight'); plt.close(fig)
print('figs OK', __import__('os').path.getsize('/tmp/fig4.png'), __import__('os').path.getsize('/tmp/fig5.png'))
+75
View File
@@ -0,0 +1,75 @@
import matplotlib
matplotlib.use('Agg')
import matplotlib.pyplot as plt
from matplotlib.patches import FancyBboxPatch, FancyArrowPatch, Rectangle
import numpy as np
# ============ Figure 1: data split grid ============
fig, ax = plt.subplots(figsize=(7, 3.2))
firms = ['Firm A', 'Firm B', 'Firm C', 'Firm D']
periods = ['20132019', '20202023']
# role per (row firm, col period)
def role(f, p):
if f == 'Firm A':
return ('Held-out test 1\n(Firm A, full record)', '#c0392b')
if p == '20132019':
return ('Calibration\n(clean reference)', '#27ae60')
return ('Held-out test 2\n(secondary)', '#2980b9')
for i, f in enumerate(firms):
for j, p in enumerate(periods):
txt, col = role(f, p)
ax.add_patch(Rectangle((j, len(firms)-1-i), 1, 1, facecolor=col, alpha=0.30, edgecolor='black', lw=1))
ax.text(j+0.5, len(firms)-1-i+0.5, txt, ha='center', va='center', fontsize=6.5)
ax.set_xlim(0, 2); ax.set_ylim(0, 4)
ax.set_xticks([0.5, 1.5]); ax.set_xticklabels(periods, fontsize=9)
ax.set_yticks([3.5, 2.5, 1.5, 0.5]); ax.set_yticklabels(firms, fontsize=9)
ax.tick_params(length=0)
for s in ax.spines.values(): s.set_visible(False)
ax.set_title('Figure 1. Data split: calibrate on the clean cell, test everything else', fontsize=9)
fig.tight_layout(); fig.savefig('/tmp/fig1.png', dpi=200, bbox_inches='tight'); plt.close(fig)
# ============ Figure 2: pipeline ============
fig, ax = plt.subplots(figsize=(9, 2.5))
steps = ['Raw PDF\nreport', 'Find signature\npage (VLM)', 'Detect signatures\n(YOLOv11)\n+ red-stamp removal',
'Feature extraction\n(ResNet-50, 2048-d)', 'Two similarities\ncosine (style)\nmin dHash (structure)', 'Five-way\nlabel']
n = len(steps); w = 1.0/n
cols = ['#ecf0f1', '#d6eaf8', '#d5f5e3', '#fcf3cf', '#fadbd8', '#e8daef']
for i, (s, c) in enumerate(zip(steps, cols)):
x = i*w + 0.01
ax.add_patch(FancyBboxPatch((x, 0.30), w-0.02, 0.40, boxstyle='round,pad=0.005,rounding_size=0.02',
facecolor=c, edgecolor='black', lw=1, transform=ax.transAxes))
ax.text(x+(w-0.02)/2, 0.50, s, ha='center', va='center', fontsize=6.8, transform=ax.transAxes)
if i < n-1:
ax.add_patch(FancyArrowPatch((x+w-0.012, 0.50), (x+w+0.002, 0.50), transform=ax.transAxes,
arrowstyle='-|>', mutation_scale=10, lw=1.2, color='black'))
ax.axis('off')
ax.set_title('Figure 2. The screening pipeline', fontsize=9, y=0.92)
fig.savefig('/tmp/fig2.png', dpi=200, bbox_inches='tight'); plt.close(fig)
# ============ Figure 3: two-measure plane, five regions ============
fig, ax = plt.subplots(figsize=(5.2, 4.2))
LO, HI = 0.8547, 0.95
DH1, DH2 = 5, 15
xmin, xmax = 0.70, 1.005
ymin, ymax = -1, 30
# LH (cos<=LO): whole column
ax.add_patch(Rectangle((xmin, ymin), LO-xmin, ymax-ymin, facecolor='#bdc3c7', alpha=0.5))
# UN (LO<cos<=HI)
ax.add_patch(Rectangle((LO, ymin), HI-LO, ymax-ymin, facecolor='#f7dc6f', alpha=0.5))
# high-cosine band subdivided by dHash
ax.add_patch(Rectangle((HI, ymin), xmax-HI, DH1-ymin, facecolor='#cb4335', alpha=0.55)) # HC dHash<=5
ax.add_patch(Rectangle((HI, DH1), xmax-HI, DH2-DH1, facecolor='#eb984e', alpha=0.55)) # MC 5<dHash<=15
ax.add_patch(Rectangle((HI, DH2), xmax-HI, ymax-DH2, facecolor='#aed6f1', alpha=0.6)) # HSC dHash>15
ax.axvline(LO, color='gray', ls=':', lw=1); ax.axvline(HI, color='black', ls='--', lw=1)
ax.plot([HI, xmax], [DH1, DH1], 'k--', lw=0.8); ax.plot([HI, xmax], [DH2, DH2], 'k--', lw=0.8)
ax.text((xmin+LO)/2, 22, 'LH', ha='center', fontsize=11, weight='bold')
ax.text((LO+HI)/2, 22, 'UN', ha='center', fontsize=11, weight='bold')
ax.text((HI+xmax)/2, 2, 'HC', ha='center', fontsize=11, weight='bold', color='white')
ax.text((HI+xmax)/2, 9.5, 'MC', ha='center', fontsize=11, weight='bold')
ax.text((HI+xmax)/2, 22, 'HSC', ha='center', fontsize=10, weight='bold')
ax.text(LO, ymin-1.5, '0.8547', ha='center', fontsize=7); ax.text(HI, ymin-1.5, '0.95', ha='center', fontsize=7)
ax.set_xlim(xmin, xmax); ax.set_ylim(ymin, ymax)
ax.set_xlabel('cosine similarity (style)'); ax.set_ylabel('dHash distance (structure)')
ax.set_title('Figure 3. The two measures and the five regions', fontsize=9)
fig.tight_layout(); fig.savefig('/tmp/fig3.png', dpi=200, bbox_inches='tight'); plt.close(fig)
print('figs 1/2/3 OK')
+63
View File
@@ -0,0 +1,63 @@
"""Imaging-pipeline audit (Table V) + byte-identity era split (Section V-B).
Classifies a stratified sample of report PDFs as scanned / OCR'd / digital-native
from embedded metadata + extractable-text heuristic, and tabulates by year and firm.
Also reports the scan-era vs digital-era split of the 262 byte-identical signatures.
Requires: PyMuPDF (fitz); signature_analysis.db; original PDFs under total-pdf/.
"""
import fitz, os, glob, sqlite3
from collections import defaultdict
fitz.TOOLS.mupdf_display_errors(False)
DB = "/Volumes/NV2/PDF-Processing/signature-analysis/signature_analysis.db"
PDF_ROOT = "/Volumes/NV2/PDF-Processing/total-pdf"
BIG4 = ('勤業眾信聯合', '資誠聯合', '安侯建業聯合', '安永聯合')
FMAP = {'勤業眾信聯合': 'A', '安侯建業聯合': 'B', '資誠聯合': 'C', '安永聯合': 'D'}
con = sqlite3.connect(DB); cur = con.cursor()
# --- stratified sample: 20 distinct PDFs per firm-year ---
cur.execute(f"""
WITH d AS (SELECT DISTINCT excel_firm, substr(year_month,1,4) yr, source_pdf,
ROW_NUMBER() OVER (PARTITION BY excel_firm, substr(year_month,1,4) ORDER BY source_pdf) rn
FROM signatures WHERE excel_firm IN ({','.join(['?']*4)}) AND source_pdf IS NOT NULL)
SELECT excel_firm, yr, source_pdf FROM d WHERE rn<=20 ORDER BY yr""", BIG4)
rows = cur.fetchall()
idx = {os.path.basename(p): p for p in glob.glob(PDF_ROOT + '/*/*.pdf')}
def classify(path):
try:
doc = fitz.open(path)
except Exception:
return None
text = sum(len(doc[i].get_text().strip()) for i in range(min(len(doc), 4)))
doc.close()
return 'DIGITAL' if text > 2000 else ('OCR' if text > 200 else 'SCAN')
byyear = defaultdict(lambda: defaultdict(int))
for firm, yr, fn in rows:
p = idx.get(fn)
if not p:
continue
k = classify(p)
if k:
byyear[yr][k] += 1
print("year | n | scan% | ocr% | digital%")
for yr in sorted(byyear):
d = byyear[yr]; n = sum(d.values())
print(f"{yr} | {n} | {100*d['SCAN']//n} | {100*d['OCR']//n} | {100*d['DIGITAL']//n}")
# --- byte-identity era split ---
cur.execute(f"""
SELECT CASE WHEN year_month<'202101' THEN 'scan-era' ELSE 'digital-era' END era,
CASE excel_firm WHEN '勤業眾信聯合' THEN 'A' WHEN '安侯建業聯合' THEN 'B'
WHEN '資誠聯合' THEN 'C' WHEN '安永聯合' THEN 'D' END firm,
COUNT(*) n
FROM signatures WHERE is_valid=1 AND pixel_identical_to_closest=1
AND excel_firm IN ({','.join(['?']*4)})
GROUP BY era, firm ORDER BY era, firm""", BIG4)
print("\nbyte-identical by era x firm:")
for era, firm, n in cur.fetchall():
print(f" {era} | {firm} | {n}")
con.close()
+28
View File
@@ -0,0 +1,28 @@
"""Table VI: HC flag rate by firm under any-pair (deployed) vs strict same-pair rule.
same-pair dHash = Hamming distance between a signature's dHash and its cosine-closest
same-accountant partner (closest_match_file). Reproduces from signature_analysis.db."""
import sqlite3
from collections import defaultdict
DB="/Volumes/NV2/PDF-Processing/signature-analysis/signature_analysis.db"
BIG4=('勤業眾信聯合','資誠聯合','安侯建業聯合','安永聯合')
FM={'勤業眾信聯合':'A','安侯建業聯合':'B','資誠聯合':'C','安永聯合':'D'}
con=sqlite3.connect(DB);cur=con.cursor()
cur.execute("SELECT image_filename, dhash_vector FROM signatures WHERE dhash_vector IS NOT NULL")
dh={fn:bytes(b) for fn,b in cur.fetchall()}
ham=lambda a,b: bin(int.from_bytes(a,'big')^int.from_bytes(b,'big')).count('1')
cur.execute(f"""SELECT excel_firm,max_similarity_to_same_accountant,min_dhash_independent,closest_match_file,image_filename
FROM signatures WHERE is_valid=1 AND max_similarity_to_same_accountant IS NOT NULL
AND min_dhash_independent IS NOT NULL AND excel_firm IN ({','.join('?'*4)})""",BIG4)
st=defaultdict(lambda:[0,0,0])
for firm,cos,mindh,cmf,imf in cur.fetchall():
f=FM[firm]; st[f][0]+=1
st[f][1]+= (cos>0.95 and mindh<=5)
sp=ham(dh[imf],dh[cmf]) if (cmf in dh and imf in dh) else 99
st[f][2]+= (cos>0.95 and sp<=5)
con.close()
print(f"{'firm':5}{'n':>8}{'any-pair%':>11}{'same-pair%':>12}")
T=[0,0,0]
for f in 'ABCD':
n,a,s=st[f]; T=[T[0]+n,T[1]+a,T[2]+s]
print(f"{f:5}{n:>8}{100*a/n:>10.1f}%{100*s/n:>11.1f}%")
n,a,s=T; print(f"{'all':5}{n:>8}{100*a/n:>10.1f}%{100*s/n:>11.1f}%")
+49
View File
@@ -0,0 +1,49 @@
import sqlite3, numpy as np
DB='/Volumes/NV2/PDF-Processing/signature-analysis/signature_analysis.db'
BCD=('安侯建業聯合','資誠聯合','安永聯合')
c=sqlite3.connect(f'file:{DB}?mode=ro',uri=True)
rows=c.execute("""SELECT s.assigned_accountant, s.max_similarity_to_same_accountant, s.min_dhash_independent
FROM signatures s JOIN accountants a ON s.assigned_accountant=a.name
WHERE a.firm IN ('安侯建業聯合','資誠聯合','安永聯合')
AND CAST(substr(s.year_month,1,4) AS INT) BETWEEN 2013 AND 2019
AND s.max_similarity_to_same_accountant IS NOT NULL AND s.min_dhash_independent IS NOT NULL""").fetchall()
from collections import defaultdict
by=defaultdict(list)
for a,cos,dh in rows: by[a].append((cos,dh))
accs={a:np.array(v) for a,v in by.items() if len(v)>=15}
print(f"BCD 2013-2019: {len(accs)} accountants with >=15 signatures (of {len(by)} total)")
rep=[]; tight=[]; rem_med=[]; klass=[]
for a,v in accs.items():
cos=v[:,0]; dh=v[:,1]
hc=(cos>0.95)&(dh<=5)
rf=hc.mean(); tf=(cos>0.95).mean()
isolated=cos[cos<=0.95]
rm=np.median(isolated) if len(isolated)>=3 else np.nan
rep.append(rf); tight.append(tf); rem_med.append(rm)
klass.append('pure-hand' if rf<0.10 else ('pure-stamp' if rf>0.90 else 'mixed'))
rep=np.array(rep); tight=np.array(tight); rem_med=np.array(rem_med); klass=np.array(klass)
import collections
print("\n=== Per-accountant replication-fraction (HC share) distribution ===")
for lo,hi in [(0,0.1),(0.1,0.3),(0.3,0.5),(0.5,0.7),(0.7,0.9),(0.9,1.01)]:
n=((rep>=lo)&(rep<hi)).sum(); print(f" rep_frac [{lo:.1f},{hi:.1f}): {n:3d} accountants")
print(" class counts:", dict(collections.Counter(klass)))
mixed=klass=='mixed'
print(f"\n=== MIXED accountants (n={mixed.sum()}): is the non-tight remainder dispersed (separable)? ===")
rm_mixed=rem_med[mixed & ~np.isnan(rem_med)]
print(f" remainder (cos<=0.95) median cosine across mixed accountants: median={np.median(rm_mixed):.3f}, IQR[{np.percentile(rm_mixed,25):.3f},{np.percentile(rm_mixed,75):.3f}]")
print(f" fraction of mixed accountants whose remainder median < 0.90 (clearly dispersed): {(rm_mixed<0.90).mean():.2f}")
print(f" fraction with remainder median < 0.85 (very dispersed): {(rm_mixed<0.85).mean():.2f}")
# gap between tight group (cos>0.95) and remainder: per mixed accountant
gaps=[]
for a,v in accs.items():
cos=v[:,0]
t=cos[cos>0.95]; r=cos[cos<=0.95]
if len(t)>=3 and len(r)>=3:
gaps.append(np.median(t)-np.median(r))
gaps=np.array(gaps)
print(f"\n=== Tight-vs-remainder cosine gap (all accountants with both parts, n={len(gaps)}) ===")
print(f" median gap = {np.median(gaps):.3f} (large gap => two-component structure is real & separable)")
print(f" fraction with gap > 0.10: {(gaps>0.10).mean():.2f}")
Binary file not shown.
Binary file not shown.
+38
View File
@@ -0,0 +1,38 @@
# Paper A v13 修訂摘要(給 Jimmy)— 2026-06-23
**現行版本**rev9.1`Paper_full_v13_filled_rev9_20260623.docx` / PDF 同名)。源檔 `paper/v13_build/paper_v13_filled.md`,已 commit+push 至 `paper-a-v4-big4`
**一句話**:用三份 AI 審稿(Gemini 3.1 + ChatGPT 5.5 + Opus 4.8 融合,共 29 點;另加兩輪 ChatGPT 5.5 敵意審稿)逐點修訂。所有新數字皆由資料庫實算、可重現,**未杜撰任何數據**。
---
## 一、核心宣稱「誠實化」(最重要,請確認你能接受降溫幅度)
- **撤回「139×」式比較**。原本「Firm A 觸發率 = 巧合率的 139 倍」是把「同一人重複」除以「不同人互撞」,方向高估。改為只報原始比率(A 82% vs B/C/D 2435%),不再乘除。
- **specificity → specificity proxy**:我們沒有 labeled negatives,明說 ICCR 是「不同會計師間的巧合率」,**不是**真正的偽陽率、連上下界都不是。
- **新增 §III-F「What HC Means and Does Not Mean」**:白紙黑字寫「**HC 不是 reuse 標籤**」——HC 只代表「同一會計師極端重複、且在不相關會計師間罕見」。reuse 是其中一種詮釋,Firm A 由 byte-identical + 訪談另外支撐;**B/C/D 完全不作 reuse 宣稱**。
- **Firm A 改稱 known-positive / quasi-positive benchmark**,不再包裝成嚴格 blinded test(因為訪談早已知道它是 stamping firm)。
- **訪談降為 contextual / corroborative**,明說「非 validation、不可獨立重製」。
## 二、新增的實證強化(讓宣稱更站得住)
- **Table VIany-pair vs same-pair**:審稿質疑「cosine 與 dHash 來自不同配對、HC 是拼湊的」。實算反駁——改用嚴格 same-pair(同一配對需同時滿足兩條件),Firm A 仍 **57.3%**、B/C/D 跌到 59%**A/其他的比值反而從 2.43.4× 升到 6.410.8×**。
- **F5 穩健性四連檢**(§IV-C):pool-size 分層、會計師層 bootstrap(差距 53.7pp [49.5, 57.5])、firm+year 固定效果、逐年剔除(53.1–54.9pp)——firm 差異穿透所有控制。
- **Table V — 影像管線審計(880 份 PDF)**:純掃描比例 2013 **82%** → 2021 **崩到 1%**,metadata 直接點名掃描機型(Fuji Xerox D125 等)。同時:(a) 坐實「事務所=影像管線」混淆是真的;(b) 但 Firm A 在純掃描年代就已高 HC,反證其訊號**不是**數位化 artifact。
- **byte-identical 分期**:262 筆中 30 筆在掃描年代(18 在 Firm A,掃描雜訊無法偽造 → 重用鐵證)、232 筆在數位年代(誠實標註此暴增含「可偵測性」成分)。
- 其餘:Figure 3 換真實密度圖、新增 Figure 6 閾值敏感度面、G5 補「全庫期望巧合 HC ≈ 888 件」。
## 三、需要你知道/拍板的三個判斷
1. **Framing 採「rebalance 不 relabel」**:審稿建議把全文改寫成「無標籤校準方法(審計只是 case study)」。我**沒有照做最強版**——把方法升為主貢獻、但**保留審計發現當 headline**,且**不宣稱 "general framework"**(避免「一個案例憑什麼叫 general」的新攻擊)。請確認你同意這個定位。
2. **不做 within-CPA「真親簽」對照組**:理想上該比「真人親簽的 HC 誤觸率」,但我們沒有標記的親簽資料、公開資料集又是不同族群——硬借會引入新假設。已在 §III-E 主動說明「考慮過、刻意不做」。
3. **PDF 管線發現是雙刃**:它讓「事務所混淆」更嚴重(我們誠實寫出),但同時用掃描年代證據鞏固核心。兩面都寫了,沒挑對我們有利的講。
## 四、剩餘待辦(你/投稿前)
- 作者、機構、DOI、biography placeholderdouble-blind,投稿前補)
- IEEE 模板最終排版;related work 可再收斂;表格 II-b/IV 是否整併
- 人工 review protocol 首次執行(未做,已列 future work
---
*完整逐點對照見 `paper/fusion_review_todo.md`(29/29 已處理)。所有分析腳本在 `paper/v13_build/scripts/`,可一鍵重現。*
+60
View File
@@ -0,0 +1,60 @@
#!/usr/bin/env python3
"""Firm x year descriptor trends (B-gate diagnostic).
Plots per-firm yearly mean cosine, mean dHash, and HC-box hit share to test
whether Firms B/C/D show a 2020 structural break converging toward Firm A.
Read-only against the production DB.
"""
import sqlite3
import matplotlib.pyplot as plt
DB = '/Volumes/NV2/PDF-Processing/signature-analysis/signature_analysis.db'
FIRMS = [('勤業眾信聯合', 'Firm A (Deloitte)', '#d62728'),
('安侯建業聯合', 'Firm B (KPMG)', '#1f77b4'),
('資誠聯合', 'Firm C (PwC)', '#2ca02c'),
('安永聯合', 'Firm D (EY)', '#ff7f0e')]
conn = sqlite3.connect(f'file:{DB}?mode=ro', uri=True)
cur = conn.cursor()
def series(firm_zh):
cur.execute("""
SELECT CAST(substr(s.year_month,1,4) AS INT) AS yr,
AVG(s.max_similarity_to_same_accountant),
AVG(s.min_dhash_independent),
AVG(CASE WHEN s.max_similarity_to_same_accountant>0.95
AND s.min_dhash_independent<=5 THEN 1.0 ELSE 0.0 END),
COUNT(*)
FROM signatures s JOIN accountants a ON s.assigned_accountant=a.name
WHERE a.firm=? AND s.year_month IS NOT NULL
AND s.max_similarity_to_same_accountant IS NOT NULL
AND s.min_dhash_independent IS NOT NULL
GROUP BY yr ORDER BY yr""", (firm_zh,))
return cur.fetchall()
fig, axes = plt.subplots(1, 3, figsize=(16, 4.8))
for firm_zh, label, color in FIRMS:
rows = series(firm_zh)
yrs = [r[0] for r in rows]
axes[0].plot(yrs, [r[1] for r in rows], 'o-', color=color, label=label)
axes[1].plot(yrs, [r[2] for r in rows], 'o-', color=color, label=label)
axes[2].plot(yrs, [r[3] for r in rows], 'o-', color=color, label=label)
for ax in axes:
ax.axvline(2020, ls='--', color='grey', alpha=0.6)
ax.text(2020.05, ax.get_ylim()[0], ' 2020', color='grey', fontsize=8, va='bottom')
ax.set_xlabel('Fiscal year')
ax.grid(alpha=0.3)
axes[0].set_title('Mean best-match cosine'); axes[0].axhline(0.95, ls=':', color='k', alpha=0.4)
axes[1].set_title('Mean independent-min dHash'); axes[1].axhline(5, ls=':', color='k', alpha=0.4)
axes[2].set_title('HC-box share (cos>0.95 & dHash$\\leq$5)')
axes[0].legend(fontsize=8, loc='lower right')
fig.suptitle('Big-4 descriptor trends 20132023 (2023 = partial, to Apr) — no 2020 break, no convergence to A',
fontsize=11)
fig.tight_layout()
out = '/Volumes/NV2/pdf_recognize/signature_analysis/firm_year_trends.png'
fig.savefig(out, dpi=130, bbox_inches='tight')
print('saved', out)
conn.close()
+87
View File
@@ -0,0 +1,87 @@
#!/usr/bin/env python3
"""Script 46: BCD-only (exclude Firm A) per-comparison ICCR recompute.
Replicates 40b's inter-CPA negative-anchor pair sampling (N=500k, seed=42)
but compares three negative-anchor pool compositions:
- ABCD : all Big-4 (current paper baseline)
- BCD : Big-4 excluding Firm A (normative-baseline proposal)
- BCD+nonB4 : BCD plus all non-Big-4 firms
Reports marginal cos>0.95, dHash<=5, and the joint HC rule cos>0.95 & dHash<=5.
Read-only.
"""
import sqlite3
from collections import defaultdict
import numpy as np
DB = '/Volumes/NV2/PDF-Processing/signature-analysis/signature_analysis.db'
N_PAIRS = 500_000
SEED = 42
FIRM_A = '勤業眾信聯合'
BIG4 = ('勤業眾信聯合', '安侯建業聯合', '資誠聯合', '安永聯合')
def hamming(a, b):
return (int.from_bytes(a, 'big') ^ int.from_bytes(b, 'big')).bit_count()
def load():
conn = sqlite3.connect(f'file:{DB}?mode=ro', uri=True)
cur = conn.cursor()
cur.execute("""
SELECT s.assigned_accountant, a.firm, s.feature_vector, s.dhash_vector
FROM signatures s JOIN accountants a ON s.assigned_accountant=a.name
WHERE s.assigned_accountant IS NOT NULL AND a.firm IS NOT NULL
AND s.feature_vector IS NOT NULL AND s.dhash_vector IS NOT NULL""")
rows = cur.fetchall()
conn.close()
return rows
def wilson(k, n, z=1.96):
if n == 0:
return (None, None)
p = k / n
d = 1 + z*z/n
c = (p + z*z/(2*n)) / d
h = z*np.sqrt(p*(1-p)/n + z*z/(4*n*n)) / d
return (max(0.0, c-h), min(1.0, c+h))
def iccr(rows, label):
by = defaultdict(list)
for acct, firm, fv, dh in rows:
by[acct].append((fv, dh))
accts = list(by.keys())
feats = {a: np.stack([np.frombuffer(r[0], dtype=np.float32) for r in by[a]]) for a in accts}
dhs = {a: [r[1] for r in by[a]] for a in accts}
rng = np.random.default_rng(SEED)
cos = np.empty(N_PAIRS, np.float32)
dv = np.empty(N_PAIRS, np.int32)
na = len(accts)
for t in range(N_PAIRS):
i, j = rng.choice(na, 2, replace=False)
a1, a2 = accts[i], accts[j]
k1 = int(rng.integers(0, len(by[a1])))
k2 = int(rng.integers(0, len(by[a2])))
cos[t] = float(feats[a1][k1] @ feats[a2][k2])
dv[t] = hamming(dhs[a1][k1], dhs[a2][k2])
n = N_PAIRS
m_cos = int((cos > 0.95).sum())
m_dh = int((dv <= 5).sum())
joint = int(((cos > 0.95) & (dv <= 5)).sum())
jlo, jhi = wilson(joint, n)
print(f'\n== {label} ==')
print(f' signatures={len(rows):,} accountants={na} pairs={n:,}')
print(f' cos>0.95 ICCR = {m_cos/n:.5f} ({m_cos})')
print(f' dHash<=5 ICCR = {m_dh/n:.5f} ({m_dh})')
print(f' JOINT (HC rule) ICCR = {joint/n:.6f} ({joint}) Wilson95% [{jlo:.6f},{jhi:.6f}]')
return joint/n
rows = load()
abcd = [r for r in rows if r[1] in BIG4]
bcd = [r for r in rows if r[1] in BIG4 and r[1] != FIRM_A]
bcd_non = [r for r in rows if r[1] != FIRM_A]
iccr(abcd, 'ABCD (current paper baseline)')
iccr(bcd, 'BCD only (exclude Firm A)')
iccr(bcd_non, 'BCD + non-Big-4')
@@ -0,0 +1,160 @@
#!/usr/bin/env python3
"""Script 47: BCD-only recompute of (1) KDE crossover, (2) per-signature
pool-normalized any-pair ICCR (cos>0.95 & dHash<=5), (3) per-document HC+MC
inter-CPA ICCR (cos>0.95 & dHash<=15), each for ABCD vs BCD-only negative-anchor
pools. Replicates Scripts 10/43/44 methodology. Document-level subsampling used
for the pool simulation (exact same-CPA pool sizes retained). Read-only.
"""
import sqlite3
from collections import defaultdict
import numpy as np
from scipy.stats import gaussian_kde
DB = '/Volumes/NV2/PDF-Processing/signature-analysis/signature_analysis.db'
FIRM_A = '勤業眾信聯合'
BIG4 = ('勤業眾信聯合', '安侯建業聯合', '資誠聯合', '安永聯合')
ALIAS = {'勤業眾信聯合': 'A', '安侯建業聯合': 'B', '資誠聯合': 'C', '安永聯合': 'D'}
SEED = 42
N_INTRA = 200_000
N_INTER = 500_000
N_DOC_SUBSAMPLE = 9000 # documents processed in pool simulation per scope
def load():
conn = sqlite3.connect(f'file:{DB}?mode=ro', uri=True)
cur = conn.cursor()
cur.execute("""
SELECT s.signature_id, s.assigned_accountant, a.firm, s.source_pdf,
s.feature_vector, s.dhash_vector
FROM signatures s JOIN accountants a ON s.assigned_accountant=a.name
WHERE s.assigned_accountant IS NOT NULL AND a.firm IN (?,?,?,?)
AND s.feature_vector IS NOT NULL AND s.dhash_vector IS NOT NULL""", BIG4)
rows = cur.fetchall()
conn.close()
return rows
def hamming1(q, c):
return (int.from_bytes(q, 'big') ^ int.from_bytes(c, 'big')).bit_count()
def wilson(k, n, z=1.96):
if n == 0:
return (None, None)
p = k/n; d = 1+z*z/n
c = (p+z*z/(2*n))/d
h = z*np.sqrt(p*(1-p)/n+z*z/(4*n*n))/d
return (max(0.0, c-h), min(1.0, c+h))
def kde_crossover(feats, cpas, label):
by = defaultdict(list)
for i, c in enumerate(cpas):
by[c].append(i)
by = {c: np.array(v) for c, v in by.items() if len(v) >= 2}
accts = list(by.keys())
rng = np.random.default_rng(SEED)
# intra: two sigs from same random CPA
intra = np.empty(N_INTRA, np.float32)
ks = rng.integers(0, len(accts), N_INTRA)
for t in range(N_INTRA):
idx = by[accts[ks[t]]]
a, b = rng.choice(idx, 2, replace=False)
intra[t] = feats[a] @ feats[b]
# inter: two sigs from different CPAs
inter = np.empty(N_INTER, np.float32)
for t in range(N_INTER):
i, j = rng.choice(len(accts), 2, replace=False)
a = rng.choice(by[accts[i]]); b = rng.choice(by[accts[j]])
inter[t] = feats[a] @ feats[b]
xs = np.linspace(0.3, 1.0, 10000)
ki = gaussian_kde(intra[:100000]); ke = gaussian_kde(inter[:100000])
diff = ki(xs) - ke(xs)
cross = xs[np.where(np.diff(np.sign(diff)))[0]]
cross = [float(x) for x in cross if 0.6 < x < 0.99]
print(f' [{label}] intra mean={intra.mean():.4f} inter mean={inter.mean():.4f}'
f' KDE crossover(s): {[f"{x:.4f}" for x in cross]}')
return cross
def pool_sim(rows, scope_firms, label):
"""Per-signature & per-document inter-CPA any-pair ICCR over a doc subsample."""
keep = [r for r in rows if ALIAS[r[2]] in scope_firms]
feats = np.stack([np.frombuffer(r[4], np.float32) for r in keep]).astype(np.float32)
feats /= np.clip(np.linalg.norm(feats, axis=1, keepdims=True), 1e-9, None)
cpas = [r[1] for r in keep]
firms = [ALIAS[r[2]] for r in keep]
docs = [r[3] for r in keep]
dh = [r[5] for r in keep]
n = len(keep)
cpa_idx = defaultdict(list)
for i, c in enumerate(cpas):
cpa_idx[c].append(i)
cpa_idx = {c: np.array(v) for c, v in cpa_idx.items()}
pool_size = {c: len(v)-1 for c, v in cpa_idx.items()}
doc_idx = defaultdict(list)
for i, d in enumerate(docs):
doc_idx[d].append(i)
rng = np.random.default_rng(SEED)
all_docs = list(doc_idx.keys())
sub = rng.choice(len(all_docs), min(N_DOC_SUBSAMPLE, len(all_docs)), replace=False)
sel_docs = [all_docs[i] for i in sub]
sig_hc = [] # per-signature: any-pair cos>0.95 & dh<=5
sig_firm = []
doc_hcmc = {} # per-document worst-case: any sig with cos>0.95 & dh<=15
doc_firm = {}
for d in sel_docs:
dhit = False
for si in doc_idx[d]:
c = cpas[si]; npool = pool_size[c]
if npool <= 0:
sig_hc.append(False); sig_firm.append(firms[si]); continue
same = cpa_idx[c]
draw = rng.choice(n, size=min(npool*2+10, n), replace=True)
cand = draw[~np.isin(draw, same)][:npool]
cosv = feats[cand] @ feats[si]
dhv = np.fromiter((hamming1(dh[si], dh[c2]) for c2 in cand), np.int32, len(cand))
cg = cosv > 0.95
hc = bool((cg & (dhv <= 5)).any())
hcmc = bool((cg & (dhv <= 15)).any())
sig_hc.append(hc); sig_firm.append(firms[si])
if hcmc:
dhit = True
doc_hcmc[d] = dhit
doc_firm[d] = firms[doc_idx[d][0]]
sig_hc = np.array(sig_hc); sig_firm = np.array(sig_firm)
k = int(sig_hc.sum()); m = len(sig_hc)
lo, hi = wilson(k, m)
print(f'\n [{label}] per-SIGNATURE any-pair HC ICCR (cos>0.95 & dh<=5): '
f'{k/m:.4f} ({k}/{m}) Wilson95% [{lo:.4f},{hi:.4f}]')
for f in sorted(set(sig_firm)):
msk = sig_firm == f
kk = int(sig_hc[msk].sum()); mm = int(msk.sum())
print(f' Firm {f}: {kk/mm:.4f} ({kk}/{mm})')
dvals = np.array(list(doc_hcmc.values())); dfirm = np.array(list(doc_firm.values()))
dk = int(dvals.sum()); dm = len(dvals)
dlo, dhi = wilson(dk, dm)
print(f' [{label}] per-DOCUMENT HC+MC ICCR (cos>0.95 & dh<=15): '
f'{dk/dm:.4f} ({dk}/{dm}) Wilson95% [{dlo:.4f},{dhi:.4f}]')
for f in sorted(set(dfirm)):
msk = dfirm == f
kk = int(dvals[msk].sum()); mm = int(msk.sum())
print(f' Firm {f}: {kk/mm:.4f} ({kk}/{mm})')
rows = load()
allf = np.stack([np.frombuffer(r[4], np.float32) for r in rows]).astype(np.float32)
allf /= np.clip(np.linalg.norm(allf, axis=1, keepdims=True), 1e-9, None)
allc = [r[1] for r in rows]
abcd_mask = [True]*len(rows)
bcd_mask = [r[2] != FIRM_A for r in rows]
print('=== (1) KDE crossover (intra vs inter cosine) ===')
kde_crossover(allf, allc, 'ABCD')
kde_crossover(allf[bcd_mask], [allc[i] for i in range(len(rows)) if bcd_mask[i]], 'BCD-only')
print('\n=== (2)(3) per-signature & per-document inter-CPA ICCR ===')
pool_sim(rows, {'A', 'B', 'C', 'D'}, 'ABCD (reproduce)')
pool_sim(rows, {'B', 'C', 'D'}, 'BCD-only')
+141
View File
@@ -0,0 +1,141 @@
#!/usr/bin/env python3
"""Script 48: full-fidelity (no subsample) BCD-only recompute of per-signature
and per-document inter-CPA any-pair ICCR, plus corpus-style KDE crossover.
Vectorized popcount. Scopes: ABCD, BCD-only, BCD+non-Big-4. Read-only.
"""
import sqlite3
from collections import defaultdict
import numpy as np
from scipy.stats import gaussian_kde
DB = '/Volumes/NV2/PDF-Processing/signature-analysis/signature_analysis.db'
FIRM_A = '勤業眾信聯合'
BIG4 = ('勤業眾信聯合', '安侯建業聯合', '資誠聯合', '安永聯合')
ALIAS = {'勤業眾信聯合': 'A', '安侯建業聯合': 'B', '資誠聯合': 'C', '安永聯合': 'D'}
SEED = 42
POP = np.array([bin(i).count('1') for i in range(256)], dtype=np.uint8)
def load():
conn = sqlite3.connect(f'file:{DB}?mode=ro', uri=True)
cur = conn.cursor()
cur.execute("""
SELECT s.assigned_accountant, a.firm, s.source_pdf,
s.feature_vector, s.dhash_vector
FROM signatures s JOIN accountants a ON s.assigned_accountant=a.name
WHERE s.assigned_accountant IS NOT NULL AND a.firm IS NOT NULL
AND s.feature_vector IS NOT NULL AND s.dhash_vector IS NOT NULL""")
rows = cur.fetchall()
conn.close()
return rows
def wilson(k, n, z=1.96):
if n == 0:
return (None, None)
p = k/n; d = 1+z*z/n
c = (p+z*z/(2*n))/d
h = z*np.sqrt(p*(1-p)/n+z*z/(4*n*n))/d
return (max(0.0, c-h), min(1.0, c+h))
def prep(rows, keep_fn):
keep = [r for r in rows if keep_fn(r[1])]
feats = np.stack([np.frombuffer(r[3], np.float32) for r in keep]).astype(np.float32)
feats /= np.clip(np.linalg.norm(feats, axis=1, keepdims=True), 1e-9, None)
dh = np.stack([np.frombuffer(r[4], np.uint8) for r in keep]) # (n,8)
cpas = np.array([r[0] for r in keep])
firms = np.array([ALIAS.get(r[1], 'X') for r in keep])
docs = np.array([r[2] for r in keep])
return feats, dh, cpas, firms, docs
def crossover(feats, cpas, label):
by = defaultdict(list)
for i, c in enumerate(cpas):
by[c].append(i)
by = {c: np.array(v) for c, v in by.items() if len(v) >= 2}
accts = list(by.keys())
rng = np.random.default_rng(SEED)
N = 100_000
intra = np.empty(N, np.float32); inter = np.empty(N, np.float32)
ks = rng.integers(0, len(accts), N)
for t in range(N):
idx = by[accts[ks[t]]]
a, b = rng.choice(idx, 2, replace=False)
intra[t] = feats[a] @ feats[b]
i, j = rng.choice(len(accts), 2, replace=False)
inter[t] = feats[rng.choice(by[accts[i]])] @ feats[rng.choice(by[accts[j]])]
xs = np.linspace(0.3, 1.0, 10000)
diff = gaussian_kde(intra)(xs) - gaussian_kde(inter)(xs)
cross = [float(x) for x in xs[np.where(np.diff(np.sign(diff)))[0]] if 0.6 < x < 0.99]
print(f' [{label}] crossover {[f"{x:.4f}" for x in cross]} '
f'(intra {intra.mean():.4f} / inter {inter.mean():.4f})')
def pool_sim(feats, dh, cpas, firms, docs, label):
n = len(cpas)
cpa_idx = defaultdict(list)
for i, c in enumerate(cpas):
cpa_idx[c].append(i)
cpa_idx = {c: np.array(v) for c, v in cpa_idx.items()}
pool_size = {c: len(v)-1 for c, v in cpa_idx.items()}
rng = np.random.default_rng(SEED)
sig_hc = np.zeros(n, bool)
doc_hcmc = defaultdict(bool)
for si in range(n):
c = cpas[si]; npool = pool_size[c]
if npool <= 0:
continue
same = cpa_idx[c]
draw = rng.integers(0, n, size=npool + same.size + 20)
cand = draw[~np.isin(draw, same)][:npool]
cosv = feats[cand] @ feats[si]
cg = cosv > 0.95
if cg.any():
dist = POP[dh[cand] ^ dh[si]].sum(axis=1)
sig_hc[si] = bool((cg & (dist <= 5)).any())
if (cg & (dist <= 15)).any():
doc_hcmc[docs[si]] = True
else:
doc_hcmc.setdefault(docs[si], doc_hcmc[docs[si]] if docs[si] in doc_hcmc else False)
# ensure every doc present
for d in docs:
doc_hcmc.setdefault(d, False)
k = int(sig_hc.sum())
lo, hi = wilson(k, n)
print(f'\n [{label}] per-SIGNATURE any-pair HC (cos>0.95 & dh<=5): '
f'{k/n:.4f} ({k}/{n}) Wilson95% [{lo:.4f},{hi:.4f}]')
for f in sorted(set(firms)):
m = firms == f
print(f' Firm {f}: {sig_hc[m].sum()/m.sum():.4f} ({int(sig_hc[m].sum())}/{int(m.sum())})')
# per-doc, with firm of first sig
dfirm = {}
for i, d in enumerate(docs):
dfirm.setdefault(d, firms[i])
dl = list(doc_hcmc.keys())
dv = np.array([doc_hcmc[d] for d in dl])
df = np.array([dfirm[d] for d in dl])
dk = int(dv.sum()); dm = len(dv)
dlo, dhi = wilson(dk, dm)
print(f' [{label}] per-DOCUMENT HC+MC (cos>0.95 & dh<=15): '
f'{dk/dm:.4f} ({dk}/{dm}) Wilson95% [{dlo:.4f},{dhi:.4f}]')
for f in sorted(set(df)):
m = df == f
print(f' Firm {f}: {dv[m].sum()/m.sum():.4f} ({int(dv[m].sum())}/{int(m.sum())})')
rows = load()
SCOPES = [('ABCD', lambda fm: fm in BIG4),
('BCD-only', lambda fm: fm in BIG4 and fm != FIRM_A),
('BCD+nonBig4', lambda fm: fm != FIRM_A)]
print('=== KDE crossover ===')
for name, fn in SCOPES[:2]:
f, _, c, _, _ = prep(rows, fn)
crossover(f, c, name)
print('\n=== per-signature & per-document inter-CPA ICCR (full) ===')
for name, fn in SCOPES:
f, dh, c, fm, dc = prep(rows, fn)
pool_sim(f, dh, c, fm, dc, name)
+104
View File
@@ -0,0 +1,104 @@
#!/usr/bin/env python3
"""Script 49: Firm A as out-of-sample target against a clean BCD baseline.
(1) A signatures scored against a BCD-only candidate pool (true out-of-sample
inter-firm coincidence).
(2) Observed deployed rate on ACTUAL same-CPA pools, per firm (the real fired
rate, from precomputed deployed descriptors), to juxtapose against the
clean BCD inter-CPA coincidence floor. Read-only.
"""
import sqlite3
from collections import defaultdict
import numpy as np
DB = '/Volumes/NV2/PDF-Processing/signature-analysis/signature_analysis.db'
FIRM_A = '勤業眾信聯合'
BIG4 = ('勤業眾信聯合', '安侯建業聯合', '資誠聯合', '安永聯合')
ALIAS = {'勤業眾信聯合': 'A', '安侯建業聯合': 'B', '資誠聯合': 'C', '安永聯合': 'D'}
SEED = 42
POP = np.array([bin(i).count('1') for i in range(256)], dtype=np.uint8)
def wilson(k, n, z=1.96):
if n == 0:
return (None, None)
p = k/n; d = 1+z*z/n
c = (p+z*z/(2*n))/d
h = z*np.sqrt(p*(1-p)/n+z*z/(4*n*n))/d
return (max(0.0, c-h), min(1.0, c+h))
conn = sqlite3.connect(f'file:{DB}?mode=ro', uri=True)
cur = conn.cursor()
cur.execute("""
SELECT s.assigned_accountant, a.firm, s.source_pdf, s.feature_vector,
s.dhash_vector, s.max_similarity_to_same_accountant, s.min_dhash_independent
FROM signatures s JOIN accountants a ON s.assigned_accountant=a.name
WHERE s.assigned_accountant IS NOT NULL AND a.firm IN (?,?,?,?)
AND s.feature_vector IS NOT NULL AND s.dhash_vector IS NOT NULL""", BIG4)
rows = cur.fetchall()
conn.close()
# ---- (1) Firm A source vs BCD-only candidate pool ----
print('=== (1) Firm A out-of-sample vs clean BCD candidate pool ===')
A = [r for r in rows if r[1] == FIRM_A]
BCD = [r for r in rows if r[1] in BIG4 and r[1] != FIRM_A]
bcd_feat = np.stack([np.frombuffer(r[3], np.float32) for r in BCD]).astype(np.float32)
bcd_feat /= np.clip(np.linalg.norm(bcd_feat, axis=1, keepdims=True), 1e-9, None)
bcd_dh = np.stack([np.frombuffer(r[4], np.uint8) for r in BCD])
nb = len(BCD)
# A CPA pool sizes (their own same-CPA count - 1), to match negative-anchor construction
a_cpa_idx = defaultdict(list)
for i, r in enumerate(A):
a_cpa_idx[r[0]].append(i)
pool_size = {c: len(v)-1 for c, v in a_cpa_idx.items()}
rng = np.random.default_rng(SEED)
sig_hc = np.zeros(len(A), bool)
doc_hcmc = defaultdict(bool)
for i, r in enumerate(A):
npool = max(pool_size[r[0]], 1)
cand = rng.integers(0, nb, size=npool)
sf = np.frombuffer(r[3], np.float32).astype(np.float32)
sf /= max(np.linalg.norm(sf), 1e-9)
cosv = bcd_feat[cand] @ sf
cg = cosv > 0.95
doc_hcmc.setdefault(r[2], False)
if cg.any():
dist = POP[bcd_dh[cand] ^ np.frombuffer(r[4], np.uint8)].sum(axis=1)
sig_hc[i] = bool((cg & (dist <= 5)).any())
if (cg & (dist <= 15)).any():
doc_hcmc[r[2]] = True
k = int(sig_hc.sum()); n = len(A); lo, hi = wilson(k, n)
print(f' A-source vs BCD-pool per-SIGNATURE HC (cos>0.95 & dh<=5): '
f'{k/n:.4f} ({k}/{n}) Wilson95% [{lo:.4f},{hi:.4f}]')
dv = np.array(list(doc_hcmc.values())); dk = int(dv.sum()); dm = len(dv)
dlo, dhi = wilson(dk, dm)
print(f' A-source vs BCD-pool per-DOCUMENT HC+MC (cos>0.95 & dh<=15): '
f'{dk/dm:.4f} ({dk}/{dm}) Wilson95% [{dlo:.4f},{dhi:.4f}]')
# ---- (2) Observed deployed rate on ACTUAL same-CPA pools, per firm ----
print('\n=== (2) Observed deployed rate on actual same-CPA pools (real fired rate) ===')
print(' per-signature HC = max_sim>0.95 & min_dh<=5 ; per-doc HC+MC worst-case dh<=15')
by_firm_sig = defaultdict(lambda: [0, 0])
doc_obs = {}
doc_firm = {}
for r in rows:
fm = ALIAS[r[1]]
ms, md = r[5], r[6]
if ms is None or md is None:
continue
hc = (ms > 0.95) and (md <= 5)
hcmc = (ms > 0.95) and (md <= 15)
by_firm_sig[fm][0] += int(hc); by_firm_sig[fm][1] += 1
doc_firm.setdefault(r[2], fm)
doc_obs[r[2]] = doc_obs.get(r[2], False) or hcmc
for fm in sorted(by_firm_sig):
k, n = by_firm_sig[fm]
lo, hi = wilson(k, n)
print(f' Firm {fm} per-SIGNATURE HC: {k/n:.4f} ({k}/{n}) [{lo:.4f},{hi:.4f}]')
dd = defaultdict(lambda: [0, 0])
for d, hit in doc_obs.items():
fm = doc_firm[d]; dd[fm][0] += int(hit); dd[fm][1] += 1
for fm in sorted(dd):
k, n = dd[fm]
print(f' Firm {fm} per-DOCUMENT HC+MC: {k/n:.4f} ({k}/{n})')
print(f'\n Clean BCD inter-CPA coincidence FLOOR: per-sig HC=0.0048, per-doc HC+MC=0.1281')
@@ -0,0 +1,107 @@
#!/usr/bin/env python3
"""Script 50: publication-grade scoped inter-CPA anchor recompute.
Faithfully reproduces Script 45's any-pair five-way pool simulation
(max_cos & min_dh over a random same-size inter-CPA pool, excl. same-CPA),
then reports for scopes ABCD / BCD / BCD+nonBig4:
- per-signature HC (D1) and HC+MC (D2) any-pair FAR
- per-document HC (D1) and HC+MC (D2) any-pair FAR
- per-firm per-document D2
ABCD is printed first to verify reproduction of published values
(per-sig HC~0.1102, per-doc D2~0.3375, Firm A~0.62). Read-only.
"""
import sqlite3
from collections import defaultdict
import numpy as np
DB = '/Volumes/NV2/PDF-Processing/signature-analysis/signature_analysis.db'
FIRM_A = '勤業眾信聯合'
BIG4 = ('勤業眾信聯合', '安侯建業聯合', '資誠聯合', '安永聯合')
ALIAS = {'勤業眾信聯合': 'A', '安侯建業聯合': 'B', '資誠聯合': 'C', '安永聯合': 'D'}
SEED = 42
POP = np.array([bin(i).count('1') for i in range(256)], dtype=np.uint8)
def wilson(k, n, z=1.96):
if n == 0:
return (None, None)
p = k/n; d = 1+z*z/n
c = (p+z*z/(2*n))/d
h = z*np.sqrt(p*(1-p)/n+z*z/(4*n*n))/d
return (max(0.0, c-h), min(1.0, c+h))
def load():
conn = sqlite3.connect(f'file:{DB}?mode=ro', uri=True)
cur = conn.cursor()
cur.execute("""
SELECT s.assigned_accountant, a.firm, s.source_pdf,
s.feature_vector, s.dhash_vector
FROM signatures s JOIN accountants a ON s.assigned_accountant=a.name
WHERE s.assigned_accountant IS NOT NULL AND a.firm IS NOT NULL
AND s.feature_vector IS NOT NULL AND s.dhash_vector IS NOT NULL""")
rows = cur.fetchall()
conn.close()
return rows
def run(rows, keep_fn, label):
keep = [r for r in rows if keep_fn(r[1])]
n = len(keep)
feats = np.stack([np.frombuffer(r[3], np.float32) for r in keep]).astype(np.float32)
feats /= np.clip(np.linalg.norm(feats, axis=1, keepdims=True), 1e-9, None)
dh = np.stack([np.frombuffer(r[4], np.uint8) for r in keep])
cpas = np.array([r[0] for r in keep])
firms = np.array([ALIAS.get(r[1], 'NonB4') for r in keep])
docs = np.array([r[2] for r in keep])
cpa_idx = defaultdict(list)
for i, c in enumerate(cpas):
cpa_idx[c].append(i)
cpa_idx = {c: np.array(v) for c, v in cpa_idx.items()}
pool_size = {c: len(v)-1 for c, v in cpa_idx.items()}
rng = np.random.default_rng(SEED)
max_cos = np.zeros(n, np.float32)
min_dh = np.full(n, 64, np.int32)
for si in range(n):
c = cpas[si]; npool = pool_size[c]
if npool <= 0:
continue
same = cpa_idx[c]
draw = rng.integers(0, n, size=npool + same.size + 20)
cand = draw[~np.isin(draw, same)][:npool]
cosv = feats[cand] @ feats[si]
dist = POP[dh[cand] ^ dh[si]].sum(axis=1)
max_cos[si] = cosv.max()
min_dh[si] = int(dist.min())
# any-pair classification
hc = (max_cos > 0.95) & (min_dh <= 5)
mc = (max_cos > 0.95) & (min_dh > 5) & (min_dh <= 15)
d1 = hc
d2 = hc | mc
print(f'\n===== {label} (n_sig={n:,}) =====')
for nm, arr in [('per-sig HC (D1)', d1), ('per-sig HC+MC (D2)', d2)]:
k = int(arr.sum()); lo, hi = wilson(k, n)
print(f' {nm}: {k/n:.4f} ({k}/{n}) [{lo:.4f},{hi:.4f}]')
# per-document worst-case
doc_d1 = defaultdict(bool); doc_d2 = defaultdict(bool); doc_firm = {}
for i in range(n):
if d1[i]: doc_d1[docs[i]] = True
if d2[i]: doc_d2[docs[i]] = True
doc_firm.setdefault(docs[i], firms[i])
doc_d1.setdefault(docs[i], False); doc_d2.setdefault(docs[i], False)
dl = list(doc_d2.keys())
nd = len(dl)
k1 = sum(doc_d1[d] for d in dl); k2 = sum(doc_d2[d] for d in dl)
l1 = wilson(k1, nd); l2 = wilson(k2, nd)
print(f' per-doc HC (D1): {k1/nd:.4f} ({k1}/{nd}) [{l1[0]:.4f},{l1[1]:.4f}]')
print(f' per-doc HC+MC (D2):{k2/nd:.4f} ({k2}/{nd}) [{l2[0]:.4f},{l2[1]:.4f}]')
df = np.array([doc_firm[d] for d in dl])
dv = np.array([doc_d2[d] for d in dl])
for f in sorted(set(df)):
m = df == f
print(f' Firm {f} per-doc D2: {dv[m].sum()/m.sum():.4f} ({int(dv[m].sum())}/{int(m.sum())})')
rows = load()
run(rows, lambda fm: fm in BIG4, 'ABCD (verify vs published: HC~0.110 / D2~0.338 / A~0.62)')
run(rows, lambda fm: fm in BIG4 and fm != FIRM_A, 'BCD-only')
run(rows, lambda fm: fm != FIRM_A, 'BCD + non-Big4')
@@ -0,0 +1,135 @@
#!/usr/bin/env python3
"""Script 51: publication polish.
Part A: CPA-block bootstrap (1000 reps) on per-signature HC any-pair rate, and
document-level bootstrap on per-document HC+MC, for ABCD & BCD.
Part B: corpus-wide KDE crossover (pair-weighted intra, reproduce 0.837) plus
BCD-only and BCD+nonBig4 variants.
Read-only.
"""
import sqlite3
from collections import defaultdict
import numpy as np
from scipy.stats import gaussian_kde
DB = '/Volumes/NV2/PDF-Processing/signature-analysis/signature_analysis.db'
FIRM_A = '勤業眾信聯合'
BIG4 = ('勤業眾信聯合', '安侯建業聯合', '資誠聯合', '安永聯合')
ALIAS = {'勤業眾信聯合': 'A', '安侯建業聯合': 'B', '資誠聯合': 'C', '安永聯合': 'D'}
SEED = 42
N_BOOT = 1000
POP = np.array([bin(i).count('1') for i in range(256)], dtype=np.uint8)
def load():
conn = sqlite3.connect(f'file:{DB}?mode=ro', uri=True)
cur = conn.cursor()
cur.execute("""
SELECT s.assigned_accountant, a.firm, s.source_pdf,
s.feature_vector, s.dhash_vector
FROM signatures s JOIN accountants a ON s.assigned_accountant=a.name
WHERE s.assigned_accountant IS NOT NULL AND a.firm IS NOT NULL
AND s.feature_vector IS NOT NULL AND s.dhash_vector IS NOT NULL""")
rows = cur.fetchall()
conn.close()
return rows
# ============ Part A: bootstrap on anchor rates ============
def simulate(keep):
n = len(keep)
feats = np.stack([np.frombuffer(r[3], np.float32) for r in keep]).astype(np.float32)
feats /= np.clip(np.linalg.norm(feats, axis=1, keepdims=True), 1e-9, None)
dh = np.stack([np.frombuffer(r[4], np.uint8) for r in keep])
cpas = np.array([r[0] for r in keep])
docs = np.array([r[2] for r in keep])
cpa_idx = defaultdict(list)
for i, c in enumerate(cpas):
cpa_idx[c].append(i)
cpa_idx = {c: np.array(v) for c, v in cpa_idx.items()}
pool_size = {c: len(v)-1 for c, v in cpa_idx.items()}
rng = np.random.default_rng(SEED)
max_cos = np.zeros(n, np.float32); min_dh = np.full(n, 64, np.int32)
for si in range(n):
c = cpas[si]; npool = pool_size[c]
if npool <= 0:
continue
same = cpa_idx[c]
draw = rng.integers(0, n, size=npool + same.size + 20)
cand = draw[~np.isin(draw, same)][:npool]
cosv = feats[cand] @ feats[si]
dist = POP[dh[cand] ^ dh[si]].sum(axis=1)
max_cos[si] = cosv.max(); min_dh[si] = int(dist.min())
hc = (max_cos > 0.95) & (min_dh <= 5)
d2 = (max_cos > 0.95) & (min_dh <= 15)
return hc, d2, cpa_idx, docs
def boot_part(keep, label):
hc, d2, cpa_idx, docs = simulate(keep)
n = len(hc)
rng = np.random.default_rng(SEED + 1)
cpa_list = list(cpa_idx.keys())
# CPA-block bootstrap on per-signature HC
bs = np.empty(N_BOOT)
for b in range(N_BOOT):
cs = rng.choice(len(cpa_list), len(cpa_list), replace=True)
idx = np.concatenate([cpa_idx[cpa_list[i]] for i in cs])
bs[b] = hc[idx].mean()
# document-level bootstrap on per-doc D2
doc_d2 = defaultdict(bool)
for i in range(n):
doc_d2[docs[i]] = doc_d2[docs[i]] or bool(d2[i])
dl = np.array(list(doc_d2.keys())); dvals = np.array([doc_d2[d] for d in dl])
nd = len(dl); bd = np.empty(N_BOOT)
for b in range(N_BOOT):
s = rng.integers(0, nd, nd)
bd[b] = dvals[s].mean()
print(f'\n [{label}] per-sig HC point={hc.mean():.4f} '
f'CPA-block boot95% [{np.percentile(bs,2.5):.4f}, {np.percentile(bs,97.5):.4f}]')
print(f' [{label}] per-doc HC+MC point={dvals.mean():.4f} '
f'doc boot95% [{np.percentile(bd,2.5):.4f}, {np.percentile(bd,97.5):.4f}]')
# ============ Part B: pair-weighted KDE crossover ============
def crossover(keep, label):
feats = np.stack([np.frombuffer(r[3], np.float32) for r in keep]).astype(np.float32)
feats /= np.clip(np.linalg.norm(feats, axis=1, keepdims=True), 1e-9, None)
cpas = np.array([r[0] for r in keep])
by = defaultdict(list)
for i, c in enumerate(cpas):
by[c].append(i)
by = {c: np.array(v) for c, v in by.items() if len(v) >= 3}
accts = list(by.keys())
pair_w = np.array([len(by[c])*(len(by[c])-1)/2 for c in accts], float)
pair_w /= pair_w.sum()
rng = np.random.default_rng(SEED)
M = 100_000
# intra: CPA sampled proportional to pair count (= uniform over all intra pairs)
intra = np.empty(M, np.float32)
ci = rng.choice(len(accts), M, p=pair_w)
for t in range(M):
a, b = rng.choice(by[accts[ci[t]]], 2, replace=False)
intra[t] = feats[a] @ feats[b]
inter = np.empty(M, np.float32)
for t in range(M):
i, j = rng.choice(len(accts), 2, replace=False)
inter[t] = feats[rng.choice(by[accts[i]])] @ feats[rng.choice(by[accts[j]])]
xs = np.linspace(0.3, 1.0, 10000)
diff = gaussian_kde(intra)(xs) - gaussian_kde(inter)(xs)
cr = [float(x) for x in xs[np.where(np.diff(np.sign(diff)))[0]] if 0.6 < x < 0.99]
print(f' [{label}] crossover {[f"{x:.4f}" for x in cr]} '
f'(intra {intra.mean():.4f}/{np.median(intra):.4f} inter {inter.mean():.4f}/{np.median(inter):.4f})')
rows = load()
abcd = [r for r in rows if r[1] in BIG4]
bcd = [r for r in rows if r[1] in BIG4 and r[1] != FIRM_A]
print('=== Part A: bootstrap CIs on anchor rates ===')
boot_part(abcd, 'ABCD (verify ~0.109 / ~0.338)')
boot_part(bcd, 'BCD-only')
print('\n=== Part B: KDE crossover (pair-weighted intra, corpus-wide reproduces 0.837) ===')
crossover(rows, 'corpus-wide (all firms)')
crossover(bcd, 'BCD-only')
crossover([r for r in rows if r[1] != FIRM_A], 'BCD + non-Big4')
@@ -0,0 +1,169 @@
#!/usr/bin/env python3
"""Script 52: canonical-correct locked publication numbers (supersedes 48/50,
fixes the per-firm assignment and A-out-of-sample any-pair issues codex flagged).
Uses the EXACT canonical candidate sampler of Scripts 43/45 (retry-loop to
collect exactly n_pool non-same-CPA candidates, rng.choice, default_rng(42)),
any-pair max-cos/min-dHash five-way classification, and dominant-firm document
assignment. Scopes: ABCD / BCD / BCD+nonBig4, plus Firm-A out-of-sample vs a
clean BCD candidate pool. Read-only.
"""
import sqlite3
from collections import defaultdict, Counter
import numpy as np
DB = '/Volumes/NV2/PDF-Processing/signature-analysis/signature_analysis.db'
FIRM_A = '勤業眾信聯合'
BIG4 = ('勤業眾信聯合', '安侯建業聯合', '資誠聯合', '安永聯合')
ALIAS = {'勤業眾信聯合': 'A', '安侯建業聯合': 'B', '資誠聯合': 'C', '安永聯合': 'D'}
SEED = 42
N_BOOT = 1000
POP = np.array([bin(i).count('1') for i in range(256)], dtype=np.uint8)
def wilson(k, n, z=1.96):
if n == 0:
return (None, None)
p = k/n; d = 1+z*z/n
c = (p+z*z/(2*n))/d
h = z*np.sqrt(p*(1-p)/n+z*z/(4*n*n))/d
return (max(0.0, c-h), min(1.0, c+h))
def load():
conn = sqlite3.connect(f'file:{DB}?mode=ro', uri=True)
cur = conn.cursor()
cur.execute("""
SELECT s.assigned_accountant, a.firm, s.source_pdf,
s.feature_vector, s.dhash_vector
FROM signatures s JOIN accountants a ON s.assigned_accountant=a.name
WHERE s.assigned_accountant IS NOT NULL AND a.firm IS NOT NULL
AND s.feature_vector IS NOT NULL AND s.dhash_vector IS NOT NULL""")
rows = cur.fetchall()
conn.close()
return rows
def canonical_sampler(rng, n, n_pool, same_cpa, all_idx):
"""EXACT Scripts 43/45 sampler: retry-loop to exactly n_pool non-same."""
need = n_pool
cand = []
attempts = 0
while need > 0 and attempts < 10:
draw = rng.choice(n, size=need * 2, replace=True)
ok = draw[~np.isin(draw, same_cpa)]
cand.extend(ok[:need].tolist())
need -= len(ok[:need])
attempts += 1
if need > 0:
pool_mask = np.ones(n, dtype=bool)
pool_mask[same_cpa] = False
fb = rng.choice(all_idx[pool_mask], size=need, replace=False)
cand.extend(fb.tolist())
return np.array(cand[:n_pool], dtype=np.int64)
def simulate(keep):
n = len(keep)
feats = np.stack([np.frombuffer(r[3], np.float32) for r in keep]).astype(np.float32)
norms = np.linalg.norm(feats, axis=1, keepdims=True); norms[norms == 0] = 1.0
feats = feats / norms
dh = np.stack([np.frombuffer(r[4], np.uint8) for r in keep])
cpas = np.array([r[0] for r in keep])
firms = np.array([ALIAS.get(r[1], 'NonB4') for r in keep])
docs = np.array([r[2] for r in keep])
cpa_idx = defaultdict(list)
for i, c in enumerate(cpas):
cpa_idx[c].append(i)
cpa_idx = {c: np.array(v) for c, v in cpa_idx.items()}
pool_size = {c: len(v)-1 for c, v in cpa_idx.items()}
all_idx = np.arange(n)
rng = np.random.default_rng(SEED)
max_cos = np.zeros(n, np.float32); min_dh = np.full(n, 64, np.int32)
for si in range(n):
np_ = pool_size[cpas[si]]
if np_ <= 0:
continue
cand = canonical_sampler(rng, n, np_, cpa_idx[cpas[si]], all_idx)
cosv = feats[cand] @ feats[si]
dist = POP[dh[cand] ^ dh[si]].sum(axis=1)
max_cos[si] = cosv.max(); min_dh[si] = int(dist.min())
return max_cos, min_dh, cpas, firms, docs, cpa_idx
def report(keep, label):
max_cos, min_dh, cpas, firms, docs, cpa_idx = simulate(keep)
n = len(cpas)
hc = (max_cos > 0.95) & (min_dh <= 5)
d2 = (max_cos > 0.95) & (min_dh <= 15)
print(f'\n===== {label} (n_sig={n:,}) =====')
for nm, a in [('per-sig HC', hc), ('per-sig HC+MC', d2)]:
k = int(a.sum()); lo, hi = wilson(k, n)
print(f' {nm}: {k/n:.6f} ({k}/{n}) [{lo:.4f},{hi:.4f}]')
# CPA-block bootstrap on per-sig HC
rng = np.random.default_rng(SEED + 1)
cl = list(cpa_idx.keys())
bs = np.empty(N_BOOT)
for b in range(N_BOOT):
cs = rng.choice(len(cl), len(cl), replace=True)
idx = np.concatenate([cpa_idx[cl[i]] for i in cs])
bs[b] = hc[idx].mean()
print(f' per-sig HC CPA-block boot95% [{np.percentile(bs,2.5):.4f},{np.percentile(bs,97.5):.4f}]')
# per-doc, dominant-firm assignment (canonical)
doc_sigs = defaultdict(list)
for i in range(n):
doc_sigs[docs[i]].append(i)
dl = list(doc_sigs.keys()); nd = len(dl)
doc_d1 = np.array([hc[doc_sigs[d]].any() for d in dl])
doc_d2 = np.array([d2[doc_sigs[d]].any() for d in dl])
doc_firm = np.array([Counter(firms[doc_sigs[d]]).most_common(1)[0][0] for d in dl])
print(f' per-doc HC: {doc_d1.mean():.6f} ({int(doc_d1.sum())}/{nd})')
print(f' per-doc HC+MC: {doc_d2.mean():.6f} ({int(doc_d2.sum())}/{nd})')
for f in sorted(set(doc_firm)):
m = doc_firm == f
print(f' Firm {f} per-doc D2: {doc_d2[m].mean():.4f} ({int(doc_d2[m].sum())}/{int(m.sum())})')
def a_out_of_sample(rows):
"""Firm A source vs clean BCD candidate pool, any-pair, pool=count-1."""
A = [r for r in rows if r[1] == FIRM_A]
BCD = [r for r in rows if r[1] in BIG4 and r[1] != FIRM_A]
bf = np.stack([np.frombuffer(r[3], np.float32) for r in BCD]).astype(np.float32)
nb = bf.shape[0]
bn = np.linalg.norm(bf, axis=1, keepdims=True); bn[bn == 0] = 1.0; bf = bf/bn
bdh = np.stack([np.frombuffer(r[4], np.uint8) for r in BCD])
a_cpa = defaultdict(list)
for i, r in enumerate(A):
a_cpa[r[0]].append(i)
pool_size = {c: len(v)-1 for c, v in a_cpa.items()}
rng = np.random.default_rng(SEED)
hc = np.zeros(len(A), bool); d2 = np.zeros(len(A), bool)
docs = np.array([r[2] for r in A])
for i, r in enumerate(A):
np_ = pool_size[r[0]]
if np_ <= 0: # singleton CPA: no same-CPA pool, skip (canonical)
continue
cand = rng.choice(nb, size=np_, replace=True) # A not in BCD pool
sf = np.frombuffer(r[3], np.float32).astype(np.float32)
sf = sf/max(np.linalg.norm(sf), 1e-9)
cosv = bf[cand] @ sf
dist = POP[bdh[cand] ^ np.frombuffer(r[4], np.uint8)].sum(axis=1)
mc, md = cosv.max(), int(dist.min())
hc[i] = (mc > 0.95) and (md <= 5)
d2[i] = (mc > 0.95) and (md <= 15)
k = int(hc.sum()); n = len(A); lo, hi = wilson(k, n)
print(f'\n===== Firm A out-of-sample vs clean BCD pool (any-pair) =====')
print(f' per-sig HC: {k/n:.6f} ({k}/{n}) [{lo:.5f},{hi:.5f}]')
ds = defaultdict(list)
for i in range(n):
ds[docs[i]].append(i)
dl = list(ds.keys())
dd2 = np.array([d2[ds[d]].any() for d in dl])
print(f' per-doc HC+MC: {dd2.mean():.6f} ({int(dd2.sum())}/{len(dl)})')
rows = load()
report([r for r in rows if r[1] in BIG4], 'ABCD (verify: per-sig HC~0.1102 / per-doc D2~0.3375)')
report([r for r in rows if r[1] in BIG4 and r[1] != FIRM_A], 'BCD-only (verify codex: HC~0.0116 / doc HC~0.0226 / doc D2~0.1905)')
report([r for r in rows if r[1] != FIRM_A], 'BCD + non-Big4')
a_out_of_sample(rows)
@@ -0,0 +1,125 @@
#!/usr/bin/env python3
"""Script 53: BCD-only firm-effect logistic regression (Firm D reference) and
BCD-only cross-firm hit matrix. Candidate pool = BCD (exclude Firm A and
same-CPA). Canonical retry-loop sampler, any-pair + same-pair. Read-only.
Replicates Script 44's logistic_fit and matrix logic, restricted to BCD.
"""
import sqlite3
from collections import defaultdict
import numpy as np
DB = '/Volumes/NV2/PDF-Processing/signature-analysis/signature_analysis.db'
FIRM_A = '勤業眾信聯合'
BIG4 = ('勤業眾信聯合', '安侯建業聯合', '資誠聯合', '安永聯合')
ALIAS = {'勤業眾信聯合': 'A', '安侯建業聯合': 'B', '資誠聯合': 'C', '安永聯合': 'D'}
SEED = 42
POP = np.array([bin(i).count('1') for i in range(256)], dtype=np.uint8)
def logistic_fit(X, y, max_iter=200, l2=0.001):
n, k = X.shape
beta = np.zeros(k)
for _ in range(max_iter):
eta = np.clip(X @ beta, -30, 30)
p = 1.0/(1.0+np.exp(-eta))
grad = X.T @ (y-p) - l2*beta
W = p*(1-p)
H = -(X.T*W) @ X - l2*np.eye(k)
try:
delta = np.linalg.solve(H, grad)
except np.linalg.LinAlgError:
delta = 0.3*grad
nb = beta - delta
if np.max(np.abs(nb-beta)) < 1e-8:
beta = nb; break
beta = nb
eta = np.clip(X @ beta, -30, 30)
p = 1.0/(1.0+np.exp(-eta)); W = p*(1-p)
cov = np.linalg.inv((X.T*W) @ X + l2*np.eye(k))
return beta, np.sqrt(np.diag(cov))
conn = sqlite3.connect(f'file:{DB}?mode=ro', uri=True)
cur = conn.cursor()
cur.execute("""SELECT s.assigned_accountant, a.firm, s.feature_vector, s.dhash_vector
FROM signatures s JOIN accountants a ON s.assigned_accountant=a.name
WHERE s.assigned_accountant IS NOT NULL AND a.firm IN (?,?,?)
AND s.feature_vector IS NOT NULL AND s.dhash_vector IS NOT NULL""",
('安侯建業聯合', '資誠聯合', '安永聯合'))
rows = cur.fetchall()
conn.close()
n = len(rows)
feats = np.stack([np.frombuffer(r[2], np.float32) for r in rows]).astype(np.float32)
norms = np.linalg.norm(feats, axis=1, keepdims=True); norms[norms == 0] = 1.0
feats = feats / norms
dh = np.stack([np.frombuffer(r[3], np.uint8) for r in rows])
cpas = np.array([r[0] for r in rows])
firms = np.array([ALIAS[r[1]] for r in rows])
cpa_idx = defaultdict(list)
for i, c in enumerate(cpas):
cpa_idx[c].append(i)
cpa_idx = {c: np.array(v) for c, v in cpa_idx.items()}
pool_size = {c: len(v)-1 for c, v in cpa_idx.items()}
all_idx = np.arange(n)
print(f'BCD signatures: {n:,}; CPAs: {len(cpa_idx)}')
rng = np.random.default_rng(SEED)
hit_any = np.zeros(n, bool)
hit_same = np.zeros(n, bool)
cand_firm_maxcos = np.empty(n, dtype=object) # any-pair partner firm
cand_firm_same = np.empty(n, dtype=object)
psize = np.zeros(n, np.int32)
for si in range(n):
np_ = pool_size[cpas[si]]; psize[si] = np_
if np_ <= 0:
continue
same = cpa_idx[cpas[si]]
need = np_; cand = []; att = 0
while need > 0 and att < 10:
draw = rng.choice(n, size=need*2, replace=True)
ok = draw[~np.isin(draw, same)]
cand.extend(ok[:need].tolist()); need -= len(ok[:need]); att += 1
if need > 0:
pm = np.ones(n, bool); pm[same] = False
cand.extend(rng.choice(all_idx[pm], size=need, replace=False).tolist())
cand = np.array(cand[:np_], dtype=np.int64)
cosv = feats[cand] @ feats[si]
dist = POP[dh[cand] ^ dh[si]].sum(axis=1)
mc = int(np.argmax(cosv)); md = int(np.argmin(dist))
if cosv[mc] > 0.95 and dist[md] <= 5:
hit_any[si] = True
cand_firm_maxcos[si] = firms[cand[mc]]
spm = (cosv > 0.95) & (dist <= 5)
if spm.any():
hit_same[si] = True
cand_firm_same[si] = firms[cand[int(np.argmax(spm))]]
# ---- Logistic regression: hit_any ~ FirmB + FirmC + log(pool), Firm D reference ----
hp = psize > 0
y = hit_any[hp].astype(np.float64)
fa = firms[hp]
lp = np.log(psize[hp].astype(np.float64)); lp = lp - lp.mean()
X = np.column_stack([np.ones(y.shape), (fa == 'B').astype(float), (fa == 'C').astype(float), lp])
beta, se = logistic_fit(X, y)
print(f'\n[BCD logistic: hit_any ~ FirmB + FirmC + log(pool); Firm D = reference] n={len(y):,}, y_mean={y.mean():.4f}')
for nm, b, s in zip(['intercept(FirmD)', 'FirmB', 'FirmC', 'log(pool,centred)'], beta, se):
print(f' {nm}: beta={b:+.4f} SE={s:.4f} OR={np.exp(b):.4f} z~{abs(b)/s if s>0 else float("inf"):.2f}')
# ---- Cross-firm hit matrix (any-pair max-cos partner) ----
print('\n[BCD cross-firm hit matrix: any-pair, source firm x max-cos partner firm]')
print(' src -> B C D | within-firm% (n hits)')
for sf in ['B', 'C', 'D']:
m = (firms == sf) & hit_any
parts = cand_firm_maxcos[m]
tot = len(parts)
cnt = {f: int((parts == f).sum()) for f in ['B', 'C', 'D']}
wf = cnt[sf]/tot if tot else 0
print(f' {sf} {cnt["B"]:5d} {cnt["C"]:5d} {cnt["D"]:5d} | {wf:6.1%} ({tot})')
print('\n[BCD same-pair within-firm concentration]')
for sf in ['B', 'C', 'D']:
m = (firms == sf) & hit_same
parts = cand_firm_same[m]; tot = len(parts)
wf = int((parts == sf).sum())/tot if tot else 0
print(f' Firm {sf}: {wf:.1%} within-firm ({int((parts==sf).sum())}/{tot})')
@@ -0,0 +1,99 @@
#!/usr/bin/env python3
"""Script 54: temporal stability of the BCD inter-CPA floor.
Does the normative BCD per-comparison HC coincidence floor drift over time /
get contaminated by post-2020 e-signing? Compares eras full / 2013-2019 /
2020-2023 using the pool-size-independent per-comparison joint HC ICCR
(cos>0.95 & dHash<=5) on BCD inter-CPA pairs (N=500k, seed 42), plus the
observed deployed per-signature HC rate by firm by era. Read-only.
"""
import sqlite3
from collections import defaultdict
import numpy as np
DB = '/Volumes/NV2/PDF-Processing/signature-analysis/signature_analysis.db'
FIRM_A = '勤業眾信聯合'
BIG4 = ('勤業眾信聯合', '安侯建業聯合', '資誠聯合', '安永聯合')
ALIAS = {'勤業眾信聯合': 'A', '安侯建業聯合': 'B', '資誠聯合': 'C', '安永聯合': 'D'}
SEED = 42
N_PAIRS = 500_000
POP = np.array([bin(i).count('1') for i in range(256)], dtype=np.uint8)
def wilson(k, n, z=1.96):
if n == 0:
return (None, None)
p = k/n; d = 1+z*z/n
c = (p+z*z/(2*n))/d
h = z*np.sqrt(p*(1-p)/n+z*z/(4*n*n))/d
return (max(0.0, c-h), min(1.0, c+h))
conn = sqlite3.connect(f'file:{DB}?mode=ro', uri=True)
cur = conn.cursor()
cur.execute("""
SELECT s.assigned_accountant, a.firm, CAST(substr(s.year_month,1,4) AS INT),
s.feature_vector, s.dhash_vector,
s.max_similarity_to_same_accountant, s.min_dhash_independent
FROM signatures s JOIN accountants a ON s.assigned_accountant=a.name
WHERE a.firm IN (?,?,?,?) AND s.year_month IS NOT NULL
AND s.feature_vector IS NOT NULL AND s.dhash_vector IS NOT NULL""", BIG4)
rows = cur.fetchall()
conn.close()
ERAS = {'full 2013-2023': lambda y: True,
'2013-2019 (pre-drift)': lambda y: 2013 <= y <= 2019,
'2020-2023': lambda y: 2020 <= y <= 2023}
def per_comparison_floor(era_fn, label):
# BCD-only (exclude Firm A), era-restricted
keep = [r for r in rows if r[1] != FIRM_A and era_fn(r[2])]
feats = np.stack([np.frombuffer(r[3], np.float32) for r in keep]).astype(np.float32)
feats /= np.clip(np.linalg.norm(feats, axis=1, keepdims=True), 1e-9, None)
dh = np.stack([np.frombuffer(r[4], np.uint8) for r in keep])
cpas = np.array([r[0] for r in keep])
by = defaultdict(list)
for i, c in enumerate(cpas):
by[c].append(i)
accts = list(by.keys())
rng = np.random.default_rng(SEED)
cos = np.empty(N_PAIRS, np.float32); dv = np.empty(N_PAIRS, np.int32)
na = len(accts)
for t in range(N_PAIRS):
i, j = rng.choice(na, 2, replace=False)
a1, a2 = accts[i], accts[j]
k1 = by[a1][int(rng.integers(0, len(by[a1])))]
k2 = by[a2][int(rng.integers(0, len(by[a2])))]
cos[t] = feats[k1] @ feats[k2]
dv[t] = POP[dh[k1] ^ dh[k2]].sum()
joint = int(((cos > 0.95) & (dv <= 5)).sum())
lo, hi = wilson(joint, N_PAIRS)
print(f' [{label}] BCD per-comparison HC floor = {joint/N_PAIRS:.6f} '
f'({joint}/{N_PAIRS}) Wilson95% [{lo:.6f},{hi:.6f}] '
f'(n_sig={len(keep):,}, CPAs={na})')
return joint/N_PAIRS
print('=== (1) BCD per-comparison HC floor by era (pool-size-independent) ===')
floors = {lab: per_comparison_floor(fn, lab) for lab, fn in ERAS.items()}
print('\n=== (2) Observed deployed per-signature HC rate by firm by era ===')
print(' (max_sim>0.95 & min_dh<=5 on actual same-CPA pools)')
for lab, fn in ERAS.items():
print(f' --- {lab} ---')
for fm_zh in BIG4:
sub = [r for r in rows if r[1] == fm_zh and fn(r[2])
and r[5] is not None and r[6] is not None]
if not sub:
continue
k = sum(1 for r in sub if r[5] > 0.95 and r[6] <= 5)
print(f' Firm {ALIAS[fm_zh]}: {k/len(sub):.4f} ({k}/{len(sub)})')
print('\n=== A-vs-floor multiple by era (observed A HC / BCD floor) ===')
for lab, fn in ERAS.items():
a = [r for r in rows if r[1] == FIRM_A and fn(r[2]) and r[5] is not None and r[6] is not None]
a_rate = sum(1 for r in a if r[5] > 0.95 and r[6] <= 5)/len(a) if a else 0
fl = floors[lab]
# per-comparison floor is not directly comparable to observed pooled rate;
# report ratio vs the per-signature floor proxy from Script 52 (0.0116 full).
print(f' {lab}: observed A HC = {a_rate:.3f}; per-comparison floor = {fl:.6f}')
@@ -0,0 +1,144 @@
#!/usr/bin/env python3
"""Script 55: PRIMARY calibration on the clean pre-e-signature baseline
BCD 2013-2019 (Firms B/C/D, fiscal years 2013-2019). Rationale: co-author
interviews confirm B/C/D progressively adopted e-signature systems after 2020
(staggered timing), so 2013-2019 BCD is the construct-clean hand-signing
baseline. Canonical retry-loop sampler (matches Scripts 43/45/52), any-pair.
Reports the floor + Firm A (all years) scored out-of-sample against it, and
BCD 2020+ scored against the same threshold. Read-only.
"""
import sqlite3
from collections import defaultdict, Counter
import numpy as np
DB = '/Volumes/NV2/PDF-Processing/signature-analysis/signature_analysis.db'
FIRM_A = '勤業眾信聯合'
BIG4 = ('勤業眾信聯合', '安侯建業聯合', '資誠聯合', '安永聯合')
ALIAS = {'勤業眾信聯合': 'A', '安侯建業聯合': 'B', '資誠聯合': 'C', '安永聯合': 'D'}
SEED = 42
N_BOOT = 1000
POP = np.array([bin(i).count('1') for i in range(256)], dtype=np.uint8)
def wilson(k, n, z=1.96):
if n == 0:
return (None, None)
p = k/n; d = 1+z*z/n; c = (p+z*z/(2*n))/d
h = z*np.sqrt(p*(1-p)/n+z*z/(4*n*n))/d
return (max(0.0, c-h), min(1.0, c+h))
def canon_sampler(rng, n, npool, same, all_idx):
need = npool; cand = []; att = 0
while need > 0 and att < 10:
draw = rng.choice(n, size=need*2, replace=True)
ok = draw[~np.isin(draw, same)]
cand.extend(ok[:need].tolist()); need -= len(ok[:need]); att += 1
if need > 0:
pm = np.ones(n, bool); pm[same] = False
cand.extend(rng.choice(all_idx[pm], size=need, replace=False).tolist())
return np.array(cand[:npool], dtype=np.int64)
conn = sqlite3.connect(f'file:{DB}?mode=ro', uri=True)
cur = conn.cursor()
cur.execute("""SELECT s.assigned_accountant,a.firm,CAST(substr(s.year_month,1,4) AS INT),
s.source_pdf,s.feature_vector,s.dhash_vector,
s.max_similarity_to_same_accountant,s.min_dhash_independent
FROM signatures s JOIN accountants a ON s.assigned_accountant=a.name
WHERE a.firm IN (?,?,?,?) AND s.year_month IS NOT NULL
AND s.feature_vector IS NOT NULL AND s.dhash_vector IS NOT NULL""", BIG4)
rows = cur.fetchall()
conn.close()
def prep(rec):
feats = np.stack([np.frombuffer(r[4], np.float32) for r in rec]).astype(np.float32)
norms = np.linalg.norm(feats, axis=1, keepdims=True); norms[norms == 0] = 1.0
feats /= norms
dh = np.stack([np.frombuffer(r[5], np.uint8) for r in rec])
return feats, dh
def floor_on(baseline_rec, label):
"""Canonical per-sig/per-doc HC floor on a baseline population."""
feats, dh = prep(baseline_rec)
n = len(baseline_rec)
cpas = np.array([r[0] for r in baseline_rec])
firms = np.array([ALIAS[r[1]] for r in baseline_rec])
docs = np.array([r[3] for r in baseline_rec])
cidx = defaultdict(list)
for i, c in enumerate(cpas):
cidx[c].append(i)
cidx = {c: np.array(v) for c, v in cidx.items()}
psize = {c: len(v)-1 for c, v in cidx.items()}
all_idx = np.arange(n)
rng = np.random.default_rng(SEED)
mx = np.zeros(n, np.float32); mn = np.full(n, 64, np.int32)
for si in range(n):
np_ = psize[cpas[si]]
if np_ <= 0:
continue
cand = canon_sampler(rng, n, np_, cidx[cpas[si]], all_idx)
cosv = feats[cand] @ feats[si]
mx[si] = cosv.max(); mn[si] = int(POP[dh[cand] ^ dh[si]].sum(axis=1).min())
hc = (mx > 0.95) & (mn <= 5); d2 = (mx > 0.95) & (mn <= 15)
k = int(hc.sum())
rng2 = np.random.default_rng(SEED+1); cl = list(cidx.keys())
bs = np.array([hc[np.concatenate([cidx[cl[i]] for i in rng2.choice(len(cl), len(cl), True)])].mean()
for _ in range(N_BOOT)])
print(f'\n [{label}] n_sig={n:,}, CPAs={len(cidx)}')
print(f' per-sig HC floor = {k/n:.4f} ({k}/{n}) CPA-boot95% [{np.percentile(bs,2.5):.4f},{np.percentile(bs,97.5):.4f}]')
dd1 = defaultdict(bool); dd2 = defaultdict(bool); dfirm = {}
for i in range(n):
if hc[i]: dd1[docs[i]] = True
if d2[i]: dd2[docs[i]] = True
dfirm.setdefault(docs[i], []).append(firms[i])
dd1.setdefault(docs[i], False); dd2.setdefault(docs[i], False)
dl = list(dd1.keys()); nd = len(dl)
print(f' per-doc HC = {sum(dd1[d] for d in dl)/nd:.4f}; per-doc HC+MC = {sum(dd2[d] for d in dl)/nd:.4f} (n_doc={nd:,})')
dom = {d: Counter(dfirm[d]).most_common(1)[0][0] for d in dl}
for f in ['B', 'C', 'D']:
ds = [d for d in dl if dom[d] == f]
if ds:
print(f' Firm {f} per-doc HC+MC: {sum(dd2[d] for d in ds)/len(ds):.4f} ({sum(dd2[d] for d in ds)}/{len(ds)})')
return k/n
def a_vs_baseline(baseline_rec, a_rec, label):
bf, bdh = prep(baseline_rec); nb = len(baseline_rec)
a_cpa = defaultdict(list)
for i, r in enumerate(a_rec):
a_cpa[r[0]].append(i)
psize = {c: len(v)-1 for c, v in a_cpa.items()}
rng = np.random.default_rng(SEED)
hc = np.zeros(len(a_rec), bool)
for i, r in enumerate(a_rec):
np_ = psize[r[0]]
if np_ <= 0:
continue
cand = rng.integers(0, nb, size=np_)
sf = np.frombuffer(r[4], np.float32).astype(np.float32); sf /= max(np.linalg.norm(sf), 1e-9)
cosv = bf[cand] @ sf
if (cosv > 0.95).any():
dist = POP[bdh[cand] ^ np.frombuffer(r[5], np.uint8)].sum(axis=1)
hc[i] = bool(((cosv > 0.95) & (dist <= 5)).any())
k = int(hc.sum()); n = len(a_rec); lo, hi = wilson(k, n)
print(f' [{label}] Firm A (all yrs) vs BCD-2013-2019 pool: per-sig HC = {k/n:.4f} ({k}/{n}) [{lo:.5f},{hi:.5f}]')
bcd_pre = [r for r in rows if r[1] != FIRM_A and 2013 <= r[2] <= 2019]
bcd_post = [r for r in rows if r[1] != FIRM_A and r[2] >= 2020]
A_all = [r for r in rows if r[1] == FIRM_A]
print('=== PRIMARY floor: BCD 2013-2019 ===')
fl = floor_on(bcd_pre, 'BCD 2013-2019 (PRIMARY)')
print('\n=== Firm A scored against the BCD-2013-2019 threshold ===')
a_vs_baseline(bcd_pre, A_all, 'A out-of-sample')
A_obs = [r for r in A_all if r[6] is not None and r[7] is not None]
ak = sum(1 for r in A_obs if r[6] > 0.95 and r[7] <= 5)
print(f' Firm A observed (all yrs, own pools): per-sig HC = {ak/len(A_obs):.4f} -> {ak/len(A_obs)/fl:.0f}x the BCD-2013-2019 floor')
print('\n=== (optional) BCD 2020+ floor, same method (may be inflated by e-signing) ===')
floor_on(bcd_post, 'BCD 2020-2023 (post e-signing)')