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,790 @@
1
+ """TDD test suite for the ARS write-scope guard PreToolUse hook (#134 Slice 1).
2
+
3
+ Spec: docs/design/2026-06-01-ars-134-conductor-rescope-deterministic-write-guard-spec.md (§3.4).
4
+
5
+ The hook's testable core is `evaluate_decision(payload, manifest, workspace_root,
6
+ plugin_root=None)`, a pure function returning a decision dict {"decision": ..., "reason": ...}.
7
+ `main()` only wires stdin -> evaluate_decision -> stdout JSON (now also covered by
8
+ MainPluginRootComputationTest, which exercises the CLAUDE_PLUGIN_ROOT plumbing #448 added).
9
+
10
+ Decision semantics under test (spec §3.2 logic, amended by #448 dual-root anchoring):
11
+ Step 2: infrastructure self-protection — RUNS FIRST, anchored on plugin_root (NOT the
12
+ workspace): a target is infra IFF it resolves inside the ARS plugin install dir
13
+ AND its plugin-relative path matches INFRA_PROTECTED_GLOBS. A user-project file
14
+ that merely shares a filename (their own CLAUDE.md, hooks/*.sh, ...) is NOT infra.
15
+ Step 1: normalize the write target against workspace_root (absolute + symlink resolve +
16
+ workspace commonpath + escape detection -> workspace-root-relative canonical).
17
+ Step 3: agent gating (Bucket A agent_type -> enforce allowed_write_globs;
18
+ absent/non-Bucket-A -> allow, but fail-loud-log absent agent_type write).
19
+ Step 4: tool-specific (Write/Edit/MultiEdit single top-level file_path;
20
+ Bash deny-all for a Bucket A agent, pass-through for non-Bucket-A — neither a
21
+ denylist nor an allowlist of Bash is sound, so all-deny is the only zero-fail-open
22
+ policy).
23
+
24
+ Tests build a REAL workspace dir tree under tmp so normalization runs against the
25
+ real filesystem (no os.path mocking).
26
+ """
27
+
28
+ import json
29
+ import os
30
+ import sys
31
+ import tempfile
32
+ import unittest
33
+ from pathlib import Path
34
+
35
+ sys.path.insert(0, os.path.dirname(os.path.abspath(__file__)))
36
+ REPO_ROOT = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) # scripts/ -> repo root
37
+
38
+ import ars_write_scope_guard as guard # noqa: E402
39
+
40
+
41
+ # A minimal in-test manifest mirroring the real shape (keys = frontmatter name).
42
+ TEST_MANIFEST = {
43
+ "version": 1,
44
+ "agents": {
45
+ "bibliography_agent": {
46
+ "bucket": "A",
47
+ "skill": "deep-research",
48
+ "phase": "2",
49
+ "allowed_write_globs": ["phase2_*/**"],
50
+ },
51
+ "synthesis_agent": {
52
+ "bucket": "A",
53
+ "skill": "deep-research",
54
+ "phase": "3",
55
+ "allowed_write_globs": ["phase3_*/**"],
56
+ },
57
+ "formatter_agent": {
58
+ "bucket": "A",
59
+ "skill": "academic-paper",
60
+ "phase": "7",
61
+ "allowed_write_globs": ["phase7_*/**"],
62
+ },
63
+ # Deliberately-broad glob agent: still must lose to Step 2 self-protection.
64
+ "broad_test_agent": {
65
+ "bucket": "A",
66
+ "skill": "test",
67
+ "phase": "X",
68
+ "allowed_write_globs": ["**"],
69
+ },
70
+ },
71
+ }
72
+
73
+
74
+ def payload(tool_name, tool_input, cwd, agent_type=None, agent_id=None):
75
+ p = {
76
+ "session_id": "test",
77
+ "cwd": cwd,
78
+ "hook_event_name": "PreToolUse",
79
+ "tool_name": tool_name,
80
+ "tool_input": tool_input,
81
+ }
82
+ if agent_type is not None:
83
+ p["agent_type"] = agent_type
84
+ if agent_id is not None:
85
+ p["agent_id"] = agent_id
86
+ return p
87
+
88
+
89
+ def symlink_or_skip(testcase, target, link_name):
90
+ """os.symlink, but skip the test on a Windows host without symlink privilege
91
+ (WinError 1314) instead of failing — the symlink-resolution tests are about realpath
92
+ behavior, not about whether the CI host granted SeCreateSymbolicLinkPrivilege."""
93
+ try:
94
+ os.symlink(target, link_name)
95
+ except (OSError, NotImplementedError) as exc:
96
+ if getattr(exc, "winerror", None) == 1314:
97
+ testcase.skipTest("Windows symlink privilege is not available")
98
+ raise
99
+
100
+
101
+ class WriteScopeGuardTest(unittest.TestCase):
102
+ def setUp(self):
103
+ self._tmp = tempfile.TemporaryDirectory()
104
+ self.ws = os.path.realpath(self._tmp.name) # workspace root
105
+ # Build real phase dirs so normalization resolves real parents.
106
+ for d in ("phase2_investigation", "phase3_analysis", "phase7_format", "hooks", "scripts"):
107
+ os.makedirs(os.path.join(self.ws, d), exist_ok=True)
108
+
109
+ def tearDown(self):
110
+ self._tmp.cleanup()
111
+
112
+ def decide(self, p):
113
+ return guard.evaluate_decision(p, TEST_MANIFEST, self.ws)
114
+
115
+ # --- Step 4 / Step 3: structured-tool in-scope vs out-of-scope ---
116
+
117
+ def test_in_scope_write_allowed(self):
118
+ p = payload("Write",
119
+ {"file_path": os.path.join(self.ws, "phase2_investigation/annotated_bib.md"), "content": "x"},
120
+ cwd=self.ws, agent_type="bibliography_agent")
121
+ self.assertEqual(self.decide(p)["decision"], "allow")
122
+
123
+ def test_out_of_scope_write_denied(self):
124
+ # bibliography_agent (phase 2) writing into phase3 dir = the #133 shape.
125
+ p = payload("Write",
126
+ {"file_path": os.path.join(self.ws, "phase3_analysis/synthesis.md"), "content": "x"},
127
+ cwd=self.ws, agent_type="bibliography_agent")
128
+ d = self.decide(p)
129
+ self.assertEqual(d["decision"], "deny")
130
+ self.assertIn("bibliography_agent", d["reason"])
131
+
132
+ def test_in_scope_edit_allowed(self):
133
+ p = payload("Edit",
134
+ {"file_path": os.path.join(self.ws, "phase3_analysis/synthesis.md"),
135
+ "old_string": "a", "new_string": "b"},
136
+ cwd=self.ws, agent_type="synthesis_agent")
137
+ self.assertEqual(self.decide(p)["decision"], "allow")
138
+
139
+ def test_out_of_scope_multiedit_denied_via_top_level_file_path(self):
140
+ # MultiEdit carries a SINGLE top-level file_path + edits[]; the path check
141
+ # must use that top-level file_path, not a non-existent per-edit path array.
142
+ p = payload("MultiEdit",
143
+ {"file_path": os.path.join(self.ws, "phase2_investigation/bib.md"),
144
+ "edits": [{"old_string": "a", "new_string": "b"},
145
+ {"old_string": "c", "new_string": "d"}]},
146
+ cwd=self.ws, agent_type="synthesis_agent") # phase3 agent, writing phase2
147
+ d = self.decide(p)
148
+ self.assertEqual(d["decision"], "deny")
149
+
150
+ def test_in_scope_multiedit_allowed(self):
151
+ p = payload("MultiEdit",
152
+ {"file_path": os.path.join(self.ws, "phase3_analysis/synthesis.md"),
153
+ "edits": [{"old_string": "a", "new_string": "b"}]},
154
+ cwd=self.ws, agent_type="synthesis_agent")
155
+ self.assertEqual(self.decide(p)["decision"], "allow")
156
+
157
+ # --- Bash policy: DENY ALL Bash for a Bucket A agent; non-Bucket-A Bash passes
158
+ # through unconstrained. ---
159
+
160
+ def test_bash_denied_wholesale_for_bucket_a(self):
161
+ # EVERY Bash command is denied for a Bucket A agent regardless of content — the only
162
+ # policy that reaches zero fail-open by construction (neither "writes a file" nor "is
163
+ # read-only" is decidable from a command string). One representative per class here
164
+ # (+ the deny flag); the exhaustive historical-bypass list lives in
165
+ # BashBypassRegressionTest.test_all_historical_bash_bypasses_denied.
166
+ for cmd in ("rm x", # plainly writing
167
+ "python make_synthesis.py", # interpreter (no denylist could enumerate)
168
+ "grep foo f", # looks read-only — still denied
169
+ "rg --pre 'sh -c touch' x f"): # "read-only" tool that executes a subprocess
170
+ p = payload("Bash", {"command": cmd}, cwd=self.ws, agent_type="bibliography_agent")
171
+ d = self.decide(p)
172
+ self.assertEqual(d["decision"], "deny", f"{cmd!r} should deny (all-Bash-deny)")
173
+ self.assertTrue(d.get("bash_denied"), f"{cmd!r} should set bash_denied")
174
+
175
+ def test_bash_deny_reason_routes_to_structured_and_search_tools(self):
176
+ # The deny reason must tell the agent what to use instead (Grep/Glob + structured).
177
+ p = payload("Bash", {"command": "grep foo f"}, cwd=self.ws, agent_type="bibliography_agent")
178
+ reason = self.decide(p)["reason"].lower()
179
+ self.assertIn("grep", reason)
180
+ self.assertIn("write/edit", reason.replace(" ", ""))
181
+
182
+ def test_bash_allowed_for_non_bucket_a(self):
183
+ # A non-Bucket-A agent / main session is unconstrained — ANY Bash passes (the guard
184
+ # only fences the 23 single-phase agents). Covers a named non-bucket-A agent and the
185
+ # absent-agent_type main session.
186
+ p = payload("Bash", {"command": "cp a b"}, cwd=self.ws, agent_type="report_compiler_agent")
187
+ self.assertEqual(self.decide(p)["decision"], "allow")
188
+ p2 = payload("Bash", {"command": "rm x"}, cwd=self.ws) # no agent_type (main session)
189
+ self.assertEqual(self.decide(p2)["decision"], "allow")
190
+
191
+ # --- Step 2: infrastructure self-protection (anchored on plugin_root; these tests use
192
+ # the 3-arg fallback where plugin_root collapses to workspace_root, so the plugin's
193
+ # own infra files sit at the workspace root and are denied for EVERY actor. The
194
+ # plugin_root != workspace_root cases live in PluginRootInfraScopeTest.) ---
195
+
196
+ def test_infra_hooks_json_denied_for_every_agent(self):
197
+ for at in ("bibliography_agent", "synthesis_agent", "formatter_agent", "broad_test_agent"):
198
+ p = payload("Write",
199
+ {"file_path": os.path.join(self.ws, "hooks/hooks.json"), "content": "x"},
200
+ cwd=self.ws, agent_type=at)
201
+ d = self.decide(p)
202
+ self.assertEqual(d["decision"], "deny", f"{at} must not write hooks/hooks.json")
203
+ self.assertIn("infrastructure", d["reason"].lower())
204
+
205
+ def test_infra_manifest_denied_even_with_broad_glob(self):
206
+ # broad_test_agent has glob ["**"] which would otherwise permit everything;
207
+ # Step 2 self-protection overrides any later allow.
208
+ p = payload("Write",
209
+ {"file_path": os.path.join(self.ws, "scripts/ars_phase_scope_manifest.json"), "content": "x"},
210
+ cwd=self.ws, agent_type="broad_test_agent")
211
+ self.assertEqual(self.decide(p)["decision"], "deny")
212
+
213
+ def test_infra_hook_script_denied(self):
214
+ # The hook script itself (lives in scripts/) is part of the enforcement surface.
215
+ p = payload("Write",
216
+ {"file_path": os.path.join(self.ws, "scripts/ars_write_scope_guard.py"), "content": "x"},
217
+ cwd=self.ws, agent_type="broad_test_agent")
218
+ self.assertEqual(self.decide(p)["decision"], "deny")
219
+
220
+ def test_infra_agent_frontmatter_denied(self):
221
+ # Agent definition files carry the agent_type==name binding; writing them would
222
+ # let an agent rename itself out of the manifest and fail the guard open.
223
+ os.makedirs(os.path.join(self.ws, "deep-research/agents"), exist_ok=True)
224
+ p = payload("Edit",
225
+ {"file_path": os.path.join(self.ws, "deep-research/agents/bibliography_agent.md"),
226
+ "old_string": "a", "new_string": "b"},
227
+ cwd=self.ws, agent_type="broad_test_agent")
228
+ self.assertEqual(self.decide(p)["decision"], "deny")
229
+
230
+ # --- Step 1 ordering: normalization precedes self-protection (traversal bypass) ---
231
+
232
+ def test_traversal_bypass_to_infra_denied(self):
233
+ # A Write whose raw file_path uses ../ to escape a phase dir back into hooks/.
234
+ # Normalization (Step 1) must canonicalize it to hooks/hooks.json BEFORE Step 2,
235
+ # so self-protection catches it. Proves normalize-first ordering.
236
+ raw = os.path.join(self.ws, "phase2_investigation/../hooks/hooks.json")
237
+ p = payload("Write", {"file_path": raw, "content": "x"},
238
+ cwd=self.ws, agent_type="bibliography_agent")
239
+ d = self.decide(p)
240
+ self.assertEqual(d["decision"], "deny")
241
+ self.assertIn("infrastructure", d["reason"].lower())
242
+
243
+ def test_traversal_escaping_workspace_denied(self):
244
+ # ../ escaping the workspace root entirely must be denied FOR A BUCKET A AGENT
245
+ # (commonpath guard). Bucket A stays fenced to its workspace regardless of actor.
246
+ raw = os.path.join(self.ws, "phase2_investigation/../../outside.md")
247
+ p = payload("Write", {"file_path": raw, "content": "x"},
248
+ cwd=self.ws, agent_type="bibliography_agent")
249
+ self.assertEqual(self.decide(p)["decision"], "deny")
250
+
251
+ def test_main_session_escape_allowed(self):
252
+ # #302: a MAIN-SESSION write whose target resolves outside the workspace root
253
+ # (e.g. a sibling git worktree) is ALLOWED — the main session is unconstrained by
254
+ # Slice 1 (§3.3). The escape deny is a Bucket A fence, not a main-session fence.
255
+ raw = os.path.join(self.ws, "../sibling-worktree/file.md")
256
+ p = payload("Write", {"file_path": raw, "content": "x"}, cwd=self.ws) # no agent_type
257
+ d = self.decide(p)
258
+ self.assertEqual(d["decision"], "allow")
259
+ # Still fail-loud about the absent agent_type (not a silent no-op).
260
+ self.assertTrue(d.get("absent_agent_type_advisory"),
261
+ "absent agent_type escape write must still surface the advisory")
262
+
263
+ def test_non_bucket_a_agent_escape_allowed(self):
264
+ # A Bucket B/C/D agent (agent_type present but not a manifest key) is also
265
+ # unconstrained by Slice 1 — an escaping write is allowed, no advisory (it HAS a type).
266
+ raw = os.path.join(self.ws, "../sibling-worktree/file.md")
267
+ p = payload("Write", {"file_path": raw, "content": "x"},
268
+ cwd=self.ws, agent_type="report_compiler_agent") # Bucket B, not in manifest
269
+ d = self.decide(p)
270
+ self.assertEqual(d["decision"], "allow")
271
+ self.assertFalse(d.get("absent_agent_type_advisory"))
272
+
273
+ # --- Step 3: agent gating edge cases ---
274
+
275
+ def test_absent_agent_type_allowed(self):
276
+ # Main session (no agent_type) is unconstrained by Slice 1.
277
+ p = payload("Write",
278
+ {"file_path": os.path.join(self.ws, "phase7_format/anything.md"), "content": "x"},
279
+ cwd=self.ws) # no agent_type
280
+ d = self.decide(p)
281
+ self.assertEqual(d["decision"], "allow")
282
+ # but it must fail-loud-log the absent-agent_type write (not silent no-op)
283
+ self.assertTrue(d.get("absent_agent_type_advisory"),
284
+ "absent agent_type write must surface a fail-loud advisory, not silently no-op")
285
+
286
+ def test_absent_agent_type_still_denied_for_infra(self):
287
+ # Even the main session may not clobber the PLUGIN's own infra. Here the 3-arg
288
+ # fallback puts plugin_root == workspace_root, so hooks/hooks.json IS a plugin infra
289
+ # file and is denied regardless of actor (the #448 carve-out only spares a SEPARATE
290
+ # user project's same-named file — see PluginRootInfraScopeTest).
291
+ p = payload("Write",
292
+ {"file_path": os.path.join(self.ws, "hooks/hooks.json"), "content": "x"},
293
+ cwd=self.ws) # no agent_type
294
+ self.assertEqual(self.decide(p)["decision"], "deny")
295
+
296
+ def test_non_bucket_a_agent_type_allowed(self):
297
+ # An agent_type not in the manifest (e.g. a Bucket B/C/D agent) is unconstrained.
298
+ p = payload("Write",
299
+ {"file_path": os.path.join(self.ws, "phase7_format/report.md"), "content": "x"},
300
+ cwd=self.ws, agent_type="report_compiler_agent") # Bucket B, not in manifest
301
+ self.assertEqual(self.decide(p)["decision"], "allow")
302
+
303
+ # --- Step 1: absolute vs relative normalization ---
304
+
305
+ def test_absolute_path_under_workspace_matches_relative_glob(self):
306
+ # A Write with an ABSOLUTE file_path under the workspace must resolve and match
307
+ # its relative glob (glob is workspace-root-anchored, not absolute, not cwd-rel).
308
+ p = payload("Write",
309
+ {"file_path": os.path.join(self.ws, "phase7_format/paper.md"), "content": "x"},
310
+ cwd=self.ws, agent_type="formatter_agent")
311
+ self.assertEqual(self.decide(p)["decision"], "allow")
312
+
313
+ def test_relative_path_resolved_against_cwd(self):
314
+ # A relative file_path resolves against cwd (= workspace here) then matches glob.
315
+ p = payload("Write",
316
+ {"file_path": "phase7_format/paper.md", "content": "x"},
317
+ cwd=self.ws, agent_type="formatter_agent")
318
+ self.assertEqual(self.decide(p)["decision"], "allow")
319
+
320
+
321
+ class GlobMatchBoundaryTest(unittest.TestCase):
322
+ """Negative + positive glob-match cases (feedback: widening a matcher needs
323
+ explicit 'should-be-rejected' cases — unit pass at one layer can still mismatch)."""
324
+
325
+ POSITIVE = [
326
+ ("phase2_investigation/notes.txt", ["phase2_*/**"]),
327
+ ("phase2_investigation/sub/deep.txt", ["phase2_*/**"]), # deep descendant
328
+ ("phase7_format/paper.md", ["phase7_*/**"]),
329
+ ("scripts/ars_write_scope_guard.py", ["**/ars_write_scope_guard.py"]), # subdir
330
+ ("a/b/c/ars_write_scope_guard.py", ["**/ars_write_scope_guard.py"]), # deep subdir
331
+ ("ars_write_scope_guard.py", ["ars_write_scope_guard.py"]), # root via bare
332
+ ("deep-research/agents/bibliography_agent.md", ["deep-research/agents/*.md"]),
333
+ ]
334
+ NEGATIVE = [
335
+ ("phase3_analysis/x.md", ["phase2_*/**"]), # wrong phase number
336
+ ("phase2x/notes.txt", ["phase2_*/**"]), # no underscore -> NOT phase2_
337
+ ("other/phase2_investigation/x.md", ["phase2_*/**"]), # nested, not workspace-root
338
+ # FALSE-OPEN regression (caught in review): a ROOT-LEVEL file whose name fnmatches the
339
+ # phase-dir glob must NOT match — `dir/**` covers descendants only, not a bare file.
340
+ ("phase2_x.md", ["phase2_*/**"]),
341
+ ("phase1_malicious.py", ["phase1_*/**"]),
342
+ ("phase2_investigation", ["phase2_*/**"]), # bare dir node: not a write target
343
+ # `**/name` matches subdirs only, NOT root (root coverage is the bare entry).
344
+ ("ars_write_scope_guard.py", ["**/ars_write_scope_guard.py"]),
345
+ ]
346
+
347
+ def test_positive_matches(self):
348
+ for rel, globs in self.POSITIVE:
349
+ self.assertTrue(guard._matches_any(rel, globs), f"{rel} should match {globs}")
350
+
351
+ def test_negative_non_matches(self):
352
+ for rel, globs in self.NEGATIVE:
353
+ self.assertFalse(guard._matches_any(rel, globs), f"{rel} should NOT match {globs}")
354
+
355
+ @unittest.skipIf(os.sep == "\\", "POSIX-only: `\\` is a path separator on Windows")
356
+ def test_posix_literal_backslash_in_filename_not_split_into_segments(self):
357
+ # On POSIX, `\` is a LEGAL filename character, NOT a separator. A root-level file
358
+ # literally named `phase2_x\notes.md` is ONE segment and must NOT be rewritten into
359
+ # two segments and matched against `phase2_*/**` — that would be a fence-escape
360
+ # false-allow. (#330 PR #450's unconditional `replace("\\","/")` had this bug; the
361
+ # rewrite is now gated on os.sep == "\\". This test pins the POSIX no-op.)
362
+ self.assertFalse(
363
+ guard._matches_any("phase2_x\\notes.md", ["phase2_*/**"]),
364
+ "a literal backslash in a POSIX filename must not be treated as a path separator")
365
+
366
+
367
+ class DenyJSONShapeTest(unittest.TestCase):
368
+ """The deny output JSON shape (spec §3.2 first-party-verified)."""
369
+
370
+ def test_render_deny_decision_json(self):
371
+ out = guard.render_hook_output({"decision": "deny", "reason": "ARS scope guard: nope"})
372
+ obj = json.loads(out)
373
+ hso = obj["hookSpecificOutput"]
374
+ self.assertEqual(hso["hookEventName"], "PreToolUse")
375
+ self.assertEqual(hso["permissionDecision"], "deny")
376
+ self.assertEqual(hso["permissionDecisionReason"], "ARS scope guard: nope")
377
+
378
+ def test_render_allow_is_passthrough_not_grant(self):
379
+ # Non-deny must be PASS-THROUGH (no permissionDecision key), NOT an explicit
380
+ # "allow" grant — an "allow" would skip every other permission rule (review
381
+ # finding). Assert the key is absent entirely.
382
+ out = guard.render_hook_output({"decision": "allow", "reason": ""})
383
+ hso = json.loads(out)["hookSpecificOutput"]
384
+ self.assertEqual(hso["hookEventName"], "PreToolUse")
385
+ self.assertNotIn("permissionDecision", hso)
386
+
387
+
388
+ class NormalizationRegressionTest(unittest.TestCase):
389
+ """Regression tests for normalization / glob-boundary findings — each must stay fixed."""
390
+
391
+ def setUp(self):
392
+ self._tmp = tempfile.TemporaryDirectory()
393
+ self.ws = os.path.realpath(self._tmp.name)
394
+ for d in ("phase2_investigation", "phase3_analysis", "hooks", "scripts", ".claude-plugin"):
395
+ os.makedirs(os.path.join(self.ws, d), exist_ok=True)
396
+
397
+ def tearDown(self):
398
+ self._tmp.cleanup()
399
+
400
+ def decide(self, p):
401
+ return guard.evaluate_decision(p, TEST_MANIFEST, self.ws)
402
+
403
+ def test_bash_bypass_shapes_that_broke_the_old_parser_still_deny(self):
404
+ # The shapes that defeated the old literal-target parser (quote-blind redirection,
405
+ # quoted `;` in cp, no-whitespace redirection, `cp -t DEST` flag order) are now ALL
406
+ # denied trivially by the all-Bash-deny policy — no parsing required. These stay as
407
+ # regression cases so a future re-introduction of literal parsing can't reopen them.
408
+ shapes = [
409
+ 'echo x > "' + os.path.join(self.ws, "hooks/hooks.json") + '"', # quoted target
410
+ "echo x>" + os.path.join(self.ws, "phase3_analysis/leak.md"), # no whitespace
411
+ 'cp "a;b" ' + os.path.join(self.ws, "phase3_analysis/leak.md"), # quoted ; in cp
412
+ "cp -t " + os.path.join(self.ws, "phase3_analysis") + " src.md", # -t flag order
413
+ ]
414
+ for cmd in shapes:
415
+ p = payload("Bash", {"command": cmd}, cwd=self.ws, agent_type="bibliography_agent")
416
+ self.assertEqual(self.decide(p)["decision"], "deny", f"{cmd!r} should deny")
417
+
418
+ def test_root_level_phase_named_file_denied(self):
419
+ # FALSE-OPEN P0: a phase2 agent writing a ROOT file named `phase2_x.md` must be
420
+ # denied — it is not inside the phase dir (dir/** = descendants only).
421
+ p = payload("Write",
422
+ {"file_path": os.path.join(self.ws, "phase2_x.md"), "content": "x"},
423
+ cwd=self.ws, agent_type="bibliography_agent")
424
+ self.assertEqual(self.decide(p)["decision"], "deny")
425
+
426
+ def test_plugin_json_infra_protected(self):
427
+ p = payload("Write",
428
+ {"file_path": os.path.join(self.ws, ".claude-plugin/plugin.json"), "content": "x"},
429
+ cwd=self.ws, agent_type="broad_test_agent")
430
+ d = self.decide(p)
431
+ self.assertEqual(d["decision"], "deny")
432
+ self.assertIn("infrastructure", d["reason"].lower())
433
+
434
+ def test_symlink_traversal_to_infra_denied(self):
435
+ # A symlinked dir + `../` must resolve through the symlink (realpath), not be
436
+ # lexically collapsed by abspath. Build: ws/link -> ws/phase2_investigation, then
437
+ # write link/../hooks/hooks.json. realpath resolves link first => ws/hooks/hooks.json.
438
+ symlink_or_skip(self, os.path.join(self.ws, "phase2_investigation"),
439
+ os.path.join(self.ws, "link"))
440
+ raw = os.path.join(self.ws, "link/../hooks/hooks.json")
441
+ p = payload("Write", {"file_path": raw, "content": "x"},
442
+ cwd=self.ws, agent_type="bibliography_agent")
443
+ d = self.decide(p)
444
+ self.assertEqual(d["decision"], "deny")
445
+ self.assertIn("infrastructure", d["reason"].lower())
446
+
447
+ def test_symlink_escaping_workspace_denied(self):
448
+ # A symlink pointing OUTSIDE the workspace must be detected as an escape, not
449
+ # approved on its lexical in-workspace name.
450
+ outside = tempfile.mkdtemp()
451
+ try:
452
+ symlink_or_skip(self, outside, os.path.join(self.ws, "exit"))
453
+ raw = os.path.join(self.ws, "exit/leak.md")
454
+ p = payload("Write", {"file_path": raw, "content": "x"},
455
+ cwd=self.ws, agent_type="bibliography_agent")
456
+ self.assertEqual(self.decide(p)["decision"], "deny")
457
+ finally:
458
+ import shutil
459
+ shutil.rmtree(outside, ignore_errors=True)
460
+
461
+
462
+ class BashBypassRegressionTest(unittest.TestCase):
463
+ """Regression pins for the historical Bash fail-open shapes + the deep-path crash.
464
+
465
+ Review surfaced a long list of Bash bypasses (quoted redirection, statement split,
466
+ `&>`/`<>`, transparent wrappers `command rm`, shell structure `(rm x)`/`$(rm x)`,
467
+ `sudo -u bob rm`, `>(rm)`, backtick `` `rm` ``, and "read-only" tools that execute
468
+ subprocesses like `rg --pre`). The final policy denies ALL Bash for a Bucket A agent, so
469
+ every one of these denies trivially. These cases stay pinned: if anyone ever re-introduces
470
+ a denylist/allowlist/parse approach, they must still deny. (The recursive-matcher crash is
471
+ a separate fix pinned at the end.)
472
+ """
473
+
474
+ def setUp(self):
475
+ self._tmp = tempfile.TemporaryDirectory()
476
+ self.ws = os.path.realpath(self._tmp.name)
477
+ for d in ("phase2_investigation", "phase3_analysis", "phase7_format", "hooks", "scripts"):
478
+ os.makedirs(os.path.join(self.ws, d), exist_ok=True)
479
+
480
+ def tearDown(self):
481
+ self._tmp.cleanup()
482
+
483
+ def decide(self, p):
484
+ return guard.evaluate_decision(p, TEST_MANIFEST, self.ws)
485
+
486
+ def _bash(self, cmd):
487
+ return self.decide(payload("Bash", {"command": cmd}, cwd=self.ws,
488
+ agent_type="bibliography_agent"))
489
+
490
+ def test_all_historical_bash_bypasses_denied(self):
491
+ # Every shape that defeated an earlier denylist OR allowlist attempt. Under the final
492
+ # all-Bash-deny policy they all deny trivially — no parsing, no allowlist membership,
493
+ # no flag guard. (Labels name the bypass class so the coverage intent survives.)
494
+ shapes = [
495
+ "echo hi &> phase3_analysis/leak.md", # combined redirect
496
+ "cat <> phase3_analysis/leak.md", # read-write open
497
+ "command rm hooks/hooks.json", # transparent wrapper
498
+ "sudo -u bob rm x", # wrapper + flag
499
+ "(rm x)", "{ rm x; }", # grouping
500
+ "if true; then rm x; fi", # conditional
501
+ "echo $(rm hooks/hooks.json)", # command substitution
502
+ "echo >(rm hooks/hooks.json)", # process substitution
503
+ "echo `rm x`", # backtick substitution
504
+ "echo x>f", 'cp "a;b" /elsewhere', # quote/no-whitespace parser bypasses
505
+ # commands that LOOK read-only but execute a subprocess / write state:
506
+ "rg --pre 'sh -c touch' x f", "git grep --open-files-in-pager=touch x",
507
+ "sort --compress-program=touch big.txt", "GIT_EXTERNAL_DIFF=touch git diff",
508
+ "uniq in.txt out.txt", "git status",
509
+ # inputs once worried about as FALSE-DENY — moot now, all Bash denies:
510
+ "grep in rm file", "grep foo 2>&1",
511
+ ]
512
+ for cmd in shapes:
513
+ self.assertEqual(self._bash(cmd)["decision"], "deny", f"{cmd!r} must deny (all-Bash-deny)")
514
+
515
+ # --- P1-c: recursive `_match_segments` blew the Python recursion limit on deep paths. ---
516
+
517
+ def test_deep_path_glob_match_does_not_crash(self):
518
+ # ~1100 path segments raised RecursionError (limit 1000) in the recursive matcher,
519
+ # crashing the hook (uncaught in main()) — fail-open or wedge depending on the CC
520
+ # contract; either way unacceptable. The matcher must handle arbitrary depth without
521
+ # blowing the stack (caught in review).
522
+ deep_under = "phase2_investigation/" + "/".join(["a"] * 2000) + "/leak.md"
523
+ # Must still produce a correct decision (it IS under phase2_*, so a structured-tool
524
+ # write is allowed; the point is: no crash).
525
+ self.assertTrue(guard._matches_any(deep_under, ["phase2_*/**"]))
526
+ deep_other = "phase3_analysis/" + "/".join(["a"] * 2000) + "/leak.md"
527
+ self.assertFalse(guard._matches_any(deep_other, ["phase2_*/**"]))
528
+ # And end-to-end through evaluate_decision (the path that actually crashed).
529
+ p = payload("Write", {"file_path": os.path.join(self.ws, deep_under), "content": "x"},
530
+ cwd=self.ws, agent_type="bibliography_agent")
531
+ self.assertEqual(self.decide(p)["decision"], "allow")
532
+
533
+
534
+ class MalformedPayloadTest(unittest.TestCase):
535
+ """Valid-JSON-wrong-shape and odd tool_input must not crash (must pass through)."""
536
+
537
+ def decide(self, p):
538
+ return guard.evaluate_decision(p, TEST_MANIFEST, "/tmp")
539
+
540
+ def test_list_payload_does_not_crash(self):
541
+ # evaluate_decision is the pure core; main() guards non-dict payloads. Here we
542
+ # assert tool_input of the wrong type does not crash the core.
543
+ p = {"tool_name": "Bash", "tool_input": [], "cwd": "/tmp"}
544
+ d = self.decide(p)
545
+ self.assertEqual(d["decision"], "allow") # no catchable target, no agent -> allow
546
+
547
+ def test_null_tool_input_does_not_crash(self):
548
+ p = {"tool_name": "Write", "tool_input": None, "cwd": "/tmp", "agent_type": "bibliography_agent"}
549
+ # Write with no usable file_path -> schema-drift deny (fail closed), not a crash.
550
+ d = self.decide(p)
551
+ self.assertEqual(d["decision"], "deny")
552
+ self.assertTrue(d.get("schema_drift_advisory"))
553
+
554
+
555
+ class PluginRootInfraScopeTest(unittest.TestCase):
556
+ """#448 — infra self-protection is anchored on the PLUGIN root, not the user's PROJECT
557
+ root. Under a plugin install the two differ; the user's own project files that happen to
558
+ share a filename with an ARS infra file (CLAUDE.md, hooks/*.sh, shared/agents/*.md, ...)
559
+ must NOT be denied. The ARS plugin's OWN files stay protected.
560
+ """
561
+
562
+ def setUp(self):
563
+ # Two DISTINCT roots: a user project and a separate plugin install dir.
564
+ self._proj = tempfile.TemporaryDirectory()
565
+ self._plugin = tempfile.TemporaryDirectory()
566
+ self.ws = os.path.realpath(self._proj.name) # user project (workspace_root)
567
+ self.plugin = os.path.realpath(self._plugin.name) # ARS plugin install (plugin_root)
568
+ for d in ("phase2_investigation", ".claude", "hooks", "shared/agents"):
569
+ os.makedirs(os.path.join(self.ws, d), exist_ok=True)
570
+ for d in ("scripts", "hooks", ".claude", "shared/agents", "agents"):
571
+ os.makedirs(os.path.join(self.plugin, d), exist_ok=True)
572
+
573
+ def tearDown(self):
574
+ self._proj.cleanup()
575
+ self._plugin.cleanup()
576
+
577
+ def decide_in_project(self, p):
578
+ # workspace = user project; plugin_root = the separate ARS install.
579
+ return guard.evaluate_decision(p, TEST_MANIFEST, self.ws, self.plugin)
580
+
581
+ # --- the reported bug: user's own CLAUDE.md must be writable by the main session ---
582
+
583
+ def test_user_project_root_claude_md_allowed_main_session(self):
584
+ # This is exactly #448. Pre-fix this was DENY; post-fix it must be ALLOW.
585
+ p = payload("Write", {"file_path": os.path.join(self.ws, "CLAUDE.md"), "content": "x"},
586
+ cwd=self.ws) # no agent_type = main session
587
+ self.assertEqual(self.decide_in_project(p)["decision"], "allow")
588
+
589
+ def test_user_project_dotclaude_claude_md_allowed_main_session(self):
590
+ p = payload("Write", {"file_path": os.path.join(self.ws, ".claude/CLAUDE.md"), "content": "x"},
591
+ cwd=self.ws)
592
+ self.assertEqual(self.decide_in_project(p)["decision"], "allow")
593
+
594
+ def test_user_project_shared_agents_md_allowed(self):
595
+ # `shared/agents/*.md` is an ARS infra glob but ALSO a plausible user-project path.
596
+ p = payload("Write", {"file_path": os.path.join(self.ws, "shared/agents/foo.md"), "content": "x"},
597
+ cwd=self.ws)
598
+ self.assertEqual(self.decide_in_project(p)["decision"], "allow")
599
+
600
+ def test_user_project_hooks_json_allowed(self):
601
+ p = payload("Write", {"file_path": os.path.join(self.ws, "hooks/hooks.json"), "content": "x"},
602
+ cwd=self.ws)
603
+ self.assertEqual(self.decide_in_project(p)["decision"], "allow")
604
+
605
+ def test_user_project_hooks_sh_allowed(self):
606
+ p = payload("Write", {"file_path": os.path.join(self.ws, "hooks/install.sh"), "content": "x"},
607
+ cwd=self.ws)
608
+ self.assertEqual(self.decide_in_project(p)["decision"], "allow")
609
+
610
+ # --- self-protection PRESERVED: the plugin's OWN files stay denied ---
611
+
612
+ def test_plugin_own_claude_md_allowed(self):
613
+ # #459: CLAUDE.md is no longer infra-protected, even the plugin's OWN copy. It is a
614
+ # doc, not a load-bearing enforcement file — editing it cannot fail the guard open,
615
+ # so it must NOT be denied. (The load-bearing files below stay protected; see
616
+ # test_plugin_own_guard_script_denied / _hooks_json_denied / _shared_agents_md_denied.)
617
+ p = payload("Write", {"file_path": os.path.join(self.plugin, "CLAUDE.md"), "content": "x"},
618
+ cwd=self.ws)
619
+ self.assertEqual(self.decide_in_project(p)["decision"], "allow")
620
+
621
+ def test_plugin_own_dotclaude_claude_md_allowed(self):
622
+ # Same for .claude/CLAUDE.md inside the plugin root (#459).
623
+ os.makedirs(os.path.join(self.plugin, ".claude"), exist_ok=True)
624
+ p = payload("Write", {"file_path": os.path.join(self.plugin, ".claude/CLAUDE.md"), "content": "x"},
625
+ cwd=self.ws)
626
+ self.assertEqual(self.decide_in_project(p)["decision"], "allow")
627
+
628
+ def test_plugin_own_guard_script_denied(self):
629
+ p = payload("Write",
630
+ {"file_path": os.path.join(self.plugin, "scripts/ars_write_scope_guard.py"), "content": "x"},
631
+ cwd=self.ws)
632
+ self.assertEqual(self.decide_in_project(p)["decision"], "deny")
633
+
634
+ def test_plugin_own_hooks_json_denied(self):
635
+ p = payload("Write", {"file_path": os.path.join(self.plugin, "hooks/hooks.json"), "content": "x"},
636
+ cwd=self.ws)
637
+ self.assertEqual(self.decide_in_project(p)["decision"], "deny")
638
+
639
+ def test_plugin_own_shared_agents_md_denied(self):
640
+ p = payload("Write", {"file_path": os.path.join(self.plugin, "shared/agents/bar.md"), "content": "x"},
641
+ cwd=self.ws)
642
+ self.assertEqual(self.decide_in_project(p)["decision"], "deny")
643
+
644
+ def test_plugin_own_toplevel_agents_md_denied(self):
645
+ # The #413-materialized top-level agents/*.md carry the agent_type==name binding too;
646
+ # #448 added `agents/*.md` to the infra globs. A user-project agents/foo.md is still
647
+ # allowed (covered by no deny test -> it falls through to Step 3 allow); only the
648
+ # PLUGIN's own copy is protected.
649
+ p = payload("Write", {"file_path": os.path.join(self.plugin, "agents/synthesis_agent.md"),
650
+ "content": "x"}, cwd=self.ws)
651
+ self.assertEqual(self.decide_in_project(p)["decision"], "deny")
652
+
653
+ def test_user_project_toplevel_agents_md_allowed(self):
654
+ # The mirror: a user's OWN agents/foo.md (inside their project, outside plugin_root)
655
+ # must remain writable — the #448 carve-out applies to agents/*.md too.
656
+ os.makedirs(os.path.join(self.ws, "agents"), exist_ok=True)
657
+ p = payload("Write", {"file_path": os.path.join(self.ws, "agents/my_agent.md"),
658
+ "content": "x"}, cwd=self.ws)
659
+ self.assertEqual(self.decide_in_project(p)["decision"], "allow")
660
+
661
+ # --- fallback: plugin_root=None -> conservative pre-fix behavior (workspace-anchored).
662
+ # This is the clone+symlink layout / ARS-on-ARS home turf, where plugin_root
663
+ # collapses onto workspace_root — the #459 crux: the SAME runtime condition is both
664
+ # "protect ARS infra" and "don't false-deny the user's CLAUDE.md". The #459 fix makes
665
+ # that condition decidable WITHOUT distinguishing the layouts: CLAUDE.md left the infra
666
+ # list (so it's allowed everywhere), while the load-bearing files stay protected. ---
667
+
668
+ def test_fallback_none_plugin_root_claude_md_allowed(self):
669
+ # #459: even under the collapsed fallback, the user's own CLAUDE.md is writable —
670
+ # because CLAUDE.md is no longer infra, not because we detected the layout.
671
+ p = payload("Write", {"file_path": os.path.join(self.ws, "CLAUDE.md"), "content": "x"},
672
+ cwd=self.ws)
673
+ d = guard.evaluate_decision(p, TEST_MANIFEST, self.ws) # 3-arg: plugin_root defaults None
674
+ self.assertEqual(d["decision"], "allow")
675
+
676
+ def test_fallback_none_plugin_root_still_protects_load_bearing_infra(self):
677
+ # The protection that MUST survive #459: under the collapsed fallback, the load-bearing
678
+ # enforcement files (here the guard script) are still denied. Dropping CLAUDE.md did not
679
+ # weaken self-protection of the files that can actually fail the guard open.
680
+ os.makedirs(os.path.join(self.ws, "scripts"), exist_ok=True)
681
+ p = payload("Write",
682
+ {"file_path": os.path.join(self.ws, "scripts/ars_write_scope_guard.py"), "content": "x"},
683
+ cwd=self.ws)
684
+ d = guard.evaluate_decision(p, TEST_MANIFEST, self.ws) # 3-arg: plugin_root defaults None
685
+ self.assertEqual(d["decision"], "deny")
686
+ self.assertIn("infrastructure", d["reason"])
687
+
688
+ # --- Bucket A phase-scope is UNCHANGED by the dual-root split ---
689
+
690
+ def test_bucket_a_phase_scope_unaffected_allow(self):
691
+ p = payload("Write",
692
+ {"file_path": os.path.join(self.ws, "phase2_investigation/bib.md"), "content": "x"},
693
+ cwd=self.ws, agent_type="bibliography_agent")
694
+ self.assertEqual(self.decide_in_project(p)["decision"], "allow")
695
+
696
+ def test_bucket_a_cannot_reach_user_claude_md(self):
697
+ # A Bucket A agent still can't write the user's root CLAUDE.md — not because of infra
698
+ # protection now, but because it's outside the agent's phase glob (Step 4). The guard
699
+ # is unchanged for agents; only the main session gained access.
700
+ p = payload("Write", {"file_path": os.path.join(self.ws, "CLAUDE.md"), "content": "x"},
701
+ cwd=self.ws, agent_type="bibliography_agent")
702
+ d = self.decide_in_project(p)
703
+ self.assertEqual(d["decision"], "deny")
704
+ self.assertIn("bibliography_agent", d["reason"]) # phase-scope deny, not infra deny
705
+
706
+ # --- dual-root regression variants (codex P2-b): traversal / symlink / Bucket A escape
707
+ # toward the plugin's OWN infra, under a real plugin_root != workspace_root install ---
708
+
709
+ def test_dual_root_traversal_from_phase_into_plugin_infra_denied(self):
710
+ # A relative target that escapes the phase dir and `..`-walks all the way into the
711
+ # plugin tree's hooks/hooks.json. realpath in _infra_protected_target must resolve it
712
+ # and deny — the infra check runs BEFORE the workspace-escape branch.
713
+ rel_into_plugin = os.path.relpath(
714
+ os.path.join(self.plugin, "hooks/hooks.json"),
715
+ os.path.join(self.ws, "phase2_investigation"))
716
+ raw = "phase2_investigation/" + rel_into_plugin
717
+ p = payload("Write", {"file_path": raw, "content": "x"}, cwd=self.ws) # main session
718
+ self.assertEqual(self.decide_in_project(p)["decision"], "deny")
719
+
720
+ def test_dual_root_symlink_into_plugin_infra_denied(self):
721
+ # A symlink inside the user workspace pointing at a plugin infra file. realpath
722
+ # resolves the link to the plugin tree -> infra-protected -> deny.
723
+ link = os.path.join(self.ws, "sneaky_link.py")
724
+ target = os.path.join(self.plugin, "scripts/ars_write_scope_guard.py")
725
+ os.makedirs(os.path.dirname(target), exist_ok=True)
726
+ with open(target, "w") as fh:
727
+ fh.write("# real guard\n")
728
+ symlink_or_skip(self, target, link)
729
+ p = payload("Write", {"file_path": link, "content": "x"}, cwd=self.ws) # main session
730
+ self.assertEqual(self.decide_in_project(p)["decision"], "deny")
731
+
732
+ def test_dual_root_bucket_a_escape_toward_plugin_infra_denied(self):
733
+ # Bucket A agent trying to reach the plugin's own guard script. It is denied — the
734
+ # infra check fires first; even if it didn't, the escape fence (#302) would catch it.
735
+ p = payload("Write",
736
+ {"file_path": os.path.join(self.plugin, "scripts/ars_write_scope_guard.py"),
737
+ "content": "x"},
738
+ cwd=self.ws, agent_type="bibliography_agent")
739
+ self.assertEqual(self.decide_in_project(p)["decision"], "deny")
740
+
741
+ def test_dual_root_bucket_a_sibling_worktree_escape_still_allowed_for_main(self):
742
+ # Sanity: a NON-infra escape (a sibling worktree outside both roots) is still allowed
743
+ # for the main session — the infra reorder didn't over-deny genuine escapes.
744
+ sibling = os.path.realpath(os.path.join(self.ws, "..", "sibling_worktree"))
745
+ os.makedirs(sibling, exist_ok=True)
746
+ try:
747
+ p = payload("Write", {"file_path": os.path.join(sibling, "notes.md"), "content": "x"},
748
+ cwd=self.ws) # main session
749
+ self.assertEqual(self.decide_in_project(p)["decision"], "allow")
750
+ finally:
751
+ import shutil
752
+ shutil.rmtree(sibling, ignore_errors=True)
753
+
754
+
755
+ class MainPluginRootComputationTest(unittest.TestCase):
756
+ """main() must compute plugin_root from CLAUDE_PLUGIN_ROOT, else the resolved repo root
757
+ (resolve() to follow the ~/.claude/skills symlink install). codex P2-b."""
758
+
759
+ def test_plugin_root_from_env(self):
760
+ import subprocess
761
+ guard_path = os.path.join(REPO_ROOT, "scripts", "ars_write_scope_guard.py")
762
+ with tempfile.TemporaryDirectory() as proj, tempfile.TemporaryDirectory() as plug:
763
+ # Writing the user project's own CLAUDE.md must pass through (no permissionDecision)
764
+ # when CLAUDE_PLUGIN_ROOT points elsewhere.
765
+ env = dict(os.environ, CLAUDE_PROJECT_DIR=proj, CLAUDE_PLUGIN_ROOT=plug)
766
+ inp = json.dumps({"tool_name": "Write", "cwd": proj,
767
+ "tool_input": {"file_path": os.path.join(proj, "CLAUDE.md"),
768
+ "content": "x"}})
769
+ out = subprocess.run([sys.executable, guard_path], input=inp, env=env,
770
+ capture_output=True, text=True)
771
+ decision = json.loads(out.stdout)
772
+ self.assertNotIn("permissionDecision", decision["hookSpecificOutput"])
773
+
774
+ def test_plugin_own_file_denied_via_env(self):
775
+ import subprocess
776
+ guard_path = os.path.join(REPO_ROOT, "scripts", "ars_write_scope_guard.py")
777
+ with tempfile.TemporaryDirectory() as proj, tempfile.TemporaryDirectory() as plug:
778
+ os.makedirs(os.path.join(plug, "scripts"))
779
+ env = dict(os.environ, CLAUDE_PROJECT_DIR=proj, CLAUDE_PLUGIN_ROOT=plug)
780
+ inp = json.dumps({"tool_name": "Write", "cwd": proj,
781
+ "tool_input": {"file_path": os.path.join(plug, "scripts/ars_write_scope_guard.py"),
782
+ "content": "x"}})
783
+ out = subprocess.run([sys.executable, guard_path], input=inp, env=env,
784
+ capture_output=True, text=True)
785
+ decision = json.loads(out.stdout)
786
+ self.assertEqual(decision["hookSpecificOutput"].get("permissionDecision"), "deny")
787
+
788
+
789
+ if __name__ == "__main__":
790
+ unittest.main()