docs-anonymizer 0.2.2__tar.gz → 0.2.4__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 (345) hide show
  1. {docs_anonymizer-0.2.2 → docs_anonymizer-0.2.4}/CHANGELOG.md +36 -0
  2. {docs_anonymizer-0.2.2 → docs_anonymizer-0.2.4}/PKG-INFO +2 -1
  3. {docs_anonymizer-0.2.2 → docs_anonymizer-0.2.4}/pyproject.toml +13 -5
  4. docs_anonymizer-0.2.4/tests/unit/test_agent_workflows.py +92 -0
  5. docs_anonymizer-0.2.4/tests/unit/test_pyproject_dependency_pins.py +150 -0
  6. {docs_anonymizer-0.2.2 → docs_anonymizer-0.2.4}/.gitignore +0 -0
  7. {docs_anonymizer-0.2.2 → docs_anonymizer-0.2.4}/LICENSE +0 -0
  8. {docs_anonymizer-0.2.2 → docs_anonymizer-0.2.4}/README.md +0 -0
  9. {docs_anonymizer-0.2.2 → docs_anonymizer-0.2.4}/installer/install.ps1 +0 -0
  10. {docs_anonymizer-0.2.2 → docs_anonymizer-0.2.4}/installer/install.sh +0 -0
  11. {docs_anonymizer-0.2.2 → docs_anonymizer-0.2.4}/src/anonymizer/__init__.py +0 -0
  12. {docs_anonymizer-0.2.2 → docs_anonymizer-0.2.4}/src/anonymizer/cli/__init__.py +0 -0
  13. {docs_anonymizer-0.2.2 → docs_anonymizer-0.2.4}/src/anonymizer/cli/__main__.py +0 -0
  14. {docs_anonymizer-0.2.2 → docs_anonymizer-0.2.4}/src/anonymizer/cli/_review_md.py +0 -0
  15. {docs_anonymizer-0.2.2 → docs_anonymizer-0.2.4}/src/anonymizer/cli/annotate_cmd.py +0 -0
  16. {docs_anonymizer-0.2.2 → docs_anonymizer-0.2.4}/src/anonymizer/cli/testkit_cmd.py +0 -0
  17. {docs_anonymizer-0.2.2 → docs_anonymizer-0.2.4}/src/anonymizer/core/__init__.py +0 -0
  18. {docs_anonymizer-0.2.2 → docs_anonymizer-0.2.4}/src/anonymizer/core/audit/__init__.py +0 -0
  19. {docs_anonymizer-0.2.2 → docs_anonymizer-0.2.4}/src/anonymizer/core/audit/crash_log.py +0 -0
  20. {docs_anonymizer-0.2.2 → docs_anonymizer-0.2.4}/src/anonymizer/core/audit/feedback_log.py +0 -0
  21. {docs_anonymizer-0.2.2 → docs_anonymizer-0.2.4}/src/anonymizer/core/coverage/__init__.py +0 -0
  22. {docs_anonymizer-0.2.2 → docs_anonymizer-0.2.4}/src/anonymizer/core/coverage/format_warnings.py +0 -0
  23. {docs_anonymizer-0.2.2 → docs_anonymizer-0.2.4}/src/anonymizer/core/detection/__init__.py +0 -0
  24. {docs_anonymizer-0.2.2 → docs_anonymizer-0.2.4}/src/anonymizer/core/detection/base.py +0 -0
  25. {docs_anonymizer-0.2.2 → docs_anonymizer-0.2.4}/src/anonymizer/core/detection/conflict_resolution.py +0 -0
  26. {docs_anonymizer-0.2.2 → docs_anonymizer-0.2.4}/src/anonymizer/core/detection/email_detector.py +0 -0
  27. {docs_anonymizer-0.2.2 → docs_anonymizer-0.2.4}/src/anonymizer/core/detection/ner_detectors/__init__.py +0 -0
  28. {docs_anonymizer-0.2.2 → docs_anonymizer-0.2.4}/src/anonymizer/core/detection/ner_detectors/_base.py +0 -0
  29. {docs_anonymizer-0.2.2 → docs_anonymizer-0.2.4}/src/anonymizer/core/detection/ner_detectors/address.py +0 -0
  30. {docs_anonymizer-0.2.2 → docs_anonymizer-0.2.4}/src/anonymizer/core/detection/ner_detectors/company_en.py +0 -0
  31. {docs_anonymizer-0.2.2 → docs_anonymizer-0.2.4}/src/anonymizer/core/detection/ner_detectors/company_ru.py +0 -0
  32. {docs_anonymizer-0.2.2 → docs_anonymizer-0.2.4}/src/anonymizer/core/detection/ner_detectors/person_en.py +0 -0
  33. {docs_anonymizer-0.2.2 → docs_anonymizer-0.2.4}/src/anonymizer/core/detection/ner_detectors/person_ru.py +0 -0
  34. {docs_anonymizer-0.2.2 → docs_anonymizer-0.2.4}/src/anonymizer/core/detection/phone_detector.py +0 -0
  35. {docs_anonymizer-0.2.2 → docs_anonymizer-0.2.4}/src/anonymizer/core/detection/regex_detectors/__init__.py +0 -0
  36. {docs_anonymizer-0.2.2 → docs_anonymizer-0.2.4}/src/anonymizer/core/detection/regex_detectors/bic_detector.py +0 -0
  37. {docs_anonymizer-0.2.2 → docs_anonymizer-0.2.4}/src/anonymizer/core/detection/regex_detectors/bic_ru_detector.py +0 -0
  38. {docs_anonymizer-0.2.2 → docs_anonymizer-0.2.4}/src/anonymizer/core/detection/regex_detectors/card_detector.py +0 -0
  39. {docs_anonymizer-0.2.2 → docs_anonymizer-0.2.4}/src/anonymizer/core/detection/regex_detectors/contract_number_detector.py +0 -0
  40. {docs_anonymizer-0.2.2 → docs_anonymizer-0.2.4}/src/anonymizer/core/detection/regex_detectors/date_detector.py +0 -0
  41. {docs_anonymizer-0.2.2 → docs_anonymizer-0.2.4}/src/anonymizer/core/detection/regex_detectors/ein_detector.py +0 -0
  42. {docs_anonymizer-0.2.2 → docs_anonymizer-0.2.4}/src/anonymizer/core/detection/regex_detectors/iban_detector.py +0 -0
  43. {docs_anonymizer-0.2.2 → docs_anonymizer-0.2.4}/src/anonymizer/core/detection/regex_detectors/inn_detector.py +0 -0
  44. {docs_anonymizer-0.2.2 → docs_anonymizer-0.2.4}/src/anonymizer/core/detection/regex_detectors/kpp_detector.py +0 -0
  45. {docs_anonymizer-0.2.2 → docs_anonymizer-0.2.4}/src/anonymizer/core/detection/regex_detectors/ogrn_detector.py +0 -0
  46. {docs_anonymizer-0.2.2 → docs_anonymizer-0.2.4}/src/anonymizer/core/detection/regex_detectors/passport_ru_detector.py +0 -0
  47. {docs_anonymizer-0.2.2 → docs_anonymizer-0.2.4}/src/anonymizer/core/detection/regex_detectors/snils_detector.py +0 -0
  48. {docs_anonymizer-0.2.2 → docs_anonymizer-0.2.4}/src/anonymizer/core/errors.py +0 -0
  49. {docs_anonymizer-0.2.2 → docs_anonymizer-0.2.4}/src/anonymizer/core/language/__init__.py +0 -0
  50. {docs_anonymizer-0.2.2 → docs_anonymizer-0.2.4}/src/anonymizer/core/language/base.py +0 -0
  51. {docs_anonymizer-0.2.2 → docs_anonymizer-0.2.4}/src/anonymizer/core/language/detection.py +0 -0
  52. {docs_anonymizer-0.2.2 → docs_anonymizer-0.2.4}/src/anonymizer/core/language/name_parsers/__init__.py +0 -0
  53. {docs_anonymizer-0.2.2 → docs_anonymizer-0.2.4}/src/anonymizer/core/language/name_parsers/english.py +0 -0
  54. {docs_anonymizer-0.2.2 → docs_anonymizer-0.2.4}/src/anonymizer/core/language/name_parsers/russian.py +0 -0
  55. {docs_anonymizer-0.2.2 → docs_anonymizer-0.2.4}/src/anonymizer/core/language/packs/__init__.py +0 -0
  56. {docs_anonymizer-0.2.2 → docs_anonymizer-0.2.4}/src/anonymizer/core/language/packs/english/__init__.py +0 -0
  57. {docs_anonymizer-0.2.2 → docs_anonymizer-0.2.4}/src/anonymizer/core/language/packs/english/cities.json +0 -0
  58. {docs_anonymizer-0.2.2 → docs_anonymizer-0.2.4}/src/anonymizer/core/language/packs/english/legal_forms.json +0 -0
  59. {docs_anonymizer-0.2.2 → docs_anonymizer-0.2.4}/src/anonymizer/core/language/packs/english/pack.py +0 -0
  60. {docs_anonymizer-0.2.2 → docs_anonymizer-0.2.4}/src/anonymizer/core/language/packs/english/regions.json +0 -0
  61. {docs_anonymizer-0.2.2 → docs_anonymizer-0.2.4}/src/anonymizer/core/language/packs/registry.py +0 -0
  62. {docs_anonymizer-0.2.2 → docs_anonymizer-0.2.4}/src/anonymizer/core/language/packs/russian/__init__.py +0 -0
  63. {docs_anonymizer-0.2.2 → docs_anonymizer-0.2.4}/src/anonymizer/core/language/packs/russian/cities.json +0 -0
  64. {docs_anonymizer-0.2.2 → docs_anonymizer-0.2.4}/src/anonymizer/core/language/packs/russian/legal_forms.json +0 -0
  65. {docs_anonymizer-0.2.2 → docs_anonymizer-0.2.4}/src/anonymizer/core/language/packs/russian/pack.py +0 -0
  66. {docs_anonymizer-0.2.2 → docs_anonymizer-0.2.4}/src/anonymizer/core/language/packs/russian/regions.json +0 -0
  67. {docs_anonymizer-0.2.2 → docs_anonymizer-0.2.4}/src/anonymizer/core/language/transliteration/__init__.py +0 -0
  68. {docs_anonymizer-0.2.2 → docs_anonymizer-0.2.4}/src/anonymizer/core/language/transliteration/base.py +0 -0
  69. {docs_anonymizer-0.2.2 → docs_anonymizer-0.2.4}/src/anonymizer/core/language/transliteration/ru_en.py +0 -0
  70. {docs_anonymizer-0.2.2 → docs_anonymizer-0.2.4}/src/anonymizer/core/manual_mask/__init__.py +0 -0
  71. {docs_anonymizer-0.2.2 → docs_anonymizer-0.2.4}/src/anonymizer/core/manual_mask/apply.py +0 -0
  72. {docs_anonymizer-0.2.2 → docs_anonymizer-0.2.4}/src/anonymizer/core/manual_mask/overrides.py +0 -0
  73. {docs_anonymizer-0.2.2 → docs_anonymizer-0.2.4}/src/anonymizer/core/metadata/__init__.py +0 -0
  74. {docs_anonymizer-0.2.2 → docs_anonymizer-0.2.4}/src/anonymizer/core/metadata/_ooxml.py +0 -0
  75. {docs_anonymizer-0.2.2 → docs_anonymizer-0.2.4}/src/anonymizer/core/metadata/base.py +0 -0
  76. {docs_anonymizer-0.2.2 → docs_anonymizer-0.2.4}/src/anonymizer/core/metadata/docx_cleaner.py +0 -0
  77. {docs_anonymizer-0.2.2 → docs_anonymizer-0.2.4}/src/anonymizer/core/metadata/pdf_cleaner.py +0 -0
  78. {docs_anonymizer-0.2.2 → docs_anonymizer-0.2.4}/src/anonymizer/core/metadata/xlsx_cleaner.py +0 -0
  79. {docs_anonymizer-0.2.2 → docs_anonymizer-0.2.4}/src/anonymizer/core/models.py +0 -0
  80. {docs_anonymizer-0.2.2 → docs_anonymizer-0.2.4}/src/anonymizer/core/parsers/__init__.py +0 -0
  81. {docs_anonymizer-0.2.2 → docs_anonymizer-0.2.4}/src/anonymizer/core/parsers/_docx_xml.py +0 -0
  82. {docs_anonymizer-0.2.2 → docs_anonymizer-0.2.4}/src/anonymizer/core/parsers/docx_parser.py +0 -0
  83. {docs_anonymizer-0.2.2 → docs_anonymizer-0.2.4}/src/anonymizer/core/parsers/format_detection.py +0 -0
  84. {docs_anonymizer-0.2.2 → docs_anonymizer-0.2.4}/src/anonymizer/core/parsers/pdf_parser.py +0 -0
  85. {docs_anonymizer-0.2.2 → docs_anonymizer-0.2.4}/src/anonymizer/core/parsers/xlsx_parser.py +0 -0
  86. {docs_anonymizer-0.2.2 → docs_anonymizer-0.2.4}/src/anonymizer/core/pipeline.py +0 -0
  87. {docs_anonymizer-0.2.2 → docs_anonymizer-0.2.4}/src/anonymizer/core/tokens/__init__.py +0 -0
  88. {docs_anonymizer-0.2.2 → docs_anonymizer-0.2.4}/src/anonymizer/core/tokens/canonical.py +0 -0
  89. {docs_anonymizer-0.2.2 → docs_anonymizer-0.2.4}/src/anonymizer/core/tokens/manager.py +0 -0
  90. {docs_anonymizer-0.2.2 → docs_anonymizer-0.2.4}/src/anonymizer/core/writers/__init__.py +0 -0
  91. {docs_anonymizer-0.2.2 → docs_anonymizer-0.2.4}/src/anonymizer/core/writers/_facade.py +0 -0
  92. {docs_anonymizer-0.2.2 → docs_anonymizer-0.2.4}/src/anonymizer/core/writers/docx_writer.py +0 -0
  93. {docs_anonymizer-0.2.2 → docs_anonymizer-0.2.4}/src/anonymizer/core/writers/pdf_writer.py +0 -0
  94. {docs_anonymizer-0.2.2 → docs_anonymizer-0.2.4}/src/anonymizer/core/writers/xlsx_writer.py +0 -0
  95. {docs_anonymizer-0.2.2 → docs_anonymizer-0.2.4}/src/anonymizer/testkit/__init__.py +0 -0
  96. {docs_anonymizer-0.2.2 → docs_anonymizer-0.2.4}/src/anonymizer/testkit/diagnostics.py +0 -0
  97. {docs_anonymizer-0.2.2 → docs_anonymizer-0.2.4}/src/anonymizer/testkit/feedback_loop/__init__.py +0 -0
  98. {docs_anonymizer-0.2.2 → docs_anonymizer-0.2.4}/src/anonymizer/testkit/feedback_loop/feedback_schema.py +0 -0
  99. {docs_anonymizer-0.2.2 → docs_anonymizer-0.2.4}/src/anonymizer/testkit/generators/__init__.py +0 -0
  100. {docs_anonymizer-0.2.2 → docs_anonymizer-0.2.4}/src/anonymizer/testkit/generators/base.py +0 -0
  101. {docs_anonymizer-0.2.2 → docs_anonymizer-0.2.4}/src/anonymizer/testkit/generators/docx_gen.py +0 -0
  102. {docs_anonymizer-0.2.2 → docs_anonymizer-0.2.4}/src/anonymizer/testkit/generators/pdf_gen.py +0 -0
  103. {docs_anonymizer-0.2.2 → docs_anonymizer-0.2.4}/src/anonymizer/testkit/generators/xlsx_gen.py +0 -0
  104. {docs_anonymizer-0.2.2 → docs_anonymizer-0.2.4}/src/anonymizer/testkit/log_analyzer.py +0 -0
  105. {docs_anonymizer-0.2.2 → docs_anonymizer-0.2.4}/src/anonymizer/testkit/log_analyzer_report.py +0 -0
  106. {docs_anonymizer-0.2.2 → docs_anonymizer-0.2.4}/src/anonymizer/testkit/manifest_v2.py +0 -0
  107. {docs_anonymizer-0.2.2 → docs_anonymizer-0.2.4}/src/anonymizer/testkit/manifest_validator.py +0 -0
  108. {docs_anonymizer-0.2.2 → docs_anonymizer-0.2.4}/src/anonymizer/testkit/metrics.py +0 -0
  109. {docs_anonymizer-0.2.2 → docs_anonymizer-0.2.4}/src/anonymizer/testkit/personas/__init__.py +0 -0
  110. {docs_anonymizer-0.2.2 → docs_anonymizer-0.2.4}/src/anonymizer/testkit/personas/base.py +0 -0
  111. {docs_anonymizer-0.2.2 → docs_anonymizer-0.2.4}/src/anonymizer/testkit/personas/english/__init__.py +0 -0
  112. {docs_anonymizer-0.2.2 → docs_anonymizer-0.2.4}/src/anonymizer/testkit/personas/english/alice_morris.py +0 -0
  113. {docs_anonymizer-0.2.2 → docs_anonymizer-0.2.4}/src/anonymizer/testkit/personas/english/benjamin_clark.py +0 -0
  114. {docs_anonymizer-0.2.2 → docs_anonymizer-0.2.4}/src/anonymizer/testkit/personas/english/charlotte_evans.py +0 -0
  115. {docs_anonymizer-0.2.2 → docs_anonymizer-0.2.4}/src/anonymizer/testkit/personas/english/daniel_foster.py +0 -0
  116. {docs_anonymizer-0.2.2 → docs_anonymizer-0.2.4}/src/anonymizer/testkit/personas/english/emily_griffiths.py +0 -0
  117. {docs_anonymizer-0.2.2 → docs_anonymizer-0.2.4}/src/anonymizer/testkit/personas/english/frank_harris.py +0 -0
  118. {docs_anonymizer-0.2.2 → docs_anonymizer-0.2.4}/src/anonymizer/testkit/personas/english/grace_irving.py +0 -0
  119. {docs_anonymizer-0.2.2 → docs_anonymizer-0.2.4}/src/anonymizer/testkit/personas/english/henry_johnson.py +0 -0
  120. {docs_anonymizer-0.2.2 → docs_anonymizer-0.2.4}/src/anonymizer/testkit/personas/english/isabella_king.py +0 -0
  121. {docs_anonymizer-0.2.2 → docs_anonymizer-0.2.4}/src/anonymizer/testkit/personas/english/jane_doe.py +0 -0
  122. {docs_anonymizer-0.2.2 → docs_anonymizer-0.2.4}/src/anonymizer/testkit/personas/russian/__init__.py +0 -0
  123. {docs_anonymizer-0.2.2 → docs_anonymizer-0.2.4}/src/anonymizer/testkit/personas/russian/fedorova_aa.py +0 -0
  124. {docs_anonymizer-0.2.2 → docs_anonymizer-0.2.4}/src/anonymizer/testkit/personas/russian/ivanov_ii.py +0 -0
  125. {docs_anonymizer-0.2.2 → docs_anonymizer-0.2.4}/src/anonymizer/testkit/personas/russian/kovaleva_lm.py +0 -0
  126. {docs_anonymizer-0.2.2 → docs_anonymizer-0.2.4}/src/anonymizer/testkit/personas/russian/kuznetsov_ev.py +0 -0
  127. {docs_anonymizer-0.2.2 → docs_anonymizer-0.2.4}/src/anonymizer/testkit/personas/russian/morozov_dn.py +0 -0
  128. {docs_anonymizer-0.2.2 → docs_anonymizer-0.2.4}/src/anonymizer/testkit/personas/russian/petrov_pp.py +0 -0
  129. {docs_anonymizer-0.2.2 → docs_anonymizer-0.2.4}/src/anonymizer/testkit/personas/russian/sidorova_es.py +0 -0
  130. {docs_anonymizer-0.2.2 → docs_anonymizer-0.2.4}/src/anonymizer/testkit/personas/russian/smirnov_aa.py +0 -0
  131. {docs_anonymizer-0.2.2 → docs_anonymizer-0.2.4}/src/anonymizer/testkit/personas/russian/sokolova_ts.py +0 -0
  132. {docs_anonymizer-0.2.2 → docs_anonymizer-0.2.4}/src/anonymizer/testkit/personas/russian/volkov_mo.py +0 -0
  133. {docs_anonymizer-0.2.2 → docs_anonymizer-0.2.4}/src/anonymizer/testkit/report.py +0 -0
  134. {docs_anonymizer-0.2.2 → docs_anonymizer-0.2.4}/src/anonymizer/testkit/runner.py +0 -0
  135. {docs_anonymizer-0.2.2 → docs_anonymizer-0.2.4}/src/anonymizer/testkit/tier_defaults.py +0 -0
  136. {docs_anonymizer-0.2.2 → docs_anonymizer-0.2.4}/src/anonymizer/updater.py +0 -0
  137. {docs_anonymizer-0.2.2 → docs_anonymizer-0.2.4}/src/anonymizer/webapp/__init__.py +0 -0
  138. {docs_anonymizer-0.2.2 → docs_anonymizer-0.2.4}/src/anonymizer/webapp/app.py +0 -0
  139. {docs_anonymizer-0.2.2 → docs_anonymizer-0.2.4}/src/anonymizer/webapp/context.py +0 -0
  140. {docs_anonymizer-0.2.2 → docs_anonymizer-0.2.4}/src/anonymizer/webapp/i18n/en.po +0 -0
  141. {docs_anonymizer-0.2.2 → docs_anonymizer-0.2.4}/src/anonymizer/webapp/i18n/ru.po +0 -0
  142. {docs_anonymizer-0.2.2 → docs_anonymizer-0.2.4}/src/anonymizer/webapp/i18n.py +0 -0
  143. {docs_anonymizer-0.2.2 → docs_anonymizer-0.2.4}/src/anonymizer/webapp/middleware/__init__.py +0 -0
  144. {docs_anonymizer-0.2.2 → docs_anonymizer-0.2.4}/src/anonymizer/webapp/middleware/cors.py +0 -0
  145. {docs_anonymizer-0.2.2 → docs_anonymizer-0.2.4}/src/anonymizer/webapp/middleware/csrf.py +0 -0
  146. {docs_anonymizer-0.2.2 → docs_anonymizer-0.2.4}/src/anonymizer/webapp/middleware/session_token.py +0 -0
  147. {docs_anonymizer-0.2.2 → docs_anonymizer-0.2.4}/src/anonymizer/webapp/network_status.py +0 -0
  148. {docs_anonymizer-0.2.2 → docs_anonymizer-0.2.4}/src/anonymizer/webapp/routes/__init__.py +0 -0
  149. {docs_anonymizer-0.2.2 → docs_anonymizer-0.2.4}/src/anonymizer/webapp/routes/detector.py +0 -0
  150. {docs_anonymizer-0.2.2 → docs_anonymizer-0.2.4}/src/anonymizer/webapp/routes/download.py +0 -0
  151. {docs_anonymizer-0.2.2 → docs_anonymizer-0.2.4}/src/anonymizer/webapp/routes/feedback.py +0 -0
  152. {docs_anonymizer-0.2.2 → docs_anonymizer-0.2.4}/src/anonymizer/webapp/routes/language.py +0 -0
  153. {docs_anonymizer-0.2.2 → docs_anonymizer-0.2.4}/src/anonymizer/webapp/routes/manual_overrides.py +0 -0
  154. {docs_anonymizer-0.2.2 → docs_anonymizer-0.2.4}/src/anonymizer/webapp/routes/preview.py +0 -0
  155. {docs_anonymizer-0.2.2 → docs_anonymizer-0.2.4}/src/anonymizer/webapp/routes/process.py +0 -0
  156. {docs_anonymizer-0.2.2 → docs_anonymizer-0.2.4}/src/anonymizer/webapp/routes/processing_helpers.py +0 -0
  157. {docs_anonymizer-0.2.2 → docs_anonymizer-0.2.4}/src/anonymizer/webapp/routes/session.py +0 -0
  158. {docs_anonymizer-0.2.2 → docs_anonymizer-0.2.4}/src/anonymizer/webapp/routes/update.py +0 -0
  159. {docs_anonymizer-0.2.2 → docs_anonymizer-0.2.4}/src/anonymizer/webapp/routes/upload.py +0 -0
  160. {docs_anonymizer-0.2.2 → docs_anonymizer-0.2.4}/src/anonymizer/webapp/session_manager.py +0 -0
  161. {docs_anonymizer-0.2.2 → docs_anonymizer-0.2.4}/src/anonymizer/webapp/stages.py +0 -0
  162. {docs_anonymizer-0.2.2 → docs_anonymizer-0.2.4}/src/anonymizer/webapp/static/app.css +0 -0
  163. {docs_anonymizer-0.2.2 → docs_anonymizer-0.2.4}/src/anonymizer/webapp/static/components.css +0 -0
  164. {docs_anonymizer-0.2.2 → docs_anonymizer-0.2.4}/src/anonymizer/webapp/static/highlight-pair.js +0 -0
  165. {docs_anonymizer-0.2.2 → docs_anonymizer-0.2.4}/src/anonymizer/webapp/static/htmx-sse.js +0 -0
  166. {docs_anonymizer-0.2.2 → docs_anonymizer-0.2.4}/src/anonymizer/webapp/static/htmx.min.js +0 -0
  167. {docs_anonymizer-0.2.2 → docs_anonymizer-0.2.4}/src/anonymizer/webapp/static/i18n-switch.js +0 -0
  168. {docs_anonymizer-0.2.2 → docs_anonymizer-0.2.4}/src/anonymizer/webapp/static/layout.css +0 -0
  169. {docs_anonymizer-0.2.2 → docs_anonymizer-0.2.4}/src/anonymizer/webapp/static/manual-mask.js +0 -0
  170. {docs_anonymizer-0.2.2 → docs_anonymizer-0.2.4}/src/anonymizer/webapp/static/preview-busy.js +0 -0
  171. {docs_anonymizer-0.2.2 → docs_anonymizer-0.2.4}/src/anonymizer/webapp/static/sync-scroll.js +0 -0
  172. {docs_anonymizer-0.2.2 → docs_anonymizer-0.2.4}/src/anonymizer/webapp/static/tokens.css +0 -0
  173. {docs_anonymizer-0.2.2 → docs_anonymizer-0.2.4}/src/anonymizer/webapp/static/tooltip.js +0 -0
  174. {docs_anonymizer-0.2.2 → docs_anonymizer-0.2.4}/src/anonymizer/webapp/templates/_drop_zone.html +0 -0
  175. {docs_anonymizer-0.2.2 → docs_anonymizer-0.2.4}/src/anonymizer/webapp/templates/_empty.html +0 -0
  176. {docs_anonymizer-0.2.2 → docs_anonymizer-0.2.4}/src/anonymizer/webapp/templates/_error_block.html +0 -0
  177. {docs_anonymizer-0.2.2 → docs_anonymizer-0.2.4}/src/anonymizer/webapp/templates/_modal_feedback.html +0 -0
  178. {docs_anonymizer-0.2.2 → docs_anonymizer-0.2.4}/src/anonymizer/webapp/templates/_modal_settings.html +0 -0
  179. {docs_anonymizer-0.2.2 → docs_anonymizer-0.2.4}/src/anonymizer/webapp/templates/_network_status.html +0 -0
  180. {docs_anonymizer-0.2.2 → docs_anonymizer-0.2.4}/src/anonymizer/webapp/templates/_preview_content.html +0 -0
  181. {docs_anonymizer-0.2.2 → docs_anonymizer-0.2.4}/src/anonymizer/webapp/templates/_preview_pane_anon.html +0 -0
  182. {docs_anonymizer-0.2.2 → docs_anonymizer-0.2.4}/src/anonymizer/webapp/templates/_preview_pane_source.html +0 -0
  183. {docs_anonymizer-0.2.2 → docs_anonymizer-0.2.4}/src/anonymizer/webapp/templates/_processing.html +0 -0
  184. {docs_anonymizer-0.2.2 → docs_anonymizer-0.2.4}/src/anonymizer/webapp/templates/_sel_popup.html +0 -0
  185. {docs_anonymizer-0.2.2 → docs_anonymizer-0.2.4}/src/anonymizer/webapp/templates/_stages.html +0 -0
  186. {docs_anonymizer-0.2.2 → docs_anonymizer-0.2.4}/src/anonymizer/webapp/templates/_status_row.html +0 -0
  187. {docs_anonymizer-0.2.2 → docs_anonymizer-0.2.4}/src/anonymizer/webapp/templates/_tooltip_sources.html +0 -0
  188. {docs_anonymizer-0.2.2 → docs_anonymizer-0.2.4}/src/anonymizer/webapp/templates/_topbar.html +0 -0
  189. {docs_anonymizer-0.2.2 → docs_anonymizer-0.2.4}/src/anonymizer/webapp/templates/_update_banner.html +0 -0
  190. {docs_anonymizer-0.2.2 → docs_anonymizer-0.2.4}/src/anonymizer/webapp/templates/_warning_banner.html +0 -0
  191. {docs_anonymizer-0.2.2 → docs_anonymizer-0.2.4}/src/anonymizer/webapp/templates/base.html +0 -0
  192. {docs_anonymizer-0.2.2 → docs_anonymizer-0.2.4}/src/anonymizer/webapp/templates/preview.html +0 -0
  193. {docs_anonymizer-0.2.2 → docs_anonymizer-0.2.4}/src/anonymizer/webapp/templates/processing.html +0 -0
  194. {docs_anonymizer-0.2.2 → docs_anonymizer-0.2.4}/src/anonymizer/webapp/templates/upload.html +0 -0
  195. {docs_anonymizer-0.2.2 → docs_anonymizer-0.2.4}/src/anonymizer/webapp/version.py +0 -0
  196. {docs_anonymizer-0.2.2 → docs_anonymizer-0.2.4}/tests/__init__.py +0 -0
  197. {docs_anonymizer-0.2.2 → docs_anonymizer-0.2.4}/tests/conftest.py +0 -0
  198. {docs_anonymizer-0.2.2 → docs_anonymizer-0.2.4}/tests/fuzz/__init__.py +0 -0
  199. {docs_anonymizer-0.2.2 → docs_anonymizer-0.2.4}/tests/fuzz/test_random_corpus.py +0 -0
  200. {docs_anonymizer-0.2.2 → docs_anonymizer-0.2.4}/tests/integration/__init__.py +0 -0
  201. {docs_anonymizer-0.2.2 → docs_anonymizer-0.2.4}/tests/integration/fixtures/golden_partial/es/01_contrato_es.docx +0 -0
  202. {docs_anonymizer-0.2.2 → docs_anonymizer-0.2.4}/tests/integration/fixtures/golden_partial/it/01_contratto_it.docx +0 -0
  203. {docs_anonymizer-0.2.2 → docs_anonymizer-0.2.4}/tests/integration/fixtures/golden_partial/manifests/01_contrato_es.yml +0 -0
  204. {docs_anonymizer-0.2.2 → docs_anonymizer-0.2.4}/tests/integration/fixtures/golden_partial/manifests/01_contratto_it.yml +0 -0
  205. {docs_anonymizer-0.2.2 → docs_anonymizer-0.2.4}/tests/integration/known_failures/README.md +0 -0
  206. {docs_anonymizer-0.2.2 → docs_anonymizer-0.2.4}/tests/integration/known_failures/_template/input.docx +0 -0
  207. {docs_anonymizer-0.2.2 → docs_anonymizer-0.2.4}/tests/integration/known_failures/_template/manifest.yml +0 -0
  208. {docs_anonymizer-0.2.2 → docs_anonymizer-0.2.4}/tests/integration/known_failures/kf-0001-passport-ru-with-no-sign/input.docx +0 -0
  209. {docs_anonymizer-0.2.2 → docs_anonymizer-0.2.4}/tests/integration/known_failures/kf-0001-passport-ru-with-no-sign/manifest.yml +0 -0
  210. {docs_anonymizer-0.2.2 → docs_anonymizer-0.2.4}/tests/integration/known_failures/kf-0002-address-uk-format-not-recognized/input.docx +0 -0
  211. {docs_anonymizer-0.2.2 → docs_anonymizer-0.2.4}/tests/integration/known_failures/kf-0002-address-uk-format-not-recognized/manifest.yml +0 -0
  212. {docs_anonymizer-0.2.2 → docs_anonymizer-0.2.4}/tests/integration/test_annotate_roundtrip.py +0 -0
  213. {docs_anonymizer-0.2.2 → docs_anonymizer-0.2.4}/tests/integration/test_audit_no_pii.py +0 -0
  214. {docs_anonymizer-0.2.2 → docs_anonymizer-0.2.4}/tests/integration/test_corpus_manifests_v2.py +0 -0
  215. {docs_anonymizer-0.2.2 → docs_anonymizer-0.2.4}/tests/integration/test_docx_digital_marketing_regression.py +0 -0
  216. {docs_anonymizer-0.2.2 → docs_anonymizer-0.2.4}/tests/integration/test_docx_end_to_end.py +0 -0
  217. {docs_anonymizer-0.2.2 → docs_anonymizer-0.2.4}/tests/integration/test_docx_with_full_pipeline.py +0 -0
  218. {docs_anonymizer-0.2.2 → docs_anonymizer-0.2.4}/tests/integration/test_feedback_cycle.py +0 -0
  219. {docs_anonymizer-0.2.2 → docs_anonymizer-0.2.4}/tests/integration/test_format_edge_cases.py +0 -0
  220. {docs_anonymizer-0.2.2 → docs_anonymizer-0.2.4}/tests/integration/test_golden_generated.py +0 -0
  221. {docs_anonymizer-0.2.2 → docs_anonymizer-0.2.4}/tests/integration/test_golden_partial.py +0 -0
  222. {docs_anonymizer-0.2.2 → docs_anonymizer-0.2.4}/tests/integration/test_known_failures.py +0 -0
  223. {docs_anonymizer-0.2.2 → docs_anonymizer-0.2.4}/tests/integration/test_no_network.py +0 -0
  224. {docs_anonymizer-0.2.2 → docs_anonymizer-0.2.4}/tests/integration/test_pdf_end_to_end.py +0 -0
  225. {docs_anonymizer-0.2.2 → docs_anonymizer-0.2.4}/tests/integration/test_pdf_service_agreement_regression.py +0 -0
  226. {docs_anonymizer-0.2.2 → docs_anonymizer-0.2.4}/tests/integration/test_schema_in_sync.py +0 -0
  227. {docs_anonymizer-0.2.2 → docs_anonymizer-0.2.4}/tests/integration/test_webapp_e2e.py +0 -0
  228. {docs_anonymizer-0.2.2 → docs_anonymizer-0.2.4}/tests/integration/test_xlsx_end_to_end.py +0 -0
  229. {docs_anonymizer-0.2.2 → docs_anonymizer-0.2.4}/tests/unit/__init__.py +0 -0
  230. {docs_anonymizer-0.2.2 → docs_anonymizer-0.2.4}/tests/unit/test_audit_crash.py +0 -0
  231. {docs_anonymizer-0.2.2 → docs_anonymizer-0.2.4}/tests/unit/test_audit_feedback.py +0 -0
  232. {docs_anonymizer-0.2.2 → docs_anonymizer-0.2.4}/tests/unit/test_bic_detector.py +0 -0
  233. {docs_anonymizer-0.2.2 → docs_anonymizer-0.2.4}/tests/unit/test_bic_ru_detector.py +0 -0
  234. {docs_anonymizer-0.2.2 → docs_anonymizer-0.2.4}/tests/unit/test_canonical_key.py +0 -0
  235. {docs_anonymizer-0.2.2 → docs_anonymizer-0.2.4}/tests/unit/test_canonical_key_extended.py +0 -0
  236. {docs_anonymizer-0.2.2 → docs_anonymizer-0.2.4}/tests/unit/test_card_detector.py +0 -0
  237. {docs_anonymizer-0.2.2 → docs_anonymizer-0.2.4}/tests/unit/test_cli.py +0 -0
  238. {docs_anonymizer-0.2.2 → docs_anonymizer-0.2.4}/tests/unit/test_cli_annotate_compile.py +0 -0
  239. {docs_anonymizer-0.2.2 → docs_anonymizer-0.2.4}/tests/unit/test_cli_annotate_prepare.py +0 -0
  240. {docs_anonymizer-0.2.2 → docs_anonymizer-0.2.4}/tests/unit/test_cli_annotate_render.py +0 -0
  241. {docs_anonymizer-0.2.2 → docs_anonymizer-0.2.4}/tests/unit/test_cli_no_update_check.py +0 -0
  242. {docs_anonymizer-0.2.2 → docs_anonymizer-0.2.4}/tests/unit/test_conflict_resolution.py +0 -0
  243. {docs_anonymizer-0.2.2 → docs_anonymizer-0.2.4}/tests/unit/test_contract_number_detector.py +0 -0
  244. {docs_anonymizer-0.2.2 → docs_anonymizer-0.2.4}/tests/unit/test_coverage_warnings_docx.py +0 -0
  245. {docs_anonymizer-0.2.2 → docs_anonymizer-0.2.4}/tests/unit/test_coverage_warnings_pdf.py +0 -0
  246. {docs_anonymizer-0.2.2 → docs_anonymizer-0.2.4}/tests/unit/test_coverage_warnings_xlsx.py +0 -0
  247. {docs_anonymizer-0.2.2 → docs_anonymizer-0.2.4}/tests/unit/test_date_detector.py +0 -0
  248. {docs_anonymizer-0.2.2 → docs_anonymizer-0.2.4}/tests/unit/test_detection_base.py +0 -0
  249. {docs_anonymizer-0.2.2 → docs_anonymizer-0.2.4}/tests/unit/test_diagnostics.py +0 -0
  250. {docs_anonymizer-0.2.2 → docs_anonymizer-0.2.4}/tests/unit/test_docx_generator.py +0 -0
  251. {docs_anonymizer-0.2.2 → docs_anonymizer-0.2.4}/tests/unit/test_docx_parser.py +0 -0
  252. {docs_anonymizer-0.2.2 → docs_anonymizer-0.2.4}/tests/unit/test_docx_writer.py +0 -0
  253. {docs_anonymizer-0.2.2 → docs_anonymizer-0.2.4}/tests/unit/test_docx_xml_helpers.py +0 -0
  254. {docs_anonymizer-0.2.2 → docs_anonymizer-0.2.4}/tests/unit/test_ein_detector.py +0 -0
  255. {docs_anonymizer-0.2.2 → docs_anonymizer-0.2.4}/tests/unit/test_email_detector.py +0 -0
  256. {docs_anonymizer-0.2.2 → docs_anonymizer-0.2.4}/tests/unit/test_english_pack.py +0 -0
  257. {docs_anonymizer-0.2.2 → docs_anonymizer-0.2.4}/tests/unit/test_errors.py +0 -0
  258. {docs_anonymizer-0.2.2 → docs_anonymizer-0.2.4}/tests/unit/test_feedback_schema.py +0 -0
  259. {docs_anonymizer-0.2.2 → docs_anonymizer-0.2.4}/tests/unit/test_feedback_schema_contract.py +0 -0
  260. {docs_anonymizer-0.2.2 → docs_anonymizer-0.2.4}/tests/unit/test_format_detection.py +0 -0
  261. {docs_anonymizer-0.2.2 → docs_anonymizer-0.2.4}/tests/unit/test_generator_base.py +0 -0
  262. {docs_anonymizer-0.2.2 → docs_anonymizer-0.2.4}/tests/unit/test_iban_detector.py +0 -0
  263. {docs_anonymizer-0.2.2 → docs_anonymizer-0.2.4}/tests/unit/test_inn_detector.py +0 -0
  264. {docs_anonymizer-0.2.2 → docs_anonymizer-0.2.4}/tests/unit/test_installer_scripts.py +0 -0
  265. {docs_anonymizer-0.2.2 → docs_anonymizer-0.2.4}/tests/unit/test_kpp_detector.py +0 -0
  266. {docs_anonymizer-0.2.2 → docs_anonymizer-0.2.4}/tests/unit/test_language_base.py +0 -0
  267. {docs_anonymizer-0.2.2 → docs_anonymizer-0.2.4}/tests/unit/test_language_detection.py +0 -0
  268. {docs_anonymizer-0.2.2 → docs_anonymizer-0.2.4}/tests/unit/test_language_registry.py +0 -0
  269. {docs_anonymizer-0.2.2 → docs_anonymizer-0.2.4}/tests/unit/test_license.py +0 -0
  270. {docs_anonymizer-0.2.2 → docs_anonymizer-0.2.4}/tests/unit/test_log_analyzer.py +0 -0
  271. {docs_anonymizer-0.2.2 → docs_anonymizer-0.2.4}/tests/unit/test_log_analyzer_report.py +0 -0
  272. {docs_anonymizer-0.2.2 → docs_anonymizer-0.2.4}/tests/unit/test_manifest_v2_migrate.py +0 -0
  273. {docs_anonymizer-0.2.2 → docs_anonymizer-0.2.4}/tests/unit/test_manifest_v2_model.py +0 -0
  274. {docs_anonymizer-0.2.2 → docs_anonymizer-0.2.4}/tests/unit/test_manifest_validator.py +0 -0
  275. {docs_anonymizer-0.2.2 → docs_anonymizer-0.2.4}/tests/unit/test_manual_apply.py +0 -0
  276. {docs_anonymizer-0.2.2 → docs_anonymizer-0.2.4}/tests/unit/test_manual_override.py +0 -0
  277. {docs_anonymizer-0.2.2 → docs_anonymizer-0.2.4}/tests/unit/test_metadata_base.py +0 -0
  278. {docs_anonymizer-0.2.2 → docs_anonymizer-0.2.4}/tests/unit/test_metadata_docx.py +0 -0
  279. {docs_anonymizer-0.2.2 → docs_anonymizer-0.2.4}/tests/unit/test_metadata_pdf.py +0 -0
  280. {docs_anonymizer-0.2.2 → docs_anonymizer-0.2.4}/tests/unit/test_metadata_xlsx.py +0 -0
  281. {docs_anonymizer-0.2.2 → docs_anonymizer-0.2.4}/tests/unit/test_metrics.py +0 -0
  282. {docs_anonymizer-0.2.2 → docs_anonymizer-0.2.4}/tests/unit/test_metrics_corpus.py +0 -0
  283. {docs_anonymizer-0.2.2 → docs_anonymizer-0.2.4}/tests/unit/test_models.py +0 -0
  284. {docs_anonymizer-0.2.2 → docs_anonymizer-0.2.4}/tests/unit/test_name_parser_english.py +0 -0
  285. {docs_anonymizer-0.2.2 → docs_anonymizer-0.2.4}/tests/unit/test_name_parser_russian.py +0 -0
  286. {docs_anonymizer-0.2.2 → docs_anonymizer-0.2.4}/tests/unit/test_ner_address.py +0 -0
  287. {docs_anonymizer-0.2.2 → docs_anonymizer-0.2.4}/tests/unit/test_ner_base.py +0 -0
  288. {docs_anonymizer-0.2.2 → docs_anonymizer-0.2.4}/tests/unit/test_ner_company_en.py +0 -0
  289. {docs_anonymizer-0.2.2 → docs_anonymizer-0.2.4}/tests/unit/test_ner_company_ru.py +0 -0
  290. {docs_anonymizer-0.2.2 → docs_anonymizer-0.2.4}/tests/unit/test_ner_language_guard.py +0 -0
  291. {docs_anonymizer-0.2.2 → docs_anonymizer-0.2.4}/tests/unit/test_ner_person_en.py +0 -0
  292. {docs_anonymizer-0.2.2 → docs_anonymizer-0.2.4}/tests/unit/test_ner_person_ru.py +0 -0
  293. {docs_anonymizer-0.2.2 → docs_anonymizer-0.2.4}/tests/unit/test_network_status.py +0 -0
  294. {docs_anonymizer-0.2.2 → docs_anonymizer-0.2.4}/tests/unit/test_ogrn_detector.py +0 -0
  295. {docs_anonymizer-0.2.2 → docs_anonymizer-0.2.4}/tests/unit/test_package_imports.py +0 -0
  296. {docs_anonymizer-0.2.2 → docs_anonymizer-0.2.4}/tests/unit/test_passport_ru_detector.py +0 -0
  297. {docs_anonymizer-0.2.2 → docs_anonymizer-0.2.4}/tests/unit/test_pdf_generator.py +0 -0
  298. {docs_anonymizer-0.2.2 → docs_anonymizer-0.2.4}/tests/unit/test_pdf_parser.py +0 -0
  299. {docs_anonymizer-0.2.2 → docs_anonymizer-0.2.4}/tests/unit/test_pdf_writer.py +0 -0
  300. {docs_anonymizer-0.2.2 → docs_anonymizer-0.2.4}/tests/unit/test_personas.py +0 -0
  301. {docs_anonymizer-0.2.2 → docs_anonymizer-0.2.4}/tests/unit/test_phone_detector.py +0 -0
  302. {docs_anonymizer-0.2.2 → docs_anonymizer-0.2.4}/tests/unit/test_pipeline.py +0 -0
  303. {docs_anonymizer-0.2.2 → docs_anonymizer-0.2.4}/tests/unit/test_project_metadata.py +0 -0
  304. {docs_anonymizer-0.2.2 → docs_anonymizer-0.2.4}/tests/unit/test_report.py +0 -0
  305. {docs_anonymizer-0.2.2 → docs_anonymizer-0.2.4}/tests/unit/test_review_md.py +0 -0
  306. {docs_anonymizer-0.2.2 → docs_anonymizer-0.2.4}/tests/unit/test_runner.py +0 -0
  307. {docs_anonymizer-0.2.2 → docs_anonymizer-0.2.4}/tests/unit/test_runner_acceptance.py +0 -0
  308. {docs_anonymizer-0.2.2 → docs_anonymizer-0.2.4}/tests/unit/test_runner_overlap_matching.py +0 -0
  309. {docs_anonymizer-0.2.2 → docs_anonymizer-0.2.4}/tests/unit/test_russian_pack.py +0 -0
  310. {docs_anonymizer-0.2.2 → docs_anonymizer-0.2.4}/tests/unit/test_snils_detector.py +0 -0
  311. {docs_anonymizer-0.2.2 → docs_anonymizer-0.2.4}/tests/unit/test_testkit_cli.py +0 -0
  312. {docs_anonymizer-0.2.2 → docs_anonymizer-0.2.4}/tests/unit/test_testkit_diff.py +0 -0
  313. {docs_anonymizer-0.2.2 → docs_anonymizer-0.2.4}/tests/unit/test_token_manager.py +0 -0
  314. {docs_anonymizer-0.2.2 → docs_anonymizer-0.2.4}/tests/unit/test_transliteration.py +0 -0
  315. {docs_anonymizer-0.2.2 → docs_anonymizer-0.2.4}/tests/unit/test_update_route.py +0 -0
  316. {docs_anonymizer-0.2.2 → docs_anonymizer-0.2.4}/tests/unit/test_updater_subprocess.py +0 -0
  317. {docs_anonymizer-0.2.2 → docs_anonymizer-0.2.4}/tests/unit/test_webapp_app_factory.py +0 -0
  318. {docs_anonymizer-0.2.2 → docs_anonymizer-0.2.4}/tests/unit/test_webapp_cors.py +0 -0
  319. {docs_anonymizer-0.2.2 → docs_anonymizer-0.2.4}/tests/unit/test_webapp_csrf.py +0 -0
  320. {docs_anonymizer-0.2.2 → docs_anonymizer-0.2.4}/tests/unit/test_webapp_detector.py +0 -0
  321. {docs_anonymizer-0.2.2 → docs_anonymizer-0.2.4}/tests/unit/test_webapp_download.py +0 -0
  322. {docs_anonymizer-0.2.2 → docs_anonymizer-0.2.4}/tests/unit/test_webapp_empty_state.py +0 -0
  323. {docs_anonymizer-0.2.2 → docs_anonymizer-0.2.4}/tests/unit/test_webapp_feedback.py +0 -0
  324. {docs_anonymizer-0.2.2 → docs_anonymizer-0.2.4}/tests/unit/test_webapp_feedback_modal.py +0 -0
  325. {docs_anonymizer-0.2.2 → docs_anonymizer-0.2.4}/tests/unit/test_webapp_i18n.py +0 -0
  326. {docs_anonymizer-0.2.2 → docs_anonymizer-0.2.4}/tests/unit/test_webapp_language_route.py +0 -0
  327. {docs_anonymizer-0.2.2 → docs_anonymizer-0.2.4}/tests/unit/test_webapp_manual_mask_guess.py +0 -0
  328. {docs_anonymizer-0.2.2 → docs_anonymizer-0.2.4}/tests/unit/test_webapp_manual_overrides.py +0 -0
  329. {docs_anonymizer-0.2.2 → docs_anonymizer-0.2.4}/tests/unit/test_webapp_preview.py +0 -0
  330. {docs_anonymizer-0.2.2 → docs_anonymizer-0.2.4}/tests/unit/test_webapp_preview_render.py +0 -0
  331. {docs_anonymizer-0.2.2 → docs_anonymizer-0.2.4}/tests/unit/test_webapp_process_sse.py +0 -0
  332. {docs_anonymizer-0.2.2 → docs_anonymizer-0.2.4}/tests/unit/test_webapp_session.py +0 -0
  333. {docs_anonymizer-0.2.2 → docs_anonymizer-0.2.4}/tests/unit/test_webapp_session_manager.py +0 -0
  334. {docs_anonymizer-0.2.2 → docs_anonymizer-0.2.4}/tests/unit/test_webapp_session_token.py +0 -0
  335. {docs_anonymizer-0.2.2 → docs_anonymizer-0.2.4}/tests/unit/test_webapp_settings.py +0 -0
  336. {docs_anonymizer-0.2.2 → docs_anonymizer-0.2.4}/tests/unit/test_webapp_stages.py +0 -0
  337. {docs_anonymizer-0.2.2 → docs_anonymizer-0.2.4}/tests/unit/test_webapp_static_assets.py +0 -0
  338. {docs_anonymizer-0.2.2 → docs_anonymizer-0.2.4}/tests/unit/test_webapp_templates.py +0 -0
  339. {docs_anonymizer-0.2.2 → docs_anonymizer-0.2.4}/tests/unit/test_webapp_token_sources.py +0 -0
  340. {docs_anonymizer-0.2.2 → docs_anonymizer-0.2.4}/tests/unit/test_webapp_topbar.py +0 -0
  341. {docs_anonymizer-0.2.2 → docs_anonymizer-0.2.4}/tests/unit/test_webapp_unmask.py +0 -0
  342. {docs_anonymizer-0.2.2 → docs_anonymizer-0.2.4}/tests/unit/test_webapp_upload.py +0 -0
  343. {docs_anonymizer-0.2.2 → docs_anonymizer-0.2.4}/tests/unit/test_xlsx_generator.py +0 -0
  344. {docs_anonymizer-0.2.2 → docs_anonymizer-0.2.4}/tests/unit/test_xlsx_parser.py +0 -0
  345. {docs_anonymizer-0.2.2 → docs_anonymizer-0.2.4}/tests/unit/test_xlsx_writer.py +0 -0
@@ -11,6 +11,42 @@ static release metadata, and posts the release notification.
11
11
 
12
12
  ## [Unreleased]
13
13
 
14
+ ## [0.2.4] - 2026-05-19
15
+
16
+ ### Added
17
+
18
+ - Vendor-neutral agent workflow infrastructure under ``.agents/skills`` so
19
+ Claude Code, Codex, and generic agents share one canonical workflow source.
20
+ ``.claude/skills`` entries are now compatibility shims that delegate to the
21
+ canonical files, with adapter notes for Claude, Codex, and generic agents.
22
+
23
+ ### Fixed
24
+
25
+ - Agent workflow consistency tests now validate YAML frontmatter with
26
+ ``yaml.safe_load``. This prevents invalid multiline ``description`` fields
27
+ from silently breaking skill discovery while still keeping Claude shims and
28
+ canonical ``.agents`` skills in sync.
29
+
30
+ ## [0.2.3] - 2026-05-19
31
+
32
+ ### Fixed
33
+
34
+ - Add ``setuptools<81`` as a hard runtime dependency in
35
+ ``[project] dependencies``. Without the runtime pin, ``uv tool
36
+ install docs-anonymizer`` end-user environments resolved the latest
37
+ setuptools (>=81), which dropped the bundled ``pkg_resources``
38
+ package; the first RU NER call then crashed with::
39
+
40
+ File ".../pymorphy2/analyzer.py", line 114, in _iter_entry_points
41
+ import pkg_resources
42
+ ModuleNotFoundError: No module named 'pkg_resources'
43
+
44
+ Surfaced in the pilot run on the first real RU ``.docx`` document.
45
+ The existing ``[tool.uv] constraint-dependencies`` line was a
46
+ uv-only override and did not propagate into the published wheel
47
+ metadata. Lifting this pin requires upgrading natasha to a release
48
+ that uses pymorphy3.
49
+
14
50
  ## [0.2.2] - 2026-05-19
15
51
 
16
52
  ### Added
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: docs-anonymizer
3
- Version: 0.2.2
3
+ Version: 0.2.4
4
4
  Summary: Offline document anonymizer for legal teams
5
5
  Project-URL: Homepage, https://anonymizer.site
6
6
  License-Expression: AGPL-3.0
@@ -32,6 +32,7 @@ Requires-Dist: pymupdf>=1.24
32
32
  Requires-Dist: python-docx>=1.1
33
33
  Requires-Dist: python-multipart>=0.0.6
34
34
  Requires-Dist: pyyaml>=6.0
35
+ Requires-Dist: setuptools<81
35
36
  Requires-Dist: spacy>=3.7
36
37
  Requires-Dist: sse-starlette>=2.0
37
38
  Requires-Dist: transliterate>=1.10
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "docs-anonymizer"
3
- version = "0.2.2"
3
+ version = "0.2.4"
4
4
  description = "Offline document anonymizer for legal teams"
5
5
  readme = "README.md"
6
6
  # Upper bound: ``blis 0.7.11`` (pulled in transitively via ``spacy 3.7`` →
@@ -54,6 +54,14 @@ dependencies = [
54
54
  "Babel>=2.14",
55
55
  "httpx>=0.27",
56
56
  "packaging>=24.0",
57
+ # ``natasha.MorphVocab`` initialises ``pymorphy2`` which calls
58
+ # ``import pkg_resources`` at runtime. Setuptools >= 81 dropped the
59
+ # bundled ``pkg_resources`` package, so the import crashes the first
60
+ # RU NER call. We need a strict runtime cap (not a uv-only constraint)
61
+ # so end-user ``uv tool install`` environments pick a compatible
62
+ # setuptools out of the box. Lifting this pin requires upgrading
63
+ # natasha to a release that uses pymorphy3.
64
+ "setuptools<81",
57
65
  ]
58
66
 
59
67
  [project.scripts]
@@ -73,10 +81,10 @@ build-backend = "hatchling.build"
73
81
  # ``thinc.backends.numpy_ops``). Lifting this pin requires upgrading to
74
82
  # spaCy 3.8+, which falls outside the locked ``en_core_web_lg-3.7.1`` model.
75
83
  #
76
- # Natasha's ``MorphVocab`` initialises ``pymorphy2`` (not pymorphy3), which
77
- # calls ``import pkg_resources`` at runtime. Setuptools >= 81 dropped the
78
- # bundled ``pkg_resources`` package, so we constrain setuptools below that
79
- # version until pymorphy2 is patched or replaced upstream.
84
+ # ``setuptools<81`` is also declared as a runtime dependency in
85
+ # ``[project] dependencies`` so end-user ``uv tool install`` picks it up.
86
+ # It remains here as a constraint to lock the dev-install path through
87
+ # the same path. See the inline comment next to ``setuptools<81`` above.
80
88
  constraint-dependencies = ["numpy<2", "setuptools<81"]
81
89
 
82
90
  [tool.uv.sources]
@@ -0,0 +1,92 @@
1
+ """Consistency checks for vendor-neutral agent workflows."""
2
+
3
+ from __future__ import annotations
4
+
5
+ from pathlib import Path
6
+
7
+ import yaml
8
+
9
+ ROOT = Path(__file__).resolve().parents[2]
10
+
11
+ EXPECTED_SKILLS = {
12
+ "analyze-feedback",
13
+ "annotate-corpus",
14
+ "generate-synthetic-doc",
15
+ "improve-detector",
16
+ "regression-check",
17
+ "release-patch",
18
+ "reproduce-failure",
19
+ }
20
+
21
+
22
+ def _skill_names(base: Path) -> set[str]:
23
+ return {path.parent.name for path in base.glob("*/SKILL.md")}
24
+
25
+
26
+ def _frontmatter_metadata(text: str) -> dict[str, object]:
27
+ frontmatter = text.split("---\n", 2)[1]
28
+ parsed = yaml.safe_load(frontmatter)
29
+ assert isinstance(parsed, dict)
30
+ return parsed
31
+
32
+
33
+ def _frontmatter_description(text: str) -> str:
34
+ description = _frontmatter_metadata(text).get("description")
35
+ assert isinstance(description, str)
36
+ return description
37
+
38
+
39
+ def test_canonical_agent_skills_exist_and_match_frontmatter() -> None:
40
+ skills_dir = ROOT / ".agents" / "skills"
41
+
42
+ assert _skill_names(skills_dir) == EXPECTED_SKILLS
43
+ for skill_name in EXPECTED_SKILLS:
44
+ text = (skills_dir / skill_name / "SKILL.md").read_text(encoding="utf-8")
45
+ assert text.startswith("---\n")
46
+ metadata = _frontmatter_metadata(text)
47
+ assert metadata.get("name") == skill_name
48
+ assert _frontmatter_description(text).startswith("Use when ")
49
+
50
+
51
+ def test_claude_skills_are_compatibility_shims() -> None:
52
+ claude_dir = ROOT / ".claude" / "skills"
53
+
54
+ assert _skill_names(claude_dir) == EXPECTED_SKILLS
55
+ for skill_name in EXPECTED_SKILLS:
56
+ canonical_text = (ROOT / ".agents" / "skills" / skill_name / "SKILL.md").read_text(
57
+ encoding="utf-8"
58
+ )
59
+ text = (claude_dir / skill_name / "SKILL.md").read_text(encoding="utf-8")
60
+ metadata = _frontmatter_metadata(text)
61
+ assert metadata.get("name") == skill_name
62
+ assert _frontmatter_description(text).startswith("Use when ")
63
+ assert _frontmatter_description(text) == _frontmatter_description(canonical_text)
64
+ assert "Claude Code" in text
65
+ assert "compatibility shim" in text.casefold()
66
+ assert f".agents/skills/{skill_name}/SKILL.md" in text
67
+ assert "source of truth" in text
68
+
69
+
70
+ def test_agent_docs_point_to_canonical_workflows() -> None:
71
+ agents_md = (ROOT / "AGENTS.md").read_text(encoding="utf-8")
72
+ guide = (ROOT / ".agents" / "AGENT_GUIDE.md").read_text(encoding="utf-8")
73
+
74
+ assert ".agents/skills" in agents_md
75
+ assert ".claude/skills" in agents_md
76
+ assert "compatibility" in agents_md.casefold()
77
+ for skill_name in EXPECTED_SKILLS:
78
+ assert guide.count(f".agents/skills/{skill_name}/SKILL.md") >= 1
79
+
80
+
81
+ def test_codex_adapter_documents_manual_skill_loading() -> None:
82
+ adapter = (ROOT / ".agents" / "adapters" / "codex.md").read_text(encoding="utf-8")
83
+
84
+ assert "does not auto-discover skills" in adapter
85
+
86
+
87
+ def test_agent_plan_uses_repository_local_instructions() -> None:
88
+ plan = (
89
+ ROOT / "docs" / "superpowers" / "plans" / "2026-05-19-agent-workflows-neutral.md"
90
+ ).read_text(encoding="utf-8")
91
+
92
+ assert "superpowers:" not in plan
@@ -0,0 +1,150 @@
1
+ """Guard critical runtime dependency pins in ``pyproject.toml``.
2
+
3
+ Each pin documented here was added because a real install failure
4
+ escaped pure-pytest coverage — the constraint lives in published wheel
5
+ metadata so end-user ``uv tool install`` environments resolve compatible
6
+ versions. Removing or weakening any of these without a coordinated
7
+ upstream fix has historically broken pilot installs.
8
+
9
+ These tests are intentionally narrow text-level assertions on the
10
+ declared dependency list; they're not a substitute for an actual
11
+ ``uv tool install`` end-to-end smoke run, but they do catch the obvious
12
+ regression of "someone deleted the pin while bumping versions".
13
+ """
14
+
15
+ from __future__ import annotations
16
+
17
+ import tomllib
18
+ from pathlib import Path
19
+
20
+ import pytest
21
+ from packaging.requirements import Requirement
22
+ from packaging.version import Version
23
+
24
+ _PYPROJECT = Path(__file__).parents[2] / "pyproject.toml"
25
+
26
+
27
+ @pytest.fixture(scope="module")
28
+ def project_metadata() -> dict:
29
+ return tomllib.loads(_PYPROJECT.read_text(encoding="utf-8"))["project"]
30
+
31
+
32
+ @pytest.fixture(scope="module")
33
+ def runtime_dependencies(project_metadata: dict) -> list[Requirement]:
34
+ return [Requirement(raw) for raw in project_metadata["dependencies"]]
35
+
36
+
37
+ def _find_dep(deps: list[Requirement], package_name: str) -> Requirement | None:
38
+ """Return the parsed ``Requirement`` for ``package_name`` (case-insensitive)."""
39
+
40
+ lowered = package_name.lower()
41
+ for req in deps:
42
+ if req.name.lower() == lowered:
43
+ return req
44
+ return None
45
+
46
+
47
+ def test_setuptools_capped_below_81(runtime_dependencies: list[Requirement]) -> None:
48
+ """``natasha`` → ``pymorphy2`` runtime-imports ``pkg_resources``.
49
+
50
+ Setuptools 81 dropped the bundled ``pkg_resources`` package, so the
51
+ first RU NER call crashes in any end-user environment that resolves
52
+ setuptools >= 81. The pin was added in 0.2.3 after pilot crash;
53
+ removing it regresses the pilot. Lift only after natasha publishes
54
+ a pymorphy3-based release.
55
+
56
+ Assert semantically via ``Requirement.specifier.contains`` so typos
57
+ like ``>=81`` or ``!=81`` don't sneak past a substring check.
58
+ """
59
+
60
+ req = _find_dep(runtime_dependencies, "setuptools")
61
+ assert req is not None, (
62
+ "setuptools must be declared as a runtime dependency with an "
63
+ "upper-bound. natasha.MorphVocab → pymorphy2 calls "
64
+ "import pkg_resources, which setuptools 81+ no longer ships."
65
+ )
66
+ # Pre-release versions of 81 (e.g. 81.0.0a1) would still drop pkg_resources;
67
+ # include them in the exclusion check too.
68
+ assert not req.specifier.contains("81.0.0", prereleases=True), (
69
+ f"setuptools 81.0.0 must be excluded by the version specifier; "
70
+ f"got {req!s}. See CHANGELOG [0.2.3]."
71
+ )
72
+ assert not req.specifier.contains("82.0.0", prereleases=True), (
73
+ f"setuptools 82.0.0 must also be excluded; got {req!s}."
74
+ )
75
+ # And the last known-good release must still satisfy the pin.
76
+ assert req.specifier.contains(Version("80.10.2")), (
77
+ f"setuptools 80.10.2 (known good) must satisfy the pin; got {req!s}."
78
+ )
79
+
80
+
81
+ def test_en_core_web_lg_runtime_dependency(
82
+ runtime_dependencies: list[Requirement],
83
+ ) -> None:
84
+ """spaCy English model is required by ``person_en`` / ``company_en``.
85
+
86
+ It is not on PyPI proper — the installer scripts inject the URL via
87
+ ``uv tool install --with "en-core-web-lg @ <github wheel URL>"``.
88
+ The bare requirement must remain in ``[project] dependencies`` so
89
+ the resolver validates the link target; the URL itself lives in
90
+ ``[tool.uv.sources]`` and the installer ``--with`` flag.
91
+ """
92
+
93
+ req = _find_dep(runtime_dependencies, "en-core-web-lg")
94
+ assert req is not None, (
95
+ "en-core-web-lg must be declared as a runtime dependency so the "
96
+ "resolver validates the spaCy model wheel injected at install "
97
+ "time via uv tool install --with."
98
+ )
99
+ # PyPI rejects direct URL references in published metadata
100
+ # (see CHANGELOG [0.2.0] direct-URL hotfix). The bare requirement
101
+ # must have neither a URL nor a strict specifier locking the model
102
+ # to a specific PyPI version.
103
+ assert req.url is None, (
104
+ f"en-core-web-lg requirement must not embed a direct URL in "
105
+ f"published wheel metadata (PyPI rejects it); got {req!s}. The "
106
+ f"URL lives in [tool.uv.sources] for dev installs and in the "
107
+ f"installer --with flag for end users."
108
+ )
109
+
110
+
111
+ def test_requires_python_capped_below_313(project_metadata: dict) -> None:
112
+ """``blis 0.7.11`` only ships pre-built wheels for cp310..cp312.
113
+
114
+ On Python 3.13/3.14 uv falls back to building blis from sdist and
115
+ the build crashes against the CPython 3.13/3.14 C ABI (removed
116
+ ``_PyDict_SetItem_KnownHash``, new ``_PyLong_AsByteArray`` sig).
117
+ The upper bound was added in 0.2.1; lifting it requires upgrading
118
+ to spacy >= 3.8 and refreshing the ``en_core_web_lg`` model URL.
119
+
120
+ Uses ``SpecifierSet.contains`` so a typo like ``>=3.13`` would still
121
+ fail the test instead of slipping past a substring check.
122
+ """
123
+
124
+ from packaging.specifiers import SpecifierSet
125
+
126
+ requires_python = SpecifierSet(project_metadata["requires-python"])
127
+ assert not requires_python.contains("3.13.0", prereleases=True), (
128
+ f"requires-python must exclude 3.13: got {requires_python!s}. "
129
+ "blis 0.7.11 has no cp313/cp314 wheels. See CHANGELOG [0.2.1]."
130
+ )
131
+ assert not requires_python.contains("3.14.0", prereleases=True), (
132
+ f"requires-python must exclude 3.14: got {requires_python!s}."
133
+ )
134
+ assert requires_python.contains("3.12.0"), (
135
+ f"requires-python must still allow 3.12: got {requires_python!s}."
136
+ )
137
+
138
+
139
+ def test_distribution_name_is_docs_anonymizer(project_metadata: dict) -> None:
140
+ """The PyPI distribution name is ``docs-anonymizer``, not ``anonymizer``.
141
+
142
+ The bare ``anonymizer`` name was unavailable on PyPI; ``docs-anonymizer``
143
+ was reserved in 0.0.1 and shipped functionally in 0.2.0. The Python
144
+ import name is unrelated and stays ``anonymizer``.
145
+ """
146
+
147
+ assert project_metadata["name"] == "docs-anonymizer", (
148
+ "distribution name on PyPI must stay 'docs-anonymizer'. "
149
+ "Python import name 'anonymizer' is decoupled from this."
150
+ )
File without changes