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,1331 @@
1
+ #!/usr/bin/env python3
2
+ """Validate Schema 13.2 reviewer cards and recompute panel synthesis.
3
+
4
+ Schema 13.2 removes per-seat failure-condition decisions. This checker parses
5
+ role-scoped dimension scores, evaluates each condition per dimension over only
6
+ its assessed eligible seats, verifies the synthesizer audit lines, and enforces
7
+ the DA-CRITICAL terminal consistency gate.
8
+
9
+ Exit codes (precedence 2 > 3 > 1):
10
+ 0 pass
11
+ 1 synthesis-layer failure
12
+ 2 contract/infra failure
13
+ 3 reviewer-report failure
14
+ """
15
+ from __future__ import annotations
16
+
17
+ import argparse
18
+ import hashlib
19
+ import json
20
+ import re
21
+ import sys
22
+ import unicodedata
23
+ from dataclasses import dataclass
24
+ from html.parser import HTMLParser
25
+ from pathlib import Path
26
+
27
+ sys.path.insert(0, str(Path(__file__).resolve().parent))
28
+ import check_sprint_contract # noqa: E402
29
+
30
+ EXIT_PASS = 0
31
+ EXIT_SYNTHESIS = 1
32
+ EXIT_CONTRACT = 2
33
+ EXIT_REVIEWER = 3
34
+
35
+ ACTION_ENUM = frozenset({
36
+ "editorial_decision=accept",
37
+ "editorial_decision=minor_revision",
38
+ "editorial_decision=major_revision",
39
+ "editorial_decision=reject",
40
+ })
41
+ SCORE_ORDER = {"pass": 0, "warn": 1, "block": 2}
42
+ ROLE_SETS = check_sprint_contract.ROLE_SETS
43
+
44
+
45
+ class ContractError(Exception):
46
+ """Contract/infra failure -> exit 2."""
47
+
48
+
49
+ class ReportError(Exception):
50
+ """Reviewer-report failure -> exit 3."""
51
+
52
+
53
+ class SynthesisError(Exception):
54
+ """Synthesis-output failure -> exit 1."""
55
+
56
+
57
+ @dataclass(frozen=True)
58
+ class DimensionScore:
59
+ score: str
60
+ block_class: str | None = None
61
+ trigger: str | None = None
62
+ abstain_reason: str | None = None
63
+
64
+
65
+ @dataclass
66
+ class ReviewerReport:
67
+ path: str
68
+ role: str
69
+ scores: dict[str, DimensionScore]
70
+ text: str
71
+
72
+
73
+ @dataclass(frozen=True)
74
+ class ExpressionAtom:
75
+ dimension_ids: tuple[str, ...]
76
+ dimension_quantifier: str
77
+ score: str | None = None
78
+ or_worse: bool = False
79
+ fatal: bool = False
80
+
81
+
82
+ @dataclass
83
+ class Synthesis:
84
+ fired: list[str]
85
+ decision: str
86
+ dimension_verdicts: dict[str, str]
87
+ adjudications: dict[str, str]
88
+ rejection_rationales: dict[str, str]
89
+ marker_count: int | None
90
+
91
+
92
+ # --- Markdown helpers shared with check_phase_conformance.py -------------------
93
+
94
+ _FENCE_OPEN_RE = re.compile(
95
+ r"^ {0,3}(?P<fence>`{3,}|~{3,})(?P<info>[^\n]*)$"
96
+ )
97
+ _FENCE_CLOSE_RE = re.compile(
98
+ r"^ {0,3}(?P<fence>`{3,}|~{3,})[ \t]*$"
99
+ )
100
+ _COMMONMARK_LINE_END_RE = re.compile(r"\r\n?|\n")
101
+ _H2_RE = re.compile(r"^## (.+?)\s*$")
102
+ _H3_RE = re.compile(r"^### (.+?)\s*$")
103
+ _H4_RE = re.compile(r"^#### (.+?)\s*$")
104
+ _DIM_H3_RE = re.compile(r"^(?P<dim>D\d+): (?P<name>.+)$")
105
+ _ROLE_RE = re.compile(r"^contract_role: (?P<role>[a-z_]+)\s*$")
106
+ _SCORE_RE = re.compile(r"^score: (?P<value>block|warn|pass|not_assessed)\s*$")
107
+ _BLOCK_CLASS_RE = re.compile(r"^block_class: (?P<value>fatal|repairable)\s*$")
108
+ _TRIGGER_RE = re.compile(r'^trigger: "(?P<value>[^"\n]+)"\s*$')
109
+ _ABSTAIN_RE = re.compile(r"^abstain_reason: (?P<value>\S.*)\s*$")
110
+ _DECISION_RE = re.compile(r"^(?P<action>editorial_decision=[a-z_]+)\s*$")
111
+ _RETIRED_DECISION_RE = re.compile(
112
+ r"^\s*editorial_decision=\S+\s*$", re.IGNORECASE
113
+ )
114
+ _DA_SEVERITY_DECL_RE = re.compile(
115
+ r"\*\*Severity(?:\*\*)?\s*:",
116
+ re.IGNORECASE,
117
+ )
118
+ _DA_ISSUE_ID_RE = re.compile(r"^[CM][1-9]\d*$", re.IGNORECASE)
119
+ _DA_TYPED_ANCHOR_RE = re.compile(
120
+ r"^(?:text|table|figure|equation|dataset|absence)\s*:",
121
+ re.IGNORECASE,
122
+ )
123
+ _RAW_HTML_TABLE_RE = re.compile(
124
+ r"<\s*/?\s*(?:table|thead|tbody|tr|th|td)\b", re.IGNORECASE
125
+ )
126
+ _HTML_COMMENT_RE = re.compile(r"<!--")
127
+ _DA_FENCED_BLOCK_SENTINEL = "\0DA_FENCED_BLOCK\0"
128
+ _DEFAULT_IGNORABLE_RANGES = (
129
+ (0x00AD, 0x00AD), (0x034F, 0x034F), (0x061C, 0x061C),
130
+ (0x115F, 0x1160), (0x17B4, 0x17B5), (0x180B, 0x180F),
131
+ (0x200B, 0x200F), (0x202A, 0x202E), (0x2060, 0x206F),
132
+ (0x3164, 0x3164), (0xFE00, 0xFE0F), (0xFEFF, 0xFEFF),
133
+ (0xFFA0, 0xFFA0), (0xFFF0, 0xFFF8), (0x1BCA0, 0x1BCA3),
134
+ (0x1D173, 0x1D17A),
135
+ (0xE0000, 0xE0FFF),
136
+ )
137
+
138
+
139
+ def strip_fences(
140
+ text: str, *, preserve_fenced_blocks: bool = False
141
+ ) -> list[str]:
142
+ """Remove CommonMark fenced blocks; optionally retain an opaque sentinel."""
143
+ out: list[str] = []
144
+ fence_char: str | None = None
145
+ fence_len = 0
146
+ for line in _COMMONMARK_LINE_END_RE.split(text):
147
+ if fence_char is not None:
148
+ match = _FENCE_CLOSE_RE.fullmatch(line)
149
+ if match:
150
+ token = match.group("fence")
151
+ if token[0] == fence_char and len(token) >= fence_len:
152
+ fence_char, fence_len = None, 0
153
+ continue
154
+ match = _FENCE_OPEN_RE.fullmatch(line)
155
+ if match:
156
+ token = match.group("fence")
157
+ info = match.group("info")
158
+ if token[0] != "`" or "`" not in info:
159
+ fence_char, fence_len = token[0], len(token)
160
+ if preserve_fenced_blocks:
161
+ out.append(_DA_FENCED_BLOCK_SENTINEL)
162
+ continue
163
+ out.append(line)
164
+ return out
165
+
166
+
167
+ _INLINE_CODE_LINE_RE = re.compile(
168
+ r"^ {0,3}(?P<ticks>`+)(?P<body>[^`]+?)(?P=ticks)[ \t]*$"
169
+ )
170
+
171
+
172
+ def audit_candidate_lines(text: str) -> list[str]:
173
+ """Candidate lines for the synthesis mechanical audit-line grammars.
174
+
175
+ The four audit lines (``dimension_verdicts`` / ``fired_conditions`` /
176
+ ``da_critical_adjudications`` / bare ``editorial_decision=``) are
177
+ routinely emitted inside a CommonMark code fence, or wrapped whole in an
178
+ inline code span — both render the line verbatim and visibly to a
179
+ reader, so rejecting them is a false abort, not a leak guard (#637:
180
+ every synthesis first attempt of the 2026-08-03 baseline cohort, 6/6,
181
+ fenced the audit block; one retry re-emitted it as inline code spans).
182
+ This walker therefore keeps fenced content (dropping only the
183
+ fence-marker lines themselves, with the same open/close state machine as
184
+ ``strip_fences``) and additionally yields the unwrapped body of any
185
+ non-fenced line that is entirely one inline code span. Candidates are
186
+ normalized to what a CommonMark renderer would DISPLAY, since rendered
187
+ visibility is the acceptance criterion: an inline span whose body has
188
+ both a leading and a trailing space renders with one space stripped
189
+ from each side, and lines inside an indented fence render dedented by
190
+ up to the opener's indent — both normalizations are applied here so
191
+ the start-anchored grammars see the displayed text.
192
+
193
+ Declared boundaries (ACCEPTED misses — change deliberately, with
194
+ tests): blockquoted or emphasis-wrapped audit lines never match the
195
+ line-anchored grammars and stay non-candidates; an inline code span
196
+ inside a fence renders its backticks literally and is not unwrapped;
197
+ the rejection-rationale and DA-consistency-marker grammars keep the
198
+ plain-line source in ``parse_synthesis`` because both are quotable
199
+ diagnostics whose fenced or wrapped occurrences read as quotation.
200
+ One asymmetry of that boundary is accepted deliberately: a fenced
201
+ marker in a state where the marker is forbidden stays invisible to
202
+ ``check_da_terminal_gate`` and no longer aborts upstream (pre-#637 the
203
+ whole fenced block aborted at ``fired_conditions``); the editorial
204
+ decision itself is independently recomputed from the reviewer cards by
205
+ the layer-2 check, so the slip is an accounting cosmetic, not a
206
+ decision channel.
207
+ """
208
+ out: list[str] = []
209
+ fence_char: str | None = None
210
+ fence_len = 0
211
+ fence_indent = 0
212
+ for line in _COMMONMARK_LINE_END_RE.split(text):
213
+ if fence_char is not None:
214
+ match = _FENCE_CLOSE_RE.fullmatch(line)
215
+ if (match and match.group("fence")[0] == fence_char
216
+ and len(match.group("fence")) >= fence_len):
217
+ fence_char, fence_len, fence_indent = None, 0, 0
218
+ else:
219
+ dedent = 0
220
+ while (dedent < fence_indent and dedent < len(line)
221
+ and line[dedent] == " "):
222
+ dedent += 1
223
+ out.append(line[dedent:])
224
+ continue
225
+ match = _FENCE_OPEN_RE.fullmatch(line)
226
+ if match:
227
+ token = match.group("fence")
228
+ info = match.group("info")
229
+ if token[0] != "`" or "`" not in info:
230
+ fence_char, fence_len = token[0], len(token)
231
+ fence_indent = match.start("fence")
232
+ continue
233
+ out.append(line)
234
+ if span := _INLINE_CODE_LINE_RE.fullmatch(line):
235
+ body = span.group("body")
236
+ if (len(body) >= 2 and body[0] == " " and body[-1] == " "
237
+ and body.strip(" ")):
238
+ body = body[1:-1]
239
+ out.append(body)
240
+ return out
241
+
242
+
243
+ def _split_by(lines: list[str], heading_re: re.Pattern[str]):
244
+ sections: dict[str, list[str]] = {}
245
+ dupes: set[str] = set()
246
+ current: list[str] | None = None
247
+ for line in lines:
248
+ match = heading_re.match(line)
249
+ if match:
250
+ title = match.group(1)
251
+ if title in sections:
252
+ dupes.add(title)
253
+ current = sections.setdefault(title, [])
254
+ continue
255
+ if current is not None:
256
+ current.append(line)
257
+ return sections, dupes
258
+
259
+
260
+ def split_sections(lines: list[str]):
261
+ return _split_by(lines, _H2_RE)
262
+
263
+
264
+ def split_subsections(lines: list[str]):
265
+ return _split_by(lines, _H3_RE)
266
+
267
+
268
+ def exactly_one(
269
+ lines: list[str],
270
+ pattern: re.Pattern[str],
271
+ field: str,
272
+ path: str,
273
+ group: str = "value",
274
+ *,
275
+ required: bool = True,
276
+ ) -> str | None:
277
+ hits = [m.group(group) for line in lines if (m := pattern.fullmatch(line))]
278
+ expected = "exactly one" if required else "at most one"
279
+ if (required and len(hits) != 1) or (not required and len(hits) > 1):
280
+ raise ReportError(
281
+ f"[REPORT-PARSE: {path}: expected {expected} {field} line, "
282
+ f"found {len(hits)}]"
283
+ )
284
+ return hits[0] if hits else None
285
+
286
+
287
+ def _split_gfm_cells(row: str) -> list[str]:
288
+ cells: list[str] = []
289
+ current: list[str] = []
290
+ for char in row:
291
+ if char == "|":
292
+ backslashes = 0
293
+ for previous in reversed(current):
294
+ if previous != "\\":
295
+ break
296
+ backslashes += 1
297
+ if backslashes % 2 == 0:
298
+ cells.append("".join(current).strip())
299
+ current = []
300
+ continue
301
+ current.append(char)
302
+ cells.append("".join(current).strip())
303
+ return cells
304
+
305
+
306
+ def _markdown_cells(line: str) -> list[str]:
307
+ stripped = line.strip()
308
+ if not stripped.startswith("|") or not stripped.endswith("|"):
309
+ return []
310
+ return _split_gfm_cells(stripped[1:-1])
311
+
312
+
313
+ def _possible_markdown_cells(line: str) -> list[str]:
314
+ """Return cells from either outer-pipe or pipe-less GFM table rows."""
315
+ stripped = line.strip()
316
+ if "|" not in stripped:
317
+ return []
318
+ if stripped.startswith("|"):
319
+ stripped = stripped[1:]
320
+ if stripped.endswith("|"):
321
+ stripped = stripped[:-1]
322
+ return _split_gfm_cells(stripped)
323
+
324
+
325
+ class _VisibleTextHTMLParser(HTMLParser):
326
+ def __init__(self) -> None:
327
+ super().__init__(convert_charrefs=True)
328
+ self.parts: list[str] = []
329
+
330
+ def handle_data(self, data: str) -> None:
331
+ self.parts.append(data)
332
+
333
+
334
+ def _is_default_ignorable(char: str) -> bool:
335
+ codepoint = ord(char)
336
+ return any(start <= codepoint <= end for start, end in _DEFAULT_IGNORABLE_RANGES)
337
+
338
+
339
+ def _rendered_header_cell(cell: str) -> str:
340
+ """Normalize common inline Markdown wrappers to their visible cell text."""
341
+ rendered = re.sub(r"\\([^\w\s])", r"\1", cell)
342
+ rendered = re.sub(
343
+ r"!?\[([^\]]*)\](?:\([^)]+\)|\[[^\]]*\])", r"\1", rendered
344
+ )
345
+ rendered = re.sub(r"\[([^\]]+)\]", r"\1", rendered)
346
+ parser = _VisibleTextHTMLParser()
347
+ parser.feed(rendered)
348
+ rendered = "".join(parser.parts)
349
+ rendered = unicodedata.normalize("NFKC", rendered)
350
+ rendered = "".join(
351
+ char for char in rendered
352
+ if unicodedata.category(char) != "Cf"
353
+ and not _is_default_ignorable(char)
354
+ )
355
+ rendered = re.sub(r"[*_~`]+", "", rendered)
356
+ return re.sub(r"\s+", " ", rendered).strip().casefold()
357
+
358
+
359
+ def _balanced_square_brackets(text: str) -> bool:
360
+ """Return whether square brackets are ordered and balanced in locator text."""
361
+ depth = 0
362
+ for char in text:
363
+ if char == "[":
364
+ depth += 1
365
+ elif char == "]":
366
+ depth -= 1
367
+ if depth < 0:
368
+ return False
369
+ return depth == 0
370
+
371
+
372
+ def _quoted_excerpts(text: str) -> list[str] | None:
373
+ """Return every balanced straight/curly excerpt, including nested pairs."""
374
+ stack: list[tuple[str, int]] = []
375
+ excerpts: list[str] = []
376
+ for index, char in enumerate(text):
377
+ if char == "“":
378
+ stack.append(("curly", index + 1))
379
+ elif char == "”":
380
+ if not stack or stack[-1][0] != "curly":
381
+ return None
382
+ _, start = stack.pop()
383
+ excerpts.append(text[start:index])
384
+ elif char == '"':
385
+ if stack and stack[-1][0] == "straight":
386
+ _, start = stack.pop()
387
+ excerpts.append(text[start:index])
388
+ else:
389
+ stack.append(("straight", index + 1))
390
+ return None if stack else excerpts
391
+
392
+
393
+ def _absence_parts(text: str) -> tuple[str, str, str] | None:
394
+ """Parse the two reserved absence separators without regex backtracking."""
395
+ expected_separator = " — expected "
396
+ checked_separator = "; checked "
397
+ if (
398
+ text.count(expected_separator) != 1
399
+ or text.count(checked_separator) != 1
400
+ ):
401
+ return None
402
+ where, found_expected, remainder = text.partition(expected_separator)
403
+ expected, found_checked, surfaces = remainder.partition(checked_separator)
404
+ if not found_expected or not found_checked:
405
+ return None
406
+ parts = (where, expected, surfaces)
407
+ return parts if all(part.strip() for part in parts) else None
408
+
409
+
410
+ def validate_evidence_anchor(anchor: str, context: str) -> None:
411
+ """Validate the shared finding-anchor grammar for either checker."""
412
+ value = anchor.strip()
413
+ if value.startswith("["):
414
+ if not value.endswith("]"):
415
+ raise ReportError(
416
+ f"[ANCHOR-INVALID: {context}: unpaired square wrapper]"
417
+ )
418
+ square_inner = value[1:-1]
419
+ if square_inner != square_inner.strip():
420
+ raise ReportError(
421
+ f"[ANCHOR-INVALID: {context}: padded square wrapper]"
422
+ )
423
+ value = square_inner
424
+ if value.startswith("`"):
425
+ if not value.endswith("`"):
426
+ raise ReportError(
427
+ f"[ANCHOR-INVALID: {context}: unpaired backtick wrapper]"
428
+ )
429
+ backtick_inner = value[1:-1]
430
+ if backtick_inner != backtick_inner.strip():
431
+ raise ReportError(
432
+ f"[ANCHOR-INVALID: {context}: padded backtick wrapper]"
433
+ )
434
+ value = backtick_inner
435
+ match = re.match(
436
+ r"^(?P<type>text|table|figure|equation|dataset|absence):\s*"
437
+ r"(?P<tail>\S.*)$",
438
+ value,
439
+ re.IGNORECASE,
440
+ )
441
+ if not match:
442
+ tag = "ANCHOR-MISSING" if not value else "ANCHOR-INVALID"
443
+ raise ReportError(f"[{tag}: {context}: expected typed anchor]")
444
+ tail = match.group("tail")
445
+ if not _balanced_square_brackets(tail) or tail.count("`") % 2:
446
+ raise ReportError(
447
+ f"[ANCHOR-INVALID: {context}: locator delimiters must be balanced]"
448
+ )
449
+ if match.group("type").casefold() == "text":
450
+ quote_texts = _quoted_excerpts(tail)
451
+ if (
452
+ not quote_texts
453
+ or any(not text.strip() or len(text.split()) > 25
454
+ for text in quote_texts)
455
+ ):
456
+ raise ReportError(
457
+ f"[ANCHOR-INVALID: {context}: text anchor needs balanced "
458
+ "quoted excerpts of at most 25 words]"
459
+ )
460
+ elif match.group("type").casefold() == "absence":
461
+ if _absence_parts(tail) is None:
462
+ raise ReportError(
463
+ f"[ANCHOR-INVALID: {context}: absence anchor needs "
464
+ "<where> — expected <item>; checked <surfaces>]"
465
+ )
466
+
467
+
468
+ def _require_single_da_table_heading(
469
+ review_lines: list[str], heading: str, path: str
470
+ ) -> int:
471
+ """Return the sole exact DA issue-table heading position."""
472
+ parse_tag = f"DA-{heading}-PARSE"
473
+ starts = [
474
+ i for i, line in enumerate(review_lines)
475
+ if _H4_RE.fullmatch(line)
476
+ and _H4_RE.fullmatch(line).group(1) == heading
477
+ ]
478
+ if len(starts) != 1:
479
+ raise ReportError(
480
+ f"[{parse_tag}: {path}: expected exactly one "
481
+ f"#### {heading} section, found {len(starts)}]"
482
+ )
483
+ return starts[0]
484
+
485
+
486
+ def _parse_da_table_block(
487
+ review_lines: list[str], heading: str, path: str, start: int, end: int
488
+ ) -> tuple[list[list[str]], int, int]:
489
+ """Return table data lines plus ``#`` and anchor column positions."""
490
+ parse_tag = f"DA-{heading}-PARSE"
491
+ block = review_lines[start + 1:end]
492
+ nonblank = [i for i, line in enumerate(block) if line.strip()]
493
+ header_index = nonblank[0] if nonblank else None
494
+ if header_index is None:
495
+ raise ReportError(
496
+ f"[{parse_tag}: {path}: missing table header with # and "
497
+ "Evidence Anchor columns]"
498
+ )
499
+ header = _markdown_cells(block[header_index])
500
+ if "#" not in header or "Evidence Anchor" not in header:
501
+ raise ReportError(
502
+ f"[{parse_tag}: {path}: missing table header: first nonblank "
503
+ "line must have # and Evidence Anchor columns]"
504
+ )
505
+ if header.count("#") != 1 or header.count("Evidence Anchor") != 1:
506
+ raise ReportError(
507
+ f"[{parse_tag}: {path}: table header must contain exactly one # "
508
+ "and one Evidence Anchor column]"
509
+ )
510
+ separator_index = header_index + 1
511
+ separator = (
512
+ _markdown_cells(block[separator_index])
513
+ if separator_index < len(block) else []
514
+ )
515
+ if (
516
+ len(separator) != len(header)
517
+ or not all(re.fullmatch(r":?-{3,}:?", cell) for cell in separator)
518
+ ):
519
+ raise ReportError(
520
+ f"[{parse_tag}: {path}: missing or malformed Markdown table separator]"
521
+ )
522
+ rows: list[list[str]] = []
523
+ table_tail = block[header_index + 2:]
524
+ for index, line in enumerate(table_tail):
525
+ if not line.strip():
526
+ if any(
527
+ trailing.strip() for trailing in table_tail[index + 1:]
528
+ ):
529
+ raise ReportError(
530
+ f"[{parse_tag}: {path}: the DA issue tables are terminal; "
531
+ "put Review Body prose before #### CRITICAL and emit no "
532
+ "nonblank content after a table ends]"
533
+ )
534
+ break
535
+ cells = _markdown_cells(line)
536
+ if len(cells) != len(header):
537
+ raise ReportError(
538
+ f"[{parse_tag}: {path}: every data row must be an "
539
+ "outer-pipe-delimited row with the header column count]"
540
+ )
541
+ rows.append(cells)
542
+ return rows, header.index("#"), header.index("Evidence Anchor")
543
+
544
+
545
+ def _check_da_shadow_issue_surfaces(lines: list[str], path: str) -> None:
546
+ """Reject issue-table surfaces outside the two canonical DA bands."""
547
+ current_h2: str | None = None
548
+ in_canonical_da_band = False
549
+ for candidate in lines:
550
+ if h2_match := _H2_RE.fullmatch(candidate):
551
+ current_h2 = h2_match.group(1)
552
+ in_canonical_da_band = False
553
+ continue
554
+ if _H3_RE.fullmatch(candidate):
555
+ in_canonical_da_band = False
556
+ continue
557
+ if h4_match := _H4_RE.fullmatch(candidate):
558
+ in_canonical_da_band = (
559
+ current_h2 == "Review Body"
560
+ and h4_match.group(1) in {"CRITICAL", "MAJOR"}
561
+ )
562
+ continue
563
+ if _RAW_HTML_TABLE_RE.search(candidate):
564
+ raise ReportError(
565
+ f"[DA-TABLE-PARSE: {path}: unexpected raw HTML issue-table "
566
+ "surface outside the canonical CRITICAL and MAJOR bands]"
567
+ )
568
+ if in_canonical_da_band:
569
+ continue
570
+ raw_cells = _possible_markdown_cells(candidate)
571
+ cells = {_rendered_header_cell(cell) for cell in raw_cells}
572
+ issue_payload = any(
573
+ _DA_ISSUE_ID_RE.fullmatch(cell)
574
+ or _DA_TYPED_ANCHOR_RE.search(cell)
575
+ for cell in cells
576
+ )
577
+ if "#" in cells or "evidence anchor" in cells or issue_payload:
578
+ raise ReportError(
579
+ f"[DA-TABLE-PARSE: {path}: unexpected issue-table band outside "
580
+ "the canonical CRITICAL and MAJOR bands]"
581
+ )
582
+
583
+
584
+ def parse_da_tables(
585
+ text: str, path: str = "<report>"
586
+ ) -> tuple[dict[str, str], list[str]]:
587
+ """Parse both mandatory DA tables from the report's ``Review Body``.
588
+
589
+ Returns ``(critical_id_to_anchor, major_anchors)``. Both exact H4 sections
590
+ and their exact ``#`` / ``Evidence Anchor`` columns are required even when
591
+ their tables are empty. This is the single structural parser used by both
592
+ the phase-conformance and synthesis checkers.
593
+ """
594
+ raw_lines = _COMMONMARK_LINE_END_RE.split(text)
595
+ if any(_HTML_COMMENT_RE.search(line) for line in raw_lines):
596
+ raise ReportError(
597
+ f"[DA-TABLE-PARSE: {path}: HTML comments are forbidden in DA reports]"
598
+ )
599
+ lines = strip_fences(text, preserve_fenced_blocks=True)
600
+ sections, dupes = split_sections(lines)
601
+ if "Review Body" in dupes or "Review Body" not in sections:
602
+ raise ReportError(
603
+ f"[DA-TABLE-PARSE: {path}: expected exactly one ## Review Body]"
604
+ )
605
+ review_lines = sections["Review Body"]
606
+ if any(_DA_SEVERITY_DECL_RE.search(line) for line in lines):
607
+ raise ReportError(
608
+ f"[DA-FINDING-GRAMMAR: {path}: standalone Severity declarations "
609
+ "are forbidden; use the CRITICAL and MAJOR issue tables]"
610
+ )
611
+ critical_start = _require_single_da_table_heading(
612
+ review_lines, "CRITICAL", path
613
+ )
614
+ major_start = _require_single_da_table_heading(
615
+ review_lines, "MAJOR", path
616
+ )
617
+ if critical_start >= major_start:
618
+ raise ReportError(
619
+ f"[DA-TABLE-PARSE: {path}: #### CRITICAL must precede #### MAJOR]"
620
+ )
621
+ _check_da_shadow_issue_surfaces(lines, path)
622
+ critical_lines, critical_id_col, critical_anchor_col = _parse_da_table_block(
623
+ review_lines, "CRITICAL", path, critical_start, major_start
624
+ )
625
+ major_lines, major_id_col, major_anchor_col = _parse_da_table_block(
626
+ review_lines, "MAJOR", path, major_start, len(review_lines)
627
+ )
628
+
629
+ rows: dict[str, str] = {}
630
+ for cells in critical_lines:
631
+ finding_id = cells[critical_id_col]
632
+ if not re.fullmatch(r"C[1-9]\d*", finding_id):
633
+ raise ReportError(
634
+ f"[DA-CRITICAL-PARSE: {path}: invalid CRITICAL ID "
635
+ f"'{finding_id}'; expected C1..Cn]"
636
+ )
637
+ if finding_id in rows:
638
+ raise ReportError(
639
+ f"[DA-CRITICAL-PARSE: {path}: duplicate CRITICAL ID {finding_id}]"
640
+ )
641
+ anchor = cells[critical_anchor_col]
642
+ validate_evidence_anchor(anchor, f"{path}:{finding_id}")
643
+ rows[finding_id] = anchor
644
+
645
+ major_anchors: list[str] = []
646
+ for cells in major_lines:
647
+ if not cells[major_id_col]:
648
+ raise ReportError(
649
+ f"[DA-MAJOR-PARSE: {path}: empty MAJOR # cell]"
650
+ )
651
+ anchor = cells[major_anchor_col]
652
+ validate_evidence_anchor(anchor, f"{path}:DA MAJOR")
653
+ major_anchors.append(anchor)
654
+ return rows, major_anchors
655
+
656
+
657
+ def parse_da_critical_table(text: str, path: str = "<report>") -> dict[str, str]:
658
+ """Compatibility wrapper over the shared two-table DA parser."""
659
+ return parse_da_tables(text, path)[0]
660
+
661
+
662
+ # --- Contract and report parsing ----------------------------------------------
663
+
664
+ def _read_text(path: Path | str) -> str:
665
+ try:
666
+ return Path(path).read_text(encoding="utf-8")
667
+ except (OSError, UnicodeDecodeError) as exc:
668
+ raise ContractError(f"[IO-ERROR: {path}: {exc}]") from exc
669
+
670
+
671
+ def load_contract(path: Path | str):
672
+ try:
673
+ contract = json.loads(_read_text(path))
674
+ except json.JSONDecodeError as exc:
675
+ raise ContractError(f"[CONTRACT-INVALID: {path}: {exc}]") from exc
676
+ problems = check_sprint_contract.validate(contract)
677
+ problems += check_sprint_contract.check_structural_invariants(contract)
678
+ if problems:
679
+ raise ContractError(
680
+ f"[CONTRACT-INVALID: {path}: {'; '.join(problems)}]"
681
+ )
682
+ mode = contract.get("mode")
683
+ if mode not in ROLE_SETS:
684
+ raise ContractError(
685
+ f"[CONTRACT-INELIGIBLE: unsupported reviewer mode {mode}]"
686
+ )
687
+ expected = check_sprint_contract.EXPECTED_PANEL_SIZE[mode]
688
+ if contract.get("panel_size") != expected:
689
+ raise ContractError(
690
+ f"[CONTRACT-INELIGIBLE: panel_size={contract.get('panel_size')} "
691
+ f"inconsistent with mode={mode}; expected {expected}]"
692
+ )
693
+ accept_grade_action(contract["failure_conditions"])
694
+ dimensions = {d["id"]: d for d in contract["acceptance_dimensions"]}
695
+ expressions = {
696
+ condition["condition_id"]: parse_expression(
697
+ condition["expression"], dimensions, condition["condition_id"]
698
+ )
699
+ for condition in contract["failure_conditions"]
700
+ }
701
+ return contract, expressions
702
+
703
+
704
+ def parse_report(path: str, text: str, contract: dict) -> ReviewerReport:
705
+ lines = strip_fences(text)
706
+ sections, dupes = split_sections(lines)
707
+ if "Dimension Scores" in dupes:
708
+ raise ReportError(
709
+ f"[REPORT-PARSE: {path}: duplicated ## Dimension Scores]"
710
+ )
711
+ if "Dimension Scores" not in sections:
712
+ raise ReportError(
713
+ f"[REPORT-PARSE: {path}: missing ## Dimension Scores]"
714
+ )
715
+ for retired in ("Failure Condition Checks", "Editorial Decision"):
716
+ if retired in sections:
717
+ raise ReportError(
718
+ f"[V1-GRAMMAR-RETIRED: {path}: ## {retired} is forbidden "
719
+ "under Schema 13.2]"
720
+ )
721
+ if any(_RETIRED_DECISION_RE.fullmatch(line) for line in lines):
722
+ raise ReportError(
723
+ f"[V1-GRAMMAR-RETIRED: {path}: bare editorial_decision line is "
724
+ "forbidden under Schema 13.2]"
725
+ )
726
+ role = exactly_one(lines, _ROLE_RE, "contract_role", path, "role")
727
+ role_set = ROLE_SETS[contract["mode"]]
728
+ if role not in role_set:
729
+ raise ReportError(
730
+ f"[REPORT-ROLE: {path}: role={role} is not valid for "
731
+ f"{contract['mode']}]"
732
+ )
733
+
734
+ dims = {d["id"]: d for d in contract["acceptance_dimensions"]}
735
+ subsections, subsection_dupes = split_subsections(sections["Dimension Scores"])
736
+ if subsection_dupes:
737
+ raise ReportError(
738
+ f"[REPORT-PARSE: {path}: duplicated Dimension Scores subsection(s) "
739
+ f"{sorted(subsection_dupes)}]"
740
+ )
741
+ scores: dict[str, DimensionScore] = {}
742
+ for title, sublines in subsections.items():
743
+ match = _DIM_H3_RE.fullmatch(title)
744
+ if not match or match.group("dim") not in dims:
745
+ raise ReportError(
746
+ f"[REPORT-PARSE: {path}: unknown Dimension Scores subsection "
747
+ f"'### {title}']"
748
+ )
749
+ did = match.group("dim")
750
+ if match.group("name") != dims[did]["name"]:
751
+ raise ReportError(
752
+ f"[REPORT-PARSE: {path}: {did} name mismatch]"
753
+ )
754
+ score = exactly_one(sublines, _SCORE_RE, f"score ({did})", path)
755
+ block_class = exactly_one(
756
+ sublines, _BLOCK_CLASS_RE, f"block_class ({did})", path,
757
+ required=False
758
+ )
759
+ trigger = exactly_one(
760
+ sublines, _TRIGGER_RE, f"trigger ({did})", path, required=False
761
+ )
762
+ abstain_reason = exactly_one(
763
+ sublines, _ABSTAIN_RE, f"abstain_reason ({did})", path,
764
+ required=False
765
+ )
766
+ eligible = role in dims[did]["eligible_roles"]
767
+ if eligible and score == "not_assessed" and not abstain_reason:
768
+ raise ReportError(
769
+ f"[ABSTENTION-INVALID: {path}: eligible role {role} must give "
770
+ f"abstain_reason for {did}]"
771
+ )
772
+ if not eligible and score != "not_assessed":
773
+ raise ReportError(
774
+ f"[OUT-OF-ROLE-SCORE: {path}: role {role} may not score {did}]"
775
+ )
776
+ if not eligible and abstain_reason:
777
+ raise ReportError(
778
+ f"[ABSTENTION-INVALID: {path}: structural abstention on {did} "
779
+ "must not carry abstain_reason]"
780
+ )
781
+ mandatory_block = (
782
+ eligible and score == "block" and dims[did]["priority"] == "mandatory"
783
+ )
784
+ if mandatory_block != bool(block_class):
785
+ raise ReportError(
786
+ f"[BLOCK-CLASS-INVALID: {path}: {did} block_class is required "
787
+ "iff an eligible mandatory dimension scores block]"
788
+ )
789
+ needs_trigger = eligible and score in {"block", "warn"}
790
+ if needs_trigger != bool(trigger):
791
+ raise ReportError(
792
+ f"[TRIGGER-GRAMMAR: {path}: {did} trigger is required iff an "
793
+ "eligible dimension scores block or warn]"
794
+ )
795
+ if score != "not_assessed" and abstain_reason:
796
+ raise ReportError(
797
+ f"[ABSTENTION-INVALID: {path}: {did} scored result may not "
798
+ "carry abstain_reason]"
799
+ )
800
+ scores[did] = DimensionScore(
801
+ score, block_class, trigger, abstain_reason
802
+ )
803
+ missing = [did for did in dims if did not in scores]
804
+ if missing:
805
+ raise ReportError(
806
+ f"[REPORT-PARSE: {path}: missing Dimension Scores for {missing}]"
807
+ )
808
+ return ReviewerReport(path, role, scores, text)
809
+
810
+
811
+ # --- Closed expression grammar and two-stage evaluation -----------------------
812
+
813
+ _SCORE = r"'(?P<score>block|warn|pass)'"
814
+ _EXPRESSION_PATTERNS = (
815
+ ("any_priority", re.compile(
816
+ r"^any (?:(?P<p1>[a-z]+) dimension|dimension with priority="
817
+ r"(?P<p2>[a-z]+)|(?P<p3>[a-z]+)-priority dimension) scores "
818
+ + _SCORE + r"$")),
819
+ ("count_priority", re.compile(
820
+ r"^two or more (?:(?P<p1>[a-z]+) dimensions|dimensions with priority="
821
+ r"(?P<p2>[a-z]+)) score " + _SCORE + r" or worse$")),
822
+ ("every_priority", re.compile(
823
+ r"^every (?P<p1>[a-z]+) dimension scores " + _SCORE + r"$")),
824
+ ("dim_exact", re.compile(r"^(?P<dim>D\d+) scores " + _SCORE + r"$")),
825
+ ("fatal_priority", re.compile(
826
+ r"^any (?P<p1>[a-z]+) dimension has a fatal block$")),
827
+ ("fatal_dim", re.compile(r"^(?P<dim>D\d+) has a fatal block$")),
828
+ ("any_all", re.compile(
829
+ r"^any dimension scores " + _SCORE + r" or worse$")),
830
+ ("dim_threshold", re.compile(
831
+ r"^(?P<dim>D\d+) scores " + _SCORE + r" or worse$")),
832
+ ("every_all", re.compile(
833
+ r"^every dimension scores " + _SCORE + r"$")),
834
+ )
835
+
836
+
837
+ def parse_expression(
838
+ expression: str, dimensions: dict[str, dict], condition_id: str
839
+ ) -> tuple[ExpressionAtom, ...]:
840
+ atoms: list[ExpressionAtom] = []
841
+ for part in expression.split(" AND "):
842
+ for kind, pattern in _EXPRESSION_PATTERNS:
843
+ match = pattern.fullmatch(part)
844
+ if match:
845
+ break
846
+ else:
847
+ raise ContractError(
848
+ f"[EXPRESSION-UNRECOGNISED: condition_id={condition_id}, "
849
+ f"expression={expression}]"
850
+ )
851
+ if kind in {"dim_exact", "fatal_dim", "dim_threshold"}:
852
+ did = match.group("dim")
853
+ if did not in dimensions:
854
+ raise ContractError(
855
+ f"[EXPRESSION-SEMANTIC: condition_id={condition_id}: "
856
+ f"unknown dimension {did}]"
857
+ )
858
+ dim_ids = (did,)
859
+ elif kind in {"any_all", "every_all"}:
860
+ dim_ids = tuple(dimensions)
861
+ else:
862
+ priority = match.group("p1") or match.groupdict().get("p2") \
863
+ or match.groupdict().get("p3")
864
+ dim_ids = tuple(
865
+ did for did, dim in dimensions.items()
866
+ if dim["priority"] == priority
867
+ )
868
+ if not dim_ids:
869
+ raise ContractError(
870
+ f"[EXPRESSION-SEMANTIC: condition_id={condition_id}: "
871
+ f"priority '{priority}' matches no dimension]"
872
+ )
873
+ fatal = kind in {"fatal_priority", "fatal_dim"}
874
+ if fatal and any(dimensions[did]["priority"] != "mandatory"
875
+ for did in dim_ids):
876
+ raise ContractError(
877
+ f"[CONTRACT-INVALID: condition_id={condition_id}: fatal atom "
878
+ "may target mandatory dimensions only]"
879
+ )
880
+ dimension_quantifier = (
881
+ "count2" if kind == "count_priority"
882
+ else "every" if kind in {"every_priority", "every_all"}
883
+ else "any"
884
+ )
885
+ atoms.append(ExpressionAtom(
886
+ dimension_ids=dim_ids,
887
+ dimension_quantifier=dimension_quantifier,
888
+ score=None if fatal else match.groupdict().get("score"),
889
+ or_worse=kind in {
890
+ "count_priority", "any_all", "dim_threshold"
891
+ },
892
+ fatal=fatal,
893
+ ))
894
+ return tuple(atoms)
895
+
896
+
897
+ def quantifier_fires(
898
+ quantifier: str, indicators: list[bool], warnings: list[str]
899
+ ) -> bool:
900
+ n = len(indicators)
901
+ if n == 0:
902
+ raise ContractError("[DIMENSION-UNASSESSED]")
903
+ k = sum(indicators)
904
+ if quantifier == "any":
905
+ return k >= 1
906
+ if quantifier == "all":
907
+ return k == n
908
+ if quantifier == "majority":
909
+ threshold = 1 if n == 1 else (2 if n == 2 else n // 2 + 1)
910
+ return k >= threshold
911
+ raise ContractError(f"unknown cross_reviewer_quantifier '{quantifier}'")
912
+
913
+
914
+ def _seat_indicator(value: DimensionScore, atom: ExpressionAtom) -> bool:
915
+ if atom.fatal:
916
+ return value.score == "block" and value.block_class == "fatal"
917
+ if atom.or_worse:
918
+ return SCORE_ORDER[value.score] >= SCORE_ORDER[atom.score]
919
+ return value.score == atom.score
920
+
921
+
922
+ def evaluate_expression(
923
+ atoms: tuple[ExpressionAtom, ...],
924
+ assessed: dict[str, list[DimensionScore]],
925
+ cross_quantifier: str,
926
+ warnings: list[str],
927
+ ) -> bool:
928
+ for atom in atoms:
929
+ dimension_results = []
930
+ for did in atom.dimension_ids:
931
+ values = assessed[did]
932
+ dimension_results.append(quantifier_fires(
933
+ cross_quantifier,
934
+ [_seat_indicator(value, atom) for value in values],
935
+ warnings,
936
+ ))
937
+ if atom.dimension_quantifier == "any":
938
+ result = any(dimension_results)
939
+ elif atom.dimension_quantifier == "every":
940
+ result = all(dimension_results)
941
+ else:
942
+ result = sum(dimension_results) >= 2
943
+ if not result:
944
+ return False
945
+ return True
946
+
947
+
948
+ def accept_grade_action(conditions: list[dict]) -> str:
949
+ for condition in conditions:
950
+ if condition["action"] == "editorial_decision=accept":
951
+ return condition["action"]
952
+ raise ContractError(
953
+ "[CONTRACT-INELIGIBLE: no accept-grade failure condition]"
954
+ )
955
+
956
+
957
+ def resolve_decision(conditions: list[dict], fired_ids: set[str]) -> str:
958
+ fired = [(index, condition) for index, condition in enumerate(conditions)
959
+ if condition["condition_id"] in fired_ids]
960
+ if not fired:
961
+ return accept_grade_action(conditions)
962
+ return max(
963
+ fired, key=lambda pair: (pair[1]["severity"], -pair[0])
964
+ )[1]["action"]
965
+
966
+
967
+ def collect_assessed(
968
+ reports: list[ReviewerReport], contract: dict
969
+ ) -> dict[str, list[DimensionScore]]:
970
+ assessed: dict[str, list[DimensionScore]] = {}
971
+ for dim in contract["acceptance_dimensions"]:
972
+ did = dim["id"]
973
+ values = [
974
+ report.scores[did]
975
+ for report in reports
976
+ if report.role in dim["eligible_roles"]
977
+ and report.scores[did].score != "not_assessed"
978
+ ]
979
+ if not values:
980
+ raise ContractError(f"[DIMENSION-UNASSESSED: {did}]")
981
+ assessed[did] = values
982
+ return assessed
983
+
984
+
985
+ def compute_dimension_verdicts(
986
+ assessed: dict[str, list[DimensionScore]]
987
+ ) -> dict[str, str]:
988
+ verdicts: dict[str, str] = {}
989
+ for did, values in assessed.items():
990
+ if any(value.score == "block" and value.block_class == "fatal"
991
+ for value in values):
992
+ verdicts[did] = "block(fatal)"
993
+ else:
994
+ verdicts[did] = max(values, key=lambda value:
995
+ SCORE_ORDER[value.score]).score
996
+ return verdicts
997
+
998
+
999
+ def recompute_panel(
1000
+ reports: list[ReviewerReport],
1001
+ contract: dict,
1002
+ expressions: dict[str, tuple[ExpressionAtom, ...]],
1003
+ warnings: list[str],
1004
+ ):
1005
+ assessed = collect_assessed(reports, contract)
1006
+ fired: list[str] = []
1007
+ for condition in contract["failure_conditions"]:
1008
+ if evaluate_expression(
1009
+ expressions[condition["condition_id"]],
1010
+ assessed,
1011
+ condition["cross_reviewer_quantifier"],
1012
+ warnings,
1013
+ ):
1014
+ fired.append(condition["condition_id"])
1015
+ decision = resolve_decision(contract["failure_conditions"], set(fired))
1016
+ return assessed, fired, decision
1017
+
1018
+
1019
+ # --- Synthesis grammar and DA-CRITICAL gate ------------------------------------
1020
+
1021
+ _LIST_BODY = r"(?P<body>[^\]]*)"
1022
+ _FIRED_LIST_RE = re.compile(r"^fired_conditions: \[" + _LIST_BODY + r"\]\s*$")
1023
+ _VERDICTS_RE = re.compile(r"^dimension_verdicts: \[" + _LIST_BODY + r"\]\s*$")
1024
+ _ADJUDICATIONS_RE = re.compile(
1025
+ r"^da_critical_adjudications: \[" + _LIST_BODY + r"\]\s*$"
1026
+ )
1027
+ _RATIONALE_RE = re.compile(
1028
+ r"^(?P<id>C[1-9]\d*) rejection rationale: (?P<text>\S.*)\s*$"
1029
+ )
1030
+ _MARKER_RE = re.compile(
1031
+ r"^\[DA-CRITICAL-VS-ACCEPT: (?P<count>\d+) "
1032
+ r"validated/unresolved\]\s*$"
1033
+ )
1034
+
1035
+
1036
+ def _one_body(
1037
+ lines: list[str], pattern: re.Pattern[str], label: str, path: str
1038
+ ) -> str:
1039
+ """Exactly one DISTINCT body for an audit-line grammar.
1040
+
1041
+ Re-statements of an audit line that parse to the SAME stripped body (a
1042
+ plain line plus its fenced copy, or a padded inline-span variant of it)
1043
+ collapse to one value; the collapse is value-level, not byte-level, by
1044
+ design — the candidate list already mixes raw lines with their
1045
+ rendering-normalized forms. Two candidates that parse to different
1046
+ bodies remain a loud abort, so a decoy that disagrees with the
1047
+ operative line can never be silently absorbed (#637).
1048
+ """
1049
+ bodies = [match.group("body").strip() for line in lines
1050
+ if (match := pattern.fullmatch(line))]
1051
+ distinct = list(dict.fromkeys(bodies))
1052
+ if len(distinct) != 1:
1053
+ raise SynthesisError(
1054
+ f"[SYNTHESIS-PARSE: {path}: expected exactly one {label} line, "
1055
+ f"found {len(distinct)}]"
1056
+ )
1057
+ return distinct[0]
1058
+
1059
+
1060
+ def _comma_tokens(body: str) -> list[str]:
1061
+ return [token.strip() for token in body.split(",") if token.strip()]
1062
+
1063
+
1064
+ def parse_synthesis(path: str, text: str, contract: dict) -> Synthesis:
1065
+ # The four mechanical audit lines read from the decoration-tolerant
1066
+ # candidate source; rationales and the DA marker stay plain-line-only
1067
+ # (see audit_candidate_lines for the declared boundary).
1068
+ lines = strip_fences(text)
1069
+ audit_lines = audit_candidate_lines(text)
1070
+ fired = _comma_tokens(_one_body(
1071
+ audit_lines, _FIRED_LIST_RE, "fired_conditions", path
1072
+ ))
1073
+ condition_ids = {c["condition_id"] for c in contract["failure_conditions"]}
1074
+ if len(fired) != len(set(fired)) or set(fired) - condition_ids:
1075
+ raise SynthesisError(
1076
+ f"[SYNTHESIS-PARSE: {path}: invalid fired_conditions {fired}]"
1077
+ )
1078
+
1079
+ verdict_tokens = _comma_tokens(_one_body(
1080
+ audit_lines, _VERDICTS_RE, "dimension_verdicts", path
1081
+ ))
1082
+ verdicts: dict[str, str] = {}
1083
+ for token in verdict_tokens:
1084
+ match = re.fullmatch(
1085
+ r"(?P<dim>D\d+)=(?P<value>pass|warn|block|block\(fatal\))", token
1086
+ )
1087
+ if not match or match.group("dim") in verdicts:
1088
+ raise SynthesisError(
1089
+ f"[SYNTHESIS-PARSE: {path}: invalid dimension verdict "
1090
+ f"'{token}']"
1091
+ )
1092
+ verdicts[match.group("dim")] = match.group("value")
1093
+
1094
+ adjudication_tokens = _comma_tokens(_one_body(
1095
+ audit_lines, _ADJUDICATIONS_RE, "da_critical_adjudications", path
1096
+ ))
1097
+ adjudications: dict[str, str] = {}
1098
+ for token in adjudication_tokens:
1099
+ match = re.fullmatch(
1100
+ r"(?P<id>C[1-9]\d*)=(?P<value>VALIDATED|REJECTED|UNRESOLVED)",
1101
+ token,
1102
+ )
1103
+ if not match or match.group("id") in adjudications:
1104
+ raise SynthesisError(
1105
+ f"[SYNTHESIS-PARSE: {path}: invalid DA adjudication "
1106
+ f"'{token}']"
1107
+ )
1108
+ adjudications[match.group("id")] = match.group("value")
1109
+
1110
+ decisions = list(dict.fromkeys(
1111
+ match.group("action") for line in audit_lines
1112
+ if (match := _DECISION_RE.fullmatch(line))
1113
+ ))
1114
+ if len(decisions) != 1 or decisions[0] not in ACTION_ENUM:
1115
+ raise SynthesisError(
1116
+ f"[SYNTHESIS-PARSE: {path}: expected exactly one valid decision]"
1117
+ )
1118
+ rationales: dict[str, str] = {}
1119
+ for line in lines:
1120
+ if match := _RATIONALE_RE.fullmatch(line):
1121
+ if match.group("id") in rationales:
1122
+ raise SynthesisError(
1123
+ f"[SYNTHESIS-PARSE: {path}: duplicate rejection rationale "
1124
+ f"for {match.group('id')}]"
1125
+ )
1126
+ rationales[match.group("id")] = match.group("text")
1127
+ markers = [int(match.group("count")) for line in lines
1128
+ if (match := _MARKER_RE.fullmatch(line))]
1129
+ if len(markers) > 1:
1130
+ raise SynthesisError(
1131
+ f"[SYNTHESIS-PARSE: {path}: duplicate DA consistency marker]"
1132
+ )
1133
+ return Synthesis(
1134
+ fired=fired,
1135
+ decision=decisions[0],
1136
+ dimension_verdicts=verdicts,
1137
+ adjudications=adjudications,
1138
+ rejection_rationales=rationales,
1139
+ marker_count=markers[0] if markers else None,
1140
+ )
1141
+
1142
+
1143
+ def check_da_terminal_gate(
1144
+ reports: list[ReviewerReport], synthesis: Synthesis
1145
+ ) -> list[str]:
1146
+ da = next((report for report in reports if report.role == "da"), None)
1147
+ da_ids = set(parse_da_tables(da.text, da.path)[0]) if da is not None else set()
1148
+ adjudicated_ids = set(synthesis.adjudications)
1149
+ diagnostics: list[str] = []
1150
+ if da_ids != adjudicated_ids:
1151
+ diagnostics.append(
1152
+ f"[DA-CRITICAL-ADJUDICATION-MISMATCH: report={sorted(da_ids)}, "
1153
+ f"synthesis={sorted(adjudicated_ids)}]"
1154
+ )
1155
+ for finding_id, value in synthesis.adjudications.items():
1156
+ if value == "REJECTED" and finding_id not in synthesis.rejection_rationales:
1157
+ diagnostics.append(
1158
+ f"[DA-CRITICAL-RATIONALE-MISSING: {finding_id}]"
1159
+ )
1160
+ active = sum(value in {"VALIDATED", "UNRESOLVED"}
1161
+ for value in synthesis.adjudications.values())
1162
+ needs_marker = (
1163
+ synthesis.decision == "editorial_decision=accept" and active > 0
1164
+ )
1165
+ if needs_marker and synthesis.marker_count != active:
1166
+ diagnostics.append(
1167
+ f"[DA-CRITICAL-VS-ACCEPT-MARKER: expected={active}, "
1168
+ f"stated={synthesis.marker_count}]"
1169
+ )
1170
+ if not needs_marker and synthesis.marker_count is not None:
1171
+ diagnostics.append(
1172
+ "[DA-CRITICAL-VS-ACCEPT-MARKER: marker forbidden in this state]"
1173
+ )
1174
+ return diagnostics
1175
+
1176
+
1177
+ def layer2_check(
1178
+ reports: list[ReviewerReport],
1179
+ contract: dict,
1180
+ expressions: dict[str, tuple[ExpressionAtom, ...]],
1181
+ synthesis: Synthesis,
1182
+ warnings: list[str],
1183
+ ) -> list[str]:
1184
+ assessed, fired, decision = recompute_panel(
1185
+ reports, contract, expressions, warnings
1186
+ )
1187
+ verdicts = compute_dimension_verdicts(assessed)
1188
+ diagnostics: list[str] = []
1189
+ if (fired != synthesis.fired or decision != synthesis.decision
1190
+ or verdicts != synthesis.dimension_verdicts):
1191
+ diagnostics.append(
1192
+ f"[PANEL-SYNTHESIS-MISMATCH: recomputed_verdicts={verdicts}, "
1193
+ f"declared_verdicts={synthesis.dimension_verdicts}, "
1194
+ f"recomputed_fired={fired}, declared_fired={synthesis.fired}, "
1195
+ f"recomputed={decision}, stated={synthesis.decision}]"
1196
+ )
1197
+ diagnostics.extend(check_da_terminal_gate(reports, synthesis))
1198
+ return diagnostics
1199
+
1200
+
1201
+ # --- CLI -----------------------------------------------------------------------
1202
+
1203
+ def _parse_args(argv):
1204
+ parser = argparse.ArgumentParser(description=__doc__)
1205
+ parser.add_argument("--contract", required=True, type=Path)
1206
+ parser.add_argument("--report", required=True, action="append",
1207
+ type=Path, dest="reports")
1208
+ parser.add_argument(
1209
+ "--roles",
1210
+ help="Comma-separated dispatch roles, positionally matched to reports",
1211
+ )
1212
+ group = parser.add_mutually_exclusive_group(required=True)
1213
+ group.add_argument("--synthesis", type=Path)
1214
+ group.add_argument("--layer1-only", action="store_true")
1215
+ return parser.parse_args(argv)
1216
+
1217
+
1218
+ def main(argv=None):
1219
+ args = _parse_args(argv)
1220
+ warnings: list[str] = []
1221
+ infra: list[str] = []
1222
+ reviewer_diags: list[str] = []
1223
+ synthesis_diags: list[str] = []
1224
+ try:
1225
+ contract, expressions = load_contract(args.contract)
1226
+ except ContractError as exc:
1227
+ print(exc)
1228
+ return EXIT_CONTRACT
1229
+
1230
+ panel_size = contract["panel_size"]
1231
+ resolved = [path.resolve() for path in args.reports]
1232
+ if len(set(resolved)) != len(resolved):
1233
+ infra.append("[PANEL-CARDINALITY: duplicate report paths]")
1234
+ if args.layer1_only:
1235
+ if not 1 <= len(args.reports) <= panel_size:
1236
+ infra.append(
1237
+ f"[PANEL-CARDINALITY: layer1-only accepts 1..{panel_size} "
1238
+ f"reports, got={len(args.reports)}]"
1239
+ )
1240
+ elif len(args.reports) != panel_size:
1241
+ infra.append(
1242
+ f"[PANEL-CARDINALITY: got={len(args.reports)}, "
1243
+ f"panel_size={panel_size}]"
1244
+ )
1245
+
1246
+ texts: dict[Path, str] = {}
1247
+ digests: set[str] = set()
1248
+ seen_paths: set[Path] = set()
1249
+ for path in args.reports:
1250
+ try:
1251
+ texts[path] = _read_text(path)
1252
+ except ContractError as exc:
1253
+ infra.append(str(exc))
1254
+ continue
1255
+ resolved_path = path.resolve()
1256
+ if resolved_path in seen_paths:
1257
+ continue
1258
+ seen_paths.add(resolved_path)
1259
+ digest = hashlib.sha256(texts[path].encode()).hexdigest()
1260
+ if digest in digests:
1261
+ infra.append(
1262
+ f"[PANEL-CARDINALITY: byte-identical report contents ({path})]"
1263
+ )
1264
+ digests.add(digest)
1265
+
1266
+ reports: list[ReviewerReport] = []
1267
+ for path in args.reports:
1268
+ if path not in texts:
1269
+ continue
1270
+ try:
1271
+ reports.append(parse_report(str(path), texts[path], contract))
1272
+ except ReportError as exc:
1273
+ reviewer_diags.append(str(exc))
1274
+
1275
+ if len(reports) == len(args.reports):
1276
+ roles = [report.role for report in reports]
1277
+ role_set = ROLE_SETS[contract["mode"]]
1278
+ if args.layer1_only:
1279
+ if len(set(roles)) != len(roles):
1280
+ infra.append(f"[PANEL-CARDINALITY: duplicate roles {roles}]")
1281
+ elif set(roles) != role_set or len(set(roles)) != len(roles):
1282
+ infra.append(
1283
+ f"[PANEL-CARDINALITY: roles {sorted(roles)} != "
1284
+ f"required {sorted(role_set)}]"
1285
+ )
1286
+ if args.roles is not None:
1287
+ dispatched = [role.strip() for role in args.roles.split(",")]
1288
+ if len(dispatched) != len(reports):
1289
+ infra.append(
1290
+ f"[ROLE-BINDING: --roles count={len(dispatched)} does not "
1291
+ f"match reports={len(reports)}]"
1292
+ )
1293
+ else:
1294
+ for index, (expected, report) in enumerate(
1295
+ zip(dispatched, reports)
1296
+ ):
1297
+ if expected != report.role:
1298
+ reviewer_diags.append(
1299
+ f"[ROLE-BINDING: report[{index}] declares "
1300
+ f"{report.role}, dispatched as {expected}]"
1301
+ )
1302
+
1303
+ if not args.layer1_only and not infra and not reviewer_diags:
1304
+ try:
1305
+ synthesis = parse_synthesis(
1306
+ str(args.synthesis), _read_text(args.synthesis), contract
1307
+ )
1308
+ synthesis_diags.extend(layer2_check(
1309
+ reports, contract, expressions, synthesis, warnings
1310
+ ))
1311
+ except ContractError as exc:
1312
+ infra.append(str(exc))
1313
+ except ReportError as exc:
1314
+ reviewer_diags.append(str(exc))
1315
+ except SynthesisError as exc:
1316
+ synthesis_diags.append(str(exc))
1317
+
1318
+ for diagnostic in warnings + infra + reviewer_diags + synthesis_diags:
1319
+ print(diagnostic)
1320
+ if infra:
1321
+ return EXIT_CONTRACT
1322
+ if reviewer_diags:
1323
+ return EXIT_REVIEWER
1324
+ if synthesis_diags:
1325
+ return EXIT_SYNTHESIS
1326
+ print("LAYER1-ONLY: PASS" if args.layer1_only else "PANEL-SYNTHESIS: PASS")
1327
+ return EXIT_PASS
1328
+
1329
+
1330
+ if __name__ == "__main__":
1331
+ sys.exit(main())