verifydoc 0.3.0__tar.gz → 0.5.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (205) hide show
  1. verifydoc-0.5.0/.github/ISSUE_TEMPLATE/bug_report.md +25 -0
  2. verifydoc-0.5.0/.github/ISSUE_TEMPLATE/feature_request.md +19 -0
  3. verifydoc-0.5.0/.github/pull_request_template.md +11 -0
  4. {verifydoc-0.3.0 → verifydoc-0.5.0}/.gitignore +12 -0
  5. {verifydoc-0.3.0 → verifydoc-0.5.0}/CHANGELOG.md +40 -0
  6. verifydoc-0.5.0/CITATION.cff +17 -0
  7. verifydoc-0.5.0/CODE_OF_CONDUCT.md +32 -0
  8. verifydoc-0.5.0/CONTRIBUTING.md +55 -0
  9. {verifydoc-0.3.0 → verifydoc-0.5.0}/Makefile +9 -1
  10. {verifydoc-0.3.0 → verifydoc-0.5.0}/PKG-INFO +76 -19
  11. {verifydoc-0.3.0 → verifydoc-0.5.0}/PROJECT.md +3 -10
  12. {verifydoc-0.3.0 → verifydoc-0.5.0}/README.md +67 -18
  13. verifydoc-0.5.0/configs/cord-apivlm.yaml +13 -0
  14. verifydoc-0.5.0/docs/MCP.md +68 -0
  15. verifydoc-0.5.0/docs/how-it-works.md +57 -0
  16. verifydoc-0.5.0/examples/README.md +25 -0
  17. verifydoc-0.5.0/examples/invoice.txt +8 -0
  18. verifydoc-0.5.0/examples/invoice_schema.json +12 -0
  19. {verifydoc-0.3.0 → verifydoc-0.5.0}/paper/generated/REAL_MODELS_RESULTS.md +29 -0
  20. verifydoc-0.5.0/paper/generated/calibration.tex +37 -0
  21. verifydoc-0.5.0/paper/generated/conformal.tex +19 -0
  22. verifydoc-0.5.0/paper/generated/cord/calibration.tex +37 -0
  23. verifydoc-0.5.0/paper/generated/cord/conformal.tex +19 -0
  24. verifydoc-0.5.0/paper/generated/cord/extraction.tex +8 -0
  25. verifydoc-0.5.0/paper/generated/cord/grounding.tex +8 -0
  26. verifydoc-0.5.0/paper/generated/cord/selective.tex +13 -0
  27. verifydoc-0.5.0/paper/generated/cord-apivlm/calibration.md +34 -0
  28. verifydoc-0.5.0/paper/generated/cord-apivlm/calibration.tex +37 -0
  29. verifydoc-0.5.0/paper/generated/cord-apivlm/conformal.tex +19 -0
  30. verifydoc-0.5.0/paper/generated/cord-apivlm/extraction.md +5 -0
  31. verifydoc-0.5.0/paper/generated/cord-apivlm/extraction.tex +8 -0
  32. verifydoc-0.5.0/paper/generated/cord-apivlm/grounding.md +5 -0
  33. verifydoc-0.5.0/paper/generated/cord-apivlm/grounding.tex +8 -0
  34. verifydoc-0.5.0/paper/generated/cord-apivlm/rc_curves.png +0 -0
  35. verifydoc-0.5.0/paper/generated/cord-apivlm/reliability.png +0 -0
  36. verifydoc-0.5.0/paper/generated/cord-apivlm/selective.md +10 -0
  37. verifydoc-0.5.0/paper/generated/cord-apivlm/selective.tex +13 -0
  38. verifydoc-0.5.0/paper/generated/cord-paddleocr/calibration.tex +37 -0
  39. verifydoc-0.5.0/paper/generated/cord-paddleocr/conformal.tex +19 -0
  40. verifydoc-0.5.0/paper/generated/cord-paddleocr/extraction.tex +8 -0
  41. verifydoc-0.5.0/paper/generated/cord-paddleocr/grounding.tex +8 -0
  42. verifydoc-0.5.0/paper/generated/cord-paddleocr/selective.tex +13 -0
  43. verifydoc-0.5.0/paper/generated/cord-rapidocr/calibration.tex +37 -0
  44. verifydoc-0.5.0/paper/generated/cord-rapidocr/conformal.tex +19 -0
  45. verifydoc-0.5.0/paper/generated/cord-rapidocr/extraction.tex +8 -0
  46. verifydoc-0.5.0/paper/generated/cord-rapidocr/grounding.tex +8 -0
  47. verifydoc-0.5.0/paper/generated/cord-rapidocr/selective.tex +13 -0
  48. verifydoc-0.5.0/paper/generated/extraction.tex +8 -0
  49. verifydoc-0.5.0/paper/generated/funsd/calibration.tex +37 -0
  50. verifydoc-0.5.0/paper/generated/funsd/conformal.tex +19 -0
  51. verifydoc-0.5.0/paper/generated/funsd/extraction.tex +8 -0
  52. verifydoc-0.5.0/paper/generated/funsd/grounding.tex +8 -0
  53. verifydoc-0.5.0/paper/generated/funsd/selective.tex +13 -0
  54. verifydoc-0.5.0/paper/generated/funsd-paddleocr/calibration.tex +37 -0
  55. verifydoc-0.5.0/paper/generated/funsd-paddleocr/conformal.tex +19 -0
  56. verifydoc-0.5.0/paper/generated/funsd-paddleocr/extraction.tex +8 -0
  57. verifydoc-0.5.0/paper/generated/funsd-paddleocr/grounding.tex +8 -0
  58. verifydoc-0.5.0/paper/generated/funsd-paddleocr/selective.tex +13 -0
  59. verifydoc-0.5.0/paper/generated/funsd-rapidocr/calibration.tex +37 -0
  60. verifydoc-0.5.0/paper/generated/funsd-rapidocr/conformal.md +16 -0
  61. verifydoc-0.5.0/paper/generated/funsd-rapidocr/conformal.tex +19 -0
  62. verifydoc-0.5.0/paper/generated/funsd-rapidocr/extraction.tex +8 -0
  63. verifydoc-0.5.0/paper/generated/funsd-rapidocr/grounding.tex +8 -0
  64. verifydoc-0.5.0/paper/generated/funsd-rapidocr/selective.tex +13 -0
  65. verifydoc-0.5.0/paper/generated/grounding.tex +8 -0
  66. verifydoc-0.5.0/paper/generated/grouped_conformal.md +12 -0
  67. verifydoc-0.5.0/paper/generated/grouped_conformal.tex +11 -0
  68. verifydoc-0.5.0/paper/generated/selective.tex +13 -0
  69. verifydoc-0.5.0/paper/main.tex +215 -0
  70. verifydoc-0.5.0/paper/refs.bib +35 -0
  71. {verifydoc-0.3.0 → verifydoc-0.5.0}/pyproject.toml +5 -1
  72. verifydoc-0.5.0/scripts/grouped_conformal_experiment.py +130 -0
  73. verifydoc-0.5.0/scripts/tables_to_latex.py +86 -0
  74. verifydoc-0.5.0/tests/test_grouped_conformal.py +126 -0
  75. verifydoc-0.5.0/tests/test_mcp_server.py +52 -0
  76. {verifydoc-0.3.0 → verifydoc-0.5.0}/tests/test_pipeline.py +42 -2
  77. {verifydoc-0.3.0 → verifydoc-0.5.0}/verifydoc/__init__.py +1 -1
  78. verifydoc-0.5.0/verifydoc/adapters/api_vlm.py +183 -0
  79. {verifydoc-0.3.0 → verifydoc-0.5.0}/verifydoc/calibration/__init__.py +6 -0
  80. verifydoc-0.5.0/verifydoc/calibration/grouped_conformal.py +110 -0
  81. {verifydoc-0.3.0 → verifydoc-0.5.0}/verifydoc/eval/harness.py +1 -1
  82. verifydoc-0.5.0/verifydoc/mcp_server.py +132 -0
  83. verifydoc-0.3.0/CLAUDE.md +0 -51
  84. verifydoc-0.3.0/paper/main.tex +0 -90
  85. verifydoc-0.3.0/verifydoc/adapters/api_vlm.py +0 -97
  86. {verifydoc-0.3.0 → verifydoc-0.5.0}/.github/workflows/ci.yml +0 -0
  87. {verifydoc-0.3.0 → verifydoc-0.5.0}/.github/workflows/release.yml +0 -0
  88. {verifydoc-0.3.0 → verifydoc-0.5.0}/.pre-commit-config.yaml +0 -0
  89. {verifydoc-0.3.0 → verifydoc-0.5.0}/LICENSE +0 -0
  90. {verifydoc-0.3.0 → verifydoc-0.5.0}/benchmark/__init__.py +0 -0
  91. {verifydoc-0.3.0 → verifydoc-0.5.0}/benchmark/card.md +0 -0
  92. {verifydoc-0.3.0 → verifydoc-0.5.0}/benchmark/datasets/__init__.py +0 -0
  93. {verifydoc-0.3.0 → verifydoc-0.5.0}/benchmark/datasets/cord.py +0 -0
  94. {verifydoc-0.3.0 → verifydoc-0.5.0}/benchmark/datasets/funsd.py +0 -0
  95. {verifydoc-0.3.0 → verifydoc-0.5.0}/benchmark/datasets/synthetic.py +0 -0
  96. {verifydoc-0.3.0 → verifydoc-0.5.0}/benchmark/labeling/guide.md +0 -0
  97. {verifydoc-0.3.0 → verifydoc-0.5.0}/configs/cord-paddleocr.yaml +0 -0
  98. {verifydoc-0.3.0 → verifydoc-0.5.0}/configs/cord-rapidocr.yaml +0 -0
  99. {verifydoc-0.3.0 → verifydoc-0.5.0}/configs/cord.yaml +0 -0
  100. {verifydoc-0.3.0 → verifydoc-0.5.0}/configs/demo.yaml +0 -0
  101. {verifydoc-0.3.0 → verifydoc-0.5.0}/configs/funsd-paddleocr.yaml +0 -0
  102. {verifydoc-0.3.0 → verifydoc-0.5.0}/configs/funsd-rapidocr.yaml +0 -0
  103. {verifydoc-0.3.0 → verifydoc-0.5.0}/configs/funsd.yaml +0 -0
  104. {verifydoc-0.3.0 → verifydoc-0.5.0}/docs/REAL_MODELS.md +0 -0
  105. {verifydoc-0.3.0 → verifydoc-0.5.0}/docs/USP.md +0 -0
  106. {verifydoc-0.3.0 → verifydoc-0.5.0}/docs/demo.gif +0 -0
  107. {verifydoc-0.3.0 → verifydoc-0.5.0}/paper/generated/calibration.md +0 -0
  108. {verifydoc-0.3.0 → verifydoc-0.5.0}/paper/generated/conformal.md +0 -0
  109. {verifydoc-0.3.0 → verifydoc-0.5.0}/paper/generated/cord/calibration.md +0 -0
  110. {verifydoc-0.3.0 → verifydoc-0.5.0}/paper/generated/cord/conformal.md +0 -0
  111. {verifydoc-0.3.0 → verifydoc-0.5.0}/paper/generated/cord/extraction.md +0 -0
  112. {verifydoc-0.3.0 → verifydoc-0.5.0}/paper/generated/cord/grounding.md +0 -0
  113. {verifydoc-0.3.0 → verifydoc-0.5.0}/paper/generated/cord/rc_curves.png +0 -0
  114. {verifydoc-0.3.0 → verifydoc-0.5.0}/paper/generated/cord/reliability.png +0 -0
  115. {verifydoc-0.3.0 → verifydoc-0.5.0}/paper/generated/cord/selective.md +0 -0
  116. {verifydoc-0.3.0 → verifydoc-0.5.0}/paper/generated/cord/summary.json +0 -0
  117. {verifydoc-0.3.0/paper/generated/cord-paddleocr → verifydoc-0.5.0/paper/generated/cord-apivlm}/conformal.md +0 -0
  118. {verifydoc-0.3.0 → verifydoc-0.5.0}/paper/generated/cord-paddleocr/calibration.md +0 -0
  119. {verifydoc-0.3.0/paper/generated/cord-rapidocr → verifydoc-0.5.0/paper/generated/cord-paddleocr}/conformal.md +0 -0
  120. {verifydoc-0.3.0 → verifydoc-0.5.0}/paper/generated/cord-paddleocr/extraction.md +0 -0
  121. {verifydoc-0.3.0 → verifydoc-0.5.0}/paper/generated/cord-paddleocr/grounding.md +0 -0
  122. {verifydoc-0.3.0 → verifydoc-0.5.0}/paper/generated/cord-paddleocr/selective.md +0 -0
  123. {verifydoc-0.3.0 → verifydoc-0.5.0}/paper/generated/cord-rapidocr/calibration.md +0 -0
  124. {verifydoc-0.3.0/paper/generated/funsd-paddleocr → verifydoc-0.5.0/paper/generated/cord-rapidocr}/conformal.md +0 -0
  125. {verifydoc-0.3.0 → verifydoc-0.5.0}/paper/generated/cord-rapidocr/extraction.md +0 -0
  126. {verifydoc-0.3.0 → verifydoc-0.5.0}/paper/generated/cord-rapidocr/grounding.md +0 -0
  127. {verifydoc-0.3.0 → verifydoc-0.5.0}/paper/generated/cord-rapidocr/selective.md +0 -0
  128. {verifydoc-0.3.0 → verifydoc-0.5.0}/paper/generated/extraction.md +0 -0
  129. {verifydoc-0.3.0 → verifydoc-0.5.0}/paper/generated/funsd/calibration.md +0 -0
  130. {verifydoc-0.3.0 → verifydoc-0.5.0}/paper/generated/funsd/conformal.md +0 -0
  131. {verifydoc-0.3.0 → verifydoc-0.5.0}/paper/generated/funsd/extraction.md +0 -0
  132. {verifydoc-0.3.0 → verifydoc-0.5.0}/paper/generated/funsd/grounding.md +0 -0
  133. {verifydoc-0.3.0 → verifydoc-0.5.0}/paper/generated/funsd/rc_curves.png +0 -0
  134. {verifydoc-0.3.0 → verifydoc-0.5.0}/paper/generated/funsd/reliability.png +0 -0
  135. {verifydoc-0.3.0 → verifydoc-0.5.0}/paper/generated/funsd/selective.md +0 -0
  136. {verifydoc-0.3.0 → verifydoc-0.5.0}/paper/generated/funsd/summary.json +0 -0
  137. {verifydoc-0.3.0 → verifydoc-0.5.0}/paper/generated/funsd-paddleocr/calibration.md +0 -0
  138. {verifydoc-0.3.0/paper/generated/funsd-rapidocr → verifydoc-0.5.0/paper/generated/funsd-paddleocr}/conformal.md +0 -0
  139. {verifydoc-0.3.0 → verifydoc-0.5.0}/paper/generated/funsd-paddleocr/extraction.md +0 -0
  140. {verifydoc-0.3.0 → verifydoc-0.5.0}/paper/generated/funsd-paddleocr/grounding.md +0 -0
  141. {verifydoc-0.3.0 → verifydoc-0.5.0}/paper/generated/funsd-paddleocr/selective.md +0 -0
  142. {verifydoc-0.3.0 → verifydoc-0.5.0}/paper/generated/funsd-rapidocr/calibration.md +0 -0
  143. {verifydoc-0.3.0 → verifydoc-0.5.0}/paper/generated/funsd-rapidocr/extraction.md +0 -0
  144. {verifydoc-0.3.0 → verifydoc-0.5.0}/paper/generated/funsd-rapidocr/grounding.md +0 -0
  145. {verifydoc-0.3.0 → verifydoc-0.5.0}/paper/generated/funsd-rapidocr/selective.md +0 -0
  146. {verifydoc-0.3.0 → verifydoc-0.5.0}/paper/generated/grounding.md +0 -0
  147. {verifydoc-0.3.0 → verifydoc-0.5.0}/paper/generated/rc_curves.png +0 -0
  148. {verifydoc-0.3.0 → verifydoc-0.5.0}/paper/generated/reliability.png +0 -0
  149. {verifydoc-0.3.0 → verifydoc-0.5.0}/paper/generated/selective.md +0 -0
  150. {verifydoc-0.3.0 → verifydoc-0.5.0}/paper/generated/summary.json +0 -0
  151. {verifydoc-0.3.0 → verifydoc-0.5.0}/scripts/make_demo_gif.py +0 -0
  152. {verifydoc-0.3.0 → verifydoc-0.5.0}/scripts/run_benchmark.py +0 -0
  153. {verifydoc-0.3.0 → verifydoc-0.5.0}/tests/__init__.py +0 -0
  154. {verifydoc-0.3.0 → verifydoc-0.5.0}/tests/test_calibration.py +0 -0
  155. {verifydoc-0.3.0 → verifydoc-0.5.0}/tests/test_calibrators.py +0 -0
  156. {verifydoc-0.3.0 → verifydoc-0.5.0}/tests/test_confidence.py +0 -0
  157. {verifydoc-0.3.0 → verifydoc-0.5.0}/tests/test_cord_loader.py +0 -0
  158. {verifydoc-0.3.0 → verifydoc-0.5.0}/tests/test_extraction.py +0 -0
  159. {verifydoc-0.3.0 → verifydoc-0.5.0}/tests/test_funsd_loader.py +0 -0
  160. {verifydoc-0.3.0 → verifydoc-0.5.0}/tests/test_grounding.py +0 -0
  161. {verifydoc-0.3.0 → verifydoc-0.5.0}/tests/test_harness.py +0 -0
  162. {verifydoc-0.3.0 → verifydoc-0.5.0}/tests/test_harness_extractors.py +0 -0
  163. {verifydoc-0.3.0 → verifydoc-0.5.0}/tests/test_learned_combiner.py +0 -0
  164. {verifydoc-0.3.0 → verifydoc-0.5.0}/tests/test_selective.py +0 -0
  165. {verifydoc-0.3.0 → verifydoc-0.5.0}/tests/test_stats.py +0 -0
  166. {verifydoc-0.3.0 → verifydoc-0.5.0}/tests/test_types.py +0 -0
  167. {verifydoc-0.3.0 → verifydoc-0.5.0}/ui/streamlit_app.py +0 -0
  168. {verifydoc-0.3.0 → verifydoc-0.5.0}/verifydoc/adapters/__init__.py +0 -0
  169. {verifydoc-0.3.0 → verifydoc-0.5.0}/verifydoc/adapters/_ocr_common.py +0 -0
  170. {verifydoc-0.3.0 → verifydoc-0.5.0}/verifydoc/adapters/base.py +0 -0
  171. {verifydoc-0.3.0 → verifydoc-0.5.0}/verifydoc/adapters/docling.py +0 -0
  172. {verifydoc-0.3.0 → verifydoc-0.5.0}/verifydoc/adapters/dots_ocr.py +0 -0
  173. {verifydoc-0.3.0 → verifydoc-0.5.0}/verifydoc/adapters/mock.py +0 -0
  174. {verifydoc-0.3.0 → verifydoc-0.5.0}/verifydoc/adapters/paddleocr_vl.py +0 -0
  175. {verifydoc-0.3.0 → verifydoc-0.5.0}/verifydoc/adapters/rapidocr.py +0 -0
  176. {verifydoc-0.3.0 → verifydoc-0.5.0}/verifydoc/adapters/text_search.py +0 -0
  177. {verifydoc-0.3.0 → verifydoc-0.5.0}/verifydoc/calibration/base.py +0 -0
  178. {verifydoc-0.3.0 → verifydoc-0.5.0}/verifydoc/calibration/conformal.py +0 -0
  179. {verifydoc-0.3.0 → verifydoc-0.5.0}/verifydoc/calibration/histogram.py +0 -0
  180. {verifydoc-0.3.0 → verifydoc-0.5.0}/verifydoc/calibration/isotonic.py +0 -0
  181. {verifydoc-0.3.0 → verifydoc-0.5.0}/verifydoc/calibration/platt.py +0 -0
  182. {verifydoc-0.3.0 → verifydoc-0.5.0}/verifydoc/calibration/splits.py +0 -0
  183. {verifydoc-0.3.0 → verifydoc-0.5.0}/verifydoc/calibration/temperature.py +0 -0
  184. {verifydoc-0.3.0 → verifydoc-0.5.0}/verifydoc/cli.py +0 -0
  185. {verifydoc-0.3.0 → verifydoc-0.5.0}/verifydoc/confidence/__init__.py +0 -0
  186. {verifydoc-0.3.0 → verifydoc-0.5.0}/verifydoc/confidence/combined.py +0 -0
  187. {verifydoc-0.3.0 → verifydoc-0.5.0}/verifydoc/confidence/consensus.py +0 -0
  188. {verifydoc-0.3.0 → verifydoc-0.5.0}/verifydoc/confidence/grounding_based.py +0 -0
  189. {verifydoc-0.3.0 → verifydoc-0.5.0}/verifydoc/confidence/learned.py +0 -0
  190. {verifydoc-0.3.0 → verifydoc-0.5.0}/verifydoc/confidence/token_prob.py +0 -0
  191. {verifydoc-0.3.0 → verifydoc-0.5.0}/verifydoc/confidence/verbalized.py +0 -0
  192. {verifydoc-0.3.0 → verifydoc-0.5.0}/verifydoc/eval/__init__.py +0 -0
  193. {verifydoc-0.3.0 → verifydoc-0.5.0}/verifydoc/eval/calibration.py +0 -0
  194. {verifydoc-0.3.0 → verifydoc-0.5.0}/verifydoc/eval/extraction.py +0 -0
  195. {verifydoc-0.3.0 → verifydoc-0.5.0}/verifydoc/eval/grounding.py +0 -0
  196. {verifydoc-0.3.0 → verifydoc-0.5.0}/verifydoc/eval/selective.py +0 -0
  197. {verifydoc-0.3.0 → verifydoc-0.5.0}/verifydoc/eval/stats.py +0 -0
  198. {verifydoc-0.3.0 → verifydoc-0.5.0}/verifydoc/grounding/__init__.py +0 -0
  199. {verifydoc-0.3.0 → verifydoc-0.5.0}/verifydoc/grounding/attach.py +0 -0
  200. {verifydoc-0.3.0 → verifydoc-0.5.0}/verifydoc/ingest/__init__.py +0 -0
  201. {verifydoc-0.3.0 → verifydoc-0.5.0}/verifydoc/ingest/loader.py +0 -0
  202. {verifydoc-0.3.0 → verifydoc-0.5.0}/verifydoc/pipeline.py +0 -0
  203. {verifydoc-0.3.0 → verifydoc-0.5.0}/verifydoc/policy/__init__.py +0 -0
  204. {verifydoc-0.3.0 → verifydoc-0.5.0}/verifydoc/policy/abstention.py +0 -0
  205. {verifydoc-0.3.0 → verifydoc-0.5.0}/verifydoc/types.py +0 -0
@@ -0,0 +1,25 @@
1
+ ---
2
+ name: Bug report
3
+ about: Something isn't working as documented
4
+ labels: bug
5
+ ---
6
+
7
+ **What happened**
8
+ A clear description of the bug.
9
+
10
+ **Minimal repro**
11
+ Ideally a tiny document + schema and the `verify(...)` call or CLI command.
12
+
13
+ ```python
14
+ # your repro here
15
+ ```
16
+
17
+ **Expected vs actual**
18
+ - Expected:
19
+ - Actual:
20
+
21
+ **Environment**
22
+ - verifydoc version (`verifydoc version`):
23
+ - Python version:
24
+ - OS:
25
+ - Extractor/adapter (if relevant):
@@ -0,0 +1,19 @@
1
+ ---
2
+ name: Feature request / new adapter or dataset
3
+ about: Propose an extractor adapter, dataset slice, signal, calibrator, or feature
4
+ labels: enhancement
5
+ ---
6
+
7
+ **What and why**
8
+ What should VerifyDoc do, and what does it enable?
9
+
10
+ **Which layer**
11
+ - [ ] Adapter (new extractor) — recall: one file in `verifydoc/adapters/`
12
+ - [ ] Dataset slice (`benchmark/datasets/`)
13
+ - [ ] Confidence signal / calibrator
14
+ - [ ] Eval metric
15
+ - [ ] Other
16
+
17
+ **Sketch (optional)**
18
+ Interface or output shape you have in mind. For metrics, include a
19
+ hand-computed expected value so it becomes a regression test.
@@ -0,0 +1,11 @@
1
+ ## What this does
2
+
3
+ Brief description. Link any issue it closes (`Closes #N`).
4
+
5
+ ## Checklist
6
+
7
+ - [ ] `make test lint typecheck` all green locally
8
+ - [ ] New/changed code has tests; metric code has a numeric regression test
9
+ - [ ] Docs updated if the public API changed (`README.md` / `PROJECT.md`)
10
+ - [ ] Conventional Commit title (`feat:` / `fix:` / `docs:` / `test:` / `bench:` …)
11
+ - [ ] If this adds a model adapter: all SDK code stays inside `verifydoc/adapters/`
@@ -37,3 +37,15 @@ outputs/
37
37
  .DS_Store
38
38
  .idea/
39
39
  .vscode/
40
+
41
+ # LaTeX build artifacts
42
+ paper/*.aux
43
+ paper/*.log
44
+ paper/*.out
45
+ paper/*.bbl
46
+ paper/*.blg
47
+ paper/main.pdf
48
+
49
+ # local secrets (never commit)
50
+ .env.secret
51
+ .env.local
@@ -1,5 +1,45 @@
1
1
  # Changelog
2
2
 
3
+ ## v0.5.0 — 2026-07-22
4
+
5
+ A novel method, a frontier-VLM comparison, and an agent-facing application.
6
+
7
+ - **Novel method — grounding-conditioned (Mondrian) conformal risk control**
8
+ (`verifydoc/calibration/grouped_conformal.py`): conditions the abstention
9
+ threshold on provenance, preserving a finite-sample per-group risk guarantee
10
+ while accepting well-grounded fields at a lower bar. Controlled study
11
+ (`scripts/grouped_conformal_experiment.py`): **+0.50 mean coverage** at a
12
+ fixed 5% risk in the uninformative-confidence regime where pooled conformal
13
+ accepts almost nothing. First use of provenance as the conditioning taxonomy
14
+ for conformal in document extraction.
15
+ - **Frontier VLM results** (`claude-sonnet-5`, k=3, on CORD): recall 0.56 but a
16
+ **0.48 hallucination rate**; verbalized confidence is informative (AUROC
17
+ 0.86) for the VLM yet useless (0.50) for OCR pipelines — a cross-extractor
18
+ finding the single-model literature misses. Cross-extractor summary in
19
+ `paper/generated/REAL_MODELS_RESULTS.md`.
20
+ - **MCP server** (`verifydoc-mcp`): exposes `verify_extraction` over the Model
21
+ Context Protocol so AI agents extract documents with confidence + grounding +
22
+ accept/review — a drop-in trust layer for the agentic era (`docs/MCP.md`).
23
+ - Paper elevated to a method contribution (6pp, compiles; novel result in the
24
+ abstract and a dedicated section). `mcp` install extra.
25
+
26
+ ## v0.4.0 — 2026-07-21
27
+
28
+ Paper-ready: fair API-VLM comparison + a compilable paper.
29
+
30
+ - **Vendor-neutral API-VLM extractor** (`verifydoc/adapters/api_vlm.py`):
31
+ OpenAI + Anthropic clients behind one `CompletionClient` protocol, with
32
+ **temperature-based k-sample sampling** so self-consistency consensus and
33
+ verbalized confidence are non-degenerate (the fair comparison the paper
34
+ needs). Harness `adapter_kwargs` passthrough; `configs/cord-apivlm.yaml`;
35
+ `ocr` and `api` install extras.
36
+ - **Compilable paper** (`paper/main.tex`) with real RapidOCR/PaddleOCR/
37
+ synthetic numbers, auto-generated LaTeX result tables
38
+ (`scripts/tables_to_latex.py`, booktabs) and `refs.bib`; `make paper`.
39
+ - **Docs**: `docs/how-it-works.md`; README documentation index; runnable
40
+ `examples/`.
41
+ - Repo hygiene: removed internal build-tooling notes; tidied PROJECT.md.
42
+
3
43
  ## v0.3.0 — 2026-07-21
4
44
 
5
45
  First **real-model** results (issue #3).
@@ -0,0 +1,17 @@
1
+ cff-version: 1.2.0
2
+ message: "If you use VerifyDoc or VerifyDocBench, please cite it."
3
+ title: "VerifyDoc: Calibrated, Abstaining, Grounded Document Extraction"
4
+ authors:
5
+ - family-names: Gurram
6
+ given-names: Bhaskar
7
+ repository-code: "https://github.com/bhaskargurram-ai/verifydoc"
8
+ license: Apache-2.0
9
+ version: 0.5.0
10
+ date-released: 2026-07-21
11
+ keywords:
12
+ - document-extraction
13
+ - calibration
14
+ - selective-prediction
15
+ - conformal-prediction
16
+ - grounding
17
+ - hallucination-detection
@@ -0,0 +1,32 @@
1
+ # Code of Conduct
2
+
3
+ ## Our pledge
4
+
5
+ We as members, contributors, and maintainers pledge to make participation in
6
+ VerifyDoc a harassment-free experience for everyone, regardless of age, body
7
+ size, visible or invisible disability, ethnicity, sex characteristics, gender
8
+ identity and expression, level of experience, education, socio-economic
9
+ status, nationality, personal appearance, race, religion, or sexual identity
10
+ and orientation.
11
+
12
+ ## Our standards
13
+
14
+ Examples of behavior that contributes to a positive environment:
15
+
16
+ - Being respectful of differing opinions, viewpoints, and experiences
17
+ - Giving and gracefully accepting constructive feedback
18
+ - Focusing on what is best for the community and the project
19
+
20
+ Unacceptable behavior includes harassment, insulting or derogatory comments,
21
+ personal or political attacks, publishing others' private information, and
22
+ other conduct that could reasonably be considered inappropriate.
23
+
24
+ ## Enforcement
25
+
26
+ Instances of abusive, harassing, or otherwise unacceptable behavior may be
27
+ reported to the project maintainers via a GitHub issue or direct contact.
28
+ Maintainers will review and respond, and will respect the privacy and
29
+ security of the reporter.
30
+
31
+ This Code of Conduct is adapted from the [Contributor Covenant](https://www.contributor-covenant.org/),
32
+ version 2.1.
@@ -0,0 +1,55 @@
1
+ # Contributing to VerifyDoc
2
+
3
+ Thanks for helping build the open trust layer for document extraction. This
4
+ project is designed so contributions are small and self-contained.
5
+
6
+ ## Ground rules (the architecture makes these easy)
7
+
8
+ 1. **Adapters are isolated.** All model-specific code lives behind the
9
+ `ExtractorAdapter` interface in `verifydoc/adapters/`. **Adding a new
10
+ extractor = one new file** — nothing outside `adapters/` imports a model SDK.
11
+ 2. **Stages are independent:** ingest → adapter → confidence → calibration →
12
+ grounding → policy → report. Each has typed inputs/outputs
13
+ (`verifydoc/types.py`) and its own tests. No stage reaches into another.
14
+ 3. **The eval harness is decoupled.** It scores anything that emits
15
+ `FieldPrediction`. Never couple a metric to a specific model.
16
+ 4. **Never tune on test.** Calibration/abstention thresholds are fit only on
17
+ the dedicated calibration split (enforced by `assert_disjoint`).
18
+ 5. **No network in unit tests.** Mock adapters. Every metric gets a numeric
19
+ regression test against a hand-computed fixture.
20
+
21
+ ## Good first issues
22
+
23
+ Look for the [`good first issue`](https://github.com/bhaskargurram-ai/verifydoc/labels/good%20first%20issue)
24
+ label. Great starting points:
25
+
26
+ - **Add an extractor adapter** (Surya, GOT-OCR2.0, an API VLM) — one file in
27
+ `adapters/`, plus a normalization test (see `tests/test_pipeline.py`).
28
+ - **Add a dataset slice** (SROIE, DocILE, XFUND) — a loader in
29
+ `benchmark/datasets/` returning `BenchDocument`s, following `funsd.py`.
30
+ - **A new confidence signal or calibrator** behind the existing interfaces.
31
+
32
+ ## Dev setup
33
+
34
+ ```bash
35
+ git clone https://github.com/bhaskargurram-ai/verifydoc && cd verifydoc
36
+ uv venv .venv && uv pip install -e ".[dev]"
37
+ make test lint typecheck # all must be green
38
+ ```
39
+
40
+ ## Before you open a PR
41
+
42
+ - `ruff`, `black`, `mypy`, and `pytest` all pass (CI enforces; no PR merges red).
43
+ - New/changed code has tests; metric code has a numeric regression test.
44
+ - Public-API changes update `README.md` / `PROJECT.md`.
45
+ - Use [Conventional Commits](https://www.conventionalcommits.org/):
46
+ `feat:` `fix:` `docs:` `test:` `refactor:` `chore:` `perf:` `bench:`.
47
+ - Branch off `main`, open a PR, we squash-merge.
48
+
49
+ ## Reporting bugs / ideas
50
+
51
+ Open an issue with a minimal repro (a tiny document + schema is ideal). For
52
+ metric bugs, include the expected hand-computed value — that becomes the
53
+ regression test.
54
+
55
+ By contributing you agree your work is licensed under Apache-2.0.
@@ -1,4 +1,4 @@
1
- .PHONY: install lint format typecheck test cov results demo clean
1
+ .PHONY: install lint format typecheck test cov results paper demo clean
2
2
 
3
3
  PY ?= python
4
4
 
@@ -28,6 +28,14 @@ results:
28
28
  $(PY) scripts/run_benchmark.py --config configs/demo.yaml --out paper/generated
29
29
  $(PY) scripts/run_benchmark.py --config configs/cord.yaml --out paper/generated/cord
30
30
  $(PY) scripts/run_benchmark.py --config configs/funsd.yaml --out paper/generated/funsd
31
+ $(PY) scripts/grouped_conformal_experiment.py
32
+ $(PY) scripts/tables_to_latex.py paper/generated
33
+
34
+ # Compile the paper (needs a LaTeX toolchain); tables come from `make results`.
35
+ paper:
36
+ $(PY) scripts/grouped_conformal_experiment.py
37
+ $(PY) scripts/tables_to_latex.py paper/generated
38
+ cd paper && pdflatex -interaction=nonstopmode main.tex && bibtex main && pdflatex -interaction=nonstopmode main.tex && pdflatex -interaction=nonstopmode main.tex
31
39
 
32
40
  demo:
33
41
  streamlit run ui/streamlit_app.py
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: verifydoc
3
- Version: 0.3.0
3
+ Version: 0.5.0
4
4
  Summary: A trust layer for document -> structured-JSON extraction: calibrated per-field confidence, source grounding, and abstention on top of any extractor.
5
5
  Project-URL: Homepage, https://github.com/bhaskargurram-ai/verifydoc
6
6
  Project-URL: Repository, https://github.com/bhaskargurram-ai/verifydoc
@@ -226,6 +226,9 @@ Requires-Dist: pyyaml>=6.0
226
226
  Requires-Dist: scikit-learn>=1.3
227
227
  Requires-Dist: scipy>=1.11
228
228
  Requires-Dist: typer>=0.9
229
+ Provides-Extra: api
230
+ Requires-Dist: anthropic>=0.39; extra == 'api'
231
+ Requires-Dist: openai>=1.40; extra == 'api'
229
232
  Provides-Extra: data
230
233
  Requires-Dist: datasets>=2.16; extra == 'data'
231
234
  Provides-Extra: dev
@@ -235,6 +238,11 @@ Requires-Dist: pre-commit>=3.6; extra == 'dev'
235
238
  Requires-Dist: pytest-cov>=4.1; extra == 'dev'
236
239
  Requires-Dist: pytest>=7.4; extra == 'dev'
237
240
  Requires-Dist: ruff>=0.4; extra == 'dev'
241
+ Provides-Extra: mcp
242
+ Requires-Dist: mcp>=1.2; extra == 'mcp'
243
+ Provides-Extra: ocr
244
+ Requires-Dist: onnxruntime>=1.17; extra == 'ocr'
245
+ Requires-Dist: rapidocr>=1.3; extra == 'ocr'
238
246
  Provides-Extra: pdf
239
247
  Requires-Dist: pdfplumber>=0.10; extra == 'pdf'
240
248
  Requires-Dist: pillow>=10.0; extra == 'pdf'
@@ -282,7 +290,8 @@ pip install 'verifydoc[pdf]' # + PDF/image ingestion
282
290
  ```python
283
291
  from verifydoc import verify
284
292
 
285
- result = verify("invoice.txt", schema="invoice_schema.json", k=3)
293
+ # ready-to-run sample lives in examples/
294
+ result = verify("examples/invoice.txt", schema="examples/invoice_schema.json")
286
295
  for f in result.fields:
287
296
  print(f"{f.path:12} = {f.value!r:24} conf={f.confidence:.2f} {f.decision}")
288
297
  if f.grounding:
@@ -290,10 +299,26 @@ for f in result.fields:
290
299
  ```
291
300
 
292
301
  ```bash
293
- verifydoc extract invoice.txt --schema invoice_schema.json --k 3 --threshold 0.8
302
+ verifydoc extract examples/invoice.txt --schema examples/invoice_schema.json --threshold 0.8
294
303
  streamlit run ui/streamlit_app.py # review UI: green/red fields + click-through to source
295
304
  ```
296
305
 
306
+ See [`examples/`](examples/) for the full runnable walk-through.
307
+
308
+ ## For AI agents (MCP)
309
+
310
+ Give any MCP-capable agent (Claude Desktop, IDEs, custom agents) a **trust
311
+ layer for reading documents** — so it acts on confident, grounded fields and
312
+ escalates the rest instead of hallucinating forward:
313
+
314
+ ```bash
315
+ pip install 'verifydoc[mcp]'
316
+ verifydoc-mcp # stdio MCP server exposing verify_extraction()
317
+ ```
318
+
319
+ Every field the agent extracts comes back with `confidence + grounding +
320
+ accept/review`. See [docs/MCP.md](docs/MCP.md) for the one-line client config.
321
+
297
322
  Schemas are plain JSON Schema, with each leaf optionally declaring **how it is scored** (the executable-schema pattern):
298
323
 
299
324
  ```json
@@ -311,14 +336,37 @@ Schemas are plain JSON Schema, with each leaf optionally declaring **how it is s
311
336
 
312
337
  | Layer | Modules | Status |
313
338
  |---|---|---|
314
- | **Adapters** (all model code isolated here) | mock · text-search · PaddleOCR-VL · dots.ocr · Docling/MinerU output · API-VLM | ✅ |
339
+ | **Adapters** (all model code isolated here) | mock · text-search · RapidOCR · PaddleOCR · dots.ocr · Docling/MinerU output · API-VLM (OpenAI/Anthropic) | ✅ |
315
340
  | **Confidence signals** | token-prob · verbalized · consensus (k-sample voting) · grounding-based · combined | ✅ |
316
- | **Calibrators** (fit on a dedicated split, never test) | temperature · Platt · isotonic · histogram · **split conformal** with finite-sample risk guarantee | ✅ |
341
+ | **Calibrators** (fit on a dedicated split, never test) | temperature · Platt · isotonic · histogram · **split conformal** · **grounding-conditioned (Mondrian) conformal** (novel — recovers coverage a pooled threshold forfeits) | ✅ |
317
342
  | **Grounding** | value → page/bbox/char-span attachment with support scores | ✅ |
318
343
  | **Policy** | empirical & conformal accept thresholds for a target selective risk | ✅ |
319
344
  | **Eval harness / VerifyDocBench scorer** | Field-F1 · exact · CER/WER · ANLS · TEDS/TEDS-Struct · GriTS · omission vs hallucination · ECE/Adaptive-ECE/MCE/Brier/NLL/TCE · RC/AURC/E-AURC/Coverage@Risk/AUROC/AUPR/FPR@95 · box IoU/span-F1/grounding-conditioned correctness · bootstrap CIs + paired tests | ✅ |
320
345
 
321
- Every metric implements the exact definition in [PROJECT.md §5](PROJECT.md) with a hand-computed numeric regression test (200 tests, `eval/` coverage 98%).
346
+ Every metric implements the exact definition in [PROJECT.md §5](PROJECT.md) with a hand-computed numeric regression test (201 tests, `eval/` coverage 98%).
347
+
348
+ ## Results on real documents
349
+
350
+ Two independent real OCR extractors (**RapidOCR** and **PaddleOCR**) on real
351
+ **CORD** receipts and **FUNSD** forms, scored by the harness
352
+ ([full tables + reading](paper/generated/REAL_MODELS_RESULTS.md)):
353
+
354
+ | Confidence signal | ranks errors? | CORD AUROC (RapidOCR / PaddleOCR) |
355
+ |---|---|---|
356
+ | **learned combiner** | ✅ best | **0.89 / 0.84** |
357
+ | **grounding** | ✅ strong | 0.82 / 0.74 |
358
+ | token-probability | ~ moderate | 0.69 / 0.68 |
359
+ | verbalized / consensus | ✗ uninformative | 0.50 / 0.50 |
360
+
361
+ - **Grounding is a real trust signal:** grounded fields are **84–85% correct
362
+ vs ~1%** for ungrounded (gap ≈ +0.84; box accuracy @IoU 0.5 = 0.75–0.78).
363
+ - **The abstention layer is honest:** with a weak field-extractor the base
364
+ error rate is high, so conformal abstention at a 2–5% budget correctly
365
+ refuses to auto-accept — you report *selective risk*, not headline accuracy.
366
+ - The synthetic slice (strong extractor) shows the other end: Coverage@2% ≈ 1.0.
367
+
368
+ The thesis holds on real data: **grounding + a learned fusion rank errors;
369
+ self-reported and single-sample-consensus confidence do not.**
322
370
 
323
371
  ## The benchmark
324
372
 
@@ -328,16 +376,13 @@ make results # regenerates every table/figure in paper/generated from config
328
376
 
329
377
  The harness runs **signals × calibrators × the full metric suite** with a
330
378
  document-level calibration split (disjointness asserted in code), bootstrap
331
- CIs, and a conformal-guarantee row. The repo ships a deterministic synthetic
332
- slice that runs in CI; loaders for CORD (and next: FUNSD, SROIE, DocILE,
333
- XFUND) extend it. Sample findings on the shipped slice
334
- ([tables](paper/generated)):
335
-
336
- - **Verbalized self-confidence is badly miscalibrated** (the extractor says ~0.9 regardless of correctness) exactly the failure mode reported for RLHF'd models.
337
- - **Consensus and grounding signals rank errors near-perfectly** (AUROC ≈ 0.98): corrupted values can't be traced back to the page, so grounding support collapses.
338
- - **The conformal row holds its guarantee** on every tested α, and reports the abstention it forces.
339
-
340
- These self-checks run as unit tests — the repo's core claims are CI-enforced, not just stated.
379
+ CIs, and a conformal-guarantee row. It ships a deterministic **synthetic**
380
+ slice (runs in CI) plus **CORD** and **FUNSD** loaders with gold source boxes;
381
+ `extractor:` dispatches to any adapter (`rapidocr`, `paddleocr-vl`, …) and
382
+ `dataset:` to any slice. See the [GPU runbook](docs/REAL_MODELS.md) to
383
+ reproduce the real-model rows. Core claims (grounding beats verbalized;
384
+ conformal holds its guarantee) are also **CI-enforced as unit tests**, not
385
+ just stated.
341
386
 
342
387
  ## Why not just use the parser's own score?
343
388
 
@@ -350,9 +395,19 @@ buys you.
350
395
  ## Roadmap
351
396
 
352
397
  - [x] v0.1 — library + CLI + harness + synthetic benchmark slice + UI
353
- - [ ] CORD/FUNSD/SROIE slices with gold source boxes (VerifyDocBench v1)
354
- - [ ] Learned signal combiner + per-field-type calibration
355
- - [ ] Paper: first systematic study of confidence signals × calibration × abstention for document extraction
398
+ - [x] v0.2 — CORD + FUNSD real slices with gold boxes; learned combiner; 1000× faster grounder
399
+ - [x] v0.3 real-model results (RapidOCR + PaddleOCR on CORD/FUNSD)
400
+ - [x] v0.4 vendor-neutral API-VLM extractor (OpenAI/Anthropic) with k-sample consensus; compilable paper with auto-generated tables
401
+ - [x] v0.5 — **novel method** (grounding-conditioned conformal, +0.50 coverage at fixed risk) + **MCP server** (agent trust layer) + real frontier-VLM results
402
+ - [ ] dots.ocr via vllm; SROIE / DocILE / XFUND slices; human-labeled correctness + IAA
403
+ - [ ] Paper submission ([contributions welcome](CONTRIBUTING.md))
404
+
405
+ ## Documentation
406
+
407
+ - [How it works](docs/how-it-works.md) — the pipeline, the abstention idea, why grounding is a trust signal
408
+ - [Real-model results](paper/generated/REAL_MODELS_RESULTS.md) — RapidOCR + PaddleOCR numbers and reading
409
+ - [GPU runbook](docs/REAL_MODELS.md) — reproduce the real-extractor rows
410
+ - [USP audit](docs/USP.md) · [Paper draft](paper/main.tex) · [Full spec](PROJECT.md)
356
411
 
357
412
  ## Development
358
413
 
@@ -360,6 +415,8 @@ buys you.
360
415
  git clone https://github.com/bhaskargurram-ai/verifydoc && cd verifydoc
361
416
  uv venv .venv && uv pip install -e ".[dev]"
362
417
  make test lint typecheck # all green before any PR (CI enforces)
418
+ make results # regenerate benchmark tables + LaTeX
419
+ make paper # compile the paper (needs a LaTeX toolchain)
363
420
  ```
364
421
 
365
422
  Contributions welcome — see the issues tagged `good-first-issue`. All model-specific code goes in `verifydoc/adapters/`; a new extractor is one file.
@@ -1,6 +1,6 @@
1
1
  # VerifyDoc — A Trust Layer for Document → Structured-JSON Extraction
2
2
 
3
- **Project document / build spec (v1.0).** This is the single source of truth for building VerifyDoc with Claude Code. It contains the motivation, the precise problem definition, the literature-grounded evaluation methodology (the core of the paper), the system architecture, the repository layout, a six-week implementation plan, the git workflow, and the paper plan. Hand this file (plus `CLAUDE.md`) to Claude Code and build module by module against the "Definition of Done" in each section.
3
+ **Project document / design spec (v1.0).** This is the single source of truth for VerifyDoc's design. It contains the motivation, the precise problem definition, the literature-grounded evaluation methodology (the core of the paper), the system architecture, the repository layout, a six-week implementation plan, the git workflow, and the paper plan. Build module by module against the "Definition of Done" in each section.
4
4
 
5
5
  One-liner: *VerifyDoc wraps any document-extraction model and returns, for every field, a calibrated confidence score, a source-grounding box/span, and an abstain-or-accept decision — so a human reviews the 5% of fields that are actually wrong instead of eyeballing all of them.*
6
6
 
@@ -12,7 +12,7 @@ Document → structured-JSON extraction is one of the highest-volume uses of LLM
12
12
 
13
13
  That is the wedge. VerifyDoc does not compete with the parsers — it *layers on top of any of them* and adds the missing reliability contract: field-level confidence + provenance + abstention. Commercial APIs already prove the demand (Box shipped field-level confidence in Jan 2026; Azure Document Intelligence, AWS Textract, and Extend all expose per-field confidence), but no popular open-source parser leads with it. Practitioner leaderboards name exactly this unmet need: whether a reviewer can trace an uncertain value back to the page before it enters a downstream system. VerifyDoc is the open-source answer.
14
14
 
15
- Why this is a good solo project: the tool is model-agnostic and thin (it wraps existing extractors), the paper contribution is the reliable "benchmark + released dataset + strong open baseline" type rather than a risky "beat-SOTA architecture" play, and the demo (highlight-the-hallucinated-field on the rendered page) is instantly shareable.
15
+ Why the scope works: the tool is model-agnostic and thin (it wraps existing extractors), the paper contribution is the reliable "benchmark + released dataset + strong open baseline" type rather than a risky "beat-SOTA architecture" play, and the demo (highlight-the-hallucinated-field on the rendered page) is instantly shareable.
16
16
 
17
17
  ---
18
18
 
@@ -216,7 +216,6 @@ Design rules: adapters isolate all model-specific code behind one interface (`ex
216
216
  ```
217
217
  verifydoc/
218
218
  ├── README.md # quickstart + the killer demo GIF
219
- ├── CLAUDE.md # Claude Code working context (see separate file)
220
219
  ├── PROJECT.md # this document
221
220
  ├── LICENSE # Apache-2.0 (permissive → adoption)
222
221
  ├── pyproject.toml # packaging (pip install verifydoc)
@@ -269,7 +268,7 @@ verifydoc/
269
268
 
270
269
  ---
271
270
 
272
- ## 9. Implementation plan (6 weeks, solo)
271
+ ## 9. Implementation plan (6 weeks)
273
272
 
274
273
  **Week 1 — skeleton + types + one adapter + eval stubs.** Repo, packaging, CI, pre-commit. Define `types.py` (`FieldPrediction`, `Grounding`). Implement ingest (PDF→images + text layer). Ship the **PaddleOCR-VL adapter** end-to-end on a handful of CORD receipts. Stub `eval/extraction.py` with Field-F1 + exact-match. *DoD: `verifydoc extract sample.pdf --schema cord.json` returns JSON with placeholder confidences; CI green.*
275
274
 
@@ -320,12 +319,6 @@ verifydoc/
320
319
 
321
320
  ---
322
321
 
323
- ## 13. EB1-A mapping (brief, honest)
324
-
325
- This project can contribute to (a) **authorship of scholarly articles** (arXiv + workshop/TMLR paper); (b) **original contributions of major significance** — best evidenced by demonstrable open-source adoption (stars, PyPI downloads, dependents, external citations of VerifyDocBench); and (c) **judging the work of others** if you also serve as a reviewer for the workshop you submit to. Be realistic: USCIS requires meeting **at least three** criteria plus a holistic final-merits determination, and strong petitions usually document more, with independent corroboration (sustained citations, media, memberships, and recommendation letters). VerifyDoc is engineered to *generate* that downstream evidence (adoption → citations → letters), but **two projects alone are not a sufficient petition** — pair it with the second project and the complementary criteria.
326
-
327
- ---
328
-
329
322
  ## References (select; verify at write-up)
330
323
 
331
324
  - ExtractBench — arXiv:2602.12247 (SIGKDD 2026); code github.com/ContextualAI/extract-bench.
@@ -36,7 +36,8 @@ pip install 'verifydoc[pdf]' # + PDF/image ingestion
36
36
  ```python
37
37
  from verifydoc import verify
38
38
 
39
- result = verify("invoice.txt", schema="invoice_schema.json", k=3)
39
+ # ready-to-run sample lives in examples/
40
+ result = verify("examples/invoice.txt", schema="examples/invoice_schema.json")
40
41
  for f in result.fields:
41
42
  print(f"{f.path:12} = {f.value!r:24} conf={f.confidence:.2f} {f.decision}")
42
43
  if f.grounding:
@@ -44,10 +45,26 @@ for f in result.fields:
44
45
  ```
45
46
 
46
47
  ```bash
47
- verifydoc extract invoice.txt --schema invoice_schema.json --k 3 --threshold 0.8
48
+ verifydoc extract examples/invoice.txt --schema examples/invoice_schema.json --threshold 0.8
48
49
  streamlit run ui/streamlit_app.py # review UI: green/red fields + click-through to source
49
50
  ```
50
51
 
52
+ See [`examples/`](examples/) for the full runnable walk-through.
53
+
54
+ ## For AI agents (MCP)
55
+
56
+ Give any MCP-capable agent (Claude Desktop, IDEs, custom agents) a **trust
57
+ layer for reading documents** — so it acts on confident, grounded fields and
58
+ escalates the rest instead of hallucinating forward:
59
+
60
+ ```bash
61
+ pip install 'verifydoc[mcp]'
62
+ verifydoc-mcp # stdio MCP server exposing verify_extraction()
63
+ ```
64
+
65
+ Every field the agent extracts comes back with `confidence + grounding +
66
+ accept/review`. See [docs/MCP.md](docs/MCP.md) for the one-line client config.
67
+
51
68
  Schemas are plain JSON Schema, with each leaf optionally declaring **how it is scored** (the executable-schema pattern):
52
69
 
53
70
  ```json
@@ -65,14 +82,37 @@ Schemas are plain JSON Schema, with each leaf optionally declaring **how it is s
65
82
 
66
83
  | Layer | Modules | Status |
67
84
  |---|---|---|
68
- | **Adapters** (all model code isolated here) | mock · text-search · PaddleOCR-VL · dots.ocr · Docling/MinerU output · API-VLM | ✅ |
85
+ | **Adapters** (all model code isolated here) | mock · text-search · RapidOCR · PaddleOCR · dots.ocr · Docling/MinerU output · API-VLM (OpenAI/Anthropic) | ✅ |
69
86
  | **Confidence signals** | token-prob · verbalized · consensus (k-sample voting) · grounding-based · combined | ✅ |
70
- | **Calibrators** (fit on a dedicated split, never test) | temperature · Platt · isotonic · histogram · **split conformal** with finite-sample risk guarantee | ✅ |
87
+ | **Calibrators** (fit on a dedicated split, never test) | temperature · Platt · isotonic · histogram · **split conformal** · **grounding-conditioned (Mondrian) conformal** (novel — recovers coverage a pooled threshold forfeits) | ✅ |
71
88
  | **Grounding** | value → page/bbox/char-span attachment with support scores | ✅ |
72
89
  | **Policy** | empirical & conformal accept thresholds for a target selective risk | ✅ |
73
90
  | **Eval harness / VerifyDocBench scorer** | Field-F1 · exact · CER/WER · ANLS · TEDS/TEDS-Struct · GriTS · omission vs hallucination · ECE/Adaptive-ECE/MCE/Brier/NLL/TCE · RC/AURC/E-AURC/Coverage@Risk/AUROC/AUPR/FPR@95 · box IoU/span-F1/grounding-conditioned correctness · bootstrap CIs + paired tests | ✅ |
74
91
 
75
- Every metric implements the exact definition in [PROJECT.md §5](PROJECT.md) with a hand-computed numeric regression test (200 tests, `eval/` coverage 98%).
92
+ Every metric implements the exact definition in [PROJECT.md §5](PROJECT.md) with a hand-computed numeric regression test (201 tests, `eval/` coverage 98%).
93
+
94
+ ## Results on real documents
95
+
96
+ Two independent real OCR extractors (**RapidOCR** and **PaddleOCR**) on real
97
+ **CORD** receipts and **FUNSD** forms, scored by the harness
98
+ ([full tables + reading](paper/generated/REAL_MODELS_RESULTS.md)):
99
+
100
+ | Confidence signal | ranks errors? | CORD AUROC (RapidOCR / PaddleOCR) |
101
+ |---|---|---|
102
+ | **learned combiner** | ✅ best | **0.89 / 0.84** |
103
+ | **grounding** | ✅ strong | 0.82 / 0.74 |
104
+ | token-probability | ~ moderate | 0.69 / 0.68 |
105
+ | verbalized / consensus | ✗ uninformative | 0.50 / 0.50 |
106
+
107
+ - **Grounding is a real trust signal:** grounded fields are **84–85% correct
108
+ vs ~1%** for ungrounded (gap ≈ +0.84; box accuracy @IoU 0.5 = 0.75–0.78).
109
+ - **The abstention layer is honest:** with a weak field-extractor the base
110
+ error rate is high, so conformal abstention at a 2–5% budget correctly
111
+ refuses to auto-accept — you report *selective risk*, not headline accuracy.
112
+ - The synthetic slice (strong extractor) shows the other end: Coverage@2% ≈ 1.0.
113
+
114
+ The thesis holds on real data: **grounding + a learned fusion rank errors;
115
+ self-reported and single-sample-consensus confidence do not.**
76
116
 
77
117
  ## The benchmark
78
118
 
@@ -82,16 +122,13 @@ make results # regenerates every table/figure in paper/generated from config
82
122
 
83
123
  The harness runs **signals × calibrators × the full metric suite** with a
84
124
  document-level calibration split (disjointness asserted in code), bootstrap
85
- CIs, and a conformal-guarantee row. The repo ships a deterministic synthetic
86
- slice that runs in CI; loaders for CORD (and next: FUNSD, SROIE, DocILE,
87
- XFUND) extend it. Sample findings on the shipped slice
88
- ([tables](paper/generated)):
89
-
90
- - **Verbalized self-confidence is badly miscalibrated** (the extractor says ~0.9 regardless of correctness) exactly the failure mode reported for RLHF'd models.
91
- - **Consensus and grounding signals rank errors near-perfectly** (AUROC ≈ 0.98): corrupted values can't be traced back to the page, so grounding support collapses.
92
- - **The conformal row holds its guarantee** on every tested α, and reports the abstention it forces.
93
-
94
- These self-checks run as unit tests — the repo's core claims are CI-enforced, not just stated.
125
+ CIs, and a conformal-guarantee row. It ships a deterministic **synthetic**
126
+ slice (runs in CI) plus **CORD** and **FUNSD** loaders with gold source boxes;
127
+ `extractor:` dispatches to any adapter (`rapidocr`, `paddleocr-vl`, …) and
128
+ `dataset:` to any slice. See the [GPU runbook](docs/REAL_MODELS.md) to
129
+ reproduce the real-model rows. Core claims (grounding beats verbalized;
130
+ conformal holds its guarantee) are also **CI-enforced as unit tests**, not
131
+ just stated.
95
132
 
96
133
  ## Why not just use the parser's own score?
97
134
 
@@ -104,9 +141,19 @@ buys you.
104
141
  ## Roadmap
105
142
 
106
143
  - [x] v0.1 — library + CLI + harness + synthetic benchmark slice + UI
107
- - [ ] CORD/FUNSD/SROIE slices with gold source boxes (VerifyDocBench v1)
108
- - [ ] Learned signal combiner + per-field-type calibration
109
- - [ ] Paper: first systematic study of confidence signals × calibration × abstention for document extraction
144
+ - [x] v0.2 — CORD + FUNSD real slices with gold boxes; learned combiner; 1000× faster grounder
145
+ - [x] v0.3 real-model results (RapidOCR + PaddleOCR on CORD/FUNSD)
146
+ - [x] v0.4 vendor-neutral API-VLM extractor (OpenAI/Anthropic) with k-sample consensus; compilable paper with auto-generated tables
147
+ - [x] v0.5 — **novel method** (grounding-conditioned conformal, +0.50 coverage at fixed risk) + **MCP server** (agent trust layer) + real frontier-VLM results
148
+ - [ ] dots.ocr via vllm; SROIE / DocILE / XFUND slices; human-labeled correctness + IAA
149
+ - [ ] Paper submission ([contributions welcome](CONTRIBUTING.md))
150
+
151
+ ## Documentation
152
+
153
+ - [How it works](docs/how-it-works.md) — the pipeline, the abstention idea, why grounding is a trust signal
154
+ - [Real-model results](paper/generated/REAL_MODELS_RESULTS.md) — RapidOCR + PaddleOCR numbers and reading
155
+ - [GPU runbook](docs/REAL_MODELS.md) — reproduce the real-extractor rows
156
+ - [USP audit](docs/USP.md) · [Paper draft](paper/main.tex) · [Full spec](PROJECT.md)
110
157
 
111
158
  ## Development
112
159
 
@@ -114,6 +161,8 @@ buys you.
114
161
  git clone https://github.com/bhaskargurram-ai/verifydoc && cd verifydoc
115
162
  uv venv .venv && uv pip install -e ".[dev]"
116
163
  make test lint typecheck # all green before any PR (CI enforces)
164
+ make results # regenerate benchmark tables + LaTeX
165
+ make paper # compile the paper (needs a LaTeX toolchain)
117
166
  ```
118
167
 
119
168
  Contributions welcome — see the issues tagged `good-first-issue`. All model-specific code goes in `verifydoc/adapters/`; a new extractor is one file.
@@ -0,0 +1,13 @@
1
+ # API-VLM comparison row: a hosted VLM reads the CORD text layer and returns
2
+ # schema fields with self-assessed (verbalized) confidence. k>1 enables real
3
+ # self-consistency consensus (temperature sampling). Needs an API key:
4
+ # export ANTHROPIC_API_KEY=... (or OPENAI_API_KEY with provider: openai)
5
+ # Cost is a few dollars for 100 receipts at k=3. See docs/REAL_MODELS.md.
6
+ dataset: cord
7
+ split: validation
8
+ limit: 100
9
+ extractor: api-vlm
10
+ k: 3 # self-consistency: makes consensus + verbalized meaningful
11
+ calibration_fraction: 0.5
12
+ alphas: [0.02, 0.05]
13
+ n_boot: 300