psyclaw 0.27.22 → 0.28.0

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 (1048) hide show
  1. package/README.md +11 -5
  2. package/dist/apps/panel/index.html +2 -2
  3. package/dist/src/adapters/pi/extension.js +225 -92
  4. package/dist/src/adapters/pi/extension.js.map +1 -1
  5. package/dist/src/agents/import.js +44 -32
  6. package/dist/src/agents/import.js.map +1 -1
  7. package/dist/src/analysis/hooks.d.ts +1 -0
  8. package/dist/src/analysis/hooks.js +20 -1
  9. package/dist/src/analysis/hooks.js.map +1 -1
  10. package/dist/src/ars/bridge.d.ts +20 -0
  11. package/dist/src/ars/bridge.js +132 -0
  12. package/dist/src/ars/bridge.js.map +1 -0
  13. package/dist/src/ars/contracts.d.ts +55 -0
  14. package/dist/src/ars/contracts.js +2 -0
  15. package/dist/src/ars/contracts.js.map +1 -0
  16. package/dist/src/ars/panel-plan.d.ts +4 -0
  17. package/dist/src/ars/panel-plan.js +11 -0
  18. package/dist/src/ars/panel-plan.js.map +1 -0
  19. package/dist/src/ars/pi-panel-executor.d.ts +30 -0
  20. package/dist/src/ars/pi-panel-executor.js +140 -0
  21. package/dist/src/ars/pi-panel-executor.js.map +1 -0
  22. package/dist/src/ars/profile.d.ts +36 -0
  23. package/dist/src/ars/profile.js +119 -0
  24. package/dist/src/ars/profile.js.map +1 -0
  25. package/dist/src/ars/re-review.d.ts +22 -0
  26. package/dist/src/ars/re-review.js +172 -0
  27. package/dist/src/ars/re-review.js.map +1 -0
  28. package/dist/src/branding.d.ts +2 -4
  29. package/dist/src/branding.js +3 -5
  30. package/dist/src/branding.js.map +1 -1
  31. package/dist/src/bundled-tools.d.ts +3 -0
  32. package/dist/src/bundled-tools.js +21 -0
  33. package/dist/src/bundled-tools.js.map +1 -0
  34. package/dist/src/chat.js +6 -5
  35. package/dist/src/chat.js.map +1 -1
  36. package/dist/src/creation/contracts.d.ts +38 -0
  37. package/dist/src/creation/contracts.js +2 -0
  38. package/dist/src/creation/contracts.js.map +1 -0
  39. package/dist/src/creation/service.d.ts +7 -0
  40. package/dist/src/creation/service.js +196 -0
  41. package/dist/src/creation/service.js.map +1 -0
  42. package/dist/src/index.d.ts +10 -0
  43. package/dist/src/index.js +10 -0
  44. package/dist/src/index.js.map +1 -1
  45. package/dist/src/install/installer.js +32 -10
  46. package/dist/src/install/installer.js.map +1 -1
  47. package/dist/src/orchestration/personas.d.ts +15 -0
  48. package/dist/src/orchestration/personas.js +51 -0
  49. package/dist/src/orchestration/personas.js.map +1 -0
  50. package/dist/src/orchestration/pi-executor.d.ts +1 -0
  51. package/dist/src/orchestration/pi-executor.js +1 -1
  52. package/dist/src/orchestration/pi-executor.js.map +1 -1
  53. package/dist/src/panel/extension.js +29 -8
  54. package/dist/src/panel/extension.js.map +1 -1
  55. package/dist/src/panel/server.js +14 -5
  56. package/dist/src/panel/server.js.map +1 -1
  57. package/dist/src/project/paths.d.ts +3 -0
  58. package/dist/src/project/paths.js +7 -0
  59. package/dist/src/project/paths.js.map +1 -1
  60. package/dist/src/rules/user-rules.d.ts +8 -0
  61. package/dist/src/rules/user-rules.js +36 -0
  62. package/dist/src/rules/user-rules.js.map +1 -0
  63. package/dist/src/skills/contracts.d.ts +4 -4
  64. package/dist/src/skills/recommended.js +1 -1
  65. package/dist/src/skills/registry.js +49 -28
  66. package/dist/src/skills/registry.js.map +1 -1
  67. package/dist/src/style/cli-ui.js +0 -1
  68. package/dist/src/style/cli-ui.js.map +1 -1
  69. package/package.json +14 -3
  70. package/scripts/rebrand-pi.mjs +6 -0
  71. package/skills/recommended/catalog.json +2 -11
  72. package/vendor/ars/.claude/CLAUDE.md +371 -0
  73. package/vendor/ars/.command-invariants.toml +24 -0
  74. package/vendor/ars/CITATION.cff +35 -0
  75. package/vendor/ars/LICENSE +417 -0
  76. package/vendor/ars/MODE_REGISTRY.md +76 -0
  77. package/vendor/ars/NOTICE.md +26 -0
  78. package/vendor/ars/POSITIONING.md +99 -0
  79. package/vendor/ars/PSYCLAW_SOURCE.json +10 -0
  80. package/vendor/ars/README.md +751 -0
  81. package/vendor/ars/SECURITY.md +52 -0
  82. package/vendor/ars/THIRD_PARTY.md +70 -0
  83. package/vendor/ars/academic-paper/SKILL.md +542 -0
  84. package/vendor/ars/academic-paper/agents/abstract_bilingual_agent.md +171 -0
  85. package/vendor/ars/academic-paper/agents/argument_builder_agent.md +276 -0
  86. package/vendor/ars/academic-paper/agents/citation_compliance_agent.md +422 -0
  87. package/vendor/ars/academic-paper/agents/draft_writer_agent.md +656 -0
  88. package/vendor/ars/academic-paper/agents/formatter_agent.md +999 -0
  89. package/vendor/ars/academic-paper/agents/intake_agent.md +393 -0
  90. package/vendor/ars/academic-paper/agents/literature_strategist_agent.md +626 -0
  91. package/vendor/ars/academic-paper/agents/peer_reviewer_agent.md +516 -0
  92. package/vendor/ars/academic-paper/agents/revision_coach_agent.md +334 -0
  93. package/vendor/ars/academic-paper/agents/socratic_mentor_agent.md +527 -0
  94. package/vendor/ars/academic-paper/agents/structure_architect_agent.md +401 -0
  95. package/vendor/ars/academic-paper/agents/visualization_agent.md +441 -0
  96. package/vendor/ars/academic-paper/examples/chinese_paper_example.md +278 -0
  97. package/vendor/ars/academic-paper/examples/clinical_citation_verification_checklist.md +95 -0
  98. package/vendor/ars/academic-paper/examples/clinical_epistemic_status_example.md +100 -0
  99. package/vendor/ars/academic-paper/examples/commitment_ledger_example.md +147 -0
  100. package/vendor/ars/academic-paper/examples/imrad_hei_example.md +234 -0
  101. package/vendor/ars/academic-paper/examples/literature_review_example.md +260 -0
  102. package/vendor/ars/academic-paper/examples/plan_mode_guided_writing.md +600 -0
  103. package/vendor/ars/academic-paper/examples/revision_mode_example.md +344 -0
  104. package/vendor/ars/academic-paper/examples/revision_recovery_example.md +506 -0
  105. package/vendor/ars/academic-paper/examples/version_family_reconciliation_example.md +89 -0
  106. package/vendor/ars/academic-paper/references/abstract_writing_guide.md +169 -0
  107. package/vendor/ars/academic-paper/references/academic_writing_style.md +188 -0
  108. package/vendor/ars/academic-paper/references/anti_leakage_protocol.md +83 -0
  109. package/vendor/ars/academic-paper/references/apa7_chinese_citation_guide.md +364 -0
  110. package/vendor/ars/academic-paper/references/apa7_extended_guide.md +198 -0
  111. package/vendor/ars/academic-paper/references/changelog.md +11 -0
  112. package/vendor/ars/academic-paper/references/citation_format_switcher.md +228 -0
  113. package/vendor/ars/academic-paper/references/committee_correspondence_protocol.md +158 -0
  114. package/vendor/ars/academic-paper/references/credit_authorship_guide.md +308 -0
  115. package/vendor/ars/academic-paper/references/disclosure_mode_protocol.md +478 -0
  116. package/vendor/ars/academic-paper/references/domain_evidence_profiles.md +38 -0
  117. package/vendor/ars/academic-paper/references/failure_paths.md +349 -0
  118. package/vendor/ars/academic-paper/references/funding_statement_guide.md +319 -0
  119. package/vendor/ars/academic-paper/references/hei_domain_glossary.md +169 -0
  120. package/vendor/ars/academic-paper/references/intro_title_rhetoric_guide.md +114 -0
  121. package/vendor/ars/academic-paper/references/journal_submission_guide.md +249 -0
  122. package/vendor/ars/academic-paper/references/latex_template_reference.md +378 -0
  123. package/vendor/ars/academic-paper/references/mode_selection_guide.md +378 -0
  124. package/vendor/ars/academic-paper/references/paper_structure_patterns.md +330 -0
  125. package/vendor/ars/academic-paper/references/plan_mode_protocol.md +112 -0
  126. package/vendor/ars/academic-paper/references/policy_anchor_disclosure_protocol.md +200 -0
  127. package/vendor/ars/academic-paper/references/policy_anchor_table.md +157 -0
  128. package/vendor/ars/academic-paper/references/revision_patch_protocol.md +173 -0
  129. package/vendor/ars/academic-paper/references/statistical_visualization_standards.md +750 -0
  130. package/vendor/ars/academic-paper/references/venue_disclosure_policies.md +259 -0
  131. package/vendor/ars/academic-paper/references/vlm_figure_verification.md +126 -0
  132. package/vendor/ars/academic-paper/references/workflow_phase_details.md +135 -0
  133. package/vendor/ars/academic-paper/references/writing_judgment_framework.md +59 -0
  134. package/vendor/ars/academic-paper/references/writing_quality_check.md +173 -0
  135. package/vendor/ars/academic-paper/templates/bilingual_abstract_template.md +78 -0
  136. package/vendor/ars/academic-paper/templates/case_study_template.md +129 -0
  137. package/vendor/ars/academic-paper/templates/conference_paper_template.md +108 -0
  138. package/vendor/ars/academic-paper/templates/credit_statement_template.md +132 -0
  139. package/vendor/ars/academic-paper/templates/funding_statement_template.md +290 -0
  140. package/vendor/ars/academic-paper/templates/imrad_template.md +183 -0
  141. package/vendor/ars/academic-paper/templates/latex_article_template.tex +199 -0
  142. package/vendor/ars/academic-paper/templates/literature_review_template.md +135 -0
  143. package/vendor/ars/academic-paper/templates/policy_brief_template.md +139 -0
  144. package/vendor/ars/academic-paper/templates/revision_tracking_template.md +199 -0
  145. package/vendor/ars/academic-paper/templates/theoretical_paper_template.md +119 -0
  146. package/vendor/ars/academic-paper-reviewer/SKILL.md +491 -0
  147. package/vendor/ars/academic-paper-reviewer/agents/devils_advocate_reviewer_agent.md +443 -0
  148. package/vendor/ars/academic-paper-reviewer/agents/domain_reviewer_agent.md +412 -0
  149. package/vendor/ars/academic-paper-reviewer/agents/editorial_synthesizer_agent.md +478 -0
  150. package/vendor/ars/academic-paper-reviewer/agents/eic_agent.md +339 -0
  151. package/vendor/ars/academic-paper-reviewer/agents/field_analyst_agent.md +221 -0
  152. package/vendor/ars/academic-paper-reviewer/agents/methodology_reviewer_agent.md +449 -0
  153. package/vendor/ars/academic-paper-reviewer/agents/perspective_reviewer_agent.md +427 -0
  154. package/vendor/ars/academic-paper-reviewer/examples/hei_paper_review_example.md +391 -0
  155. package/vendor/ars/academic-paper-reviewer/examples/interdisciplinary_review_example.md +299 -0
  156. package/vendor/ars/academic-paper-reviewer/examples/subclaim_decomposition_example.md +80 -0
  157. package/vendor/ars/academic-paper-reviewer/references/calibration_mode_protocol.md +256 -0
  158. package/vendor/ars/academic-paper-reviewer/references/changelog.md +10 -0
  159. package/vendor/ars/academic-paper-reviewer/references/editorial_decision_standards.md +236 -0
  160. package/vendor/ars/academic-paper-reviewer/references/guided_mode_protocol.md +34 -0
  161. package/vendor/ars/academic-paper-reviewer/references/integration_guide.md +15 -0
  162. package/vendor/ars/academic-paper-reviewer/references/quality_rubrics.md +84 -0
  163. package/vendor/ars/academic-paper-reviewer/references/re_review_mode_protocol.md +340 -0
  164. package/vendor/ars/academic-paper-reviewer/references/review_criteria_framework.md +98 -0
  165. package/vendor/ars/academic-paper-reviewer/references/review_panel_provenance_protocol.md +197 -0
  166. package/vendor/ars/academic-paper-reviewer/references/review_quality_thinking.md +58 -0
  167. package/vendor/ars/academic-paper-reviewer/references/reviewer_sprint_prompt_source.md +324 -0
  168. package/vendor/ars/academic-paper-reviewer/references/sprint_contract_protocol.md +296 -0
  169. package/vendor/ars/academic-paper-reviewer/references/statistical_reporting_standards.md +505 -0
  170. package/vendor/ars/academic-paper-reviewer/references/top_journals_by_field.md +206 -0
  171. package/vendor/ars/academic-paper-reviewer/templates/editorial_decision_template.md +235 -0
  172. package/vendor/ars/academic-paper-reviewer/templates/peer_review_report_template.md +305 -0
  173. package/vendor/ars/academic-paper-reviewer/templates/revision_response_template.md +248 -0
  174. package/vendor/ars/academic-pipeline/SKILL.md +736 -0
  175. package/vendor/ars/academic-pipeline/agents/claim_ref_alignment_audit_agent.md +382 -0
  176. package/vendor/ars/academic-pipeline/agents/collaboration_depth_agent.md +164 -0
  177. package/vendor/ars/academic-pipeline/agents/integrity_verification_agent.md +870 -0
  178. package/vendor/ars/academic-pipeline/agents/pipeline_orchestrator_agent.md +1379 -0
  179. package/vendor/ars/academic-pipeline/agents/state_tracker_agent.md +622 -0
  180. package/vendor/ars/academic-pipeline/examples/full_pipeline_example.md +482 -0
  181. package/vendor/ars/academic-pipeline/examples/integrity_failure_recovery.md +389 -0
  182. package/vendor/ars/academic-pipeline/examples/mid_entry_example.md +414 -0
  183. package/vendor/ars/academic-pipeline/references/adapters/.gitkeep +0 -0
  184. package/vendor/ars/academic-pipeline/references/adapters/overview.md +153 -0
  185. package/vendor/ars/academic-pipeline/references/ai_research_failure_modes.md +185 -0
  186. package/vendor/ars/academic-pipeline/references/changelog.md +14 -0
  187. package/vendor/ars/academic-pipeline/references/claim_audit_calibration_protocol.md +175 -0
  188. package/vendor/ars/academic-pipeline/references/claim_verification_protocol.md +282 -0
  189. package/vendor/ars/academic-pipeline/references/external_review_protocol.md +131 -0
  190. package/vendor/ars/academic-pipeline/references/integrity_review_protocol.md +110 -0
  191. package/vendor/ars/academic-pipeline/references/literature_corpus_consumers.md +193 -0
  192. package/vendor/ars/academic-pipeline/references/mode_advisor.md +135 -0
  193. package/vendor/ars/academic-pipeline/references/passport_as_reset_boundary.md +132 -0
  194. package/vendor/ars/academic-pipeline/references/pipeline_state_machine.md +405 -0
  195. package/vendor/ars/academic-pipeline/references/plagiarism_detection_protocol.md +239 -0
  196. package/vendor/ars/academic-pipeline/references/process_summary_protocol.md +209 -0
  197. package/vendor/ars/academic-pipeline/references/progress_dashboard_template.md +38 -0
  198. package/vendor/ars/academic-pipeline/references/reinforcement_content.md +15 -0
  199. package/vendor/ars/academic-pipeline/references/reproducibility_audit.md +55 -0
  200. package/vendor/ars/academic-pipeline/references/score_trajectory_protocol.md +78 -0
  201. package/vendor/ars/academic-pipeline/references/team_collaboration_protocol.md +261 -0
  202. package/vendor/ars/academic-pipeline/references/two_stage_review_protocol.md +27 -0
  203. package/vendor/ars/academic-pipeline/templates/pipeline_status_template.md +146 -0
  204. package/vendor/ars/agents/report_compiler_agent.md +341 -0
  205. package/vendor/ars/agents/research_architect_agent.md +298 -0
  206. package/vendor/ars/agents/synthesis_agent.md +356 -0
  207. package/vendor/ars/commands/ars-3w.md +10 -0
  208. package/vendor/ars/commands/ars-abstract.md +10 -0
  209. package/vendor/ars/commands/ars-cache-invalidate.md +20 -0
  210. package/vendor/ars/commands/ars-citation-check.md +10 -0
  211. package/vendor/ars/commands/ars-disclosure.md +10 -0
  212. package/vendor/ars/commands/ars-format-convert.md +10 -0
  213. package/vendor/ars/commands/ars-full.md +9 -0
  214. package/vendor/ars/commands/ars-lit-review.md +12 -0
  215. package/vendor/ars/commands/ars-mark-read.md +18 -0
  216. package/vendor/ars/commands/ars-outline.md +10 -0
  217. package/vendor/ars/commands/ars-plan.md +10 -0
  218. package/vendor/ars/commands/ars-rebuttal-audit.md +12 -0
  219. package/vendor/ars/commands/ars-reviewer.md +9 -0
  220. package/vendor/ars/commands/ars-revision-coach.md +9 -0
  221. package/vendor/ars/commands/ars-revision.md +10 -0
  222. package/vendor/ars/commands/ars-unmark-read.md +16 -0
  223. package/vendor/ars/deep-research/SKILL.md +600 -0
  224. package/vendor/ars/deep-research/agents/bibliography_agent.md +473 -0
  225. package/vendor/ars/deep-research/agents/devils_advocate_agent.md +192 -0
  226. package/vendor/ars/deep-research/agents/editor_in_chief_agent.md +167 -0
  227. package/vendor/ars/deep-research/agents/ethics_review_agent.md +267 -0
  228. package/vendor/ars/deep-research/agents/meta_analysis_agent.md +325 -0
  229. package/vendor/ars/deep-research/agents/monitoring_agent.md +209 -0
  230. package/vendor/ars/deep-research/agents/report_compiler_agent.md +341 -0
  231. package/vendor/ars/deep-research/agents/research_architect_agent.md +298 -0
  232. package/vendor/ars/deep-research/agents/research_question_agent.md +216 -0
  233. package/vendor/ars/deep-research/agents/risk_of_bias_agent.md +231 -0
  234. package/vendor/ars/deep-research/agents/socratic_mentor_agent.md +764 -0
  235. package/vendor/ars/deep-research/agents/source_verification_agent.md +219 -0
  236. package/vendor/ars/deep-research/agents/synthesis_agent.md +356 -0
  237. package/vendor/ars/deep-research/agents/timeline_extraction_agent.md +99 -0
  238. package/vendor/ars/deep-research/examples/exploratory_research.md +157 -0
  239. package/vendor/ars/deep-research/examples/fact_check_mode.md +173 -0
  240. package/vendor/ars/deep-research/examples/handoff_to_paper.md +318 -0
  241. package/vendor/ars/deep-research/examples/idea_diversity_coverage_gap_advisory.md +64 -0
  242. package/vendor/ars/deep-research/examples/policy_analysis.md +161 -0
  243. package/vendor/ars/deep-research/examples/review_mode.md +253 -0
  244. package/vendor/ars/deep-research/examples/socratic_guided_research.md +331 -0
  245. package/vendor/ars/deep-research/examples/systematic_review.md +133 -0
  246. package/vendor/ars/deep-research/references/apa7_style_guide.md +162 -0
  247. package/vendor/ars/deep-research/references/argumentation_reasoning_framework.md +68 -0
  248. package/vendor/ars/deep-research/references/arxiv_api_protocol.md +76 -0
  249. package/vendor/ars/deep-research/references/changelog.md +22 -0
  250. package/vendor/ars/deep-research/references/chinese_literature_api_protocol.md +317 -0
  251. package/vendor/ars/deep-research/references/cross_agent_quality_definitions.md +14 -0
  252. package/vendor/ars/deep-research/references/crossref_api_protocol.md +84 -0
  253. package/vendor/ars/deep-research/references/equator_reporting_guidelines.md +482 -0
  254. package/vendor/ars/deep-research/references/ethics_checklist.md +282 -0
  255. package/vendor/ars/deep-research/references/failure_paths.md +355 -0
  256. package/vendor/ars/deep-research/references/interdisciplinary_bridges.md +292 -0
  257. package/vendor/ars/deep-research/references/irb_decision_tree.md +315 -0
  258. package/vendor/ars/deep-research/references/literature_monitoring_strategies.md +263 -0
  259. package/vendor/ars/deep-research/references/logical_fallacies.md +192 -0
  260. package/vendor/ars/deep-research/references/methodology_patterns.md +462 -0
  261. package/vendor/ars/deep-research/references/mode_selection_guide.md +331 -0
  262. package/vendor/ars/deep-research/references/openalex_api_protocol.md +82 -0
  263. package/vendor/ars/deep-research/references/preregistration_guide.md +324 -0
  264. package/vendor/ars/deep-research/references/semantic_scholar_api_protocol.md +107 -0
  265. package/vendor/ars/deep-research/references/socratic_mode_protocol.md +99 -0
  266. package/vendor/ars/deep-research/references/socratic_questioning_framework.md +232 -0
  267. package/vendor/ars/deep-research/references/source_quality_hierarchy.md +188 -0
  268. package/vendor/ars/deep-research/references/systematic_review_protocol.md +95 -0
  269. package/vendor/ars/deep-research/references/systematic_review_toolkit.md +353 -0
  270. package/vendor/ars/deep-research/templates/evidence_assessment_template.md +127 -0
  271. package/vendor/ars/deep-research/templates/literature_matrix_template.md +85 -0
  272. package/vendor/ars/deep-research/templates/preregistration_template.md +318 -0
  273. package/vendor/ars/deep-research/templates/prisma_protocol_template.md +248 -0
  274. package/vendor/ars/deep-research/templates/prisma_report_template.md +415 -0
  275. package/vendor/ars/deep-research/templates/research_brief_template.md +93 -0
  276. package/vendor/ars/package.json +24 -0
  277. package/vendor/ars/pi/README.md +161 -0
  278. package/vendor/ars/pi/package.json +26 -0
  279. package/vendor/ars/pi/wrapper.js +193 -0
  280. package/vendor/ars/pi/wrapper.test.mjs +201 -0
  281. package/vendor/ars/pyproject.toml +2 -0
  282. package/vendor/ars/requirements-pdf-content-classifier.txt +5 -0
  283. package/vendor/ars/scripts/_block_parser.py +396 -0
  284. package/vendor/ars/scripts/_ci_pytest_manifest.toml +661 -0
  285. package/vendor/ars/scripts/_claim_audit_constants.py +268 -0
  286. package/vendor/ars/scripts/_e4_evidence.py +110 -0
  287. package/vendor/ars/scripts/_eval_threshold_gate.py +73 -0
  288. package/vendor/ars/scripts/_markdown_lint_util.py +224 -0
  289. package/vendor/ars/scripts/_next_verified_at_ms.py +176 -0
  290. package/vendor/ars/scripts/_passport_yaml.py +53 -0
  291. package/vendor/ars/scripts/_skill_lint.py +254 -0
  292. package/vendor/ars/scripts/_text_similarity.py +141 -0
  293. package/vendor/ars/scripts/adapters/README.md +89 -0
  294. package/vendor/ars/scripts/adapters/_common.py +209 -0
  295. package/vendor/ars/scripts/adapters/examples/folder_scan/expected_passport.yaml +25 -0
  296. package/vendor/ars/scripts/adapters/examples/folder_scan/expected_rejection_log.yaml +18 -0
  297. package/vendor/ars/scripts/adapters/examples/folder_scan/input_fixture/Chen2024_AIAssessment.pdf +0 -0
  298. package/vendor/ars/scripts/adapters/examples/folder_scan/input_fixture/Wang_2023_formative_feedback.pdf +0 -0
  299. package/vendor/ars/scripts/adapters/examples/folder_scan/input_fixture/paper1.pdf +0 -0
  300. package/vendor/ars/scripts/adapters/examples/folder_scan/input_fixture//344/270/255/346/226/207/346/252/224/345/220/215_2024.pdf +0 -0
  301. package/vendor/ars/scripts/adapters/examples/obsidian/expected_passport.yaml +40 -0
  302. package/vendor/ars/scripts/adapters/examples/obsidian/expected_rejection_log.yaml +13 -0
  303. package/vendor/ars/scripts/adapters/examples/obsidian/input_fixture/vault/.gitkeep +0 -0
  304. package/vendor/ars/scripts/adapters/examples/obsidian/input_fixture/vault/.obsidian/app.json +1 -0
  305. package/vendor/ars/scripts/adapters/examples/obsidian/input_fixture/vault/_templates/tmpl.md +7 -0
  306. package/vendor/ars/scripts/adapters/examples/obsidian/input_fixture/vault/chen2024ai.md +13 -0
  307. package/vendor/ars/scripts/adapters/examples/obsidian/input_fixture/vault/invalid.md +1 -0
  308. package/vendor/ars/scripts/adapters/examples/obsidian/input_fixture/vault/wang2023formative.md +10 -0
  309. package/vendor/ars/scripts/adapters/examples/zotero/expected_passport.yaml +34 -0
  310. package/vendor/ars/scripts/adapters/examples/zotero/expected_rejection_log.yaml +34 -0
  311. package/vendor/ars/scripts/adapters/examples/zotero/input_fixture/.gitkeep +0 -0
  312. package/vendor/ars/scripts/adapters/examples/zotero/input_fixture/export.json +43 -0
  313. package/vendor/ars/scripts/adapters/folder_scan.py +214 -0
  314. package/vendor/ars/scripts/adapters/obsidian.py +336 -0
  315. package/vendor/ars/scripts/adapters/tests/.gitkeep +0 -0
  316. package/vendor/ars/scripts/adapters/tests/conftest.py +77 -0
  317. package/vendor/ars/scripts/adapters/tests/test_check_corpus_consumer_protocol.py +632 -0
  318. package/vendor/ars/scripts/adapters/tests/test_check_literature_corpus_schema.py +631 -0
  319. package/vendor/ars/scripts/adapters/tests/test_common.py +365 -0
  320. package/vendor/ars/scripts/adapters/tests/test_conftest.py +96 -0
  321. package/vendor/ars/scripts/adapters/tests/test_folder_scan.py +260 -0
  322. package/vendor/ars/scripts/adapters/tests/test_literature_corpus_entry_schema.py +745 -0
  323. package/vendor/ars/scripts/adapters/tests/test_obsidian.py +357 -0
  324. package/vendor/ars/scripts/adapters/tests/test_rejection_log_schema.py +271 -0
  325. package/vendor/ars/scripts/adapters/tests/test_sync_adapter_docs.py +88 -0
  326. package/vendor/ars/scripts/adapters/tests/test_zotero.py +454 -0
  327. package/vendor/ars/scripts/adapters/zotero.py +318 -0
  328. package/vendor/ars/scripts/adjudication_activity.py +1592 -0
  329. package/vendor/ars/scripts/announce-ars-loaded.sh +144 -0
  330. package/vendor/ars/scripts/ars_anchorize_draft.py +170 -0
  331. package/vendor/ars/scripts/ars_apply_revision_patch.py +912 -0
  332. package/vendor/ars/scripts/ars_cache_invalidate.py +40 -0
  333. package/vendor/ars/scripts/ars_mark_read.py +521 -0
  334. package/vendor/ars/scripts/ars_phase_scope_manifest.json +33 -0
  335. package/vendor/ars/scripts/ars_update_check.sh +215 -0
  336. package/vendor/ars/scripts/ars_write_scope_guard.py +506 -0
  337. package/vendor/ars/scripts/arxiv_client.py +222 -0
  338. package/vendor/ars/scripts/audit_snapshot.py +572 -0
  339. package/vendor/ars/scripts/bibliographic_integrity_signals.py +800 -0
  340. package/vendor/ars/scripts/bootstrap_timeline_yaml.py +146 -0
  341. package/vendor/ars/scripts/build_claim_standing_candidate_ledger.py +1238 -0
  342. package/vendor/ars/scripts/build_claim_standing_query_plan.py +643 -0
  343. package/vendor/ars/scripts/build_content_coverage_advisory.py +1205 -0
  344. package/vendor/ars/scripts/build_cross_document_consistency_advisory.py +2332 -0
  345. package/vendor/ars/scripts/build_review_pathway_rule_trace.py +830 -0
  346. package/vendor/ars/scripts/build_submission_packet_manifest.py +2310 -0
  347. package/vendor/ars/scripts/check_215_field_norm.py +173 -0
  348. package/vendor/ars/scripts/check_216_surface_form.py +250 -0
  349. package/vendor/ars/scripts/check_268_nested_commitment_ledger.py +180 -0
  350. package/vendor/ars/scripts/check_390_revision_patch_discipline.py +296 -0
  351. package/vendor/ars/scripts/check_392_citation_verification_intake.py +126 -0
  352. package/vendor/ars/scripts/check_394_submission_policy.py +178 -0
  353. package/vendor/ars/scripts/check_439_format_profile.py +307 -0
  354. package/vendor/ars/scripts/check_619_disclosure_closeout.py +237 -0
  355. package/vendor/ars/scripts/check_630_codex_subscription_transport.py +456 -0
  356. package/vendor/ars/scripts/check_669_review_pathway_rule_trace.py +662 -0
  357. package/vendor/ars/scripts/check_670_revision_roadmap_integration.py +518 -0
  358. package/vendor/ars/scripts/check_673_adjudication_activity.py +684 -0
  359. package/vendor/ars/scripts/check_684_review_criteria_binding.py +557 -0
  360. package/vendor/ars/scripts/check_agents_mirror_sync.py +115 -0
  361. package/vendor/ars/scripts/check_audit_artifact_consistency.py +2313 -0
  362. package/vendor/ars/scripts/check_benchmark_report.py +79 -0
  363. package/vendor/ars/scripts/check_bibliographic_integrity_signals.py +831 -0
  364. package/vendor/ars/scripts/check_calibration_tiers.py +235 -0
  365. package/vendor/ars/scripts/check_changelog_covers_merges.py +289 -0
  366. package/vendor/ars/scripts/check_ci_pytest_manifest.py +204 -0
  367. package/vendor/ars/scripts/check_claim_audit_consistency.py +1664 -0
  368. package/vendor/ars/scripts/check_claim_standing_candidate_ledger_integration.py +500 -0
  369. package/vendor/ars/scripts/check_claim_standing_freshness.py +253 -0
  370. package/vendor/ars/scripts/check_claim_standing_transmissions.py +449 -0
  371. package/vendor/ars/scripts/check_collaboration_depth_rubric.py +180 -0
  372. package/vendor/ars/scripts/check_command_frontmatter_name.py +116 -0
  373. package/vendor/ars/scripts/check_committee_correspondence.py +333 -0
  374. package/vendor/ars/scripts/check_compliance_report.py +108 -0
  375. package/vendor/ars/scripts/check_content_coverage_advisory_integration.py +796 -0
  376. package/vendor/ars/scripts/check_control_availability.py +172 -0
  377. package/vendor/ars/scripts/check_corpus_consumer_protocol.py +404 -0
  378. package/vendor/ars/scripts/check_cross_document_consistency_advisory_integration.py +1191 -0
  379. package/vendor/ars/scripts/check_cross_model_handoff_contract.py +234 -0
  380. package/vendor/ars/scripts/check_cross_model_verification_sync.py +261 -0
  381. package/vendor/ars/scripts/check_data_access_level.py +131 -0
  382. package/vendor/ars/scripts/check_data_flows.py +252 -0
  383. package/vendor/ars/scripts/check_decision_contract.py +464 -0
  384. package/vendor/ars/scripts/check_degradation_registry.py +326 -0
  385. package/vendor/ars/scripts/check_distribution_surface_claims.py +226 -0
  386. package/vendor/ars/scripts/check_domain_evidence_profile.py +538 -0
  387. package/vendor/ars/scripts/check_e4_promotion.py +195 -0
  388. package/vendor/ars/scripts/check_evals_gold_set.py +279 -0
  389. package/vendor/ars/scripts/check_evidence_row_integration.py +396 -0
  390. package/vendor/ars/scripts/check_experiment_provenance.py +117 -0
  391. package/vendor/ars/scripts/check_field_norm_severity.py +144 -0
  392. package/vendor/ars/scripts/check_firm_rules_sync.py +375 -0
  393. package/vendor/ars/scripts/check_heldout_measurement_report.py +1179 -0
  394. package/vendor/ars/scripts/check_human_subjects_output_contract.py +139 -0
  395. package/vendor/ars/scripts/check_human_subjects_reference_migration.py +844 -0
  396. package/vendor/ars/scripts/check_indirect_prompt_injection_no_call.py +328 -0
  397. package/vendor/ars/scripts/check_instruction_data_boundary.py +236 -0
  398. package/vendor/ars/scripts/check_judge_prompt_version.py +125 -0
  399. package/vendor/ars/scripts/check_literature_corpus_schema.py +402 -0
  400. package/vendor/ars/scripts/check_model_tiering.py +223 -0
  401. package/vendor/ars/scripts/check_panel_synthesis.py +1331 -0
  402. package/vendor/ars/scripts/check_passport_reset_contract.py +214 -0
  403. package/vendor/ars/scripts/check_pattern_eval_manifest.py +422 -0
  404. package/vendor/ars/scripts/check_persuasion_invariance_fixtures.py +637 -0
  405. package/vendor/ars/scripts/check_phase_conformance.py +2180 -0
  406. package/vendor/ars/scripts/check_pipeline_boundary_semantics.py +600 -0
  407. package/vendor/ars/scripts/check_pipeline_integrity.py +340 -0
  408. package/vendor/ars/scripts/check_policy_anchor_protocol.py +159 -0
  409. package/vendor/ars/scripts/check_policy_anchor_table.py +286 -0
  410. package/vendor/ars/scripts/check_preprint_venues_consistency.py +123 -0
  411. package/vendor/ars/scripts/check_prisma_trAIce_freshness.py +84 -0
  412. package/vendor/ars/scripts/check_promotion_bakeoff_preregistration.py +1303 -0
  413. package/vendor/ars/scripts/check_ranking_lift.py +323 -0
  414. package/vendor/ars/scripts/check_re_review_synthesis.py +2719 -0
  415. package/vendor/ars/scripts/check_receipt_enum_sync.py +203 -0
  416. package/vendor/ars/scripts/check_repro_lock.py +85 -0
  417. package/vendor/ars/scripts/check_review_pathway_output.py +276 -0
  418. package/vendor/ars/scripts/check_reviewer_data_fences.py +224 -0
  419. package/vendor/ars/scripts/check_reviewer_finding_contract.py +783 -0
  420. package/vendor/ars/scripts/check_reviewer_role_label.py +447 -0
  421. package/vendor/ars/scripts/check_reviewer_scoring_honesty.py +292 -0
  422. package/vendor/ars/scripts/check_reviewer_sprint_prompt_sync.py +409 -0
  423. package/vendor/ars/scripts/check_revision_claim_drift_suite_v2.py +1622 -0
  424. package/vendor/ars/scripts/check_revision_token_conservation.py +263 -0
  425. package/vendor/ars/scripts/check_risk_register.py +280 -0
  426. package/vendor/ars/scripts/check_role_scoped_contract.py +702 -0
  427. package/vendor/ars/scripts/check_rq_framing_patterns.py +184 -0
  428. package/vendor/ars/scripts/check_rubric_weight_consistency.py +32 -0
  429. package/vendor/ars/scripts/check_seeded_defect_fixtures.py +425 -0
  430. package/vendor/ars/scripts/check_setup_cross_model_parity.py +139 -0
  431. package/vendor/ars/scripts/check_spec_consistency.py +1249 -0
  432. package/vendor/ars/scripts/check_sprint_contract.py +371 -0
  433. package/vendor/ars/scripts/check_stage_capability_matrix.py +784 -0
  434. package/vendor/ars/scripts/check_submission_packet_manifest_integration.py +358 -0
  435. package/vendor/ars/scripts/check_surface_form_parity.py +445 -0
  436. package/vendor/ars/scripts/check_task_type.py +22 -0
  437. package/vendor/ars/scripts/check_tools_allowlist.py +538 -0
  438. package/vendor/ars/scripts/check_tortured_phrase_screening_integration.py +1974 -0
  439. package/vendor/ars/scripts/check_v3_10_134_write_scope.py +286 -0
  440. package/vendor/ars/scripts/check_v3_10_policy.py +656 -0
  441. package/vendor/ars/scripts/check_v3_6_6_ab_manifest.py +364 -0
  442. package/vendor/ars/scripts/check_v3_6_7_pattern_protection.py +1366 -0
  443. package/vendor/ars/scripts/check_v3_6_8_audit_scope_block.py +464 -0
  444. package/vendor/ars/scripts/check_v3_6_8_cite_provenance_pipeline.py +231 -0
  445. package/vendor/ars/scripts/check_v3_6_8_frontmatter_trust_schema.py +248 -0
  446. package/vendor/ars/scripts/check_v3_6_8_mark_read_commands.py +79 -0
  447. package/vendor/ars/scripts/check_v3_6_8_pattern_protection.py +941 -0
  448. package/vendor/ars/scripts/check_v3_7_3_three_layer_citation.py +318 -0
  449. package/vendor/ars/scripts/check_v3_8_annotation_literal_sync.py +228 -0
  450. package/vendor/ars/scripts/check_v3_9_0_triangulation.py +366 -0
  451. package/vendor/ars/scripts/check_v3_9_2_phase_boundary.py +270 -0
  452. package/vendor/ars/scripts/check_v3_9_4_temporal_verification.py +139 -0
  453. package/vendor/ars/scripts/check_venue_disclosure_policies.py +63 -0
  454. package/vendor/ars/scripts/check_version_consistency.py +826 -0
  455. package/vendor/ars/scripts/check_workflow_classification.py +223 -0
  456. package/vendor/ars/scripts/chinese_literature_client.py +1938 -0
  457. package/vendor/ars/scripts/citation_verification_summary.py +85 -0
  458. package/vendor/ars/scripts/claim_audit_calibration.py +517 -0
  459. package/vendor/ars/scripts/claim_audit_finalizer.py +456 -0
  460. package/vendor/ars/scripts/claim_audit_pipeline.py +1594 -0
  461. package/vendor/ars/scripts/claim_registry_coverage.py +493 -0
  462. package/vendor/ars/scripts/claim_standing_discovery.py +784 -0
  463. package/vendor/ars/scripts/claim_standing_stance_runner.py +758 -0
  464. package/vendor/ars/scripts/claim_standing_stance_scorer.py +239 -0
  465. package/vendor/ars/scripts/claim_strength_drift_disposition.py +666 -0
  466. package/vendor/ars/scripts/contamination_signals.py +689 -0
  467. package/vendor/ars/scripts/corpus_consumer_manifest.json +19 -0
  468. package/vendor/ars/scripts/cross_model_codex_transport.py +1374 -0
  469. package/vendor/ars/scripts/cross_model_codex_verify.sh +6 -0
  470. package/vendor/ars/scripts/cross_model_handoff.py +359 -0
  471. package/vendor/ars/scripts/cross_model_smoke_test.sh +183 -0
  472. package/vendor/ars/scripts/cross_model_smoke_test_codex.sh +35 -0
  473. package/vendor/ars/scripts/cross_model_verification/gemini_is_grounded.jq +45 -0
  474. package/vendor/ars/scripts/cross_model_verification/gemini_sources.jq +45 -0
  475. package/vendor/ars/scripts/cross_model_verification/normalize_compat_verdict.py +57 -0
  476. package/vendor/ars/scripts/cross_model_verification/openai_has_completed_web_search.jq +15 -0
  477. package/vendor/ars/scripts/cross_model_verification/openai_sources.jq +17 -0
  478. package/vendor/ars/scripts/cross_model_verification/openai_text.jq +11 -0
  479. package/vendor/ars/scripts/crossref_client.py +225 -0
  480. package/vendor/ars/scripts/dispatch_e4_panel.py +2731 -0
  481. package/vendor/ars/scripts/evidence_rows.py +2043 -0
  482. package/vendor/ars/scripts/fixtures/adjudication_activity/author_stage3.json +32 -0
  483. package/vendor/ars/scripts/fixtures/adjudication_activity/author_stage3_input.json +27 -0
  484. package/vendor/ars/scripts/fixtures/adjudication_activity/author_stage3_prime.json +32 -0
  485. package/vendor/ars/scripts/fixtures/adjudication_activity/author_stage3_prime_input.json +27 -0
  486. package/vendor/ars/scripts/fixtures/adjudication_activity/compliance_override.json +50 -0
  487. package/vendor/ars/scripts/fixtures/adjudication_activity/compliance_override_action.json +14 -0
  488. package/vendor/ars/scripts/fixtures/adjudication_activity/compliance_pass.json +44 -0
  489. package/vendor/ars/scripts/fixtures/adjudication_activity/explicit_user_request_log.json +26 -0
  490. package/vendor/ars/scripts/fixtures/adjudication_activity/mandatory_checkpoint_log.json +116 -0
  491. package/vendor/ars/scripts/fixtures/audit_artifact_consistency/README.md +56 -0
  492. package/vendor/ars/scripts/fixtures/audit_artifact_consistency/negative/a1_pass_with_p1/2026-04-30T15-22-04Z-d8f3.audit_artifact_entry.json +24 -0
  493. package/vendor/ars/scripts/fixtures/audit_artifact_consistency/negative/a1_pass_with_p1/2026-04-30T15-22-04Z-d8f3.jsonl +4 -0
  494. package/vendor/ars/scripts/fixtures/audit_artifact_consistency/negative/a1_pass_with_p1/2026-04-30T15-22-04Z-d8f3.meta.json +43 -0
  495. package/vendor/ars/scripts/fixtures/audit_artifact_consistency/negative/a1_pass_with_p1/2026-04-30T15-22-04Z-d8f3.verdict.yaml +19 -0
  496. package/vendor/ars/scripts/fixtures/audit_artifact_consistency/negative/a7_orphan_completion/2026-04-30T15-22-04Z-d8f3.jsonl +3 -0
  497. package/vendor/ars/scripts/fixtures/audit_artifact_consistency/positive/persisted_minor/2026-04-30T15-22-04Z-d8f3.audit_artifact_entry.json +26 -0
  498. package/vendor/ars/scripts/fixtures/audit_artifact_consistency/positive/persisted_minor/2026-04-30T15-22-04Z-d8f3.jsonl +4 -0
  499. package/vendor/ars/scripts/fixtures/audit_artifact_consistency/positive/persisted_minor/2026-04-30T15-22-04Z-d8f3.meta.json +43 -0
  500. package/vendor/ars/scripts/fixtures/audit_artifact_consistency/positive/persisted_minor/2026-04-30T15-22-04Z-d8f3.verdict.yaml +19 -0
  501. package/vendor/ars/scripts/fixtures/audit_artifact_consistency/positive/proposal_pass/2026-04-30T15-22-04Z-d8f3.audit_artifact_entry.json +24 -0
  502. package/vendor/ars/scripts/fixtures/audit_artifact_consistency/positive/proposal_pass/2026-04-30T15-22-04Z-d8f3.jsonl +4 -0
  503. package/vendor/ars/scripts/fixtures/audit_artifact_consistency/positive/proposal_pass/2026-04-30T15-22-04Z-d8f3.meta.json +43 -0
  504. package/vendor/ars/scripts/fixtures/audit_artifact_consistency/positive/proposal_pass/2026-04-30T15-22-04Z-d8f3.verdict.yaml +12 -0
  505. package/vendor/ars/scripts/fixtures/bibliographic_integrity_signals/retraction.json +46 -0
  506. package/vendor/ars/scripts/fixtures/bibliographic_integrity_signals/retraction_check_attestation.json +44 -0
  507. package/vendor/ars/scripts/fixtures/bibliographic_integrity_signals/tortured_phrase.json +44 -0
  508. package/vendor/ars/scripts/fixtures/bibliographic_integrity_signals/tortured_phrase_v1_2_abstract_missing.json +107 -0
  509. package/vendor/ars/scripts/fixtures/bibliographic_integrity_signals/tortured_phrase_v1_2_detected.json +124 -0
  510. package/vendor/ars/scripts/fixtures/check_evals_gold_set/clean/expected_outcomes.json +77 -0
  511. package/vendor/ars/scripts/fixtures/check_evals_gold_set/clean/manifest.yaml +37 -0
  512. package/vendor/ars/scripts/fixtures/check_evals_gold_set/clean/tuples/001-valid-doi-test.json +20 -0
  513. package/vendor/ars/scripts/fixtures/check_evals_gold_set/clean/tuples/002-valid-arxiv-test.json +19 -0
  514. package/vendor/ars/scripts/fixtures/check_evals_gold_set/clean/tuples/003-fabricated-test.json +20 -0
  515. package/vendor/ars/scripts/fixtures/claim_audit_calibration/gold_set.json +344 -0
  516. package/vendor/ars/scripts/fixtures/claim_standing_candidate_ledger/query_plan.json +108 -0
  517. package/vendor/ars/scripts/fixtures/claim_standing_candidate_ledger/retrieval_input.json +179 -0
  518. package/vendor/ars/scripts/fixtures/committee_correspondence/16fd83f6aec7/concern_tracker.json +129 -0
  519. package/vendor/ars/scripts/fixtures/committee_correspondence/16fd83f6aec7/response_skeleton.md +19 -0
  520. package/vendor/ars/scripts/fixtures/committee_correspondence/16fd83f6aec7/source_letter.txt +9 -0
  521. package/vendor/ars/scripts/fixtures/content_coverage_advisory/base_draft.json +48 -0
  522. package/vendor/ars/scripts/fixtures/content_coverage_advisory/base_inventory.json +38 -0
  523. package/vendor/ars/scripts/fixtures/content_coverage_advisory/packet/consent.txt +1 -0
  524. package/vendor/ars/scripts/fixtures/content_coverage_advisory/session_sources.json +3 -0
  525. package/vendor/ars/scripts/fixtures/cross_document_consistency/README.md +6 -0
  526. package/vendor/ars/scripts/fixtures/cross_document_consistency/accepted_draft.md +35 -0
  527. package/vendor/ars/scripts/fixtures/cross_document_consistency/cases.json +75 -0
  528. package/vendor/ars/scripts/fixtures/cross_document_consistency/preregistration.md +5 -0
  529. package/vendor/ars/scripts/fixtures/cross_model_codex_transport/forbidden_event.jsonl +4 -0
  530. package/vendor/ars/scripts/fixtures/cross_model_codex_transport/grounded_verified.jsonl +3 -0
  531. package/vendor/ars/scripts/fixtures/cross_model_codex_transport/malformed.jsonl +3 -0
  532. package/vendor/ars/scripts/fixtures/cross_model_codex_transport/missing_search.jsonl +2 -0
  533. package/vendor/ars/scripts/fixtures/cross_model_codex_transport/multiple_finals.jsonl +4 -0
  534. package/vendor/ars/scripts/fixtures/cross_model_codex_transport/not_found.jsonl +3 -0
  535. package/vendor/ars/scripts/fixtures/cross_model_codex_transport/unbound_source.jsonl +3 -0
  536. package/vendor/ars/scripts/fixtures/cross_model_codex_transport/wrong_search_shape.jsonl +3 -0
  537. package/vendor/ars/scripts/fixtures/evidence_rows/phase_e_inputs.json +114 -0
  538. package/vendor/ars/scripts/fixtures/evidence_rows/session_sources.json +5 -0
  539. package/vendor/ars/scripts/fixtures/human_subjects_authority/cross-border-us-tw-gdpr.json +71 -0
  540. package/vendor/ars/scripts/fixtures/human_subjects_authority/gdpr-member-state-unresolved.json +62 -0
  541. package/vendor/ars/scripts/fixtures/human_subjects_authority/missing-data-axis.json +45 -0
  542. package/vendor/ars/scripts/fixtures/human_subjects_authority/no-profile.json +33 -0
  543. package/vendor/ars/scripts/fixtures/human_subjects_authority/tw-gdpr-two-axis.json +74 -0
  544. package/vendor/ars/scripts/fixtures/human_subjects_authority/us-gdpr-two-axis.json +74 -0
  545. package/vendor/ars/scripts/fixtures/review_pathway_rule_trace/lint-near-misses.json +72 -0
  546. package/vendor/ars/scripts/fixtures/review_pathway_rule_trace/no-profile-request.json +18 -0
  547. package/vendor/ars/scripts/fixtures/review_pathway_rule_trace/tw-candidates-request.json +63 -0
  548. package/vendor/ars/scripts/fixtures/review_pathway_rule_trace/us-candidates-request.json +77 -0
  549. package/vendor/ars/scripts/fixtures/review_target_context/exact-declaration.json +24 -0
  550. package/vendor/ars/scripts/fixtures/review_target_context/field-general-declaration.json +24 -0
  551. package/vendor/ars/scripts/fixtures/review_target_context/msr-2027-technical-full-declaration.json +24 -0
  552. package/vendor/ars/scripts/fixtures/review_target_context/synthetic-registry.json +92 -0
  553. package/vendor/ars/scripts/fixtures/revision_claim_drift_v2/README.md +21 -0
  554. package/vendor/ars/scripts/fixtures/revision_claim_drift_v2/subject_context_attested_only.json +55 -0
  555. package/vendor/ars/scripts/fixtures/revision_claim_drift_v2/subject_context_machine_supported.json +49 -0
  556. package/vendor/ars/scripts/fixtures/revision_claim_drift_v2/subject_context_not_isolated.json +56 -0
  557. package/vendor/ars/scripts/fixtures/revision_claim_drift_v2/subject_context_unknown.json +49 -0
  558. package/vendor/ars/scripts/fixtures/submission_package/clean/paper.md +16 -0
  559. package/vendor/ars/scripts/fixtures/submission_package/clean/references.bib +13 -0
  560. package/vendor/ars/scripts/fixtures/submission_package/fallback_authoryear/paper.md +11 -0
  561. package/vendor/ars/scripts/fixtures/submission_package/fallback_authoryear/references.bib +13 -0
  562. package/vendor/ars/scripts/fixtures/submission_package/fallback_latex/paper.tex +9 -0
  563. package/vendor/ars/scripts/fixtures/submission_package/fallback_latex/references.bib +13 -0
  564. package/vendor/ars/scripts/fixtures/submission_package/marker_no_join/paper.md +7 -0
  565. package/vendor/ars/scripts/fixtures/submission_package/orphan_intext/paper.md +8 -0
  566. package/vendor/ars/scripts/fixtures/submission_package/orphan_intext/references.bib +6 -0
  567. package/vendor/ars/scripts/fixtures/submission_package/passports/corpus_only.yaml +9 -0
  568. package/vendor/ars/scripts/fixtures/submission_package/passports/summary_join.yaml +16 -0
  569. package/vendor/ars/scripts/fixtures/submission_package/profiles/full.yaml +15 -0
  570. package/vendor/ars/scripts/fixtures/submission_package/profiles/tight.yaml +15 -0
  571. package/vendor/ars/scripts/fixtures/submission_package/summary_join/paper.md +7 -0
  572. package/vendor/ars/scripts/fixtures/submission_package/uncited_reference/paper.md +9 -0
  573. package/vendor/ars/scripts/fixtures/submission_package/uncited_reference/references.bib +13 -0
  574. package/vendor/ars/scripts/fixtures/submission_package/venue_clean/paper.md +26 -0
  575. package/vendor/ars/scripts/fixtures/submission_package/venue_clean/references.bib +13 -0
  576. package/vendor/ars/scripts/fixtures/submission_package/venue_violations/paper.md +20 -0
  577. package/vendor/ars/scripts/fixtures/submission_package/venue_violations/references.bib +13 -0
  578. package/vendor/ars/scripts/fixtures/submission_packet_manifest/base_inventory.json +101 -0
  579. package/vendor/ars/scripts/fixtures/submission_packet_manifest/packet/consent-materials.txt +3 -0
  580. package/vendor/ars/scripts/fixtures/submission_packet_manifest/packet/training-certificate.txt +2 -0
  581. package/vendor/ars/scripts/fixtures/submission_packet_manifest/packet/tw-consent-materials.txt +3 -0
  582. package/vendor/ars/scripts/fixtures/tortured_phrase_screening/corpus_input.yaml +30 -0
  583. package/vendor/ars/scripts/fixtures/tortured_phrase_screening/own_draft.md +36 -0
  584. package/vendor/ars/scripts/fixtures/tortured_phrase_screening/own_draft.tex +21 -0
  585. package/vendor/ars/scripts/fixtures/tortured_phrase_screening/seed_expectations.json +218 -0
  586. package/vendor/ars/scripts/fixtures/tortured_phrase_screening/snapshot.json +164 -0
  587. package/vendor/ars/scripts/fixtures/tortured_phrase_screening/snapshot_manifest.json +29 -0
  588. package/vendor/ars/scripts/fixtures/transport_bodies/README.md +55 -0
  589. package/vendor/ars/scripts/fixtures/transport_bodies/arxiv/empty_feed.xml +10 -0
  590. package/vendor/ars/scripts/fixtures/transport_bodies/arxiv/error_5xx.html +7 -0
  591. package/vendor/ars/scripts/fixtures/transport_bodies/arxiv/id_hit.xml +26 -0
  592. package/vendor/ars/scripts/fixtures/transport_bodies/chinese_literature/README.md +69 -0
  593. package/vendor/ars/scripts/fixtures/transport_bodies/chinese_literature/cnki_landing_page.html +13 -0
  594. package/vendor/ars/scripts/fixtures/transport_bodies/chinese_literature/error_5xx.html +2 -0
  595. package/vendor/ars/scripts/fixtures/transport_bodies/chinese_literature/esearch_coordinate_ambiguous.json +16 -0
  596. package/vendor/ars/scripts/fixtures/transport_bodies/chinese_literature/esearch_coordinate_hit.json +16 -0
  597. package/vendor/ars/scripts/fixtures/transport_bodies/chinese_literature/esearch_coordinate_zero.json +14 -0
  598. package/vendor/ars/scripts/fixtures/transport_bodies/chinese_literature/esearch_coverage_hit.json +15 -0
  599. package/vendor/ars/scripts/fixtures/transport_bodies/chinese_literature/esearch_coverage_zero.json +13 -0
  600. package/vendor/ars/scripts/fixtures/transport_bodies/chinese_literature/esummary_hit.json +43 -0
  601. package/vendor/ars/scripts/fixtures/transport_bodies/chinese_literature/esummary_issn_mismatch.json +31 -0
  602. package/vendor/ars/scripts/fixtures/transport_bodies/chinese_literature/esummary_no_doi.json +31 -0
  603. package/vendor/ars/scripts/fixtures/transport_bodies/chinese_literature/esummary_unknown_ra.json +34 -0
  604. package/vendor/ars/scripts/fixtures/transport_bodies/chinese_literature/esummary_year_mismatch.json +31 -0
  605. package/vendor/ars/scripts/fixtures/transport_bodies/chinese_literature/handle_absent.json +4 -0
  606. package/vendor/ars/scripts/fixtures/transport_bodies/chinese_literature/handle_exists.json +16 -0
  607. package/vendor/ars/scripts/fixtures/transport_bodies/chinese_literature/handle_internal_error.json +4 -0
  608. package/vendor/ars/scripts/fixtures/transport_bodies/chinese_literature/istic_csl_hit.json +25 -0
  609. package/vendor/ars/scripts/fixtures/transport_bodies/chinese_literature/istic_csl_other_title.json +18 -0
  610. package/vendor/ars/scripts/fixtures/transport_bodies/chinese_literature/ra_cnki.json +6 -0
  611. package/vendor/ars/scripts/fixtures/transport_bodies/chinese_literature/ra_crossref.json +6 -0
  612. package/vendor/ars/scripts/fixtures/transport_bodies/chinese_literature/ra_istic.json +6 -0
  613. package/vendor/ars/scripts/fixtures/transport_bodies/chinese_literature/ra_unknown_prefix.json +6 -0
  614. package/vendor/ars/scripts/fixtures/transport_bodies/crossref/doi_hit.json +24 -0
  615. package/vendor/ars/scripts/fixtures/transport_bodies/crossref/error_5xx.html +7 -0
  616. package/vendor/ars/scripts/fixtures/transport_bodies/crossref/title_search_miss.json +15 -0
  617. package/vendor/ars/scripts/fixtures/transport_bodies/openalex/doi_hit.json +29 -0
  618. package/vendor/ars/scripts/fixtures/transport_bodies/openalex/error_5xx.json +4 -0
  619. package/vendor/ars/scripts/fixtures/transport_bodies/openalex/title_search_miss.json +11 -0
  620. package/vendor/ars/scripts/fixtures/transport_bodies/semantic_scholar/doi_hit.json +14 -0
  621. package/vendor/ars/scripts/fixtures/transport_bodies/semantic_scholar/error_5xx.json +3 -0
  622. package/vendor/ars/scripts/fixtures/transport_bodies/semantic_scholar/title_search_miss.json +5 -0
  623. package/vendor/ars/scripts/human_read_attestation_resolver.py +467 -0
  624. package/vendor/ars/scripts/ideation_diversity_assignment_gate.py +430 -0
  625. package/vendor/ars/scripts/inquiry_branch_ledger.py +2540 -0
  626. package/vendor/ars/scripts/legacy/ars_apply_revision_patch_v1_0.py +715 -0
  627. package/vendor/ars/scripts/legacy/check_re_review_synthesis_v1_0.py +2215 -0
  628. package/vendor/ars/scripts/migrate_literature_corpus_to_v3_10.py +223 -0
  629. package/vendor/ars/scripts/migrate_literature_corpus_to_v3_7_3.py +277 -0
  630. package/vendor/ars/scripts/migrate_literature_corpus_to_v3_9_0.py +304 -0
  631. package/vendor/ars/scripts/model_tiering_manifest.json +46 -0
  632. package/vendor/ars/scripts/openalex_client.py +232 -0
  633. package/vendor/ars/scripts/parse_audit_verdict.py +802 -0
  634. package/vendor/ars/scripts/pdf_content_classifier_worker.py +176 -0
  635. package/vendor/ars/scripts/pdf_read_preflight.py +1455 -0
  636. package/vendor/ars/scripts/policy_anchor_disclosure_referee.py +354 -0
  637. package/vendor/ars/scripts/recompute_receipts.py +1414 -0
  638. package/vendor/ars/scripts/render_claim_standing_view.py +374 -0
  639. package/vendor/ars/scripts/render_eval_comment.py +130 -0
  640. package/vendor/ars/scripts/render_harness_retirement_issue.py +167 -0
  641. package/vendor/ars/scripts/repro_lock_validation.py +90 -0
  642. package/vendor/ars/scripts/research_workflow_profile.py +1079 -0
  643. package/vendor/ars/scripts/resolve_human_subjects_authority.py +1158 -0
  644. package/vendor/ars/scripts/resolve_review_target_context.py +683 -0
  645. package/vendor/ars/scripts/resume_e4_record.py +509 -0
  646. package/vendor/ars/scripts/retraction_status.py +484 -0
  647. package/vendor/ars/scripts/review_criteria_binding.py +889 -0
  648. package/vendor/ars/scripts/review_panel_provenance.py +744 -0
  649. package/vendor/ars/scripts/revision_roadmap.py +1967 -0
  650. package/vendor/ars/scripts/run_ci_pytest_manifest.py +116 -0
  651. package/vendor/ars/scripts/run_codex_audit.sh +1191 -0
  652. package/vendor/ars/scripts/run_evals.py +513 -0
  653. package/vendor/ars/scripts/run_ideation_diversity_no_call.py +3505 -0
  654. package/vendor/ars/scripts/run_indirect_prompt_injection_no_call.py +3330 -0
  655. package/vendor/ars/scripts/run_indirect_prompt_injection_probe.py +399 -0
  656. package/vendor/ars/scripts/run_review_criteria_constructive_value.py +1895 -0
  657. package/vendor/ars/scripts/run_role_topology_utility_dry_run.py +606 -0
  658. package/vendor/ars/scripts/score_review_criteria_constructive_value.py +617 -0
  659. package/vendor/ars/scripts/semantic_scholar_client.py +291 -0
  660. package/vendor/ars/scripts/slr_lineage.py +59 -0
  661. package/vendor/ars/scripts/sync_adapter_docs.py +118 -0
  662. package/vendor/ars/scripts/temporal_integrity_audit.py +840 -0
  663. package/vendor/ars/scripts/test_431_exact_or_bust.py +253 -0
  664. package/vendor/ars/scripts/test__eval_threshold_gate.py +125 -0
  665. package/vendor/ars/scripts/test__markdown_lint_util.py +129 -0
  666. package/vendor/ars/scripts/test__next_verified_at_ms.py +256 -0
  667. package/vendor/ars/scripts/test_adjacent_framing_probe_lint.py +171 -0
  668. package/vendor/ars/scripts/test_adjudication_activity.py +1515 -0
  669. package/vendor/ars/scripts/test_ars_anchorize_draft.py +178 -0
  670. package/vendor/ars/scripts/test_ars_apply_revision_patch.py +1335 -0
  671. package/vendor/ars/scripts/test_ars_cache_invalidate.py +51 -0
  672. package/vendor/ars/scripts/test_ars_mark_read.py +910 -0
  673. package/vendor/ars/scripts/test_ars_update_check.py +816 -0
  674. package/vendor/ars/scripts/test_ars_write_scope_guard.py +790 -0
  675. package/vendor/ars/scripts/test_arxiv_client.py +374 -0
  676. package/vendor/ars/scripts/test_audit_schemas.py +560 -0
  677. package/vendor/ars/scripts/test_audit_snapshot_render_section_0.py +105 -0
  678. package/vendor/ars/scripts/test_block_parser.py +259 -0
  679. package/vendor/ars/scripts/test_bootstrap_timeline_yaml.py +148 -0
  680. package/vendor/ars/scripts/test_build_claim_standing_candidate_ledger.py +1203 -0
  681. package/vendor/ars/scripts/test_build_claim_standing_query_plan.py +791 -0
  682. package/vendor/ars/scripts/test_build_submission_packet_manifest.py +2644 -0
  683. package/vendor/ars/scripts/test_check_215_field_norm.py +238 -0
  684. package/vendor/ars/scripts/test_check_216_surface_form.py +341 -0
  685. package/vendor/ars/scripts/test_check_268_nested_commitment_ledger.py +194 -0
  686. package/vendor/ars/scripts/test_check_390_revision_patch_discipline.py +279 -0
  687. package/vendor/ars/scripts/test_check_392_citation_verification_intake.py +144 -0
  688. package/vendor/ars/scripts/test_check_394_submission_policy.py +200 -0
  689. package/vendor/ars/scripts/test_check_439_format_profile.py +252 -0
  690. package/vendor/ars/scripts/test_check_619_disclosure_closeout.py +158 -0
  691. package/vendor/ars/scripts/test_check_630_codex_subscription_transport.py +245 -0
  692. package/vendor/ars/scripts/test_check_669_review_pathway_rule_trace.py +304 -0
  693. package/vendor/ars/scripts/test_check_670_revision_roadmap_integration.py +260 -0
  694. package/vendor/ars/scripts/test_check_673_adjudication_activity.py +367 -0
  695. package/vendor/ars/scripts/test_check_684_review_criteria_binding.py +274 -0
  696. package/vendor/ars/scripts/test_check_agents_mirror_sync.py +137 -0
  697. package/vendor/ars/scripts/test_check_audit_artifact_consistency.py +2133 -0
  698. package/vendor/ars/scripts/test_check_benchmark_report.py +117 -0
  699. package/vendor/ars/scripts/test_check_bibliographic_integrity_signals.py +609 -0
  700. package/vendor/ars/scripts/test_check_calibration_tiers.py +376 -0
  701. package/vendor/ars/scripts/test_check_changelog_covers_merges.py +509 -0
  702. package/vendor/ars/scripts/test_check_ci_pytest_manifest.py +425 -0
  703. package/vendor/ars/scripts/test_check_claim_standing_candidate_ledger_integration.py +256 -0
  704. package/vendor/ars/scripts/test_check_claim_standing_freshness.py +277 -0
  705. package/vendor/ars/scripts/test_check_collaboration_depth_rubric.py +239 -0
  706. package/vendor/ars/scripts/test_check_command_frontmatter_name.py +178 -0
  707. package/vendor/ars/scripts/test_check_committee_correspondence.py +298 -0
  708. package/vendor/ars/scripts/test_check_compliance_report.py +381 -0
  709. package/vendor/ars/scripts/test_check_content_coverage_advisory_integration.py +308 -0
  710. package/vendor/ars/scripts/test_check_control_availability.py +361 -0
  711. package/vendor/ars/scripts/test_check_cross_document_consistency_advisory_integration.py +698 -0
  712. package/vendor/ars/scripts/test_check_cross_model_handoff_contract.py +301 -0
  713. package/vendor/ars/scripts/test_check_cross_model_verification_sync.py +203 -0
  714. package/vendor/ars/scripts/test_check_data_access_level.py +227 -0
  715. package/vendor/ars/scripts/test_check_data_flows.py +382 -0
  716. package/vendor/ars/scripts/test_check_decision_contract.py +387 -0
  717. package/vendor/ars/scripts/test_check_degradation_registry.py +270 -0
  718. package/vendor/ars/scripts/test_check_distribution_surface_claims.py +225 -0
  719. package/vendor/ars/scripts/test_check_domain_evidence_profile.py +439 -0
  720. package/vendor/ars/scripts/test_check_e4_promotion.py +163 -0
  721. package/vendor/ars/scripts/test_check_evals_gold_set.py +312 -0
  722. package/vendor/ars/scripts/test_check_evidence_row_integration.py +187 -0
  723. package/vendor/ars/scripts/test_check_field_norm_severity.py +173 -0
  724. package/vendor/ars/scripts/test_check_firm_rules_sync.py +342 -0
  725. package/vendor/ars/scripts/test_check_heldout_measurement_report.py +1508 -0
  726. package/vendor/ars/scripts/test_check_human_subjects_output_contract.py +129 -0
  727. package/vendor/ars/scripts/test_check_human_subjects_reference_migration.py +756 -0
  728. package/vendor/ars/scripts/test_check_instruction_data_boundary.py +204 -0
  729. package/vendor/ars/scripts/test_check_judge_prompt_version.py +90 -0
  730. package/vendor/ars/scripts/test_check_model_tiering.py +236 -0
  731. package/vendor/ars/scripts/test_check_panel_synthesis.py +1658 -0
  732. package/vendor/ars/scripts/test_check_passport_reset_contract.py +249 -0
  733. package/vendor/ars/scripts/test_check_pattern_eval_manifest.py +381 -0
  734. package/vendor/ars/scripts/test_check_persuasion_invariance_fixtures.py +591 -0
  735. package/vendor/ars/scripts/test_check_phase_conformance.py +4366 -0
  736. package/vendor/ars/scripts/test_check_pipeline_boundary_semantics.py +931 -0
  737. package/vendor/ars/scripts/test_check_pipeline_integrity.py +243 -0
  738. package/vendor/ars/scripts/test_check_policy_anchor_protocol.py +236 -0
  739. package/vendor/ars/scripts/test_check_policy_anchor_table.py +295 -0
  740. package/vendor/ars/scripts/test_check_prisma_trAIce_freshness.py +68 -0
  741. package/vendor/ars/scripts/test_check_promotion_bakeoff_preregistration.py +799 -0
  742. package/vendor/ars/scripts/test_check_ranking_lift.py +377 -0
  743. package/vendor/ars/scripts/test_check_re_review_synthesis.py +3398 -0
  744. package/vendor/ars/scripts/test_check_receipt_enum_sync.py +176 -0
  745. package/vendor/ars/scripts/test_check_repro_lock.py +107 -0
  746. package/vendor/ars/scripts/test_check_reviewer_data_fences.py +334 -0
  747. package/vendor/ars/scripts/test_check_reviewer_finding_contract.py +1107 -0
  748. package/vendor/ars/scripts/test_check_reviewer_role_label.py +491 -0
  749. package/vendor/ars/scripts/test_check_reviewer_scoring_honesty.py +222 -0
  750. package/vendor/ars/scripts/test_check_reviewer_sprint_prompt_sync.py +373 -0
  751. package/vendor/ars/scripts/test_check_revision_claim_drift_suite_v2.py +1925 -0
  752. package/vendor/ars/scripts/test_check_revision_token_conservation.py +398 -0
  753. package/vendor/ars/scripts/test_check_risk_register.py +336 -0
  754. package/vendor/ars/scripts/test_check_role_scoped_contract.py +1104 -0
  755. package/vendor/ars/scripts/test_check_rq_framing_patterns.py +110 -0
  756. package/vendor/ars/scripts/test_check_rubric_weight_consistency.py +32 -0
  757. package/vendor/ars/scripts/test_check_seeded_defect_fixtures.py +392 -0
  758. package/vendor/ars/scripts/test_check_setup_cross_model_parity.py +121 -0
  759. package/vendor/ars/scripts/test_check_spec_consistency.py +1081 -0
  760. package/vendor/ars/scripts/test_check_sprint_contract.py +458 -0
  761. package/vendor/ars/scripts/test_check_stage_capability_matrix.py +698 -0
  762. package/vendor/ars/scripts/test_check_submission_packet_manifest_integration.py +177 -0
  763. package/vendor/ars/scripts/test_check_surface_form_parity.py +417 -0
  764. package/vendor/ars/scripts/test_check_task_type.py +116 -0
  765. package/vendor/ars/scripts/test_check_tools_allowlist.py +835 -0
  766. package/vendor/ars/scripts/test_check_tortured_phrase_screening_integration.py +1306 -0
  767. package/vendor/ars/scripts/test_check_v3_10_134_write_scope.py +251 -0
  768. package/vendor/ars/scripts/test_check_v3_10_policy.py +547 -0
  769. package/vendor/ars/scripts/test_check_v3_6_7_pattern_protection.py +960 -0
  770. package/vendor/ars/scripts/test_check_v3_6_8_audit_scope_block.py +1000 -0
  771. package/vendor/ars/scripts/test_check_v3_6_8_cite_provenance_pipeline.py +454 -0
  772. package/vendor/ars/scripts/test_check_v3_6_8_frontmatter_trust_schema.py +581 -0
  773. package/vendor/ars/scripts/test_check_v3_6_8_mark_read_commands.py +120 -0
  774. package/vendor/ars/scripts/test_check_v3_6_8_pattern_protection.py +1138 -0
  775. package/vendor/ars/scripts/test_check_v3_7_3_three_layer_citation.py +566 -0
  776. package/vendor/ars/scripts/test_check_v3_8_annotation_literal_sync.py +262 -0
  777. package/vendor/ars/scripts/test_check_v3_9_0_triangulation.py +321 -0
  778. package/vendor/ars/scripts/test_check_v3_9_2_phase_boundary.py +190 -0
  779. package/vendor/ars/scripts/test_check_v3_9_4_temporal_verification.py +471 -0
  780. package/vendor/ars/scripts/test_check_version_consistency.py +1462 -0
  781. package/vendor/ars/scripts/test_check_workflow_classification.py +225 -0
  782. package/vendor/ars/scripts/test_chinese_literature_client.py +1889 -0
  783. package/vendor/ars/scripts/test_citation_existence_policy.py +480 -0
  784. package/vendor/ars/scripts/test_citation_verification_summary.py +342 -0
  785. package/vendor/ars/scripts/test_claim_audit_calibration.py +882 -0
  786. package/vendor/ars/scripts/test_claim_audit_finalizer.py +979 -0
  787. package/vendor/ars/scripts/test_claim_audit_pipeline.py +2398 -0
  788. package/vendor/ars/scripts/test_claim_audit_schema.py +1778 -0
  789. package/vendor/ars/scripts/test_claim_intent_manifest.py +666 -0
  790. package/vendor/ars/scripts/test_claim_registry_coverage.py +246 -0
  791. package/vendor/ars/scripts/test_claim_standing_discovery.py +579 -0
  792. package/vendor/ars/scripts/test_claim_standing_pipeline_wiring.py +290 -0
  793. package/vendor/ars/scripts/test_claim_standing_stance_assets.py +399 -0
  794. package/vendor/ars/scripts/test_claim_standing_stance_contracts.py +383 -0
  795. package/vendor/ars/scripts/test_claim_standing_stance_runner.py +349 -0
  796. package/vendor/ars/scripts/test_claim_standing_transmissions.py +605 -0
  797. package/vendor/ars/scripts/test_claim_strength_drift_disposition.py +517 -0
  798. package/vendor/ars/scripts/test_claim_verification_coverage_contract.py +104 -0
  799. package/vendor/ars/scripts/test_contamination_signals.py +1086 -0
  800. package/vendor/ars/scripts/test_content_coverage_advisory.py +1767 -0
  801. package/vendor/ars/scripts/test_cross_document_consistency_advisory.py +1270 -0
  802. package/vendor/ars/scripts/test_cross_model_codex_transport.py +1152 -0
  803. package/vendor/ars/scripts/test_cross_model_handoff.py +571 -0
  804. package/vendor/ars/scripts/test_cross_model_verification_guards.py +792 -0
  805. package/vendor/ars/scripts/test_crossref_client.py +393 -0
  806. package/vendor/ars/scripts/test_dispatch_e4_panel.py +4235 -0
  807. package/vendor/ars/scripts/test_e2e_claim_audit.py +540 -0
  808. package/vendor/ars/scripts/test_eval_harness_workflow.py +140 -0
  809. package/vendor/ars/scripts/test_evals_citation_extraction.py +150 -0
  810. package/vendor/ars/scripts/test_evals_lift_report_schema.py +108 -0
  811. package/vendor/ars/scripts/test_evidence_rows.py +2593 -0
  812. package/vendor/ars/scripts/test_experiment_provenance.py +915 -0
  813. package/vendor/ars/scripts/test_human_read_attestation_resolver.py +477 -0
  814. package/vendor/ars/scripts/test_ideation_diversity_assignment_gate.py +615 -0
  815. package/vendor/ars/scripts/test_indirect_prompt_injection_behavior_probe.py +250 -0
  816. package/vendor/ars/scripts/test_inquiry_branch_ledger.py +2296 -0
  817. package/vendor/ars/scripts/test_migrate_literature_corpus_to_v3_10.py +248 -0
  818. package/vendor/ars/scripts/test_migrate_literature_corpus_to_v3_7_3.py +545 -0
  819. package/vendor/ars/scripts/test_migrate_literature_corpus_to_v3_9_0.py +497 -0
  820. package/vendor/ars/scripts/test_normalize_compat_verdict.py +149 -0
  821. package/vendor/ars/scripts/test_openalex_client.py +490 -0
  822. package/vendor/ars/scripts/test_passport_yaml.py +104 -0
  823. package/vendor/ars/scripts/test_pattern_eval_runtime.py +1295 -0
  824. package/vendor/ars/scripts/test_pdf_read_preflight.py +1943 -0
  825. package/vendor/ars/scripts/test_policy_anchor_disclosure.py +666 -0
  826. package/vendor/ars/scripts/test_reading_probe_lint.py +218 -0
  827. package/vendor/ars/scripts/test_recompute_receipts.py +778 -0
  828. package/vendor/ars/scripts/test_render_claim_standing_view.py +192 -0
  829. package/vendor/ars/scripts/test_render_eval_comment.py +162 -0
  830. package/vendor/ars/scripts/test_render_harness_retirement_issue.py +110 -0
  831. package/vendor/ars/scripts/test_repro_lock_validation_drift.py +100 -0
  832. package/vendor/ars/scripts/test_research_workflow_profile.py +734 -0
  833. package/vendor/ars/scripts/test_resolve_human_subjects_authority.py +1219 -0
  834. package/vendor/ars/scripts/test_resolve_review_target_context.py +703 -0
  835. package/vendor/ars/scripts/test_resume_e4_record.py +315 -0
  836. package/vendor/ars/scripts/test_retraction_status.py +456 -0
  837. package/vendor/ars/scripts/test_review_criteria_binding.py +629 -0
  838. package/vendor/ars/scripts/test_review_panel_provenance.py +565 -0
  839. package/vendor/ars/scripts/test_review_pathway_rule_trace.py +821 -0
  840. package/vendor/ars/scripts/test_revision_roadmap.py +1255 -0
  841. package/vendor/ars/scripts/test_run_ci_pytest_manifest.py +186 -0
  842. package/vendor/ars/scripts/test_run_codex_audit_e2e.py +369 -0
  843. package/vendor/ars/scripts/test_run_evals.py +430 -0
  844. package/vendor/ars/scripts/test_run_guard_launcher.py +500 -0
  845. package/vendor/ars/scripts/test_run_ideation_diversity_no_call.py +1833 -0
  846. package/vendor/ars/scripts/test_run_indirect_prompt_injection_no_call.py +1889 -0
  847. package/vendor/ars/scripts/test_run_review_criteria_constructive_value.py +586 -0
  848. package/vendor/ars/scripts/test_run_role_topology_utility_dry_run.py +428 -0
  849. package/vendor/ars/scripts/test_score_review_criteria_constructive_value.py +340 -0
  850. package/vendor/ars/scripts/test_semantic_scholar_client.py +554 -0
  851. package/vendor/ars/scripts/test_slr_lineage_emission.py +230 -0
  852. package/vendor/ars/scripts/test_socratic_rq_non_generation_contract.py +173 -0
  853. package/vendor/ars/scripts/test_temporal_integrity_audit.py +438 -0
  854. package/vendor/ars/scripts/test_text_similarity.py +95 -0
  855. package/vendor/ars/scripts/test_title_fuzzy_false_positive.py +111 -0
  856. package/vendor/ars/scripts/test_tortured_phrase_screening.py +2959 -0
  857. package/vendor/ars/scripts/test_transport_fixture_citation_gate.py +338 -0
  858. package/vendor/ars/scripts/test_uncited_assertion.py +558 -0
  859. package/vendor/ars/scripts/test_v3_6_7_phase_6_6.py +1279 -0
  860. package/vendor/ars/scripts/test_validate_compliance_fixtures.py +36 -0
  861. package/vendor/ars/scripts/test_validate_ideation_diversity_assets.py +230 -0
  862. package/vendor/ars/scripts/test_venue_disclosure_contract.py +755 -0
  863. package/vendor/ars/scripts/test_verification_cache.py +280 -0
  864. package/vendor/ars/scripts/test_verification_gate.py +461 -0
  865. package/vendor/ars/scripts/test_verify_passport_cli.py +123 -0
  866. package/vendor/ars/scripts/test_verify_submission_package.py +1407 -0
  867. package/vendor/ars/scripts/test_version_records_schema.py +211 -0
  868. package/vendor/ars/scripts/tortured_phrase_screening.py +3502 -0
  869. package/vendor/ars/scripts/uncited_assertion_detector.py +254 -0
  870. package/vendor/ars/scripts/v3_6_7_inversion_manifest.json +9 -0
  871. package/vendor/ars/scripts/v3_6_8_inversion_manifest.json +10 -0
  872. package/vendor/ars/scripts/validate_claim_standing_stance_assets.py +249 -0
  873. package/vendor/ars/scripts/validate_compliance_fixtures.py +56 -0
  874. package/vendor/ars/scripts/validate_ideation_diversity_assets.py +303 -0
  875. package/vendor/ars/scripts/venue_disclosure_contract_harness.py +837 -0
  876. package/vendor/ars/scripts/verification_cache.py +276 -0
  877. package/vendor/ars/scripts/verification_gate/__init__.py +345 -0
  878. package/vendor/ars/scripts/verify_passport.py +133 -0
  879. package/vendor/ars/scripts/verify_submission_package.py +1657 -0
  880. package/vendor/ars/shared/agents/compliance_agent.md +136 -0
  881. package/vendor/ars/shared/artifact_reproducibility_pattern.md +173 -0
  882. package/vendor/ars/shared/benchmark_report.schema.json +81 -0
  883. package/vendor/ars/shared/benchmark_report_pattern.md +180 -0
  884. package/vendor/ars/shared/bibliographic_integrity_signals.md +142 -0
  885. package/vendor/ars/shared/collaboration_depth_rubric.md +154 -0
  886. package/vendor/ars/shared/compliance_checkpoint_protocol.md +162 -0
  887. package/vendor/ars/shared/compliance_report.schema.json +187 -0
  888. package/vendor/ars/shared/contracts/README.md +938 -0
  889. package/vendor/ars/shared/contracts/activity/adjudication_activity_input.schema.json +555 -0
  890. package/vendor/ars/shared/contracts/activity/adjudication_activity_store.schema.json +560 -0
  891. package/vendor/ars/shared/contracts/audit/audit_jsonl.schema.json +128 -0
  892. package/vendor/ars/shared/contracts/audit/audit_sidecar.schema.json +169 -0
  893. package/vendor/ars/shared/contracts/audit/audit_verdict.schema.json +133 -0
  894. package/vendor/ars/shared/contracts/audit/cross_document_consistency_advisory.schema.json +480 -0
  895. package/vendor/ars/shared/contracts/audit/cross_document_consistency_advisory_draft.schema.json +564 -0
  896. package/vendor/ars/shared/contracts/audit/cross_document_source_manifest.schema.json +202 -0
  897. package/vendor/ars/shared/contracts/audit/tortured_phrase_advisory.schema.json +1362 -0
  898. package/vendor/ars/shared/contracts/audit/tortured_phrase_snapshot.schema.json +208 -0
  899. package/vendor/ars/shared/contracts/audit/tortured_phrase_snapshot_manifest.schema.json +335 -0
  900. package/vendor/ars/shared/contracts/capability/stage_capability_matrix.json +434 -0
  901. package/vendor/ars/shared/contracts/claim_standing/candidate_ledger.schema.json +705 -0
  902. package/vendor/ars/shared/contracts/claim_standing/query_plan.schema.json +389 -0
  903. package/vendor/ars/shared/contracts/claim_standing/query_plan_v1_1.schema.json +782 -0
  904. package/vendor/ars/shared/contracts/claim_standing/retrieval_input.schema.json +440 -0
  905. package/vendor/ars/shared/contracts/claim_standing/stance_record.schema.json +460 -0
  906. package/vendor/ars/shared/contracts/claim_standing/transmission_ledger.schema.json +282 -0
  907. package/vendor/ars/shared/contracts/cross_model/codex_citation_receipt.schema.json +157 -0
  908. package/vendor/ars/shared/contracts/cross_model/codex_citation_request.schema.json +23 -0
  909. package/vendor/ars/shared/contracts/cross_model/promotion_bakeoff_sealed_commitment.schema.json +55 -0
  910. package/vendor/ars/shared/contracts/cross_model/promotion_bakeoff_sealed_reveal.schema.json +50 -0
  911. package/vendor/ars/shared/contracts/degradation_registry.json +428 -0
  912. package/vendor/ars/shared/contracts/evaluator/full.json +126 -0
  913. package/vendor/ars/shared/contracts/evidence/claim_registry.schema.json +50 -0
  914. package/vendor/ars/shared/contracts/evidence/claim_registry_coverage_report.schema.json +79 -0
  915. package/vendor/ars/shared/contracts/evidence/evidence_row.schema.json +504 -0
  916. package/vendor/ars/shared/contracts/evidence/evidence_row_v1_1.schema.json +364 -0
  917. package/vendor/ars/shared/contracts/evidence/evidence_row_v1_2.schema.json +714 -0
  918. package/vendor/ars/shared/contracts/evidence/evidence_row_v1_3.schema.json +524 -0
  919. package/vendor/ars/shared/contracts/human_subjects/authority_profile_registry.schema.json +497 -0
  920. package/vendor/ars/shared/contracts/human_subjects/committee_correspondence.schema.json +253 -0
  921. package/vendor/ars/shared/contracts/human_subjects/content_coverage_advisory.schema.json +620 -0
  922. package/vendor/ars/shared/contracts/human_subjects/irb_context_record.schema.json +329 -0
  923. package/vendor/ars/shared/contracts/human_subjects/resolved_authority_context.schema.json +347 -0
  924. package/vendor/ars/shared/contracts/human_subjects/review_pathway_rule_trace.schema.json +265 -0
  925. package/vendor/ars/shared/contracts/human_subjects/review_pathway_trace_request.schema.json +127 -0
  926. package/vendor/ars/shared/contracts/human_subjects/submission_packet_inventory.schema.json +240 -0
  927. package/vendor/ars/shared/contracts/human_subjects/submission_packet_manifest.schema.json +999 -0
  928. package/vendor/ars/shared/contracts/passport/audit_artifact_entry.schema.json +266 -0
  929. package/vendor/ars/shared/contracts/passport/bibliographic_integrity_signal.schema.json +1676 -0
  930. package/vendor/ars/shared/contracts/passport/citation_provenance.schema.json +107 -0
  931. package/vendor/ars/shared/contracts/passport/citation_verification_summary.schema.json +164 -0
  932. package/vendor/ars/shared/contracts/passport/claim_audit_result.schema.json +124 -0
  933. package/vendor/ars/shared/contracts/passport/claim_drift.schema.json +58 -0
  934. package/vendor/ars/shared/contracts/passport/claim_intent_manifest.schema.json +107 -0
  935. package/vendor/ars/shared/contracts/passport/constraint_violation.schema.json +65 -0
  936. package/vendor/ars/shared/contracts/passport/experiment_alignment_result.schema.json +69 -0
  937. package/vendor/ars/shared/contracts/passport/experiment_provenance_entry.schema.json +169 -0
  938. package/vendor/ars/shared/contracts/passport/human_read_log.schema.json +86 -0
  939. package/vendor/ars/shared/contracts/passport/inquiry_ledger_ref.schema.json +22 -0
  940. package/vendor/ars/shared/contracts/passport/literature_corpus_entry.schema.json +650 -0
  941. package/vendor/ars/shared/contracts/passport/preregistration_artifact.schema.json +132 -0
  942. package/vendor/ars/shared/contracts/passport/rejection_log.schema.json +89 -0
  943. package/vendor/ars/shared/contracts/passport/reset_ledger_entry.schema.json +158 -0
  944. package/vendor/ars/shared/contracts/passport/temporal_audit_results.schema.json +208 -0
  945. package/vendor/ars/shared/contracts/passport/terminal_policies.schema.json +50 -0
  946. package/vendor/ars/shared/contracts/passport/timeline.schema.json +102 -0
  947. package/vendor/ars/shared/contracts/passport/uncited_assertion.schema.json +56 -0
  948. package/vendor/ars/shared/contracts/passport/uncited_audit_failure.schema.json +72 -0
  949. package/vendor/ars/shared/contracts/passport/user_attested_read_resolution.schema.json +87 -0
  950. package/vendor/ars/shared/contracts/passport/version_records.schema.json +138 -0
  951. package/vendor/ars/shared/contracts/patch/block_manifest.schema.json +45 -0
  952. package/vendor/ars/shared/contracts/patch/legacy/v1_0/revision_patch.schema.json +110 -0
  953. package/vendor/ars/shared/contracts/patch/revision_patch.schema.json +250 -0
  954. package/vendor/ars/shared/contracts/pdf/pdf_content_classifier_diagnostic.schema.json +39 -0
  955. package/vendor/ars/shared/contracts/pdf/pdf_content_classifier_worker.schema.json +88 -0
  956. package/vendor/ars/shared/contracts/pdf/pdf_read_preflight.schema.json +227 -0
  957. package/vendor/ars/shared/contracts/re_review/input_manifest.schema.json +161 -0
  958. package/vendor/ars/shared/contracts/re_review/legacy/v1_0/input_manifest.schema.json +134 -0
  959. package/vendor/ars/shared/contracts/re_review/legacy/v1_0/precommitment.schema.json +193 -0
  960. package/vendor/ars/shared/contracts/re_review/legacy/v1_0/traceability.schema.json +841 -0
  961. package/vendor/ars/shared/contracts/re_review/legacy/v1_0/verdict_record.schema.json +244 -0
  962. package/vendor/ars/shared/contracts/re_review/precommitment.schema.json +193 -0
  963. package/vendor/ars/shared/contracts/re_review/traceability.schema.json +916 -0
  964. package/vendor/ars/shared/contracts/re_review/verdict_record.schema.json +245 -0
  965. package/vendor/ars/shared/contracts/research_workflow/inquiry_branch_ledger.schema.json +449 -0
  966. package/vendor/ars/shared/contracts/research_workflow/research_workflow_profile.schema.json +222 -0
  967. package/vendor/ars/shared/contracts/research_workflow/research_workflow_profile_selection_receipt.schema.json +111 -0
  968. package/vendor/ars/shared/contracts/review_target/constructive_review_findings.schema.json +172 -0
  969. package/vendor/ars/shared/contracts/review_target/criteria_registry.schema.json +97 -0
  970. package/vendor/ars/shared/contracts/review_target/review_criteria_binding_manifest.schema.json +235 -0
  971. package/vendor/ars/shared/contracts/review_target/review_criteria_source_receipt.schema.json +158 -0
  972. package/vendor/ars/shared/contracts/review_target/review_target_context.schema.json +106 -0
  973. package/vendor/ars/shared/contracts/review_target/review_target_declaration.schema.json +118 -0
  974. package/vendor/ars/shared/contracts/reviewer/full.json +114 -0
  975. package/vendor/ars/shared/contracts/reviewer/methodology_focus.json +75 -0
  976. package/vendor/ars/shared/contracts/reviewer/review_panel_provenance.schema.json +263 -0
  977. package/vendor/ars/shared/contracts/reviewer/review_panel_provenance_carrier.schema.json +122 -0
  978. package/vendor/ars/shared/contracts/reviewer/review_panel_provenance_input.schema.json +120 -0
  979. package/vendor/ars/shared/contracts/revision/author_adjudication.schema.json +251 -0
  980. package/vendor/ars/shared/contracts/revision/author_adjudication_input.schema.json +25 -0
  981. package/vendor/ars/shared/contracts/revision/claim_strength_drift_disposition.schema.json +97 -0
  982. package/vendor/ars/shared/contracts/revision/claim_strength_drift_disposition_input.schema.json +80 -0
  983. package/vendor/ars/shared/contracts/revision/claim_strength_drift_findings.schema.json +139 -0
  984. package/vendor/ars/shared/contracts/revision/claim_surface_manifest.schema.json +99 -0
  985. package/vendor/ars/shared/contracts/revision/integrity_correction_authorization.schema.json +140 -0
  986. package/vendor/ars/shared/contracts/revision/integrity_correction_authorization_input.schema.json +28 -0
  987. package/vendor/ars/shared/contracts/revision/integrity_correction_list.schema.json +48 -0
  988. package/vendor/ars/shared/contracts/revision/integrity_pass_receipt.schema.json +16 -0
  989. package/vendor/ars/shared/contracts/revision/revision_evidence_bundle.schema.json +134 -0
  990. package/vendor/ars/shared/contracts/revision/revision_roadmap.schema.json +334 -0
  991. package/vendor/ars/shared/contracts/submission/format_profile.example.yaml +33 -0
  992. package/vendor/ars/shared/contracts/submission/format_profile.schema.json +102 -0
  993. package/vendor/ars/shared/contracts/submission/submission_verification_report.schema.json +233 -0
  994. package/vendor/ars/shared/contracts/submission/venue_profile.schema.json +114 -0
  995. package/vendor/ars/shared/contracts/writer/full.json +87 -0
  996. package/vendor/ars/shared/cross_model_verification.md +714 -0
  997. package/vendor/ars/shared/evals_lift_report.schema.json +141 -0
  998. package/vendor/ars/shared/ground_truth_isolation_pattern.md +275 -0
  999. package/vendor/ars/shared/handoff_schemas.md +1209 -0
  1000. package/vendor/ars/shared/human_subjects_authority_registry.json +1278 -0
  1001. package/vendor/ars/shared/mode_spectrum.md +57 -0
  1002. package/vendor/ars/shared/model_tiering.md +83 -0
  1003. package/vendor/ars/shared/policy_data/nature_policy.md +56 -0
  1004. package/vendor/ars/shared/prisma_trAIce_protocol.md +157 -0
  1005. package/vendor/ars/shared/raise_framework.md +129 -0
  1006. package/vendor/ars/shared/references/authority_content_coverage_advisory_protocol.md +275 -0
  1007. package/vendor/ars/shared/references/claim_standing_candidate_ledger_protocol.md +66 -0
  1008. package/vendor/ars/shared/references/claim_strength_ladder.md +93 -0
  1009. package/vendor/ars/shared/references/cross_document_consistency_advisory_protocol.md +263 -0
  1010. package/vendor/ars/shared/references/evidence_row_protocol.md +260 -0
  1011. package/vendor/ars/shared/references/firm_rules.md +90 -0
  1012. package/vendor/ars/shared/references/human_subjects_authority_protocol.md +274 -0
  1013. package/vendor/ars/shared/references/intent_clarification_protocol.md +168 -0
  1014. package/vendor/ars/shared/references/irb_terminology_glossary.md +229 -0
  1015. package/vendor/ars/shared/references/protected_hedging_phrases.md +118 -0
  1016. package/vendor/ars/shared/references/psychometric_terminology_glossary.md +109 -0
  1017. package/vendor/ars/shared/references/review_criteria_consumer_protocol.md +238 -0
  1018. package/vendor/ars/shared/references/review_pathway_rule_trace_protocol.md +166 -0
  1019. package/vendor/ars/shared/references/submission_packet_manifest_protocol.md +292 -0
  1020. package/vendor/ars/shared/references/word_count_conventions.md +124 -0
  1021. package/vendor/ars/shared/research_workflow_profiles/field_general.json +1 -0
  1022. package/vendor/ars/shared/review_criteria_registry.json +207 -0
  1023. package/vendor/ars/shared/review_criteria_sources/msr-2027-technical-papers.2026-08-24.json +46 -0
  1024. package/vendor/ars/shared/review_criteria_sources/sigsoft-empirical-standards.2026-08-24.json +31 -0
  1025. package/vendor/ars/shared/sprint_contract.schema.json +482 -0
  1026. package/vendor/ars/shared/style_calibration_protocol.md +151 -0
  1027. package/vendor/ars/shared/templates/codex_audit_multifile_template.md +263 -0
  1028. package/vendor/ars/tools/release-discipline/.toolkit-version +1 -0
  1029. package/vendor/ars/tools/release-discipline/README.md +4 -0
  1030. package/vendor/ars/tools/release-discipline/scripts/_release_doc_alignment_schema.py +1011 -0
  1031. package/vendor/ars/tools/release-discipline/scripts/check_command_invariants.py +497 -0
  1032. package/vendor/ars/tools/release-discipline/scripts/check_release_doc_alignment.py +263 -0
  1033. package/vendor/ars/tools/release-discipline/scripts/sync-toolkit.sh +147 -0
  1034. package/vendor/windows/NOTICE.md +12 -0
  1035. package/vendor/windows/arm64/fd.exe +0 -0
  1036. package/vendor/windows/arm64/licenses/fd/LICENSE-APACHE +201 -0
  1037. package/vendor/windows/arm64/licenses/fd/LICENSE-MIT +21 -0
  1038. package/vendor/windows/arm64/licenses/ripgrep/COPYING +3 -0
  1039. package/vendor/windows/arm64/licenses/ripgrep/LICENSE-MIT +21 -0
  1040. package/vendor/windows/arm64/licenses/ripgrep/UNLICENSE +24 -0
  1041. package/vendor/windows/arm64/rg.exe +0 -0
  1042. package/vendor/windows/x64/fd.exe +0 -0
  1043. package/vendor/windows/x64/licenses/fd/LICENSE-APACHE +201 -0
  1044. package/vendor/windows/x64/licenses/fd/LICENSE-MIT +21 -0
  1045. package/vendor/windows/x64/licenses/ripgrep/COPYING +3 -0
  1046. package/vendor/windows/x64/licenses/ripgrep/LICENSE-MIT +21 -0
  1047. package/vendor/windows/x64/licenses/ripgrep/UNLICENSE +24 -0
  1048. package/vendor/windows/x64/rg.exe +0 -0
@@ -0,0 +1,1086 @@
1
+ #!/usr/bin/env python3
2
+ """#105 v3.7.3 contamination_signals resolver tests.
3
+
4
+ Tests the two pure-function signals defined in v3.7.3 spec §3.2 that
5
+ the migration tool uses to backfill pre-v3.7.3 literature_corpus entries.
6
+
7
+ Signal 1 (preprint_post_llm_inflection): year >= 2024 AND venue in 10-server
8
+ closed list (per spec §3.2 Vector 1 + schema description).
9
+
10
+ Signal 2 (semantic_scholar_unmatched): SS API lookup with manual exemption
11
+ + API degradation handling (per spec §3.2 Vector 2 + R-L3-2-B).
12
+
13
+ Design: docs/design/2026-05-15-issue-105-contamination-signals-backfill-design.md
14
+ """
15
+ from __future__ import annotations
16
+
17
+ import sys
18
+ import unittest
19
+ from pathlib import Path
20
+ from unittest.mock import MagicMock
21
+
22
+ REPO_ROOT = Path(__file__).resolve().parent.parent
23
+ if str(REPO_ROOT / "scripts") not in sys.path:
24
+ sys.path.insert(0, str(REPO_ROOT / "scripts"))
25
+
26
+ import contamination_signals as cs # noqa: E402
27
+
28
+
29
+ # ============================================================================
30
+ # Signal 1 — preprint_post_llm_inflection
31
+ # ============================================================================
32
+ class PreprintSignalTest(unittest.TestCase):
33
+ """Signal 1 per v3.7.3 spec §3.2 Vector 1: True iff year >= 2024 AND
34
+ venue ∈ 10-server closed list."""
35
+
36
+ def test_arxiv_2024_returns_true(self) -> None:
37
+ self.assertTrue(cs.compute_preprint_signal({"year": 2024, "venue": "arXiv"}))
38
+
39
+ def test_arxiv_2023_returns_false(self) -> None:
40
+ # Year boundary: 2023 is below threshold
41
+ self.assertFalse(cs.compute_preprint_signal({"year": 2023, "venue": "arXiv"}))
42
+
43
+ def test_arxiv_2025_returns_true(self) -> None:
44
+ self.assertTrue(cs.compute_preprint_signal({"year": 2025, "venue": "arXiv"}))
45
+
46
+ def test_biorxiv_2024_returns_true(self) -> None:
47
+ self.assertTrue(cs.compute_preprint_signal({"year": 2024, "venue": "bioRxiv"}))
48
+
49
+ def test_medrxiv_2024_returns_true(self) -> None:
50
+ self.assertTrue(cs.compute_preprint_signal({"year": 2024, "venue": "medRxiv"}))
51
+
52
+ def test_ssrn_2024_returns_true(self) -> None:
53
+ self.assertTrue(cs.compute_preprint_signal({"year": 2024, "venue": "SSRN"}))
54
+
55
+ def test_research_square_2024_returns_true(self) -> None:
56
+ self.assertTrue(
57
+ cs.compute_preprint_signal({"year": 2024, "venue": "Research Square"})
58
+ )
59
+
60
+ def test_preprints_org_2024_returns_true(self) -> None:
61
+ self.assertTrue(
62
+ cs.compute_preprint_signal({"year": 2024, "venue": "Preprints.org"})
63
+ )
64
+
65
+ def test_chemrxiv_2024_returns_true(self) -> None:
66
+ """v3.7.3 codex F6 / gemini review F6 expansion."""
67
+ self.assertTrue(cs.compute_preprint_signal({"year": 2024, "venue": "ChemRxiv"}))
68
+
69
+ def test_eartharxiv_2024_returns_true(self) -> None:
70
+ self.assertTrue(
71
+ cs.compute_preprint_signal({"year": 2024, "venue": "EarthArXiv"})
72
+ )
73
+
74
+ def test_osf_preprints_2024_returns_true(self) -> None:
75
+ self.assertTrue(
76
+ cs.compute_preprint_signal({"year": 2024, "venue": "OSF Preprints"})
77
+ )
78
+
79
+ def test_techrxiv_2024_returns_true(self) -> None:
80
+ self.assertTrue(cs.compute_preprint_signal({"year": 2024, "venue": "TechRxiv"}))
81
+
82
+ def test_non_preprint_venue_2024_returns_false(self) -> None:
83
+ # Year passes threshold but venue is not in the closed list
84
+ self.assertFalse(
85
+ cs.compute_preprint_signal({"year": 2024, "venue": "Nature"})
86
+ )
87
+
88
+ def test_missing_venue_returns_false(self) -> None:
89
+ # Defensive: entries lacking venue cannot satisfy the AND
90
+ self.assertFalse(cs.compute_preprint_signal({"year": 2024}))
91
+
92
+ def test_missing_year_returns_false(self) -> None:
93
+ # Defensive: entries lacking year cannot satisfy the AND
94
+ self.assertFalse(cs.compute_preprint_signal({"venue": "arXiv"}))
95
+
96
+ def test_source_pointer_infers_arxiv(self) -> None:
97
+ """Codex R2-1 closure: when venue is missing, source_pointer
98
+ URLs to preprint servers must satisfy Signal 1."""
99
+ self.assertTrue(
100
+ cs.compute_preprint_signal(
101
+ {"year": 2024, "source_pointer": "https://arxiv.org/abs/2401.12345"}
102
+ )
103
+ )
104
+
105
+ def test_source_pointer_infers_biorxiv(self) -> None:
106
+ self.assertTrue(
107
+ cs.compute_preprint_signal(
108
+ {"year": 2025, "source_pointer": "https://www.biorxiv.org/content/10.1101/2025.01.01.000000v1"}
109
+ )
110
+ )
111
+
112
+ def test_source_pointer_infers_osf_preprints(self) -> None:
113
+ self.assertTrue(
114
+ cs.compute_preprint_signal(
115
+ {"year": 2024, "source_pointer": "https://osf.io/preprints/socarxiv/xyz123"}
116
+ )
117
+ )
118
+
119
+ def test_source_pointer_non_preprint_returns_false(self) -> None:
120
+ """An arbitrary URL with no preprint-server hint stays False."""
121
+ self.assertFalse(
122
+ cs.compute_preprint_signal(
123
+ {"year": 2024, "source_pointer": "https://nature.com/articles/x"}
124
+ )
125
+ )
126
+
127
+ def test_source_pointer_ignored_when_venue_present(self) -> None:
128
+ """Explicit `venue` field takes precedence — Nature 2024 with an
129
+ arxiv source_pointer is still venue=Nature (Signal 1 false)."""
130
+ self.assertFalse(
131
+ cs.compute_preprint_signal(
132
+ {
133
+ "year": 2024,
134
+ "venue": "Nature",
135
+ "source_pointer": "https://arxiv.org/abs/2401.x",
136
+ }
137
+ )
138
+ )
139
+
140
+ def test_source_pointer_pre_2024_returns_false(self) -> None:
141
+ """Year < 2024 short-circuits before pointer inference fires."""
142
+ self.assertFalse(
143
+ cs.compute_preprint_signal(
144
+ {"year": 2023, "source_pointer": "https://arxiv.org/abs/2301.x"}
145
+ )
146
+ )
147
+
148
+
149
+ # ============================================================================
150
+ # Signal 2 — semantic_scholar_unmatched
151
+ # ============================================================================
152
+ class SemanticScholarSignalTest(unittest.TestCase):
153
+ """Signal 2 per v3.7.3 spec §3.2 Vector 2: SS API lookup. Returns None
154
+ on (a) manual exemption (b) API degradation; True/False otherwise.
155
+
156
+ The SS client is dependency-injected — tests use a MagicMock that
157
+ returns whatever match shape the test specifies."""
158
+
159
+ def _entry(self, **overrides):
160
+ base = {
161
+ "citation_key": "chen2024ai",
162
+ "title": "Test paper",
163
+ "authors": [{"family": "Chen", "given": "A"}],
164
+ "year": 2024,
165
+ "doi": "10.1234/xyz",
166
+ "obtained_via": "folder-scan",
167
+ }
168
+ return base | overrides
169
+
170
+ def test_manual_entry_returns_none(self) -> None:
171
+ """v3.7.3 spec §3.2 + schema allOf rule #4: obtained_via='manual'
172
+ triggers SKIP — the field MUST be omitted from the emission."""
173
+ client = MagicMock()
174
+ result = cs.compute_ss_unmatched_signal(
175
+ self._entry(obtained_via="manual"), client
176
+ )
177
+ self.assertIsNone(result)
178
+ # The exemption is a skip, not an API call
179
+ client.lookup.assert_not_called()
180
+
181
+ def test_ss_match_returns_false(self) -> None:
182
+ client = MagicMock()
183
+ client.lookup.return_value = {"matched": True, "paperId": "abc123"}
184
+ self.assertFalse(cs.compute_ss_unmatched_signal(self._entry(), client))
185
+
186
+ def test_ss_no_match_returns_true(self) -> None:
187
+ client = MagicMock()
188
+ client.lookup.return_value = {"matched": False, "paperId": None}
189
+ self.assertTrue(cs.compute_ss_unmatched_signal(self._entry(), client))
190
+
191
+ def test_ss_api_degradation_returns_none(self) -> None:
192
+ """Per spec §3.2: API unreachable (network failure / rate-limit-
193
+ exhausted / 5xx) returns None. Absence ≠ negative confirmation;
194
+ setting False would imply 'checked and found'."""
195
+ client = MagicMock()
196
+ client.lookup.side_effect = cs.SemanticScholarUnavailable("rate limit exhausted")
197
+ self.assertIsNone(cs.compute_ss_unmatched_signal(self._entry(), client))
198
+
199
+ def test_ss_network_failure_returns_none(self) -> None:
200
+ client = MagicMock()
201
+ client.lookup.side_effect = cs.SemanticScholarUnavailable("connection refused")
202
+ self.assertIsNone(cs.compute_ss_unmatched_signal(self._entry(), client))
203
+
204
+ def test_unexpected_exception_propagates(self) -> None:
205
+ """Distinguish 'API degradation' (a known-handled signal) from
206
+ unknown bugs. ValueError isn't SS-API-degradation; let it surface
207
+ so the migration tool can fail loudly rather than silently OMIT."""
208
+ client = MagicMock()
209
+ client.lookup.side_effect = ValueError("bug in client")
210
+ with self.assertRaises(ValueError):
211
+ cs.compute_ss_unmatched_signal(self._entry(), client)
212
+
213
+
214
+ # ============================================================================
215
+ # Emission rules — building the contamination_signals object
216
+ # ============================================================================
217
+ class EmissionRulesTest(unittest.TestCase):
218
+ """Per spec §3.2 emission rules: emit object with both fields false
219
+ when computed-and-clean; emit partial object when one signal can't
220
+ be computed; omit semantic_scholar_unmatched on manual exemption."""
221
+
222
+ def _entry(self, **overrides):
223
+ base = {
224
+ "year": 2024,
225
+ "venue": "arXiv",
226
+ "obtained_via": "folder-scan",
227
+ }
228
+ return base | overrides
229
+
230
+ def test_both_signals_computed_emits_full_object(self) -> None:
231
+ client = MagicMock()
232
+ client.lookup.return_value = {"matched": False}
233
+ result = cs.build_signals_object(self._entry(), client)
234
+ self.assertEqual(
235
+ result,
236
+ {"preprint_post_llm_inflection": True, "semantic_scholar_unmatched": True},
237
+ )
238
+
239
+ def test_clean_entry_emits_both_false(self) -> None:
240
+ client = MagicMock()
241
+ client.lookup.return_value = {"matched": True}
242
+ result = cs.build_signals_object(self._entry(year=2023, venue="Nature"), client)
243
+ self.assertEqual(
244
+ result,
245
+ {"preprint_post_llm_inflection": False, "semantic_scholar_unmatched": False},
246
+ )
247
+
248
+ def test_manual_entry_omits_unmatched_field(self) -> None:
249
+ client = MagicMock()
250
+ result = cs.build_signals_object(
251
+ self._entry(obtained_via="manual"), client
252
+ )
253
+ self.assertEqual(result, {"preprint_post_llm_inflection": True})
254
+ self.assertNotIn("semantic_scholar_unmatched", result)
255
+
256
+ def test_api_degradation_omits_unmatched_field(self) -> None:
257
+ """Partial computation: Signal 1 still emits (trivial from
258
+ year+venue), Signal 2 omitted (API down). Per spec §3.2."""
259
+ client = MagicMock()
260
+ client.lookup.side_effect = cs.SemanticScholarUnavailable("5xx")
261
+ result = cs.build_signals_object(self._entry(), client)
262
+ self.assertEqual(result, {"preprint_post_llm_inflection": True})
263
+ self.assertNotIn("semantic_scholar_unmatched", result)
264
+
265
+
266
+ class ResetClientOutageLatchHelperTest(unittest.TestCase):
267
+ """#115 R5-3 helper: production clients implementing the outage-latch
268
+ pattern expose `reset_outage_latch()`; minimal mocks may not. The
269
+ helper invokes when present, no-ops when absent. Avoids
270
+ AttributeError for callers that swap in test mocks."""
271
+
272
+ def test_helper_invokes_reset_when_present(self) -> None:
273
+ client = MagicMock()
274
+ cs.reset_client_outage_latch(client)
275
+ client.reset_outage_latch.assert_called_once()
276
+
277
+ def test_helper_no_ops_when_method_absent(self) -> None:
278
+ client = MagicMock(spec=["lookup"]) # only the Protocol's lookup
279
+ # Should NOT raise AttributeError
280
+ cs.reset_client_outage_latch(client)
281
+
282
+
283
+
284
+
285
+ class BuildSignalsWithOmissionsTest(unittest.TestCase):
286
+ """#511 Part A: the omissions half distinguishes degraded from derivable."""
287
+
288
+ def _entry(self, **over):
289
+ base = {
290
+ "citation_key": "chen2024",
291
+ "title": "AI in education",
292
+ "authors": [{"family": "Chen"}],
293
+ "year": 2024,
294
+ "source_pointer": "file:///x.pdf",
295
+ "obtained_via": "folder-scan",
296
+ }
297
+ base.update(over)
298
+ return base
299
+
300
+ def _client(self, *, matched=False, degraded=False):
301
+ client = MagicMock()
302
+ if degraded:
303
+ client.lookup.side_effect = cs.SemanticScholarUnavailable("down")
304
+ else:
305
+ client.lookup.return_value = {"matched": matched, "paperId": "x"}
306
+ return client
307
+
308
+ def test_degraded_lookup_yields_omission(self):
309
+ signals, omissions = cs.build_signals_with_omissions(
310
+ self._entry(), self._client(degraded=True))
311
+ self.assertNotIn("semantic_scholar_unmatched", signals)
312
+ self.assertEqual(
313
+ omissions, {"semantic_scholar_unmatched": "api_degraded"})
314
+
315
+ def test_computed_lookup_yields_no_omission(self):
316
+ signals, omissions = cs.build_signals_with_omissions(
317
+ self._entry(), self._client(matched=True))
318
+ self.assertIs(signals["semantic_scholar_unmatched"], False)
319
+ self.assertEqual(omissions, {})
320
+
321
+ def test_manual_entry_yields_no_omission(self):
322
+ """Manual exemption is derivable from obtained_via — never recorded."""
323
+ signals, omissions = cs.build_signals_with_omissions(
324
+ self._entry(obtained_via="manual"), self._client(degraded=True))
325
+ self.assertNotIn("semantic_scholar_unmatched", signals)
326
+ self.assertEqual(omissions, {})
327
+
328
+ def test_no_arxiv_id_skips_arxiv_row(self):
329
+ """The no-arxiv-id skip is derivable from the entry — never recorded,
330
+ even when an arxiv client is supplied."""
331
+ ax = MagicMock()
332
+ signals, omissions = cs.build_signals_with_omissions(
333
+ self._entry(), self._client(), ax)
334
+ self.assertNotIn("arxiv_unmatched", signals)
335
+ self.assertEqual(omissions, {})
336
+ ax.arxiv_id_lookup.assert_not_called()
337
+
338
+ def test_degraded_arxiv_yields_omission(self):
339
+ ax = MagicMock()
340
+ ax.arxiv_id_lookup.side_effect = cs.ArxivUnavailable("down")
341
+ ax.title_search.side_effect = cs.ArxivUnavailable("down")
342
+ signals, omissions = cs.build_signals_with_omissions(
343
+ self._entry(arxiv_id="2401.00001"), self._client(), ax)
344
+ self.assertEqual(omissions.get("arxiv_unmatched"), "api_degraded")
345
+
346
+ def test_build_signals_object_stays_equivalent(self):
347
+ """The legacy single-return API is the signals half, byte-equal."""
348
+ for client in (self._client(), self._client(degraded=True)):
349
+ entry = self._entry()
350
+ self.assertEqual(
351
+ cs.build_signals_object(entry, client),
352
+ cs.build_signals_with_omissions(entry, client)[0])
353
+
354
+
355
+ class OmissionHelpersTest(unittest.TestCase):
356
+ """#511 Part A: record/clear are idempotent and keep the schema shape
357
+ (no empty omissions object)."""
358
+
359
+ def test_record_then_rerecord_is_idempotent(self):
360
+ entry = {}
361
+ self.assertTrue(cs.record_signal_omission(entry, "openalex_unmatched"))
362
+ self.assertFalse(cs.record_signal_omission(entry, "openalex_unmatched"))
363
+ self.assertEqual(
364
+ entry["contamination_signal_omissions"],
365
+ {"openalex_unmatched": "api_degraded"})
366
+
367
+ def test_clear_removes_key_and_empty_object(self):
368
+ entry = {"contamination_signal_omissions": {
369
+ "openalex_unmatched": "api_degraded"}}
370
+ self.assertTrue(cs.clear_signal_omission(entry, "openalex_unmatched"))
371
+ self.assertNotIn("contamination_signal_omissions", entry)
372
+
373
+ def test_clear_keeps_other_keys(self):
374
+ entry = {"contamination_signal_omissions": {
375
+ "openalex_unmatched": "api_degraded",
376
+ "crossref_unmatched": "api_degraded"}}
377
+ self.assertTrue(cs.clear_signal_omission(entry, "openalex_unmatched"))
378
+ self.assertEqual(
379
+ entry["contamination_signal_omissions"],
380
+ {"crossref_unmatched": "api_degraded"})
381
+
382
+ def test_clear_on_absent_is_noop(self):
383
+ entry = {}
384
+ self.assertFalse(cs.clear_signal_omission(entry, "openalex_unmatched"))
385
+ self.assertEqual(entry, {})
386
+
387
+
388
+ if __name__ == "__main__":
389
+ unittest.main()
390
+
391
+
392
+ # ============================================================================
393
+ # v3.9.0 — resolve_openalex_unmatched
394
+ # ============================================================================
395
+
396
+
397
+ class ResolveOpenAlexUnmatchedTest(unittest.TestCase):
398
+ """Tests for resolve_openalex_unmatched per spec v3.9.0 §3.4."""
399
+
400
+ def test_match(self):
401
+ """OpenAlex hit via DOI cross-check → False."""
402
+ from contamination_signals import resolve_openalex_unmatched
403
+
404
+ mock_client = MagicMock()
405
+ mock_client.doi_lookup_with_title_check.return_value = {"title": "X"}
406
+
407
+ entry = {
408
+ "title": "X",
409
+ "doi": "10.5555/abc",
410
+ "obtained_via": "zotero-bbt-export",
411
+ }
412
+ result = resolve_openalex_unmatched(entry, mock_client)
413
+ self.assertIs(result, False)
414
+
415
+ def test_no_match(self):
416
+ """OpenAlex no DOI hit + no title hit → True."""
417
+ from contamination_signals import resolve_openalex_unmatched
418
+
419
+ mock_client = MagicMock()
420
+ mock_client.doi_lookup_with_title_check.return_value = None
421
+ mock_client.title_search.return_value = None
422
+
423
+ entry = {
424
+ "title": "Nonexistent Paper",
425
+ "doi": "10.5555/fake",
426
+ "obtained_via": "folder-scan",
427
+ }
428
+ result = resolve_openalex_unmatched(entry, mock_client)
429
+ self.assertIs(result, True)
430
+
431
+ def test_manual_exempt(self):
432
+ """obtained_via='manual' → return None, no client calls."""
433
+ from contamination_signals import resolve_openalex_unmatched
434
+
435
+ mock_client = MagicMock()
436
+ entry = {"title": "X", "obtained_via": "manual"}
437
+ result = resolve_openalex_unmatched(entry, mock_client)
438
+ self.assertIsNone(result)
439
+ mock_client.doi_lookup_with_title_check.assert_not_called()
440
+ mock_client.title_search.assert_not_called()
441
+
442
+ def test_doi_absent_falls_through_to_title(self):
443
+ """DOI absent: title search alone, NO DOI lookup attempted."""
444
+ from contamination_signals import resolve_openalex_unmatched
445
+
446
+ mock_client = MagicMock()
447
+ mock_client.title_search.return_value = {"title": "X"}
448
+
449
+ entry = {"title": "X", "obtained_via": "zotero-bbt-export"} # no doi
450
+ result = resolve_openalex_unmatched(entry, mock_client)
451
+ self.assertIs(result, False)
452
+ mock_client.doi_lookup_with_title_check.assert_not_called()
453
+
454
+ def test_api_down_raises(self):
455
+ """API degraded → re-raise OpenAlexUnavailable for caller to omit field."""
456
+ from contamination_signals import resolve_openalex_unmatched
457
+ from openalex_client import OpenAlexUnavailable
458
+
459
+ mock_client = MagicMock()
460
+ mock_client.doi_lookup_with_title_check.side_effect = OpenAlexUnavailable("down")
461
+
462
+ entry = {"title": "X", "doi": "10.5555/abc", "obtained_via": "folder-scan"}
463
+ with self.assertRaises(OpenAlexUnavailable):
464
+ resolve_openalex_unmatched(entry, mock_client)
465
+
466
+
467
+ # ============================================================================
468
+ # v3.9.0 — resolve_crossref_unmatched
469
+ # ============================================================================
470
+
471
+
472
+ class ResolveCrossrefUnmatchedTest(unittest.TestCase):
473
+ """Tests for resolve_crossref_unmatched per spec v3.9.0 §3.5."""
474
+
475
+ def test_match(self):
476
+ """Crossref hit via DOI cross-check → False."""
477
+ from contamination_signals import resolve_crossref_unmatched
478
+
479
+ mock_client = MagicMock()
480
+ mock_client.doi_lookup_with_title_check.return_value = {"title": ["X"]}
481
+
482
+ entry = {
483
+ "title": "X",
484
+ "doi": "10.5555/abc",
485
+ "obtained_via": "zotero-bbt-export",
486
+ }
487
+ result = resolve_crossref_unmatched(entry, mock_client)
488
+ self.assertIs(result, False)
489
+
490
+ def test_no_match(self):
491
+ """Crossref no DOI hit + no title hit → True."""
492
+ from contamination_signals import resolve_crossref_unmatched
493
+
494
+ mock_client = MagicMock()
495
+ mock_client.doi_lookup_with_title_check.return_value = None
496
+ mock_client.title_search.return_value = None
497
+
498
+ entry = {
499
+ "title": "Nonexistent",
500
+ "doi": "10.5555/fake",
501
+ "obtained_via": "folder-scan",
502
+ }
503
+ result = resolve_crossref_unmatched(entry, mock_client)
504
+ self.assertIs(result, True)
505
+
506
+ def test_manual_exempt(self):
507
+ """obtained_via='manual' → return None, no client calls."""
508
+ from contamination_signals import resolve_crossref_unmatched
509
+
510
+ mock_client = MagicMock()
511
+ entry = {"title": "X", "obtained_via": "manual"}
512
+ result = resolve_crossref_unmatched(entry, mock_client)
513
+ self.assertIsNone(result)
514
+ mock_client.doi_lookup_with_title_check.assert_not_called()
515
+ mock_client.title_search.assert_not_called()
516
+
517
+ def test_doi_absent_falls_through_to_title(self):
518
+ """DOI absent: title search alone, NO DOI lookup attempted."""
519
+ from contamination_signals import resolve_crossref_unmatched
520
+
521
+ mock_client = MagicMock()
522
+ mock_client.title_search.return_value = {"title": ["X"]}
523
+
524
+ entry = {"title": "X", "obtained_via": "obsidian-vault"} # no doi
525
+ result = resolve_crossref_unmatched(entry, mock_client)
526
+ self.assertIs(result, False)
527
+ mock_client.doi_lookup_with_title_check.assert_not_called()
528
+
529
+ def test_api_down_raises(self):
530
+ """API degraded → re-raise CrossrefUnavailable for caller to omit field."""
531
+ from contamination_signals import resolve_crossref_unmatched
532
+ from crossref_client import CrossrefUnavailable
533
+
534
+ mock_client = MagicMock()
535
+ mock_client.doi_lookup_with_title_check.side_effect = CrossrefUnavailable("down")
536
+
537
+ entry = {"title": "X", "doi": "10.5555/abc", "obtained_via": "folder-scan"}
538
+ with self.assertRaises(CrossrefUnavailable):
539
+ resolve_crossref_unmatched(entry, mock_client)
540
+
541
+
542
+ # ============================================================================
543
+ # v3.11 #182 Delta 1 — resolve_arxiv_unmatched
544
+ # ============================================================================
545
+
546
+
547
+ class ResolveArxivUnmatchedTest(unittest.TestCase):
548
+ """Tests for resolve_arxiv_unmatched per spec v3.11 #182 Delta 1.
549
+
550
+ Differs from the crossref/openalex resolvers: keyed by entry['arxiv_id']
551
+ (not 'doi'), and the client exact-key method is arxiv_id_lookup, not
552
+ doi_lookup_with_title_check."""
553
+
554
+ def test_match(self):
555
+ """arXiv hit via ID cross-check → False."""
556
+ from contamination_signals import resolve_arxiv_unmatched
557
+
558
+ mock_client = MagicMock()
559
+ mock_client.arxiv_id_lookup.return_value = {"title": "X", "year": 2017}
560
+
561
+ entry = {
562
+ "title": "X",
563
+ "arxiv_id": "1706.03762",
564
+ "obtained_via": "zotero-bbt-export",
565
+ }
566
+ result = resolve_arxiv_unmatched(entry, mock_client)
567
+ self.assertIs(result, False)
568
+
569
+ def test_no_match(self):
570
+ """arXiv no ID hit + no title hit → True."""
571
+ from contamination_signals import resolve_arxiv_unmatched
572
+
573
+ mock_client = MagicMock()
574
+ mock_client.arxiv_id_lookup.return_value = None
575
+ mock_client.title_search.return_value = None
576
+
577
+ entry = {
578
+ "title": "Nonexistent",
579
+ "arxiv_id": "9999.99999",
580
+ "obtained_via": "folder-scan",
581
+ }
582
+ result = resolve_arxiv_unmatched(entry, mock_client)
583
+ self.assertIs(result, True)
584
+
585
+ def test_manual_exempt(self):
586
+ """obtained_via='manual' → return None, no client calls."""
587
+ from contamination_signals import resolve_arxiv_unmatched
588
+
589
+ mock_client = MagicMock()
590
+ entry = {"title": "X", "arxiv_id": "1706.03762", "obtained_via": "manual"}
591
+ result = resolve_arxiv_unmatched(entry, mock_client)
592
+ self.assertIsNone(result)
593
+ mock_client.arxiv_id_lookup.assert_not_called()
594
+ mock_client.title_search.assert_not_called()
595
+
596
+ def test_arxiv_id_absent_skips_resolver(self):
597
+ """arXiv ID absent (#331 P2): the arXiv resolver is SKIPPED — return None
598
+ (caller omits arxiv_unmatched) and run NO network query. A non-arXiv
599
+ citation (e.g. a DOI-keyed journal article) must not be title-searched
600
+ against arXiv: a title miss there is a coverage gap, not non-existence
601
+ evidence, and would emit a false arxiv_unmatched=true (inflating the
602
+ triangulation k on a clean citation). Spec §4 / the orchestrator k_max
603
+ rule both state arxiv_unmatched is ABSENT on citations with no arXiv ID
604
+ ('arXiv resolver skipped on a non-arXiv citation per Delta 1')."""
605
+ from contamination_signals import resolve_arxiv_unmatched
606
+
607
+ mock_client = MagicMock()
608
+
609
+ entry = {"title": "X", "obtained_via": "obsidian-vault"} # no arxiv_id
610
+ result = resolve_arxiv_unmatched(entry, mock_client)
611
+ self.assertIsNone(result)
612
+ mock_client.arxiv_id_lookup.assert_not_called()
613
+ mock_client.title_search.assert_not_called()
614
+
615
+ def test_arxiv_id_miss_falls_through_to_title(self):
616
+ """ID present but ID lookup misses → fall through to title search."""
617
+ from contamination_signals import resolve_arxiv_unmatched
618
+
619
+ mock_client = MagicMock()
620
+ mock_client.arxiv_id_lookup.return_value = None
621
+ mock_client.title_search.return_value = {"title": "X", "year": 2017}
622
+
623
+ entry = {"title": "X", "arxiv_id": "1706.03762", "obtained_via": "folder-scan"}
624
+ result = resolve_arxiv_unmatched(entry, mock_client)
625
+ self.assertIs(result, False)
626
+ mock_client.title_search.assert_called_once()
627
+
628
+ def test_api_down_raises(self):
629
+ """API degraded → re-raise ArxivUnavailable for caller to omit field."""
630
+ from contamination_signals import resolve_arxiv_unmatched
631
+ from arxiv_client import ArxivUnavailable
632
+
633
+ mock_client = MagicMock()
634
+ mock_client.arxiv_id_lookup.side_effect = ArxivUnavailable("down")
635
+
636
+ entry = {"title": "X", "arxiv_id": "1706.03762", "obtained_via": "folder-scan"}
637
+ with self.assertRaises(ArxivUnavailable):
638
+ resolve_arxiv_unmatched(entry, mock_client)
639
+
640
+
641
+ # ============================================================================
642
+ # v3.11 #182 Delta 1 — build_signals_object arxiv extension
643
+ # ============================================================================
644
+
645
+
646
+ class BuildSignalsArxivExtensionTest(unittest.TestCase):
647
+ """build_signals_object grows an optional arxiv_client keyword arg; when
648
+ omitted, behavior is byte-equivalent to the v3.7.3 caller (no arxiv field).
649
+ Per spec §2 Delta 1 'signal computation only' scope."""
650
+
651
+ def _entry(self, **overrides):
652
+ base = {"year": 2024, "venue": "arXiv", "obtained_via": "folder-scan"}
653
+ return base | overrides
654
+
655
+ def test_no_arxiv_client_omits_arxiv_field(self) -> None:
656
+ """Byte-equivalent v3.7.3 path: no arxiv_client → no arxiv_unmatched."""
657
+ ss = MagicMock()
658
+ ss.lookup.return_value = {"matched": True}
659
+ result = cs.build_signals_object(self._entry(), ss)
660
+ self.assertNotIn("arxiv_unmatched", result)
661
+
662
+ def test_arxiv_client_emits_arxiv_field(self) -> None:
663
+ """With arxiv_client, a non-manual entry emits arxiv_unmatched."""
664
+ ss = MagicMock()
665
+ ss.lookup.return_value = {"matched": True}
666
+ ax = MagicMock()
667
+ ax.arxiv_id_lookup.return_value = None
668
+ ax.title_search.return_value = None
669
+ result = cs.build_signals_object(
670
+ self._entry(arxiv_id="9999.99999"), ss, arxiv_client=ax
671
+ )
672
+ self.assertIs(result["arxiv_unmatched"], True)
673
+
674
+ def test_no_arxiv_id_omits_arxiv_field_even_with_client(self) -> None:
675
+ """#331: a non-arXiv citation (arxiv_client present but entry has no
676
+ arxiv_id) omits arxiv_unmatched and runs NO arXiv query. Without the
677
+ skip, the resolver would title-search arXiv and emit a false
678
+ arxiv_unmatched=true, inflating triangulation k on a clean citation."""
679
+ ss = MagicMock()
680
+ ss.lookup.return_value = {"matched": True}
681
+ ax = MagicMock()
682
+ result = cs.build_signals_object(
683
+ self._entry(), ss, arxiv_client=ax # _entry() carries no arxiv_id
684
+ )
685
+ self.assertNotIn("arxiv_unmatched", result)
686
+ ax.arxiv_id_lookup.assert_not_called()
687
+ ax.title_search.assert_not_called()
688
+
689
+ def test_manual_entry_omits_arxiv_field_even_with_client(self) -> None:
690
+ """Manual entry: arxiv_unmatched omitted (not-rule), like the ss field."""
691
+ ss = MagicMock()
692
+ ax = MagicMock()
693
+ result = cs.build_signals_object(
694
+ self._entry(obtained_via="manual", arxiv_id="1706.03762"), ss,
695
+ arxiv_client=ax
696
+ )
697
+ self.assertNotIn("arxiv_unmatched", result)
698
+ ax.arxiv_id_lookup.assert_not_called()
699
+
700
+ def test_arxiv_api_down_omits_arxiv_field(self) -> None:
701
+ """arXiv API degradation → omit arxiv_unmatched (absent != false)."""
702
+ ss = MagicMock()
703
+ ss.lookup.return_value = {"matched": True}
704
+ ax = MagicMock()
705
+ ax.arxiv_id_lookup.side_effect = cs.ArxivUnavailable("5xx")
706
+ result = cs.build_signals_object(
707
+ self._entry(arxiv_id="1706.03762"), ss, arxiv_client=ax
708
+ )
709
+ self.assertNotIn("arxiv_unmatched", result)
710
+
711
+
712
+ # ============================================================================
713
+ # v3.11 #182 Delta 2 — resolver cache integration (wrapper layer)
714
+ # ============================================================================
715
+
716
+
717
+ class _FakeCache:
718
+ """Minimal in-memory stand-in for VerificationCache. Records get/put calls
719
+ so tests can assert hit/skip behavior without SQLite."""
720
+
721
+ def __init__(self, seed=None):
722
+ self._store = dict(seed or {})
723
+ self.get_calls = []
724
+ self.put_calls = []
725
+
726
+ def get(self, citation_key, resolver_name, query_form):
727
+ self.get_calls.append((citation_key, resolver_name, query_form))
728
+ return self._store.get((citation_key, resolver_name, query_form))
729
+
730
+ def put(self, citation_key, resolver_name, query_form, response):
731
+ self.put_calls.append((citation_key, resolver_name, query_form, response))
732
+ self._store[(citation_key, resolver_name, query_form)] = response
733
+
734
+
735
+ class ResolveCrossrefCacheTest(unittest.TestCase):
736
+ """Cache integration is byte-equivalent when cache=None, consults the cache
737
+ before the network on hit, and populates on miss. Per spec §2 Delta 2."""
738
+
739
+ def _entry(self, **overrides):
740
+ base = {
741
+ "citation_key": "vaswani2017",
742
+ "title": "Attention Is All You Need",
743
+ "doi": "10.5555/abc",
744
+ "obtained_via": "folder-scan",
745
+ }
746
+ return base | overrides
747
+
748
+ def test_cache_none_is_byte_equivalent(self):
749
+ from contamination_signals import resolve_crossref_unmatched
750
+
751
+ client = MagicMock()
752
+ client.doi_lookup_with_title_check.return_value = {"title": ["X"]}
753
+ result = resolve_crossref_unmatched(self._entry(), client, cache=None)
754
+ self.assertIs(result, False)
755
+ client.doi_lookup_with_title_check.assert_called_once()
756
+
757
+ def test_cache_hit_skips_network(self):
758
+ from contamination_signals import resolve_crossref_unmatched
759
+
760
+ client = MagicMock()
761
+ qf = "doi:10.5555/abc|title:Attention Is All You Need"
762
+ # A same-decision-version row IS reused (#431 §0.12.3b).
763
+ cache = _FakeCache(seed={
764
+ ("vaswani2017", "crossref", qf): {
765
+ "matched": True, "matched_by": "doi",
766
+ "decision_version": cs.RESOLVER_DECISION_VERSION,
767
+ }
768
+ })
769
+ result = resolve_crossref_unmatched(self._entry(), client, cache=cache)
770
+ self.assertIs(result, False) # matched=True → unmatched=False
771
+ client.doi_lookup_with_title_check.assert_not_called()
772
+ client.title_search.assert_not_called()
773
+
774
+ def test_stale_pre_v5_row_forces_recompute(self):
775
+ """#431 §0.12.3b (ship blocker): a pre-v5 row written under the
776
+ author-agree logic (matched_by=title, NO decision_version) must be
777
+ treated as a MISS so the v5 candidate loop actually runs — without this
778
+ the pivot is a no-op for up to 90 days of cached `matched` rows. The
779
+ stale row says matched=True; under v5 the DOI misses and the title
780
+ fallback (non-exact) returns no match → unmatched=True, and the live
781
+ client methods ARE called."""
782
+ from contamination_signals import resolve_crossref_unmatched
783
+
784
+ client = MagicMock()
785
+ client.doi_lookup_with_title_check.return_value = None # DOI miss
786
+ client.title_search.return_value = None # v5: non-exact → no match
787
+ qf = "doi:10.5555/abc|title:Attention Is All You Need"
788
+ cache = _FakeCache(seed={
789
+ ("vaswani2017", "crossref", qf): {
790
+ "matched": True, "matched_by": "title", # stale, no version
791
+ }
792
+ })
793
+ result = resolve_crossref_unmatched(self._entry(), client, cache=cache)
794
+ self.assertIs(result, True) # recomputed unmatched, NOT stale matched
795
+ client.title_search.assert_called_once() # v5 loop ran
796
+ # The recomputed verdict is re-stored WITH the current version.
797
+ _, _, _, response = cache.put_calls[0]
798
+ self.assertEqual(
799
+ response["decision_version"], cs.RESOLVER_DECISION_VERSION
800
+ )
801
+
802
+ def test_cache_miss_calls_network_and_populates(self):
803
+ from contamination_signals import resolve_crossref_unmatched
804
+
805
+ client = MagicMock()
806
+ client.doi_lookup_with_title_check.return_value = None
807
+ client.title_search.return_value = None # unmatched
808
+ cache = _FakeCache()
809
+ result = resolve_crossref_unmatched(self._entry(), client, cache=cache)
810
+ self.assertIs(result, True) # unmatched
811
+ self.assertEqual(len(cache.put_calls), 1)
812
+ # The negative verdict is cached (so repeat runs don't re-hammer API).
813
+ _, resolver, qf, response = cache.put_calls[0]
814
+ self.assertEqual(resolver, "crossref")
815
+ self.assertIs(response["matched"], False)
816
+
817
+ def test_malformed_cache_payload_treated_as_miss(self):
818
+ """A persistent on-disk cache row written by an older/other tool that
819
+ lacks the 'matched' key must be treated as a MISS (force live recompute),
820
+ not crash with KeyError for 90 days. Robustness guard."""
821
+ from contamination_signals import resolve_crossref_unmatched
822
+
823
+ client = MagicMock()
824
+ client.doi_lookup_with_title_check.return_value = {"title": ["X"]} # match
825
+ qf = "doi:10.5555/abc|title:Attention Is All You Need"
826
+ cache = _FakeCache(seed={
827
+ ("vaswani2017", "crossref", qf): {"legacy": "no matched key"}
828
+ })
829
+ result = resolve_crossref_unmatched(self._entry(), client, cache=cache)
830
+ # Falls through to live call (which matched) → unmatched=False.
831
+ self.assertIs(result, False)
832
+ client.doi_lookup_with_title_check.assert_called_once()
833
+
834
+ def test_degradation_is_not_cached(self):
835
+ from contamination_signals import resolve_crossref_unmatched
836
+ from crossref_client import CrossrefUnavailable
837
+
838
+ client = MagicMock()
839
+ client.doi_lookup_with_title_check.side_effect = CrossrefUnavailable("down")
840
+ cache = _FakeCache()
841
+ with self.assertRaises(CrossrefUnavailable):
842
+ resolve_crossref_unmatched(self._entry(), client, cache=cache)
843
+ self.assertEqual(cache.put_calls, []) # NEVER cache a degradation
844
+
845
+ def test_manual_entry_does_not_touch_cache(self):
846
+ from contamination_signals import resolve_crossref_unmatched
847
+
848
+ client = MagicMock()
849
+ cache = _FakeCache()
850
+ result = resolve_crossref_unmatched(
851
+ self._entry(obtained_via="manual"), client, cache=cache
852
+ )
853
+ self.assertIsNone(result)
854
+ self.assertEqual(cache.get_calls, [])
855
+ self.assertEqual(cache.put_calls, [])
856
+
857
+
858
+ class ResolveArxivCacheTest(unittest.TestCase):
859
+ """Same cache contract for the arXiv resolver (ID-keyed query_form)."""
860
+
861
+ def _entry(self, **overrides):
862
+ base = {
863
+ "citation_key": "vaswani2017",
864
+ "title": "Attention Is All You Need",
865
+ "arxiv_id": "1706.03762",
866
+ "obtained_via": "folder-scan",
867
+ }
868
+ return base | overrides
869
+
870
+ def test_cache_hit_skips_network(self):
871
+ from contamination_signals import resolve_arxiv_unmatched
872
+
873
+ client = MagicMock()
874
+ qf = "arxiv:1706.03762|title:Attention Is All You Need"
875
+ cache = _FakeCache(seed={
876
+ ("vaswani2017", "arxiv", qf): {
877
+ "matched": False, "matched_by": None,
878
+ "decision_version": cs.RESOLVER_DECISION_VERSION,
879
+ }
880
+ })
881
+ result = resolve_arxiv_unmatched(self._entry(), client, cache=cache)
882
+ self.assertIs(result, True) # matched=False → unmatched=True
883
+ client.arxiv_id_lookup.assert_not_called()
884
+
885
+ def test_stale_pre_v5_row_forces_recompute(self):
886
+ """#431 §0.12.3b: a pre-v5 arXiv row with no decision_version is a MISS;
887
+ the ID lookup runs live under v5."""
888
+ from contamination_signals import resolve_arxiv_unmatched
889
+
890
+ client = MagicMock()
891
+ client.arxiv_id_lookup.return_value = None # ID miss
892
+ client.title_search.return_value = None # v5: non-exact → no match
893
+ qf = "arxiv:1706.03762|title:Attention Is All You Need"
894
+ cache = _FakeCache(seed={
895
+ ("vaswani2017", "arxiv", qf): {
896
+ "matched": True, "matched_by": "title", # stale, no version
897
+ }
898
+ })
899
+ result = resolve_arxiv_unmatched(self._entry(), client, cache=cache)
900
+ self.assertIs(result, True) # recomputed, NOT stale matched
901
+ client.arxiv_id_lookup.assert_called_once()
902
+
903
+ def test_cache_miss_populates(self):
904
+ from contamination_signals import resolve_arxiv_unmatched
905
+
906
+ client = MagicMock()
907
+ client.arxiv_id_lookup.return_value = {"title": "X", "year": 2017}
908
+ cache = _FakeCache()
909
+ result = resolve_arxiv_unmatched(self._entry(), client, cache=cache)
910
+ self.assertIs(result, False) # matched
911
+ self.assertEqual(len(cache.put_calls), 1)
912
+ _, resolver, _, response = cache.put_calls[0]
913
+ self.assertEqual(resolver, "arxiv")
914
+ self.assertIs(response["matched"], True)
915
+
916
+
917
+ class SemanticScholarCacheTest(unittest.TestCase):
918
+ """S2's wrapper is compute_ss_unmatched_signal (the lone client.lookup is
919
+ entry-keyed already). Cache integration lives at that wrapper, matching
920
+ Option A — the resolver_name is 'semantic_scholar'. Per spec §2 Delta 2
921
+ 'the S2 lookup'."""
922
+
923
+ def _entry(self, **overrides):
924
+ base = {
925
+ "citation_key": "chen2024ai",
926
+ "title": "Test paper",
927
+ "doi": "10.1234/xyz",
928
+ "obtained_via": "folder-scan",
929
+ }
930
+ return base | overrides
931
+
932
+ def test_cache_none_byte_equivalent(self):
933
+ client = MagicMock()
934
+ client.lookup.return_value = {"matched": True}
935
+ self.assertFalse(cs.compute_ss_unmatched_signal(self._entry(), client, cache=None))
936
+ client.lookup.assert_called_once()
937
+
938
+ def test_cache_hit_skips_lookup(self):
939
+ client = MagicMock()
940
+ qf = "doi:10.1234/xyz|title:Test paper"
941
+ cache = _FakeCache(seed={
942
+ ("chen2024ai", "semantic_scholar", qf): {
943
+ "matched": False, "matched_by": None,
944
+ "decision_version": cs.RESOLVER_DECISION_VERSION,
945
+ }
946
+ })
947
+ result = cs.compute_ss_unmatched_signal(self._entry(), client, cache=cache)
948
+ self.assertTrue(result) # matched=False → unmatched=True
949
+ client.lookup.assert_not_called()
950
+
951
+ def test_stale_pre_v5_row_forces_recompute(self):
952
+ """#431 §0.12.3b (ship blocker), the exact regression the spec names: a
953
+ stale `{matched: True, matched_by: title}` row with no decision_version
954
+ (written under v3/v4 author-agree, e.g. a Study 1 / Study 2 same-author
955
+ pair) MUST be a miss so client.lookup runs under v5 — not returned as a
956
+ stale `matched`."""
957
+ client = MagicMock()
958
+ client.lookup.return_value = {"matched": False} # v5 live verdict
959
+ qf = "doi:10.1234/xyz|title:Test paper"
960
+ cache = _FakeCache(seed={
961
+ ("chen2024ai", "semantic_scholar", qf): {
962
+ "matched": True, "matched_by": "title", # stale, no version
963
+ }
964
+ })
965
+ result = cs.compute_ss_unmatched_signal(self._entry(), client, cache=cache)
966
+ self.assertTrue(result) # recomputed unmatched=True, NOT stale matched
967
+ client.lookup.assert_called_once() # v5 loop ran
968
+
969
+ def test_cache_miss_populates(self):
970
+ client = MagicMock()
971
+ client.lookup.return_value = {"matched": True}
972
+ cache = _FakeCache()
973
+ result = cs.compute_ss_unmatched_signal(self._entry(), client, cache=cache)
974
+ self.assertFalse(result)
975
+ self.assertEqual(len(cache.put_calls), 1)
976
+ _, resolver, _, response = cache.put_calls[0]
977
+ self.assertEqual(resolver, "semantic_scholar")
978
+ self.assertIs(response["matched"], True)
979
+
980
+ def test_manual_does_not_touch_cache(self):
981
+ client = MagicMock()
982
+ cache = _FakeCache()
983
+ result = cs.compute_ss_unmatched_signal(
984
+ self._entry(obtained_via="manual"), client, cache=cache
985
+ )
986
+ self.assertIsNone(result)
987
+ self.assertEqual(cache.get_calls, [])
988
+ self.assertEqual(cache.put_calls, [])
989
+
990
+ def test_degradation_not_cached(self):
991
+ client = MagicMock()
992
+ client.lookup.side_effect = cs.SemanticScholarUnavailable("5xx")
993
+ cache = _FakeCache()
994
+ result = cs.compute_ss_unmatched_signal(self._entry(), client, cache=cache)
995
+ self.assertIsNone(result) # degradation → None (omit field)
996
+ self.assertEqual(cache.put_calls, []) # never cache degradation
997
+
998
+
999
+ # ============================================================================
1000
+ # v3.11 #182 Delta 4 — queried_by retrofit (the ID-keyed-unmatched signal that
1001
+ # the narrowed-false reducer C-V6(a) needs). The internal resolver-flow helpers
1002
+ # return (unmatched, matched_by, queried_by) where queried_by records what the
1003
+ # resolver ACTUALLY queried by, so a title-only unmatched is distinguishable
1004
+ # from an ID-keyed unmatched at reduce time.
1005
+ # ============================================================================
1006
+
1007
+
1008
+ class ResolveDoiThenTitleQueriedByTest(unittest.TestCase):
1009
+ """_resolve_doi_then_title now returns (unmatched, matched_by, queried_by).
1010
+ queried_by ∈ {'id', 'title'} for unmatched; mirrors matched_by for matched."""
1011
+
1012
+ def test_doi_match_queried_by_id(self):
1013
+ client = MagicMock()
1014
+ client.doi_lookup_with_title_check.return_value = {"title": ["X"]}
1015
+ unmatched, matched_by, queried_by = cs._resolve_doi_then_title(
1016
+ {"title": "X", "doi": "10.5/x"}, client
1017
+ )
1018
+ self.assertIs(unmatched, False)
1019
+ self.assertEqual(matched_by, "doi")
1020
+ self.assertEqual(queried_by, "id")
1021
+
1022
+ def test_doi_present_but_unmatched_queried_by_id(self):
1023
+ """DOI present, ID lookup miss, title miss → unmatched, queried_by='id'
1024
+ (an ID lookup WAS attempted — this is ID-keyed unmatched, C-V6(a))."""
1025
+ client = MagicMock()
1026
+ client.doi_lookup_with_title_check.return_value = None
1027
+ client.title_search.return_value = None
1028
+ unmatched, matched_by, queried_by = cs._resolve_doi_then_title(
1029
+ {"title": "Ghost", "doi": "10.5/fake"}, client
1030
+ )
1031
+ self.assertIs(unmatched, True)
1032
+ self.assertIsNone(matched_by)
1033
+ self.assertEqual(queried_by, "id")
1034
+
1035
+ def test_no_doi_unmatched_queried_by_title(self):
1036
+ """No DOI to key on → title-only search → unmatched, queried_by='title'
1037
+ (NOT id-keyed — coverage gap, must reduce to unresolvable not false)."""
1038
+ client = MagicMock()
1039
+ client.title_search.return_value = None
1040
+ unmatched, matched_by, queried_by = cs._resolve_doi_then_title(
1041
+ {"title": "Unindexed regional paper"}, client # no doi
1042
+ )
1043
+ self.assertIs(unmatched, True)
1044
+ self.assertIsNone(matched_by)
1045
+ self.assertEqual(queried_by, "title")
1046
+
1047
+ def test_no_doi_title_match_queried_by_title(self):
1048
+ client = MagicMock()
1049
+ client.title_search.return_value = {"title": ["X"]}
1050
+ unmatched, matched_by, queried_by = cs._resolve_doi_then_title(
1051
+ {"title": "X"}, client # no doi
1052
+ )
1053
+ self.assertIs(unmatched, False)
1054
+ self.assertEqual(matched_by, "title")
1055
+ self.assertEqual(queried_by, "title")
1056
+
1057
+
1058
+ class ResolveArxivQueriedByTest(unittest.TestCase):
1059
+ """_resolve_arxiv_id_then_title queried_by uses arxiv_id presence."""
1060
+
1061
+ def test_arxiv_id_present_unmatched_queried_by_id(self):
1062
+ client = MagicMock()
1063
+ client.arxiv_id_lookup.return_value = None
1064
+ client.title_search.return_value = None
1065
+ unmatched, matched_by, queried_by = cs._resolve_arxiv_id_then_title(
1066
+ {"title": "Ghost", "arxiv_id": "9999.99999"}, client
1067
+ )
1068
+ self.assertIs(unmatched, True)
1069
+ self.assertEqual(queried_by, "id")
1070
+
1071
+ # (#331) No test for the no-arxiv_id case here: _resolve_arxiv_id_then_title's
1072
+ # precondition is now "entry has an arxiv_id" — both callers
1073
+ # (resolve_arxiv_unmatched and verification_gate._run_arxiv) skip the resolver
1074
+ # before reaching it when arxiv_id is absent. The skip is covered by
1075
+ # ResolveArxivUnmatchedTest.test_arxiv_id_absent_skips_resolver and the
1076
+ # verification_gate skipped-status tests.
1077
+
1078
+ def test_arxiv_id_match_queried_by_id(self):
1079
+ client = MagicMock()
1080
+ client.arxiv_id_lookup.return_value = {"title": "X", "year": 2017}
1081
+ unmatched, matched_by, queried_by = cs._resolve_arxiv_id_then_title(
1082
+ {"title": "X", "arxiv_id": "1706.03762"}, client
1083
+ )
1084
+ self.assertIs(unmatched, False)
1085
+ self.assertEqual(matched_by, "arxiv")
1086
+ self.assertEqual(queried_by, "id")