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,1592 @@
1
+ #!/usr/bin/env python3
2
+ """Deterministic, advisory-only cross-run adjudication activity recorder.
3
+
4
+ The runtime intentionally has no default paths, clock, network, model, judge,
5
+ directory scan, or environment-variable inputs. All authority comes from an
6
+ explicit terminal state, its sealed five-family inventory, and hash-bound
7
+ artifacts beneath an explicit artifact root.
8
+ """
9
+
10
+ from __future__ import annotations
11
+
12
+ import argparse
13
+ import copy
14
+ import errno
15
+ import fcntl
16
+ import hashlib
17
+ import json
18
+ import os
19
+ import re
20
+ import stat
21
+ import sys
22
+ import tempfile
23
+ from contextlib import contextmanager
24
+ from pathlib import Path, PurePosixPath
25
+ from typing import Any, Iterator, Sequence
26
+
27
+ from jsonschema import Draft202012Validator, FormatChecker
28
+ from referencing import Registry, Resource
29
+
30
+
31
+ REPO_ROOT = Path(__file__).resolve().parents[1]
32
+ INPUT_SCHEMA_PATH = REPO_ROOT / "shared/contracts/activity/adjudication_activity_input.schema.json"
33
+ STORE_SCHEMA_PATH = REPO_ROOT / "shared/contracts/activity/adjudication_activity_store.schema.json"
34
+ COMPLIANCE_SCHEMA_PATH = REPO_ROOT / "shared/compliance_report.schema.json"
35
+ REVISION_CONTRACTS = REPO_ROOT / "shared/contracts/revision"
36
+ REREVIEW_CONTRACTS = REPO_ROOT / "shared/contracts/re_review"
37
+
38
+ INPUT_VERSION = "adjudication-activity-input/1.0"
39
+ STORE_VERSION = "adjudication-activity-store/1.0"
40
+ SOURCE_FAMILIES = (
41
+ "revision_author_adjudication",
42
+ "compliance_report",
43
+ "re_review_traceability",
44
+ "explicit_user_request",
45
+ "mandatory_checkpoint_response",
46
+ )
47
+ STAGES = (
48
+ "pipeline_stage_1", "pipeline_stage_2", "pipeline_stage_2_5",
49
+ "pipeline_stage_3", "pipeline_stage_3_prime", "pipeline_stage_4",
50
+ "pipeline_stage_4_prime", "pipeline_stage_4_5", "pipeline_stage_5",
51
+ "pipeline_stage_6",
52
+ )
53
+ RAW_TO_STAGE = {
54
+ "1": STAGES[0], "2": STAGES[1], "2.5": STAGES[2], "3": STAGES[3],
55
+ "3p": STAGES[4], "4": STAGES[5], "4p": STAGES[6], "4.5": STAGES[7],
56
+ "5": STAGES[8], "6": STAGES[9],
57
+ }
58
+ STAGE_TO_RAW = {value: key for key, value in RAW_TO_STAGE.items()}
59
+ STATUS_VALUES = {"pending", "in_progress", "completed", "skipped", "blocked"}
60
+ REASON_UNAVAILABLE = {
61
+ "source_not_provided", "source_unreadable", "source_invalid",
62
+ "capture_not_supported",
63
+ }
64
+ ROLE_ORDER = {
65
+ "revision_author_adjudication": ("author_adjudication_input", "author_adjudication"),
66
+ "compliance_report": ("compliance_report", "compliance_override_action_receipt"),
67
+ "re_review_traceability": ("input_manifest", "precommitment", "verdict_record", "traceability"),
68
+ "explicit_user_request": ("explicit_user_request_log",),
69
+ "mandatory_checkpoint_response": ("mandatory_checkpoint_response_log",),
70
+ }
71
+ OVERTURN_TYPES = {
72
+ "author_triage_not_on_point", "compliance_block_override",
73
+ "re_review_verdict_changed",
74
+ }
75
+ MAX_INPUT = 1 << 20
76
+ MAX_ARTIFACT = 8 << 20
77
+ MAX_ARTIFACT_TOTAL = 64 << 20
78
+ MAX_STORE = 16 << 20
79
+ MAX_EVENTS_RUN = 4096
80
+ MAX_EVENTS_STORE = 100000
81
+ MAX_RUNS = 10000
82
+ LIMITATION = "This records explicit adjudication activity only. It cannot determine correctness, attentiveness, engagement, or whether human ownership is real; genuine agreement and non-review can produce the same history."
83
+ ADVISORY = "This series is advisory only; it never gates, blocks, scores, or changes any verdict."
84
+ COVERAGE = "Coverage: only successfully retained records in this explicitly selected store are shown; runs without this store selection or whose append failed are not represented."
85
+ DATA_MINIMIZATION = {
86
+ "raw_prose_embedded": False,
87
+ "user_identity_embedded": False,
88
+ "absolute_paths_embedded": False,
89
+ }
90
+ HEX_RE = re.compile(r"^[0-9a-f]{64}$")
91
+ ID_RE = re.compile(r"^[A-Za-z0-9][A-Za-z0-9._:-]{0,127}$")
92
+ GROUP_RE = re.compile(r"^SOURCE-GROUP-[A-Za-z0-9][A-Za-z0-9._-]{0,95}$")
93
+
94
+
95
+ class ActivityError(Exception):
96
+ """Bounded public failure with a closed CLI error code."""
97
+
98
+ def __init__(self, code: str, detail: str):
99
+ super().__init__(detail)
100
+ self.code = code
101
+ self.detail = detail[:500]
102
+
103
+
104
+ EXIT_BY_CODE = {
105
+ "USAGE": 2, "PATH": 3, "INPUT": 3, "SOURCE": 3, "STORE": 4,
106
+ "CONFLICT": 5, "CAP": 5, "DELETE_CONFIRMATION": 6,
107
+ "LOCK": 7, "WRITE": 7,
108
+ }
109
+
110
+
111
+ def _pairs(pairs: list[tuple[str, Any]]) -> dict[str, Any]:
112
+ result: dict[str, Any] = {}
113
+ for key, value in pairs:
114
+ if key in result:
115
+ raise ValueError("duplicate object key")
116
+ result[key] = value
117
+ return result
118
+
119
+
120
+ def _reject_number(token: str) -> None:
121
+ raise ValueError(f"forbidden JSON number {token}")
122
+
123
+
124
+ def strict_json(raw: bytes, *, code: str) -> Any:
125
+ if raw.startswith(b"\xef\xbb\xbf"):
126
+ raise ActivityError(code, "UTF-8 BOM is forbidden")
127
+ try:
128
+ value = json.loads(
129
+ raw.decode("utf-8"), object_pairs_hook=_pairs,
130
+ parse_float=_reject_number, parse_constant=_reject_number,
131
+ )
132
+ except (UnicodeDecodeError, json.JSONDecodeError, ValueError) as exc:
133
+ raise ActivityError(code, f"invalid strict JSON: {exc.__class__.__name__}") from None
134
+ _canonical_domain(value, code=code)
135
+ return value
136
+
137
+
138
+ def _canonical_domain(value: Any, *, code: str, depth: int = 0) -> None:
139
+ if depth > 256:
140
+ raise ActivityError(code, "JSON nesting exceeds contract bound")
141
+ if isinstance(value, str):
142
+ if any(0xD800 <= ord(char) <= 0xDFFF for char in value):
143
+ raise ActivityError(code, "lone UTF-16 surrogate is forbidden")
144
+ return
145
+ if value is None or isinstance(value, bool):
146
+ return
147
+ if isinstance(value, int) and not isinstance(value, bool):
148
+ return
149
+ if isinstance(value, list):
150
+ for child in value:
151
+ _canonical_domain(child, code=code, depth=depth + 1)
152
+ return
153
+ if isinstance(value, dict):
154
+ for key, child in value.items():
155
+ if not isinstance(key, str) or not key.isascii():
156
+ raise ActivityError(code, "contract object keys must be ASCII")
157
+ _canonical_domain(child, code=code, depth=depth + 1)
158
+ return
159
+ raise ActivityError(code, "floats and non-contract JSON values are forbidden")
160
+
161
+
162
+ def canonical_bytes(value: Any, *, code: str = "INPUT") -> bytes:
163
+ _canonical_domain(value, code=code)
164
+ return json.dumps(
165
+ value, sort_keys=True, separators=(",", ":"), ensure_ascii=False,
166
+ allow_nan=False,
167
+ ).encode("utf-8")
168
+
169
+
170
+ def _digest(domain: bytes, value: Any) -> str:
171
+ return hashlib.sha256(domain + canonical_bytes(value)).hexdigest()
172
+
173
+
174
+ def interaction_sha256(run_id: str, interaction_id: str) -> str:
175
+ return _digest(
176
+ b"ars.adjudication-activity.interaction/1.0\0",
177
+ {"run_id": run_id, "interaction_id": interaction_id},
178
+ )
179
+
180
+
181
+ def _load_schema(path: Path) -> dict[str, Any]:
182
+ value = strict_json(path.read_bytes(), code="SOURCE")
183
+ if not isinstance(value, dict):
184
+ raise ActivityError("SOURCE", "schema root is not an object")
185
+ return value
186
+
187
+
188
+ def _validator(path: Path, *, revision_registry: bool = False) -> Draft202012Validator:
189
+ schema = _load_schema(path)
190
+ registry = Registry()
191
+ if revision_registry:
192
+ for candidate_path in (
193
+ REVISION_CONTRACTS / "author_adjudication.schema.json",
194
+ REVISION_CONTRACTS / "author_adjudication_input.schema.json",
195
+ ):
196
+ candidate = _load_schema(candidate_path)
197
+ if "$id" in candidate:
198
+ registry = registry.with_resource(candidate["$id"], Resource.from_contents(candidate))
199
+ return Draft202012Validator(schema, registry=registry, format_checker=FormatChecker())
200
+
201
+
202
+ def _schema_validate(value: Any, path: Path, *, code: str, revision_registry: bool = False) -> None:
203
+ errors = sorted(
204
+ _validator(path, revision_registry=revision_registry).iter_errors(value),
205
+ key=lambda error: tuple(str(part) for part in error.absolute_path),
206
+ )
207
+ if errors:
208
+ raise ActivityError(code, f"schema validation failed at {list(errors[0].absolute_path)!r}")
209
+
210
+
211
+ def _read_limited_identity(path: Path, limit: int, *, code: str) -> tuple[bytes, tuple[int, int, int]]:
212
+ try:
213
+ fd = os.open(path, os.O_RDONLY | getattr(os, "O_NOFOLLOW", 0))
214
+ try:
215
+ info = os.fstat(fd)
216
+ if not stat.S_ISREG(info.st_mode) or info.st_nlink != 1:
217
+ raise ActivityError("PATH", "selected path is not a single-linked regular file")
218
+ identity = (info.st_dev, info.st_ino, info.st_size)
219
+ if info.st_size > limit:
220
+ raise ActivityError("CAP", "file exceeds hard byte cap")
221
+ chunks: list[bytes] = []
222
+ size = 0
223
+ while True:
224
+ chunk = os.read(fd, min(1024 * 1024, limit + 1 - size))
225
+ if not chunk:
226
+ break
227
+ chunks.append(chunk)
228
+ size += len(chunk)
229
+ if size > limit:
230
+ raise ActivityError("CAP", "file exceeds hard byte cap")
231
+ after = os.fstat(fd)
232
+ if (after.st_dev, after.st_ino, after.st_size) != identity or size != info.st_size:
233
+ raise ActivityError(code, "file changed while being read")
234
+ return b"".join(chunks), identity
235
+ finally:
236
+ os.close(fd)
237
+ except ActivityError:
238
+ raise
239
+ except OSError as exc:
240
+ raise ActivityError(code, f"file read failed: {exc.__class__.__name__}") from None
241
+
242
+
243
+ def _read_limited(path: Path, limit: int, *, code: str) -> bytes:
244
+ return _read_limited_identity(path, limit, code=code)[0]
245
+
246
+
247
+ def _path_identity(path: Path) -> tuple[int, int, int]:
248
+ try:
249
+ info = path.lstat()
250
+ except OSError as exc:
251
+ raise ActivityError("WRITE", f"target identity check failed: {exc.__class__.__name__}") from None
252
+ return info.st_dev, info.st_ino, info.st_size
253
+
254
+
255
+ def _assert_identity(path: Path, expected: tuple[int, int, int]) -> None:
256
+ if _path_identity(path) != expected:
257
+ raise ActivityError("CONFLICT", "target changed after validated read")
258
+
259
+
260
+ def _relative_binding(root: Path, path: Path) -> str:
261
+ try:
262
+ root_real = root.resolve(strict=True)
263
+ path_real = path.resolve(strict=True)
264
+ relative = path_real.relative_to(root_real).as_posix()
265
+ except (OSError, ValueError):
266
+ raise ActivityError("PATH", "path is not contained beneath artifact root") from None
267
+ _safe_relative(root, relative)
268
+ return relative
269
+
270
+
271
+ def _safe_relative(root: Path, relative: str) -> Path:
272
+ if not isinstance(relative, str) or not relative or len(relative) > 512:
273
+ raise ActivityError("PATH", "invalid relative artifact path")
274
+ pure = PurePosixPath(relative)
275
+ if pure.is_absolute() or "\\" in relative or relative.endswith("/"):
276
+ raise ActivityError("PATH", "unsafe relative artifact path")
277
+ if re.match(r"^[A-Za-z]:/", relative) or any(part in {"", ".", ".."} for part in pure.parts):
278
+ raise ActivityError("PATH", "unsafe relative artifact path")
279
+ if any(ord(char) < 32 or ord(char) == 127 for char in relative):
280
+ raise ActivityError("PATH", "unsafe relative artifact path")
281
+ try:
282
+ root_info = root.lstat()
283
+ if stat.S_ISLNK(root_info.st_mode) or not stat.S_ISDIR(root_info.st_mode):
284
+ raise ActivityError("PATH", "artifact root must be a non-symlink directory")
285
+ cursor = root
286
+ for part in pure.parts:
287
+ cursor = cursor / part
288
+ info = cursor.lstat()
289
+ if stat.S_ISLNK(info.st_mode):
290
+ raise ActivityError("PATH", "symlink artifact path is forbidden")
291
+ resolved = cursor.resolve(strict=True)
292
+ resolved.relative_to(root.resolve(strict=True))
293
+ if not stat.S_ISREG(cursor.stat().st_mode):
294
+ raise ActivityError("PATH", "artifact must be a regular file")
295
+ return cursor
296
+ except ActivityError:
297
+ raise
298
+ except (OSError, ValueError):
299
+ raise ActivityError("PATH", "artifact path cannot be safely resolved") from None
300
+
301
+
302
+ def _read_artifact_relative(root: Path, relative: str, limit: int) -> bytes:
303
+ """Descriptor-relative no-follow traversal prevents parent-component swaps."""
304
+ if not isinstance(relative, str) or not relative or len(relative) > 512:
305
+ raise ActivityError("PATH", "invalid relative artifact path")
306
+ pure = PurePosixPath(relative)
307
+ if (
308
+ pure.is_absolute() or "\\" in relative or relative.endswith("/")
309
+ or re.match(r"^[A-Za-z]:/", relative)
310
+ or any(part in {"", ".", ".."} for part in pure.parts)
311
+ or any(ord(char) < 32 or ord(char) == 127 for char in relative)
312
+ ):
313
+ raise ActivityError("PATH", "unsafe relative artifact path")
314
+ directory_flags = os.O_RDONLY | getattr(os, "O_DIRECTORY", 0) | getattr(os, "O_NOFOLLOW", 0)
315
+ opened: list[int] = []
316
+ try:
317
+ directory_fd = os.open(root, directory_flags)
318
+ opened.append(directory_fd)
319
+ for part in pure.parts[:-1]:
320
+ directory_fd = os.open(part, directory_flags, dir_fd=directory_fd)
321
+ opened.append(directory_fd)
322
+ fd = os.open(
323
+ pure.parts[-1], os.O_RDONLY | getattr(os, "O_NOFOLLOW", 0),
324
+ dir_fd=directory_fd,
325
+ )
326
+ opened.append(fd)
327
+ info = os.fstat(fd)
328
+ identity = (info.st_dev, info.st_ino, info.st_size)
329
+ if not stat.S_ISREG(info.st_mode) or info.st_nlink != 1:
330
+ raise ActivityError("PATH", "artifact must be a single-linked regular file")
331
+ if info.st_size > limit:
332
+ raise ActivityError("CAP", "artifact exceeds hard byte cap")
333
+ chunks: list[bytes] = []
334
+ size = 0
335
+ while True:
336
+ chunk = os.read(fd, min(1024 * 1024, limit + 1 - size))
337
+ if not chunk:
338
+ break
339
+ chunks.append(chunk)
340
+ size += len(chunk)
341
+ if size > limit:
342
+ raise ActivityError("CAP", "artifact exceeds hard byte cap")
343
+ after = os.fstat(fd)
344
+ if (after.st_dev, after.st_ino, after.st_size) != identity or size != info.st_size:
345
+ raise ActivityError("SOURCE", "artifact changed while being read")
346
+ return b"".join(chunks)
347
+ except ActivityError:
348
+ raise
349
+ except OSError as exc:
350
+ if exc.errno == errno.ELOOP:
351
+ raise ActivityError("PATH", "symlink artifact path is forbidden") from None
352
+ raise ActivityError("PATH", f"artifact traversal failed: {exc.__class__.__name__}") from None
353
+ finally:
354
+ for opened_fd in reversed(opened):
355
+ os.close(opened_fd)
356
+
357
+
358
+ @contextmanager
359
+ def _store_lock(path: Path, *, exclusive: bool) -> Iterator[None]:
360
+ lock_path = path.with_name(path.name + ".lock")
361
+ try:
362
+ fd = os.open(lock_path, os.O_RDWR | os.O_CREAT | getattr(os, "O_NOFOLLOW", 0), 0o600)
363
+ info = os.fstat(fd)
364
+ if not stat.S_ISREG(info.st_mode) or info.st_nlink != 1 or info.st_size != 0:
365
+ raise ActivityError("LOCK", "lock metadata is not an empty single-linked regular file")
366
+ operation = (fcntl.LOCK_EX if exclusive else fcntl.LOCK_SH) | fcntl.LOCK_NB
367
+ fcntl.flock(fd, operation)
368
+ except ActivityError:
369
+ if "fd" in locals():
370
+ os.close(fd)
371
+ raise
372
+ except OSError as exc:
373
+ if "fd" in locals():
374
+ os.close(fd)
375
+ raise ActivityError("LOCK", f"lock acquisition failed: {exc.__class__.__name__}") from None
376
+ try:
377
+ yield
378
+ finally:
379
+ fcntl.flock(fd, fcntl.LOCK_UN)
380
+ os.close(fd)
381
+
382
+
383
+ def _write_all(fd: int, raw: bytes) -> None:
384
+ view = memoryview(raw)
385
+ while view:
386
+ written = os.write(fd, view)
387
+ if written <= 0:
388
+ raise OSError("write made no progress")
389
+ view = view[written:]
390
+
391
+
392
+ def _atomic_replace(path: Path, raw: bytes, *, expected_identity: tuple[int, int, int] | None = None) -> None:
393
+ path.parent.mkdir(parents=False, exist_ok=True)
394
+ temporary: str | None = None
395
+ try:
396
+ fd, temporary = tempfile.mkstemp(prefix=f".{path.name}.", dir=path.parent)
397
+ try:
398
+ os.fchmod(fd, 0o600)
399
+ _write_all(fd, raw)
400
+ os.fsync(fd)
401
+ finally:
402
+ os.close(fd)
403
+ if os.stat(temporary).st_size != len(raw):
404
+ raise OSError("temporary file size mismatch")
405
+ if expected_identity is not None:
406
+ _assert_identity(path, expected_identity)
407
+ os.replace(temporary, path)
408
+ temporary = None
409
+ directory_fd = os.open(path.parent, os.O_RDONLY)
410
+ try:
411
+ os.fsync(directory_fd)
412
+ finally:
413
+ os.close(directory_fd)
414
+ except OSError as exc:
415
+ raise ActivityError("WRITE", f"atomic write failed: {exc.__class__.__name__}") from None
416
+ finally:
417
+ if temporary is not None:
418
+ try:
419
+ os.unlink(temporary)
420
+ except OSError:
421
+ pass
422
+
423
+
424
+ def _atomic_create(path: Path, raw: bytes) -> None:
425
+ if path.exists() or path.is_symlink():
426
+ raise ActivityError("CONFLICT", "output path already exists")
427
+ temporary: str | None = None
428
+ try:
429
+ fd, temporary = tempfile.mkstemp(prefix=f".{path.name}.", dir=path.parent)
430
+ try:
431
+ os.fchmod(fd, 0o600)
432
+ _write_all(fd, raw)
433
+ os.fsync(fd)
434
+ finally:
435
+ os.close(fd)
436
+ if os.stat(temporary).st_size != len(raw):
437
+ raise OSError("temporary file size mismatch")
438
+ os.link(temporary, path)
439
+ os.unlink(temporary)
440
+ temporary = None
441
+ directory_fd = os.open(path.parent, os.O_RDONLY)
442
+ try:
443
+ os.fsync(directory_fd)
444
+ finally:
445
+ os.close(directory_fd)
446
+ except FileExistsError:
447
+ raise ActivityError("CONFLICT", "output path already exists") from None
448
+ except OSError as exc:
449
+ raise ActivityError("WRITE", f"atomic create failed: {exc.__class__.__name__}") from None
450
+ finally:
451
+ if temporary:
452
+ try:
453
+ os.unlink(temporary)
454
+ except OSError:
455
+ pass
456
+
457
+
458
+ def _state_replay(state: dict[str, Any]) -> tuple[str, str, str, str]:
459
+ if not isinstance(state, dict) or not ID_RE.fullmatch(str(state.get("run_id", ""))):
460
+ raise ActivityError("INPUT", "terminal state lacks a valid stable run_id")
461
+ pipeline_state = state.get("pipeline_state")
462
+ if pipeline_state not in {"completed", "aborted"}:
463
+ raise ActivityError("INPUT", "pipeline state is not eligible terminal state")
464
+ raw_stage = str(state.get("current_stage", ""))
465
+ stage = RAW_TO_STAGE.get(raw_stage)
466
+ stages = state.get("stages")
467
+ if stage is None or not isinstance(stages, dict) or not isinstance(stages.get(raw_stage), dict):
468
+ raise ActivityError("INPUT", "current stage cannot be strictly replayed")
469
+ status = stages[raw_stage].get("status")
470
+ if status not in STATUS_VALUES:
471
+ raise ActivityError("INPUT", "current stage status is outside the closed vocabulary")
472
+ if pipeline_state == "completed" and not (raw_stage == "6" and status in {"completed", "skipped"}):
473
+ raise ActivityError("INPUT", "completed state must replay Stage 6 completed or skipped")
474
+ return state["run_id"], pipeline_state, stage, status
475
+
476
+
477
+ def _terminal_receipt(state: dict[str, Any], state_raw: bytes, relative_path: str) -> dict[str, Any]:
478
+ run_id, pipeline_state, stage, status = _state_replay(state)
479
+ return {
480
+ "artifact_id": "pipeline-state-terminal-receipt",
481
+ "relative_path": relative_path,
482
+ "sha256": hashlib.sha256(state_raw).hexdigest(),
483
+ "run_id": run_id,
484
+ "pipeline_state": pipeline_state,
485
+ "current_stage": stage,
486
+ "current_stage_status": status,
487
+ }
488
+
489
+
490
+ def _validate_source_rows(rows: Any, *, pending: bool = False) -> None:
491
+ if not isinstance(rows, list) or len(rows) != 5:
492
+ raise ActivityError("SOURCE", "source inventory must contain exactly five rows")
493
+ for index, (row, family) in enumerate(zip(rows, SOURCE_FAMILIES)):
494
+ if not isinstance(row, dict) or row.get("source_family") != family:
495
+ raise ActivityError("SOURCE", f"source family order mismatch at row {index}")
496
+ if set(row) != {"source_family", "capture_state", "reason_code", "artifacts"}:
497
+ raise ActivityError("SOURCE", "source row has unknown or missing fields")
498
+ state = row.get("capture_state")
499
+ reason = row.get("reason_code")
500
+ artifacts = row.get("artifacts")
501
+ if not isinstance(artifacts, list) or len(artifacts) > 64:
502
+ raise ActivityError("SOURCE", "invalid source artifact list")
503
+ if state == "captured":
504
+ if reason is not None or not artifacts:
505
+ raise ActivityError("SOURCE", "captured source requires artifacts and null reason")
506
+ elif state == "not_applicable":
507
+ if reason != "not_applicable_for_run" or artifacts:
508
+ raise ActivityError("SOURCE", "not-applicable source shape is invalid")
509
+ elif state == "unavailable":
510
+ if reason not in REASON_UNAVAILABLE or artifacts:
511
+ raise ActivityError("SOURCE", "unavailable source shape is invalid")
512
+ else:
513
+ raise ActivityError("SOURCE", "unknown capture state")
514
+ for artifact in artifacts:
515
+ expected = {
516
+ "artifact_id", "artifact_role", "artifact_group_id",
517
+ "artifact_group_stage", "relative_path",
518
+ }
519
+ if not pending:
520
+ expected.add("sha256")
521
+ if not isinstance(artifact, dict) or set(artifact) != expected:
522
+ raise ActivityError("SOURCE", "artifact binding has unknown or missing fields")
523
+ if not isinstance(artifact.get("artifact_id"), str) or not ID_RE.fullmatch(artifact["artifact_id"]):
524
+ raise ActivityError("SOURCE", "artifact id is outside the closed identifier grammar")
525
+ if artifact.get("artifact_role") not in ROLE_ORDER[family]:
526
+ raise ActivityError("SOURCE", "artifact role is outside the source-family vocabulary")
527
+ if not isinstance(artifact.get("artifact_group_id"), str) or not GROUP_RE.fullmatch(artifact["artifact_group_id"]):
528
+ raise ActivityError("SOURCE", "artifact group id is invalid")
529
+ group_stage = artifact.get("artifact_group_stage")
530
+ if family == SOURCE_FAMILIES[0]:
531
+ if group_stage not in {"pipeline_stage_3", "pipeline_stage_3_prime"}:
532
+ raise ActivityError("SOURCE", "author artifact group stage is invalid")
533
+ elif group_stage is not None:
534
+ raise ActivityError("SOURCE", "non-author artifact group stage must be null")
535
+ relative_path = artifact.get("relative_path")
536
+ if not isinstance(relative_path, str):
537
+ raise ActivityError("SOURCE", "artifact relative path must be a string")
538
+ if not pending and (not isinstance(artifact.get("sha256"), str) or not HEX_RE.fullmatch(artifact["sha256"])):
539
+ raise ActivityError("SOURCE", "artifact hash is invalid")
540
+
541
+
542
+ def _group_artifacts(row: dict[str, Any]) -> list[list[dict[str, Any]]]:
543
+ family = row["source_family"]
544
+ artifacts = row["artifacts"]
545
+ groups: list[list[dict[str, Any]]] = []
546
+ seen_ids: set[str] = set()
547
+ cursor = 0
548
+ while cursor < len(artifacts):
549
+ group_id = artifacts[cursor].get("artifact_group_id")
550
+ if not isinstance(group_id, str) or not GROUP_RE.fullmatch(group_id) or group_id in seen_ids:
551
+ raise ActivityError("SOURCE", "invalid or repeated artifact group id")
552
+ seen_ids.add(group_id)
553
+ group: list[dict[str, Any]] = []
554
+ while cursor < len(artifacts) and artifacts[cursor].get("artifact_group_id") == group_id:
555
+ group.append(artifacts[cursor])
556
+ cursor += 1
557
+ groups.append(group)
558
+ if row["capture_state"] != "captured":
559
+ return groups
560
+ expected_roles = ROLE_ORDER[family]
561
+ if family == "revision_author_adjudication":
562
+ if len(groups) not in {1, 2}:
563
+ raise ActivityError("SOURCE", "author family requires one or two groups")
564
+ expected_stages = ["pipeline_stage_3", "pipeline_stage_3_prime"] if len(groups) == 2 else None
565
+ for index, group in enumerate(groups):
566
+ if tuple(item.get("artifact_role") for item in group) != expected_roles:
567
+ raise ActivityError("SOURCE", "author group role order is invalid")
568
+ stages = {item.get("artifact_group_stage") for item in group}
569
+ if len(stages) != 1 or next(iter(stages)) not in {"pipeline_stage_3", "pipeline_stage_3_prime"}:
570
+ raise ActivityError("SOURCE", "author group stage is invalid")
571
+ if expected_stages and next(iter(stages)) != expected_stages[index]:
572
+ raise ActivityError("SOURCE", "author group stage order is invalid")
573
+ elif family == "compliance_report":
574
+ if not 1 <= len(groups) <= 16:
575
+ raise ActivityError("SOURCE", "compliance family requires 1..16 groups")
576
+ for group in groups:
577
+ roles = tuple(item.get("artifact_role") for item in group)
578
+ if roles not in {(expected_roles[0],), expected_roles}:
579
+ raise ActivityError("SOURCE", "compliance group role set/order is invalid")
580
+ if any(item.get("artifact_group_stage") is not None for item in group):
581
+ raise ActivityError("SOURCE", "non-author artifact stage must be null")
582
+ else:
583
+ if len(groups) != 1 or tuple(item.get("artifact_role") for item in groups[0]) != expected_roles:
584
+ raise ActivityError("SOURCE", "captured family has invalid exact group roles")
585
+ if any(item.get("artifact_group_stage") is not None for item in groups[0]):
586
+ raise ActivityError("SOURCE", "non-author artifact stage must be null")
587
+ return groups
588
+
589
+
590
+ def seal_terminal_inventory(state_path: str | Path, artifact_root: str | Path, pending_bindings: list[dict[str, Any]]) -> list[dict[str, Any]]:
591
+ """Post-terminal best-effort helper: hash explicit pending rows and seal them.
592
+
593
+ ``pending_bindings`` is authority supplied by the state tracker's sole
594
+ writer. It contains no hashes. This helper performs no discovery.
595
+ """
596
+ state_file = Path(state_path)
597
+ root = Path(artifact_root)
598
+ _validate_source_rows(pending_bindings, pending=True)
599
+ with _store_lock(state_file, exclusive=True):
600
+ state_raw, state_identity = _read_limited_identity(state_file, MAX_STORE, code="INPUT")
601
+ state = strict_json(state_raw, code="INPUT")
602
+ _state_replay(state)
603
+ sealed_rows = copy.deepcopy(pending_bindings)
604
+ total = 0
605
+ for row in sealed_rows:
606
+ _group_artifacts(row)
607
+ for artifact in row["artifacts"]:
608
+ raw = _read_artifact_relative(root, artifact["relative_path"], MAX_ARTIFACT)
609
+ total += len(raw)
610
+ if total > MAX_ARTIFACT_TOTAL:
611
+ raise ActivityError("CAP", "referenced artifacts exceed per-run byte cap")
612
+ artifact["sha256"] = hashlib.sha256(raw).hexdigest()
613
+ _validate_source_rows(sealed_rows)
614
+ candidate = copy.deepcopy(state)
615
+ existing = candidate.get("adjudication_activity_sources")
616
+ if existing is not None and existing != sealed_rows:
617
+ raise ActivityError("CONFLICT", "terminal source inventory is already sealed differently")
618
+ if existing == sealed_rows:
619
+ return sealed_rows
620
+ candidate["adjudication_activity_sources"] = sealed_rows
621
+ _atomic_replace(
622
+ state_file, canonical_bytes(candidate) + b"\n",
623
+ expected_identity=state_identity,
624
+ )
625
+ return sealed_rows
626
+
627
+
628
+ def author_source_record(adjudication: dict[str, Any], event: dict[str, Any], digest: str) -> dict[str, Any]:
629
+ return {
630
+ "item_id": adjudication["item_id"],
631
+ "author_event_id": adjudication["author_event_id"],
632
+ "author_triage": adjudication["author_triage"],
633
+ "input_sha256": event["input_sha256"],
634
+ "interaction_sha256": digest,
635
+ }
636
+
637
+
638
+ def compliance_source_record(
639
+ group_id: str, stage: str, blockers: list[str], report_hash: str,
640
+ receipt_hash: str, receipt: dict[str, Any],
641
+ ) -> dict[str, Any]:
642
+ return {
643
+ "artifact_group_id": group_id,
644
+ "stage": stage,
645
+ "blocking_contributor_ids": blockers,
646
+ "report_sha256": report_hash,
647
+ "action_receipt_sha256": receipt_hash,
648
+ "interaction_id": receipt["interaction_id"],
649
+ "interaction_sha256": receipt["interaction_sha256"],
650
+ }
651
+
652
+
653
+ def re_review_source_record(
654
+ round_id: str, dissent_id: str, item_id: str, reapplication_id: str,
655
+ adjustment: dict[str, Any], traceability_hash: str,
656
+ ) -> dict[str, Any]:
657
+ return {
658
+ "round_id": round_id,
659
+ "dissent_id": dissent_id,
660
+ "item_id": item_id,
661
+ "reapplication_id": reapplication_id,
662
+ "adjustment_id": adjustment["adjustment_id"],
663
+ "from_verdict": adjustment["from_verdict"],
664
+ "to_verdict": adjustment["to_verdict"],
665
+ "traceability_sha256": traceability_hash,
666
+ }
667
+
668
+
669
+ def explicit_source_record(record: dict[str, Any]) -> dict[str, Any]:
670
+ return {key: record[key] for key in (
671
+ "request_id", "actor_role", "source", "action", "stage", "finding_id",
672
+ "interaction_id", "interaction_sha256",
673
+ )}
674
+
675
+
676
+ def mandatory_source_record(record: dict[str, Any]) -> dict[str, Any]:
677
+ return {key: record[key] for key in (
678
+ "response_id", "checkpoint_id", "checkpoint_type", "actor_role", "source",
679
+ "stage", "disposition", "interaction_id", "interaction_sha256",
680
+ )}
681
+
682
+
683
+ def _event(
684
+ run_id: str, family: str, event_type: str, stage: str, disposition: str,
685
+ interaction: str | None, source_record: dict[str, Any],
686
+ ) -> dict[str, Any]:
687
+ source_hash = _digest(
688
+ b"ars.adjudication-activity.source-event/1.0\0",
689
+ {"source_family": family, "source_record": source_record},
690
+ )
691
+ payload = {
692
+ "run_id": run_id, "source_family": family, "event_type": event_type,
693
+ "stage": stage, "disposition": disposition,
694
+ "interaction_sha256": interaction, "source_event_sha256": source_hash,
695
+ }
696
+ return {
697
+ "event_id": "ACTIVITY-EVENT-" + _digest(b"ars.adjudication-activity.event-id/1.0\0", payload),
698
+ "event_type": event_type, "stage": stage, "disposition": disposition,
699
+ "interaction_sha256": interaction, "source_event_sha256": source_hash,
700
+ }
701
+
702
+
703
+ def _load_artifact(root: Path, binding: dict[str, Any], total: list[int]) -> tuple[dict[str, Any], bytes]:
704
+ raw = _read_artifact_relative(root, binding["relative_path"], MAX_ARTIFACT)
705
+ total[0] += len(raw)
706
+ if total[0] > MAX_ARTIFACT_TOTAL:
707
+ raise ActivityError("CAP", "referenced artifacts exceed per-run byte cap")
708
+ if hashlib.sha256(raw).hexdigest() != binding["sha256"]:
709
+ raise ActivityError("SOURCE", "artifact raw-byte hash mismatch")
710
+ value = strict_json(raw, code="SOURCE")
711
+ if not isinstance(value, dict):
712
+ raise ActivityError("SOURCE", "source artifact root must be an object")
713
+ return value, raw
714
+
715
+
716
+ def _author_events(run_id: str, stage: str, group: list[dict[str, Any]], root: Path, total: list[int]) -> list[dict[str, Any]]:
717
+ input_value, _ = _load_artifact(root, group[0], total)
718
+ output_value, _ = _load_artifact(root, group[1], total)
719
+ _schema_validate(input_value, REVISION_CONTRACTS / "author_adjudication_input.schema.json", code="SOURCE", revision_registry=True)
720
+ _schema_validate(output_value, REVISION_CONTRACTS / "author_adjudication.schema.json", code="SOURCE", revision_registry=True)
721
+ projection_keys = ("author_events", "author_adjudications", "display_order", "collateral_authorizations")
722
+ if any(input_value[key] != output_value[key] for key in projection_keys):
723
+ raise ActivityError("SOURCE", "author input/output projection mismatch")
724
+ event_by_id: dict[str, dict[str, Any]] = {}
725
+ for source_event in output_value["author_events"]:
726
+ event_id = source_event["event_id"]
727
+ if event_id in event_by_id:
728
+ raise ActivityError("SOURCE", "duplicate author event id")
729
+ event_by_id[event_id] = source_event
730
+ derived: list[dict[str, Any]] = []
731
+ for adjudication in output_value["author_adjudications"]:
732
+ event_id = adjudication["author_event_id"]
733
+ if event_id not in event_by_id:
734
+ raise ActivityError("SOURCE", "author adjudication event id is unresolved")
735
+ triage = adjudication["author_triage"]
736
+ if triage == "will_address":
737
+ continue
738
+ digest = interaction_sha256(run_id, event_id)
739
+ event_type, disposition = (
740
+ ("author_triage_wont_address", "wont_address") if triage == "wont_address"
741
+ else ("author_triage_not_on_point", "not_on_point")
742
+ )
743
+ derived.append(_event(
744
+ run_id, SOURCE_FAMILIES[0], event_type, stage, disposition, digest,
745
+ author_source_record(adjudication, event_by_id[event_id], digest),
746
+ ))
747
+ return derived
748
+
749
+
750
+ def _receipt_shape(value: dict[str, Any], keys: set[str], version: str) -> None:
751
+ if set(value) != keys or value.get("schema_version") != version:
752
+ raise ActivityError("SOURCE", "closed action receipt shape/version is invalid")
753
+
754
+
755
+ def _blocking_contributors(report: dict[str, Any]) -> list[str]:
756
+ if report.get("mode") != "systematic_review":
757
+ return []
758
+ result: set[str] = set()
759
+ prisma = report.get("prisma_trAIce")
760
+ if isinstance(prisma, dict) and prisma.get("block_decision") == "block":
761
+ failed = prisma["by_tier"]["mandatory"]["fail"]
762
+ if len(failed) != len(set(failed)):
763
+ raise ActivityError("SOURCE", "PRISMA blocking contributor ids must be unique")
764
+ result.update(failed)
765
+ raise_part = report.get("raise")
766
+ if isinstance(raise_part, dict) and raise_part.get("block_decision") == "block":
767
+ result.update(name for name, status_value in raise_part["principles"].items() if status_value == "fail")
768
+ return sorted(result)
769
+
770
+
771
+ def _compliance_events(run_id: str, groups: list[list[dict[str, Any]]], root: Path, total: list[int]) -> list[dict[str, Any]]:
772
+ derived: list[dict[str, Any]] = []
773
+ expected_ordinal = {"pipeline_stage_2_5": 1, "pipeline_stage_4_5": 1}
774
+ receipt_ids: set[str] = set()
775
+ receipt_keys = {
776
+ "schema_version", "receipt_id", "run_id", "actor_role", "source", "action",
777
+ "stage", "scope", "report_sha256", "override_ordinal", "interaction_id",
778
+ "interaction_sha256",
779
+ }
780
+ for group in groups:
781
+ report, _ = _load_artifact(root, group[0], total)
782
+ _schema_validate(report, COMPLIANCE_SCHEMA_PATH, code="SOURCE")
783
+ has_override = "user_override" in report
784
+ if not has_override and len(group) == 1:
785
+ continue
786
+ if not has_override or len(group) != 2:
787
+ raise ActivityError("SOURCE", "compliance action receipt pairing is invalid")
788
+ receipt, _ = _load_artifact(root, group[1], total)
789
+ _receipt_shape(receipt, receipt_keys, "adjudication-compliance-override-action/1.0")
790
+ receipt_id = receipt.get("receipt_id")
791
+ interaction_id = receipt.get("interaction_id")
792
+ scope = receipt.get("scope")
793
+ ordinal = receipt.get("override_ordinal")
794
+ if (
795
+ not isinstance(receipt_id, str) or not ID_RE.fullmatch(receipt_id)
796
+ or not isinstance(interaction_id, str) or not ID_RE.fullmatch(interaction_id)
797
+ or not isinstance(scope, list) or not scope
798
+ or any(not isinstance(item, str) or not ID_RE.fullmatch(item) for item in scope)
799
+ or len(scope) != len(set(scope))
800
+ or not isinstance(ordinal, int) or isinstance(ordinal, bool) or ordinal < 1
801
+ or not isinstance(receipt.get("report_sha256"), str)
802
+ or not HEX_RE.fullmatch(receipt["report_sha256"])
803
+ or not isinstance(receipt.get("interaction_sha256"), str)
804
+ or not HEX_RE.fullmatch(receipt["interaction_sha256"])
805
+ ):
806
+ raise ActivityError("SOURCE", "compliance action receipt field types are invalid")
807
+ blockers = _blocking_contributors(report)
808
+ report_stage = {"2.5": "pipeline_stage_2_5", "4.5": "pipeline_stage_4_5"}.get(report.get("stage"))
809
+ override = report["user_override"]
810
+ valid = (
811
+ report.get("overall_decision") == "block"
812
+ and report.get("user_action_required") is True
813
+ and bool(blockers)
814
+ and override.get("decision") is True
815
+ and report_stage == receipt.get("stage")
816
+ and receipt.get("run_id") == run_id
817
+ and receipt.get("actor_role") == "user"
818
+ and receipt.get("source") == "explicit_session_user_action"
819
+ and receipt.get("action") == "acknowledge_compliance_limitation"
820
+ and receipt.get("report_sha256") == group[0]["sha256"]
821
+ )
822
+ scopes = (override.get("scope"), receipt.get("scope"))
823
+ for candidate_scope in scopes:
824
+ if (
825
+ not isinstance(candidate_scope, list)
826
+ or any(not isinstance(item, str) for item in candidate_scope)
827
+ or len(candidate_scope) != len(set(candidate_scope))
828
+ or set(candidate_scope) != set(blockers)
829
+ ):
830
+ valid = False
831
+ stage = receipt.get("stage")
832
+ if stage not in expected_ordinal or ordinal != expected_ordinal.get(stage):
833
+ valid = False
834
+ else:
835
+ expected_ordinal[stage] += 1
836
+ rationale = override.get("rationale")
837
+ if ordinal == 2 and (not isinstance(rationale, str) or not rationale):
838
+ valid = False
839
+ if isinstance(ordinal, int) and ordinal >= 3 and (not isinstance(rationale, str) or len(rationale) < 100):
840
+ valid = False
841
+ if receipt_id in receipt_ids:
842
+ valid = False
843
+ else:
844
+ receipt_ids.add(receipt_id)
845
+ expected_digest = interaction_sha256(run_id, interaction_id)
846
+ if receipt.get("interaction_sha256") != expected_digest:
847
+ valid = False
848
+ if not valid:
849
+ raise ActivityError("SOURCE", "qualifying compliance override replay failed")
850
+ source = compliance_source_record(
851
+ group[0]["artifact_group_id"], stage, blockers, group[0]["sha256"],
852
+ group[1]["sha256"], receipt,
853
+ )
854
+ derived.append(_event(
855
+ run_id, SOURCE_FAMILIES[1], "compliance_block_override", stage,
856
+ "block_overridden", expected_digest, source,
857
+ ))
858
+ return derived
859
+
860
+
861
+ def _rereview_events(run_id: str, group: list[dict[str, Any]], root: Path, total: list[int]) -> list[dict[str, Any]]:
862
+ names = ("input_manifest", "precommitment", "verdict_record", "traceability")
863
+ values: dict[str, dict[str, Any]] = {}
864
+ for name, binding in zip(names, group):
865
+ value, _ = _load_artifact(root, binding, total)
866
+ _schema_validate(value, REREVIEW_CONTRACTS / f"{name}.schema.json", code="SOURCE")
867
+ values[name] = value
868
+ round_ids = {values[name].get("round_id") for name in names}
869
+ if len(round_ids) != 1:
870
+ raise ActivityError("SOURCE", "re-review round ids do not agree")
871
+ if values["precommitment"].get("input_manifest_hash") != hashlib.sha256(canonical_bytes(values["input_manifest"])).hexdigest():
872
+ raise ActivityError("SOURCE", "re-review input/precommitment hash chain mismatch")
873
+ if values["verdict_record"].get("precommitment_hash") != hashlib.sha256(canonical_bytes(values["precommitment"])).hexdigest():
874
+ raise ActivityError("SOURCE", "re-review precommitment/verdict hash chain mismatch")
875
+ if values["traceability"].get("verdict_record_hash") != hashlib.sha256(canonical_bytes(values["verdict_record"])).hexdigest():
876
+ raise ActivityError("SOURCE", "re-review verdict/traceability hash chain mismatch")
877
+ verdict = values["verdict_record"]
878
+ trace = values["traceability"]
879
+ dissent_item: dict[str, str] = {}
880
+ for dissent in verdict["dissents"]:
881
+ if dissent["dissent_id"] in dissent_item:
882
+ raise ActivityError("SOURCE", "duplicate re-review dissent id")
883
+ dissent_item[dissent["dissent_id"]] = dissent["item_id"]
884
+ adjudications_by_id: dict[str, dict[str, Any]] = {}
885
+ for item in trace["dissent_adjudications"]:
886
+ if item["dissent_id"] in adjudications_by_id:
887
+ raise ActivityError("SOURCE", "duplicate dissent adjudication id")
888
+ adjudications_by_id[item["dissent_id"]] = item
889
+ qualifying_dissents = {
890
+ dissent_id: item for dissent_id, item in adjudications_by_id.items()
891
+ if item["adjudicator"] == "user" and item["outcome"] == "original_upheld"
892
+ }
893
+ reapp_by_id: dict[str, dict[str, Any]] = {}
894
+ for item in trace["reapplications"]:
895
+ if item["reapplication_id"] in reapp_by_id:
896
+ raise ActivityError("SOURCE", "duplicate reapplication id")
897
+ reapp_by_id[item["reapplication_id"]] = item
898
+ superseded_by: dict[str, str] = {}
899
+ for item in trace["reapplications"]:
900
+ previous = item.get("supersedes_reapplication_id")
901
+ if previous is not None:
902
+ previous_item = reapp_by_id.get(previous)
903
+ if previous_item is None or previous_item["item_id"] != item["item_id"] or previous in superseded_by:
904
+ raise ActivityError("SOURCE", "invalid reapplication supersession")
905
+ superseded_by[previous] = item["reapplication_id"]
906
+ for item in trace["reapplications"]:
907
+ seen: set[str] = set()
908
+ cursor: dict[str, Any] | None = item
909
+ while cursor is not None:
910
+ cursor_id = cursor["reapplication_id"]
911
+ if cursor_id in seen:
912
+ raise ActivityError("SOURCE", "reapplication supersession cycle")
913
+ seen.add(cursor_id)
914
+ previous = cursor.get("supersedes_reapplication_id")
915
+ cursor = reapp_by_id.get(previous) if previous is not None else None
916
+ current_reapps = [item for item in trace["reapplications"] if item["reapplication_id"] not in superseded_by]
917
+ for reapp in trace["reapplications"]:
918
+ for answer_ref in reapp["answer_refs"]:
919
+ if answer_ref.startswith("adjudication:"):
920
+ dissent_id = answer_ref.split(":", 1)[1]
921
+ adjudication = adjudications_by_id.get(dissent_id)
922
+ if (
923
+ adjudication is None
924
+ or adjudication["outcome"] != "original_upheld"
925
+ or dissent_item.get(dissent_id) != reapp["item_id"]
926
+ ):
927
+ raise ActivityError("SOURCE", "reapplication adjudication ref is unresolved or cross-item")
928
+ for dissent_id, adjudication in adjudications_by_id.items():
929
+ if adjudication["outcome"] == "original_upheld":
930
+ holders = [
931
+ reapp for reapp in current_reapps
932
+ if f"adjudication:{dissent_id}" in reapp["answer_refs"]
933
+ ]
934
+ if len(holders) != 1:
935
+ raise ActivityError("SOURCE", "original-upheld dissent requires exactly one current reapplication")
936
+ if (
937
+ holders[0]["reapplied_verdict"] == "CANNOT_VERIFY"
938
+ or holders[0]["reapplied_verdict"] == holders[0]["pre_reapplication_verdict"]
939
+ ):
940
+ raise ActivityError("SOURCE", "original-upheld current reapplication must prove a verdict change")
941
+ adjustments_by_item: dict[str, list[dict[str, Any]]] = {}
942
+ global_adjustment_ids: set[str] = set()
943
+ for adjustment in trace["adjustments"]:
944
+ if adjustment["adjustment_id"] in global_adjustment_ids:
945
+ raise ActivityError("SOURCE", "duplicate adjustment id")
946
+ global_adjustment_ids.add(adjustment["adjustment_id"])
947
+ adjustments_by_item.setdefault(adjustment["item_id"], []).append(adjustment)
948
+ row_by_item: dict[str, dict[str, Any]] = {}
949
+ for row in trace["rows"]:
950
+ if row["item_id"] in row_by_item:
951
+ raise ActivityError("SOURCE", "duplicate traceability row item id")
952
+ row_by_item[row["item_id"]] = row
953
+ adjustments_by_source: dict[str, list[dict[str, Any]]] = {}
954
+ for adjustment in trace["adjustments"]:
955
+ source_ref = adjustment.get("source_ref")
956
+ if source_ref is not None:
957
+ if source_ref.startswith("reapplication:") and source_ref.split(":", 1)[1] not in reapp_by_id:
958
+ raise ActivityError("SOURCE", "adjustment source_ref names an unknown reapplication")
959
+ adjustments_by_source.setdefault(source_ref, []).append(adjustment)
960
+ for reapp in trace["reapplications"]:
961
+ derived = adjustments_by_source.get(f"reapplication:{reapp['reapplication_id']}", [])
962
+ changing = (
963
+ reapp["reapplied_verdict"] != "CANNOT_VERIFY"
964
+ and reapp["reapplied_verdict"] != reapp["pre_reapplication_verdict"]
965
+ )
966
+ if not changing:
967
+ if derived:
968
+ raise ActivityError("SOURCE", "non-changing/CANNOT reapplication has a derived adjustment")
969
+ continue
970
+ if len(derived) != 1:
971
+ raise ActivityError("SOURCE", "verdict-changing reapplication requires exactly one derived adjustment")
972
+ adjustment = derived[0]
973
+ if (
974
+ adjustment["item_id"] != reapp["item_id"]
975
+ or adjustment["basis"] != "cross_model_adjudication"
976
+ or adjustment["from_verdict"] != reapp["pre_reapplication_verdict"]
977
+ or adjustment["to_verdict"] != reapp["reapplied_verdict"]
978
+ or adjustment["rationale"] != reapp["rationale"]
979
+ or adjustment.get("residual_gap") != reapp.get("residual_gap")
980
+ or adjustment.get("evidence_anchor") != reapp.get("evidence_anchor")
981
+ ):
982
+ raise ActivityError("SOURCE", "derived adjustment does not mirror its reapplication")
983
+ candidates: list[tuple[int, dict[str, Any], str, str]] = []
984
+ counted_adjustments: set[str] = set()
985
+ for dissent_id in qualifying_dissents:
986
+ item_id = dissent_item.get(dissent_id)
987
+ if item_id is None:
988
+ raise ActivityError("SOURCE", "adjudicated dissent does not resolve to verdict dissent")
989
+ reapps = [item for item in current_reapps if item["item_id"] == item_id and f"adjudication:{dissent_id}" in item["answer_refs"]]
990
+ if len(reapps) != 1:
991
+ raise ActivityError("SOURCE", "dissent must resolve to one current reapplication")
992
+ if (
993
+ reapps[0]["reapplied_verdict"] == "CANNOT_VERIFY"
994
+ or reapps[0]["reapplied_verdict"] == reapps[0]["pre_reapplication_verdict"]
995
+ ):
996
+ raise ActivityError("SOURCE", "original-upheld current reapplication must prove a verdict change")
997
+ records = adjustments_by_item.get(item_id, [])
998
+ by_id = {item["adjustment_id"]: item for item in records}
999
+ if len(by_id) != len(records):
1000
+ raise ActivityError("SOURCE", "duplicate adjustment id")
1001
+ followers: dict[str, dict[str, Any]] = {}
1002
+ heads: list[dict[str, Any]] = []
1003
+ for adjustment in records:
1004
+ previous = adjustment.get("supersedes_adjustment_id")
1005
+ if previous is None:
1006
+ heads.append(adjustment)
1007
+ elif previous not in by_id or previous in followers:
1008
+ raise ActivityError("SOURCE", "forked or orphan adjustment chain")
1009
+ else:
1010
+ followers[previous] = adjustment
1011
+ if len(heads) != 1:
1012
+ raise ActivityError("SOURCE", "adjustment chain must have exactly one head")
1013
+ chain = [heads[0]]
1014
+ while chain[-1]["adjustment_id"] in followers:
1015
+ next_item = followers[chain[-1]["adjustment_id"]]
1016
+ if next_item["from_verdict"] != chain[-1]["to_verdict"]:
1017
+ raise ActivityError("SOURCE", "adjustment chain verdict join mismatch")
1018
+ chain.append(next_item)
1019
+ if len(chain) != len(records):
1020
+ raise ActivityError("SOURCE", "adjustment chain contains a cycle or disconnected record")
1021
+ row = row_by_item.get(item_id)
1022
+ if not row or row.get("adjustment_id") != chain[-1]["adjustment_id"] or row.get("final_verdict") != chain[-1]["to_verdict"]:
1023
+ raise ActivityError("SOURCE", "final row does not bind adjustment chain tail")
1024
+ reapp = reapps[0]
1025
+ for adjustment in chain:
1026
+ if (
1027
+ adjustment["basis"] == "cross_model_adjudication"
1028
+ and adjustment.get("source_ref") == f"reapplication:{reapp['reapplication_id']}"
1029
+ and adjustment["from_verdict"] != adjustment["to_verdict"]
1030
+ ):
1031
+ if adjustment["adjustment_id"] in counted_adjustments:
1032
+ raise ActivityError("SOURCE", "one adjustment cannot produce multiple activity events")
1033
+ counted_adjustments.add(adjustment["adjustment_id"])
1034
+ numeric = int(adjustment["adjustment_id"].split("-", 1)[1])
1035
+ candidates.append((numeric, adjustment, dissent_id, reapp["reapplication_id"]))
1036
+ trace_hash = group[3]["sha256"]
1037
+ return [
1038
+ _event(
1039
+ run_id, SOURCE_FAMILIES[2], "re_review_verdict_changed",
1040
+ "pipeline_stage_3_prime", "verdict_changed", None,
1041
+ re_review_source_record(
1042
+ values["input_manifest"]["round_id"], dissent_id,
1043
+ adjustment["item_id"], reapplication_id, adjustment, trace_hash,
1044
+ ),
1045
+ )
1046
+ for _, adjustment, dissent_id, reapplication_id in sorted(candidates, key=lambda item: item[0])
1047
+ ]
1048
+
1049
+
1050
+ def _validate_action_log(value: dict[str, Any], *, run_id: str, mandatory: bool) -> list[dict[str, Any]]:
1051
+ version = "adjudication-mandatory-checkpoint-log/1.0" if mandatory else "adjudication-explicit-user-request-log/1.0"
1052
+ if set(value) != {"schema_version", "run_id", "records"} or value.get("schema_version") != version or value.get("run_id") != run_id:
1053
+ raise ActivityError("SOURCE", "action log root is invalid")
1054
+ records = value.get("records")
1055
+ if not isinstance(records, list) or len(records) > MAX_EVENTS_RUN:
1056
+ raise ActivityError("SOURCE", "action log record list is invalid")
1057
+ ids: set[str] = set()
1058
+ for record in records:
1059
+ common = {"actor_role", "source", "stage", "interaction_id", "interaction_sha256"}
1060
+ expected = common | (
1061
+ {"response_id", "checkpoint_id", "checkpoint_type", "disposition"}
1062
+ if mandatory else {"request_id", "action", "finding_id"}
1063
+ )
1064
+ if not isinstance(record, dict) or set(record) != expected:
1065
+ raise ActivityError("SOURCE", "action log record closed shape is invalid")
1066
+ record_id = record["response_id" if mandatory else "request_id"]
1067
+ if not isinstance(record_id, str) or not ID_RE.fullmatch(record_id) or record_id in ids:
1068
+ raise ActivityError("SOURCE", "action log record id is invalid or repeated")
1069
+ ids.add(record_id)
1070
+ identifier_fields = (
1071
+ ("checkpoint_id", "interaction_id")
1072
+ if mandatory else ("finding_id", "interaction_id")
1073
+ )
1074
+ if any(
1075
+ not isinstance(record.get(field), str) or not ID_RE.fullmatch(record[field])
1076
+ for field in identifier_fields
1077
+ ):
1078
+ raise ActivityError("SOURCE", "action log identifier is outside the closed grammar")
1079
+ if record.get("actor_role") != "user" or record.get("source") != "explicit_session_user_action" or record.get("stage") not in STAGES:
1080
+ raise ActivityError("SOURCE", "action log authority/stage is invalid")
1081
+ interaction_id = record.get("interaction_id")
1082
+ if not isinstance(interaction_id, str) or not ID_RE.fullmatch(interaction_id) or record.get("interaction_sha256") != interaction_sha256(run_id, interaction_id):
1083
+ raise ActivityError("SOURCE", "action log interaction digest is invalid")
1084
+ if mandatory:
1085
+ if record.get("checkpoint_type") != "MANDATORY" or record.get("disposition") not in {"proceed", "skip", "pause", "adjust", "view_progress", "redo", "abort"}:
1086
+ raise ActivityError("SOURCE", "mandatory checkpoint record is invalid")
1087
+ elif record.get("action") not in {"justify_finding", "redo_finding"}:
1088
+ raise ActivityError("SOURCE", "explicit request action is invalid")
1089
+ return records
1090
+
1091
+
1092
+ def _log_events(run_id: str, family: str, group: list[dict[str, Any]], root: Path, total: list[int]) -> tuple[list[dict[str, Any]], int]:
1093
+ value, _ = _load_artifact(root, group[0], total)
1094
+ mandatory = family == SOURCE_FAMILIES[4]
1095
+ records = _validate_action_log(value, run_id=run_id, mandatory=mandatory)
1096
+ result: list[dict[str, Any]] = []
1097
+ for record in records:
1098
+ if mandatory:
1099
+ source_disposition = record["disposition"]
1100
+ if source_disposition == "proceed":
1101
+ continue
1102
+ disposition = "skip_refused" if source_disposition == "skip" else source_disposition
1103
+ result.append(_event(
1104
+ run_id, family, "mandatory_checkpoint_non_proceed", record["stage"],
1105
+ disposition, record["interaction_sha256"], mandatory_source_record(record),
1106
+ ))
1107
+ else:
1108
+ event_type, disposition = (
1109
+ ("finding_justification_requested", "justification_requested")
1110
+ if record["action"] == "justify_finding"
1111
+ else ("finding_redo_requested", "redo_requested")
1112
+ )
1113
+ result.append(_event(
1114
+ run_id, family, event_type, record["stage"], disposition,
1115
+ record["interaction_sha256"], explicit_source_record(record),
1116
+ ))
1117
+ return result, len(records)
1118
+
1119
+
1120
+ def _validate_manifest_authority(manifest: dict[str, Any], root: Path) -> tuple[dict[str, Any], bytes]:
1121
+ _schema_validate(manifest, INPUT_SCHEMA_PATH, code="INPUT")
1122
+ terminal = manifest["terminal_receipt"]
1123
+ state_raw = _read_artifact_relative(root, terminal["relative_path"], MAX_STORE)
1124
+ if hashlib.sha256(state_raw).hexdigest() != terminal["sha256"]:
1125
+ raise ActivityError("INPUT", "terminal receipt raw-byte hash mismatch")
1126
+ state = strict_json(state_raw, code="INPUT")
1127
+ run_id, pipeline_state, stage, status = _state_replay(state)
1128
+ exact = {
1129
+ "artifact_id": "pipeline-state-terminal-receipt",
1130
+ "relative_path": terminal["relative_path"],
1131
+ "sha256": hashlib.sha256(state_raw).hexdigest(),
1132
+ "run_id": run_id, "pipeline_state": pipeline_state,
1133
+ "current_stage": stage, "current_stage_status": status,
1134
+ }
1135
+ if terminal != exact:
1136
+ raise ActivityError("INPUT", "terminal receipt projection does not exactly replay")
1137
+ if manifest["run_id"] != run_id or manifest["terminal_state"] != pipeline_state or manifest["terminal_stage"] != stage:
1138
+ raise ActivityError("INPUT", "input root does not match terminal state authority")
1139
+ inventory = state.get("adjudication_activity_sources")
1140
+ if inventory != manifest["sources"]:
1141
+ raise ActivityError("INPUT", "input sources differ from sealed terminal inventory")
1142
+ _validate_source_rows(inventory)
1143
+ for row in inventory:
1144
+ _group_artifacts(row)
1145
+ if row["source_family"] == SOURCE_FAMILIES[0] and row["capture_state"] == "captured":
1146
+ for group in _group_artifacts(row):
1147
+ raw_stage = STAGE_TO_RAW[group[0]["artifact_group_stage"]]
1148
+ stage_row = state.get("stages", {}).get(raw_stage)
1149
+ if not isinstance(stage_row, dict) or stage_row.get("status") != "completed":
1150
+ raise ActivityError("INPUT", "author source stage is not completed in terminal state")
1151
+ return state, state_raw
1152
+
1153
+
1154
+ def _extract_run(manifest: dict[str, Any], root: Path, sequence: int) -> dict[str, Any]:
1155
+ _, _ = _validate_manifest_authority(manifest, root)
1156
+ run_id = manifest["run_id"]
1157
+ total = [0]
1158
+ source_rows: list[dict[str, Any]] = []
1159
+ all_events: list[list[dict[str, Any]]] = []
1160
+ action_log_record_count = 0
1161
+ for row in manifest["sources"]:
1162
+ groups = _group_artifacts(row)
1163
+ events: list[dict[str, Any]] = []
1164
+ if row["capture_state"] == "captured":
1165
+ family = row["source_family"]
1166
+ if family == SOURCE_FAMILIES[0]:
1167
+ for group in groups:
1168
+ events.extend(_author_events(run_id, group[0]["artifact_group_stage"], group, root, total))
1169
+ elif family == SOURCE_FAMILIES[1]:
1170
+ events = _compliance_events(run_id, groups, root, total)
1171
+ elif family == SOURCE_FAMILIES[2]:
1172
+ events = _rereview_events(run_id, groups[0], root, total)
1173
+ else:
1174
+ events, source_record_count = _log_events(run_id, family, groups[0], root, total)
1175
+ action_log_record_count += source_record_count
1176
+ if action_log_record_count > MAX_EVENTS_RUN:
1177
+ raise ActivityError("CAP", "combined action-log records exceed per-run cap")
1178
+ all_events.append(events)
1179
+ source_rows.append({
1180
+ "source_family": row["source_family"],
1181
+ "capture_state": row["capture_state"],
1182
+ "reason_code": row["reason_code"],
1183
+ "artifact_sha256s": [item["sha256"] for item in row["artifacts"]],
1184
+ "events": events,
1185
+ })
1186
+ winner: dict[str, int] = {}
1187
+ for family_index, events in enumerate(all_events):
1188
+ for event in events:
1189
+ digest = event["interaction_sha256"]
1190
+ if digest is not None and digest not in winner:
1191
+ winner[digest] = family_index
1192
+ for family_index, source in enumerate(source_rows):
1193
+ source["events"] = [
1194
+ event for event in source["events"]
1195
+ if event["interaction_sha256"] is None or winner[event["interaction_sha256"]] == family_index
1196
+ ]
1197
+ event_count = sum(len(row["events"]) for row in source_rows)
1198
+ if event_count > MAX_EVENTS_RUN:
1199
+ raise ActivityError("CAP", "derived events exceed per-run cap")
1200
+ record: dict[str, Any] = {
1201
+ "append_sequence": sequence,
1202
+ "run_id": run_id,
1203
+ "terminal_state": manifest["terminal_state"],
1204
+ "terminal_stage": manifest["terminal_stage"],
1205
+ "terminal_receipt_sha256": manifest["terminal_receipt"]["sha256"],
1206
+ "input_receipt_sha256": _digest(b"ars.adjudication-activity.input/1.0\0", manifest),
1207
+ "record_sha256": "",
1208
+ "sealed": True,
1209
+ "sources": source_rows,
1210
+ }
1211
+ preimage = {key: value for key, value in record.items() if key != "record_sha256"}
1212
+ record["record_sha256"] = _digest(b"ars.adjudication-activity.run/1.0\0", preimage)
1213
+ return record
1214
+
1215
+
1216
+ def _empty_store(store_id: str) -> dict[str, Any]:
1217
+ return {
1218
+ "schema_version": STORE_VERSION, "store_id": store_id,
1219
+ "revision": 0, "next_sequence": 1, "runs": [],
1220
+ "data_minimization": copy.deepcopy(DATA_MINIMIZATION),
1221
+ }
1222
+
1223
+
1224
+ def _validate_store(value: Any) -> dict[str, Any]:
1225
+ if not isinstance(value, dict):
1226
+ raise ActivityError("STORE", "store root must be an object")
1227
+ _schema_validate(value, STORE_SCHEMA_PATH, code="STORE")
1228
+ runs = value["runs"]
1229
+ if len(runs) > MAX_RUNS:
1230
+ raise ActivityError("CAP", "retained runs exceed hard cap")
1231
+ sequences: list[int] = []
1232
+ identities: dict[str, set[Any]] = {
1233
+ "run": set(), "input": set(), "record": set(), "event": set(),
1234
+ }
1235
+ total_events = 0
1236
+ for run in runs:
1237
+ sequences.append(run["append_sequence"])
1238
+ checks = (("run", run["run_id"]), ("input", run["input_receipt_sha256"]), ("record", run["record_sha256"]))
1239
+ for kind, identity in checks:
1240
+ if identity in identities[kind]:
1241
+ raise ActivityError("STORE", f"duplicate {kind} identity")
1242
+ identities[kind].add(identity)
1243
+ preimage = {key: item for key, item in run.items() if key != "record_sha256"}
1244
+ if run["record_sha256"] != _digest(b"ars.adjudication-activity.run/1.0\0", preimage):
1245
+ raise ActivityError("STORE", "run record digest mismatch")
1246
+ if [row["source_family"] for row in run["sources"]] != list(SOURCE_FAMILIES):
1247
+ raise ActivityError("STORE", "stored source family order mismatch")
1248
+ captured_counts = (
1249
+ {2, 4}, set(range(1, 33)), {4}, {1}, {1},
1250
+ )
1251
+ cross_family: dict[str, int] = {}
1252
+ for family_index, row in enumerate(run["sources"]):
1253
+ artifact_count = len(row["artifact_sha256s"])
1254
+ if row["capture_state"] == "captured" and artifact_count not in captured_counts[family_index]:
1255
+ raise ActivityError("STORE", "captured source artifact count violates family contract")
1256
+ if row["capture_state"] != "captured" and artifact_count != 0:
1257
+ raise ActivityError("STORE", "non-captured source retains artifact hashes")
1258
+ for event in row["events"]:
1259
+ if event["event_id"] in identities["event"]:
1260
+ raise ActivityError("STORE", "duplicate event id")
1261
+ identities["event"].add(event["event_id"])
1262
+ digest = event["interaction_sha256"]
1263
+ if digest is not None and digest in cross_family and cross_family[digest] != family_index:
1264
+ raise ActivityError("STORE", "cross-family causal duplicate remains in store")
1265
+ if digest is not None:
1266
+ cross_family[digest] = family_index
1267
+ payload = {
1268
+ "run_id": run["run_id"], "source_family": row["source_family"],
1269
+ "event_type": event["event_type"], "stage": event["stage"],
1270
+ "disposition": event["disposition"],
1271
+ "interaction_sha256": digest,
1272
+ "source_event_sha256": event["source_event_sha256"],
1273
+ }
1274
+ expected_id = "ACTIVITY-EVENT-" + _digest(b"ars.adjudication-activity.event-id/1.0\0", payload)
1275
+ if event["event_id"] != expected_id:
1276
+ raise ActivityError("STORE", "event id digest mismatch")
1277
+ total_events += 1
1278
+ if sequences != sorted(sequences) or len(sequences) != len(set(sequences)):
1279
+ raise ActivityError("STORE", "append sequences are not strictly increasing")
1280
+ if sequences and value["next_sequence"] <= sequences[-1]:
1281
+ raise ActivityError("STORE", "next_sequence does not exceed retained sequences")
1282
+ if value["revision"] < len(runs):
1283
+ raise ActivityError("STORE", "revision cannot be below retained append count")
1284
+ if value["revision"] < value["next_sequence"] - 1:
1285
+ raise ActivityError("STORE", "revision cannot be below allocated append sequences")
1286
+ if total_events > MAX_EVENTS_STORE:
1287
+ raise ActivityError("CAP", "store event count exceeds hard cap")
1288
+ return value
1289
+
1290
+
1291
+ def _read_store(path: Path) -> tuple[dict[str, Any], bytes, tuple[int, int, int]]:
1292
+ raw, identity = _read_limited_identity(path, MAX_STORE, code="STORE")
1293
+ value = strict_json(raw, code="STORE")
1294
+ if raw != canonical_bytes(value, code="STORE") + b"\n":
1295
+ raise ActivityError("STORE", "store bytes are not canonical JSON plus one LF")
1296
+ return _validate_store(value), raw, identity
1297
+
1298
+
1299
+ def _store_bytes(value: dict[str, Any]) -> bytes:
1300
+ _validate_store(value)
1301
+ raw = canonical_bytes(value, code="STORE") + b"\n"
1302
+ if len(raw) > MAX_STORE:
1303
+ raise ActivityError("CAP", "persisted store exceeds hard byte cap")
1304
+ return raw
1305
+
1306
+
1307
+ def _json_id(value: str) -> str:
1308
+ return json.dumps(value, ensure_ascii=False, separators=(",", ":"))
1309
+
1310
+
1311
+ def _cmd_init(args: argparse.Namespace) -> str:
1312
+ path = Path(args.store)
1313
+ with _store_lock(path, exclusive=True):
1314
+ if path.exists() or path.is_symlink():
1315
+ raise ActivityError("CONFLICT", "store path already exists")
1316
+ store = _empty_store(args.store_id)
1317
+ _schema_validate(store, STORE_SCHEMA_PATH, code="STORE")
1318
+ _atomic_create(path, _store_bytes(store))
1319
+ return f"[ARS-ADJUDICATION-ACTIVITY] initialized store_id={_json_id(args.store_id)}; revision=0; next_sequence=1"
1320
+
1321
+
1322
+ def _cmd_build(args: argparse.Namespace) -> str:
1323
+ state_path, root = Path(args.state), Path(args.artifact_root)
1324
+ state_raw = _read_limited(state_path, MAX_STORE, code="INPUT")
1325
+ state = strict_json(state_raw, code="INPUT")
1326
+ run_id, pipeline_state, stage, _ = _state_replay(state)
1327
+ inventory = state.get("adjudication_activity_sources")
1328
+ _validate_source_rows(inventory)
1329
+ relative = _relative_binding(root, state_path)
1330
+ manifest = {
1331
+ "schema_version": INPUT_VERSION, "store_id": args.store_id,
1332
+ "run_id": run_id, "terminal_state": pipeline_state,
1333
+ "terminal_stage": stage,
1334
+ "terminal_receipt": _terminal_receipt(state, state_raw, relative),
1335
+ "sources": copy.deepcopy(inventory),
1336
+ "data_minimization": copy.deepcopy(DATA_MINIMIZATION),
1337
+ }
1338
+ _validate_manifest_authority(manifest, root)
1339
+ # Full extraction here proves every projected artifact before publishing input.
1340
+ _extract_run(manifest, root, 1)
1341
+ _atomic_create(Path(args.output), canonical_bytes(manifest) + b"\n")
1342
+ return f"[ARS-ADJUDICATION-ACTIVITY] built_input run_id={_json_id(run_id)}; source_count=5"
1343
+
1344
+
1345
+ def _load_manifest(path: Path) -> dict[str, Any]:
1346
+ raw = _read_limited(path, MAX_INPUT, code="INPUT")
1347
+ value = strict_json(raw, code="INPUT")
1348
+ if not isinstance(value, dict):
1349
+ raise ActivityError("INPUT", "input manifest root must be an object")
1350
+ _schema_validate(value, INPUT_SCHEMA_PATH, code="INPUT")
1351
+ return value
1352
+
1353
+
1354
+ def _cmd_append(args: argparse.Namespace) -> str:
1355
+ manifest = _load_manifest(Path(args.input))
1356
+ root, path = Path(args.artifact_root), Path(args.store)
1357
+ receipt = _digest(b"ars.adjudication-activity.input/1.0\0", manifest)
1358
+ with _store_lock(path, exclusive=True):
1359
+ if path.exists() or path.is_symlink():
1360
+ store, _, store_identity = _read_store(path)
1361
+ if store["store_id"] != manifest["store_id"]:
1362
+ raise ActivityError("CONFLICT", "store id differs from input store id")
1363
+ else:
1364
+ store = _empty_store(manifest["store_id"])
1365
+ store_identity = None
1366
+ for retained in store["runs"]:
1367
+ if retained["run_id"] == manifest["run_id"]:
1368
+ if retained["input_receipt_sha256"] == receipt:
1369
+ return (
1370
+ f"[ARS-ADJUDICATION-ACTIVITY] already_appended run_id={_json_id(retained['run_id'])}; "
1371
+ f"append_sequence={retained['append_sequence']}; revision={store['revision']}"
1372
+ )
1373
+ raise ActivityError("CONFLICT", "run id is retained with a different input receipt")
1374
+ if retained["input_receipt_sha256"] == receipt:
1375
+ raise ActivityError("CONFLICT", "input receipt is retained under a different run id")
1376
+ if len(store["runs"]) >= MAX_RUNS:
1377
+ raise ActivityError("CAP", "retained run cap reached")
1378
+ # Source and terminal replay occurs only for a genuinely new identity.
1379
+ record = _extract_run(manifest, root, store["next_sequence"])
1380
+ candidate = copy.deepcopy(store)
1381
+ candidate["runs"].append(record)
1382
+ candidate["next_sequence"] += 1
1383
+ candidate["revision"] += 1
1384
+ raw = _store_bytes(candidate)
1385
+ if store_identity is not None:
1386
+ _atomic_replace(path, raw, expected_identity=store_identity)
1387
+ else:
1388
+ _atomic_create(path, raw)
1389
+ return (
1390
+ f"[ARS-ADJUDICATION-ACTIVITY] appended run_id={_json_id(record['run_id'])}; "
1391
+ f"append_sequence={record['append_sequence']}; revision={candidate['revision']}"
1392
+ )
1393
+
1394
+
1395
+ def _render(store: dict[str, Any], window: int) -> str:
1396
+ selected = store["runs"][-window:]
1397
+ count = sum(len(source["events"]) for run in selected for source in run["sources"])
1398
+ overturn = sum(
1399
+ event["event_type"] in OVERTURN_TYPES
1400
+ for run in selected for source in run["sources"] for event in source["events"]
1401
+ )
1402
+ unavailable_runs = sum(any(source["capture_state"] == "unavailable" for source in run["sources"]) for run in selected)
1403
+ lines: list[str] = []
1404
+ if len(selected) < 2:
1405
+ lines.append(
1406
+ f"[ARS-ADJUDICATION-ACTIVITY INSUFFICIENT_HISTORY] selected_retained_eligible_run_count={len(selected)}; "
1407
+ f"minimum_required=2; requested_window={window}."
1408
+ )
1409
+ lines.append(
1410
+ f"[ARS-ADJUDICATION-ACTIVITY COUNTS] adjudication_count={count} (denominator: {len(selected)} retained eligible terminal run records); "
1411
+ f"overturn_count={overturn} (denominator: {count} recorded adjudications); unavailable_run_count={unavailable_runs} "
1412
+ f"(denominator: {len(selected)} retained eligible terminal run records)."
1413
+ )
1414
+ else:
1415
+ lines.append(
1416
+ f"[ARS-ADJUDICATION-ACTIVITY] selected_retained_eligible_run_count={len(selected)}; requested_window={window}; "
1417
+ f"adjudication_count={count} (denominator: {len(selected)} retained eligible terminal run records); "
1418
+ f"overturn_count={overturn} (denominator: {count} recorded adjudications); unavailable_run_count={unavailable_runs} "
1419
+ f"(denominator: {len(selected)} retained eligible terminal run records)."
1420
+ )
1421
+ for run in selected:
1422
+ run_count = sum(len(source["events"]) for source in run["sources"])
1423
+ run_overturn = sum(event["event_type"] in OVERTURN_TYPES for source in run["sources"] for event in source["events"])
1424
+ unavailable = sum(source["capture_state"] == "unavailable" for source in run["sources"])
1425
+ lines.append(
1426
+ f"sequence={run['append_sequence']}; run_id={_json_id(run['run_id'])}; terminal_state={run['terminal_state']}; "
1427
+ f"adjudication_count={run_count} (denominator: 1 retained eligible terminal run record); "
1428
+ f"overturn_count={run_overturn} (denominator: {run_count} recorded adjudications); "
1429
+ f"unavailable_source_count={unavailable} (denominator: 5 source families)."
1430
+ )
1431
+ lines.extend((COVERAGE, LIMITATION, ADVISORY))
1432
+ return "\n".join(lines)
1433
+
1434
+
1435
+ def _cmd_render(args: argparse.Namespace) -> str:
1436
+ path = Path(args.store)
1437
+ with _store_lock(path, exclusive=False):
1438
+ store, _, _ = _read_store(path)
1439
+ return _render(store, args.window)
1440
+
1441
+
1442
+ def _cmd_validate(args: argparse.Namespace) -> str:
1443
+ path = Path(args.store)
1444
+ with _store_lock(path, exclusive=False):
1445
+ store, _, _ = _read_store(path)
1446
+ return (
1447
+ f"[ARS-ADJUDICATION-ACTIVITY] valid store_id={_json_id(store['store_id'])}; "
1448
+ f"retained_runs={len(store['runs'])}; revision={store['revision']}; next_sequence={store['next_sequence']}"
1449
+ )
1450
+
1451
+
1452
+ def _confirmation(store_id: str, expected_hash: str, raw: bytes) -> None:
1453
+ if not HEX_RE.fullmatch(expected_hash) or hashlib.sha256(raw).hexdigest() != expected_hash:
1454
+ raise ActivityError("DELETE_CONFIRMATION", "store raw-byte hash confirmation mismatch")
1455
+ if store_id is None:
1456
+ raise ActivityError("DELETE_CONFIRMATION", "store id confirmation is required")
1457
+
1458
+
1459
+ def _cmd_delete_runs(args: argparse.Namespace) -> str:
1460
+ path = Path(args.store)
1461
+ with _store_lock(path, exclusive=True):
1462
+ store, raw, store_identity = _read_store(path)
1463
+ _confirmation(args.store_id, args.expect_store_sha256, raw)
1464
+ if store["store_id"] != args.store_id:
1465
+ raise ActivityError("DELETE_CONFIRMATION", "store id confirmation mismatch")
1466
+ if args.run_id:
1467
+ if len(args.run_id) != len(set(args.run_id)):
1468
+ raise ActivityError("DELETE_CONFIRMATION", "run id deletion set has duplicates")
1469
+ wanted = set(args.run_id)
1470
+ existing = {run["run_id"] for run in store["runs"]}
1471
+ if not wanted or not wanted <= existing:
1472
+ raise ActivityError("DELETE_CONFIRMATION", "run id deletion target mismatch")
1473
+ survivors = [run for run in store["runs"] if run["run_id"] not in wanted]
1474
+ else:
1475
+ try:
1476
+ first_text, last_text = args.sequence_range.split(":", 1)
1477
+ first, last = int(first_text), int(last_text)
1478
+ except (AttributeError, ValueError):
1479
+ raise ActivityError("DELETE_CONFIRMATION", "invalid sequence range") from None
1480
+ if first < 1 or first > last:
1481
+ raise ActivityError("DELETE_CONFIRMATION", "invalid sequence range")
1482
+ selected = {run["append_sequence"] for run in store["runs"] if first <= run["append_sequence"] <= last}
1483
+ if not selected:
1484
+ raise ActivityError("DELETE_CONFIRMATION", "sequence range selects no retained run")
1485
+ survivors = [run for run in store["runs"] if run["append_sequence"] not in selected]
1486
+ deleted = len(store["runs"]) - len(survivors)
1487
+ candidate = copy.deepcopy(store)
1488
+ candidate["runs"] = survivors
1489
+ candidate["revision"] += 1
1490
+ _atomic_replace(path, _store_bytes(candidate), expected_identity=store_identity)
1491
+ return f"[ARS-ADJUDICATION-ACTIVITY] deleted_runs={deleted}; revision={candidate['revision']}; next_sequence={candidate['next_sequence']}"
1492
+
1493
+
1494
+ def _cmd_delete_store(args: argparse.Namespace) -> str:
1495
+ if args.confirm != "DELETE-ADJUDICATION-ACTIVITY-STORE":
1496
+ raise ActivityError("DELETE_CONFIRMATION", "whole-store confirmation token mismatch")
1497
+ path = Path(args.store)
1498
+ with _store_lock(path, exclusive=True):
1499
+ raw, store_identity = _read_limited_identity(path, MAX_STORE, code="STORE")
1500
+ _confirmation(args.store_id, args.expect_store_sha256, raw)
1501
+ try:
1502
+ parsed = strict_json(raw, code="STORE")
1503
+ if raw != canonical_bytes(parsed, code="STORE") + b"\n":
1504
+ raise ActivityError("STORE", "store bytes are noncanonical")
1505
+ store = _validate_store(parsed)
1506
+ except ActivityError:
1507
+ store = None
1508
+ if store is not None and store["store_id"] != args.store_id:
1509
+ raise ActivityError("DELETE_CONFIRMATION", "store id confirmation mismatch")
1510
+ try:
1511
+ _assert_identity(path, store_identity)
1512
+ os.unlink(path)
1513
+ directory_fd = os.open(path.parent, os.O_RDONLY)
1514
+ try:
1515
+ os.fsync(directory_fd)
1516
+ finally:
1517
+ os.close(directory_fd)
1518
+ except OSError as exc:
1519
+ raise ActivityError("WRITE", f"store deletion failed: {exc.__class__.__name__}") from None
1520
+ return "[ARS-ADJUDICATION-ACTIVITY] deleted_store=true"
1521
+
1522
+
1523
+ class _Parser(argparse.ArgumentParser):
1524
+ def error(self, message: str) -> None:
1525
+ raise ActivityError("USAGE", message)
1526
+
1527
+
1528
+ def build_cli_parser() -> argparse.ArgumentParser:
1529
+ parser = _Parser(prog="adjudication_activity.py")
1530
+ subparsers = parser.add_subparsers(dest="command", required=True)
1531
+
1532
+ init_parser = subparsers.add_parser("init-store")
1533
+ init_parser.add_argument("--store", required=True)
1534
+ init_parser.add_argument("--store-id", required=True)
1535
+ init_parser.set_defaults(handler=_cmd_init)
1536
+
1537
+ build_parser = subparsers.add_parser("build-input")
1538
+ build_parser.add_argument("--state", required=True)
1539
+ build_parser.add_argument("--artifact-root", required=True)
1540
+ build_parser.add_argument("--store-id", required=True)
1541
+ build_parser.add_argument("--output", required=True)
1542
+ build_parser.set_defaults(handler=_cmd_build)
1543
+
1544
+ append_parser = subparsers.add_parser("append-run")
1545
+ append_parser.add_argument("--store", required=True)
1546
+ append_parser.add_argument("--artifact-root", required=True)
1547
+ append_parser.add_argument("--input", required=True)
1548
+ append_parser.set_defaults(handler=_cmd_append)
1549
+
1550
+ render_parser = subparsers.add_parser("render")
1551
+ render_parser.add_argument("--store", required=True)
1552
+ render_parser.add_argument("--window", type=int, default=10)
1553
+ render_parser.set_defaults(handler=_cmd_render)
1554
+
1555
+ validate_parser = subparsers.add_parser("validate")
1556
+ validate_parser.add_argument("--store", required=True)
1557
+ validate_parser.set_defaults(handler=_cmd_validate)
1558
+
1559
+ delete_runs_parser = subparsers.add_parser("delete-runs")
1560
+ delete_runs_parser.add_argument("--store", required=True)
1561
+ delete_runs_parser.add_argument("--store-id", required=True)
1562
+ delete_runs_parser.add_argument("--expect-store-sha256", required=True)
1563
+ selection = delete_runs_parser.add_mutually_exclusive_group(required=True)
1564
+ selection.add_argument("--run-id", action="append")
1565
+ selection.add_argument("--sequence-range")
1566
+ delete_runs_parser.set_defaults(handler=_cmd_delete_runs)
1567
+
1568
+ delete_store_parser = subparsers.add_parser("delete-store")
1569
+ delete_store_parser.add_argument("--store", required=True)
1570
+ delete_store_parser.add_argument("--store-id", required=True)
1571
+ delete_store_parser.add_argument("--expect-store-sha256", required=True)
1572
+ delete_store_parser.add_argument("--confirm", required=True)
1573
+ delete_store_parser.set_defaults(handler=_cmd_delete_store)
1574
+ return parser
1575
+
1576
+
1577
+ def main(argv: Sequence[str] | None = None) -> int:
1578
+ try:
1579
+ args = build_cli_parser().parse_args(argv)
1580
+ if getattr(args, "window", 10) not in range(2, 51):
1581
+ raise ActivityError("USAGE", "window must be in the closed range 2..50")
1582
+ output = args.handler(args)
1583
+ if output:
1584
+ print(output)
1585
+ return 0
1586
+ except ActivityError as exc:
1587
+ print(f"[ARS-ADJUDICATION-ACTIVITY ERROR:{exc.code}] {exc.detail}", file=sys.stderr)
1588
+ return EXIT_BY_CODE[exc.code]
1589
+
1590
+
1591
+ if __name__ == "__main__":
1592
+ raise SystemExit(main())