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.
- package/README.md +11 -5
- package/dist/apps/panel/index.html +2 -2
- package/dist/src/adapters/pi/extension.js +225 -92
- package/dist/src/adapters/pi/extension.js.map +1 -1
- package/dist/src/agents/import.js +44 -32
- package/dist/src/agents/import.js.map +1 -1
- package/dist/src/analysis/hooks.d.ts +1 -0
- package/dist/src/analysis/hooks.js +20 -1
- package/dist/src/analysis/hooks.js.map +1 -1
- package/dist/src/ars/bridge.d.ts +20 -0
- package/dist/src/ars/bridge.js +132 -0
- package/dist/src/ars/bridge.js.map +1 -0
- package/dist/src/ars/contracts.d.ts +55 -0
- package/dist/src/ars/contracts.js +2 -0
- package/dist/src/ars/contracts.js.map +1 -0
- package/dist/src/ars/panel-plan.d.ts +4 -0
- package/dist/src/ars/panel-plan.js +11 -0
- package/dist/src/ars/panel-plan.js.map +1 -0
- package/dist/src/ars/pi-panel-executor.d.ts +30 -0
- package/dist/src/ars/pi-panel-executor.js +140 -0
- package/dist/src/ars/pi-panel-executor.js.map +1 -0
- package/dist/src/ars/profile.d.ts +36 -0
- package/dist/src/ars/profile.js +119 -0
- package/dist/src/ars/profile.js.map +1 -0
- package/dist/src/ars/re-review.d.ts +22 -0
- package/dist/src/ars/re-review.js +172 -0
- package/dist/src/ars/re-review.js.map +1 -0
- package/dist/src/branding.d.ts +2 -4
- package/dist/src/branding.js +3 -5
- package/dist/src/branding.js.map +1 -1
- package/dist/src/bundled-tools.d.ts +3 -0
- package/dist/src/bundled-tools.js +21 -0
- package/dist/src/bundled-tools.js.map +1 -0
- package/dist/src/chat.js +6 -5
- package/dist/src/chat.js.map +1 -1
- package/dist/src/creation/contracts.d.ts +38 -0
- package/dist/src/creation/contracts.js +2 -0
- package/dist/src/creation/contracts.js.map +1 -0
- package/dist/src/creation/service.d.ts +7 -0
- package/dist/src/creation/service.js +196 -0
- package/dist/src/creation/service.js.map +1 -0
- package/dist/src/index.d.ts +10 -0
- package/dist/src/index.js +10 -0
- package/dist/src/index.js.map +1 -1
- package/dist/src/install/installer.js +32 -10
- package/dist/src/install/installer.js.map +1 -1
- package/dist/src/orchestration/personas.d.ts +15 -0
- package/dist/src/orchestration/personas.js +51 -0
- package/dist/src/orchestration/personas.js.map +1 -0
- package/dist/src/orchestration/pi-executor.d.ts +1 -0
- package/dist/src/orchestration/pi-executor.js +1 -1
- package/dist/src/orchestration/pi-executor.js.map +1 -1
- package/dist/src/panel/extension.js +29 -8
- package/dist/src/panel/extension.js.map +1 -1
- package/dist/src/panel/server.js +14 -5
- package/dist/src/panel/server.js.map +1 -1
- package/dist/src/project/paths.d.ts +3 -0
- package/dist/src/project/paths.js +7 -0
- package/dist/src/project/paths.js.map +1 -1
- package/dist/src/rules/user-rules.d.ts +8 -0
- package/dist/src/rules/user-rules.js +36 -0
- package/dist/src/rules/user-rules.js.map +1 -0
- package/dist/src/skills/contracts.d.ts +4 -4
- package/dist/src/skills/recommended.js +1 -1
- package/dist/src/skills/registry.js +49 -28
- package/dist/src/skills/registry.js.map +1 -1
- package/dist/src/style/cli-ui.js +0 -1
- package/dist/src/style/cli-ui.js.map +1 -1
- package/package.json +14 -3
- package/scripts/rebrand-pi.mjs +6 -0
- package/skills/recommended/catalog.json +2 -11
- package/vendor/ars/.claude/CLAUDE.md +371 -0
- package/vendor/ars/.command-invariants.toml +24 -0
- package/vendor/ars/CITATION.cff +35 -0
- package/vendor/ars/LICENSE +417 -0
- package/vendor/ars/MODE_REGISTRY.md +76 -0
- package/vendor/ars/NOTICE.md +26 -0
- package/vendor/ars/POSITIONING.md +99 -0
- package/vendor/ars/PSYCLAW_SOURCE.json +10 -0
- package/vendor/ars/README.md +751 -0
- package/vendor/ars/SECURITY.md +52 -0
- package/vendor/ars/THIRD_PARTY.md +70 -0
- package/vendor/ars/academic-paper/SKILL.md +542 -0
- package/vendor/ars/academic-paper/agents/abstract_bilingual_agent.md +171 -0
- package/vendor/ars/academic-paper/agents/argument_builder_agent.md +276 -0
- package/vendor/ars/academic-paper/agents/citation_compliance_agent.md +422 -0
- package/vendor/ars/academic-paper/agents/draft_writer_agent.md +656 -0
- package/vendor/ars/academic-paper/agents/formatter_agent.md +999 -0
- package/vendor/ars/academic-paper/agents/intake_agent.md +393 -0
- package/vendor/ars/academic-paper/agents/literature_strategist_agent.md +626 -0
- package/vendor/ars/academic-paper/agents/peer_reviewer_agent.md +516 -0
- package/vendor/ars/academic-paper/agents/revision_coach_agent.md +334 -0
- package/vendor/ars/academic-paper/agents/socratic_mentor_agent.md +527 -0
- package/vendor/ars/academic-paper/agents/structure_architect_agent.md +401 -0
- package/vendor/ars/academic-paper/agents/visualization_agent.md +441 -0
- package/vendor/ars/academic-paper/examples/chinese_paper_example.md +278 -0
- package/vendor/ars/academic-paper/examples/clinical_citation_verification_checklist.md +95 -0
- package/vendor/ars/academic-paper/examples/clinical_epistemic_status_example.md +100 -0
- package/vendor/ars/academic-paper/examples/commitment_ledger_example.md +147 -0
- package/vendor/ars/academic-paper/examples/imrad_hei_example.md +234 -0
- package/vendor/ars/academic-paper/examples/literature_review_example.md +260 -0
- package/vendor/ars/academic-paper/examples/plan_mode_guided_writing.md +600 -0
- package/vendor/ars/academic-paper/examples/revision_mode_example.md +344 -0
- package/vendor/ars/academic-paper/examples/revision_recovery_example.md +506 -0
- package/vendor/ars/academic-paper/examples/version_family_reconciliation_example.md +89 -0
- package/vendor/ars/academic-paper/references/abstract_writing_guide.md +169 -0
- package/vendor/ars/academic-paper/references/academic_writing_style.md +188 -0
- package/vendor/ars/academic-paper/references/anti_leakage_protocol.md +83 -0
- package/vendor/ars/academic-paper/references/apa7_chinese_citation_guide.md +364 -0
- package/vendor/ars/academic-paper/references/apa7_extended_guide.md +198 -0
- package/vendor/ars/academic-paper/references/changelog.md +11 -0
- package/vendor/ars/academic-paper/references/citation_format_switcher.md +228 -0
- package/vendor/ars/academic-paper/references/committee_correspondence_protocol.md +158 -0
- package/vendor/ars/academic-paper/references/credit_authorship_guide.md +308 -0
- package/vendor/ars/academic-paper/references/disclosure_mode_protocol.md +478 -0
- package/vendor/ars/academic-paper/references/domain_evidence_profiles.md +38 -0
- package/vendor/ars/academic-paper/references/failure_paths.md +349 -0
- package/vendor/ars/academic-paper/references/funding_statement_guide.md +319 -0
- package/vendor/ars/academic-paper/references/hei_domain_glossary.md +169 -0
- package/vendor/ars/academic-paper/references/intro_title_rhetoric_guide.md +114 -0
- package/vendor/ars/academic-paper/references/journal_submission_guide.md +249 -0
- package/vendor/ars/academic-paper/references/latex_template_reference.md +378 -0
- package/vendor/ars/academic-paper/references/mode_selection_guide.md +378 -0
- package/vendor/ars/academic-paper/references/paper_structure_patterns.md +330 -0
- package/vendor/ars/academic-paper/references/plan_mode_protocol.md +112 -0
- package/vendor/ars/academic-paper/references/policy_anchor_disclosure_protocol.md +200 -0
- package/vendor/ars/academic-paper/references/policy_anchor_table.md +157 -0
- package/vendor/ars/academic-paper/references/revision_patch_protocol.md +173 -0
- package/vendor/ars/academic-paper/references/statistical_visualization_standards.md +750 -0
- package/vendor/ars/academic-paper/references/venue_disclosure_policies.md +259 -0
- package/vendor/ars/academic-paper/references/vlm_figure_verification.md +126 -0
- package/vendor/ars/academic-paper/references/workflow_phase_details.md +135 -0
- package/vendor/ars/academic-paper/references/writing_judgment_framework.md +59 -0
- package/vendor/ars/academic-paper/references/writing_quality_check.md +173 -0
- package/vendor/ars/academic-paper/templates/bilingual_abstract_template.md +78 -0
- package/vendor/ars/academic-paper/templates/case_study_template.md +129 -0
- package/vendor/ars/academic-paper/templates/conference_paper_template.md +108 -0
- package/vendor/ars/academic-paper/templates/credit_statement_template.md +132 -0
- package/vendor/ars/academic-paper/templates/funding_statement_template.md +290 -0
- package/vendor/ars/academic-paper/templates/imrad_template.md +183 -0
- package/vendor/ars/academic-paper/templates/latex_article_template.tex +199 -0
- package/vendor/ars/academic-paper/templates/literature_review_template.md +135 -0
- package/vendor/ars/academic-paper/templates/policy_brief_template.md +139 -0
- package/vendor/ars/academic-paper/templates/revision_tracking_template.md +199 -0
- package/vendor/ars/academic-paper/templates/theoretical_paper_template.md +119 -0
- package/vendor/ars/academic-paper-reviewer/SKILL.md +491 -0
- package/vendor/ars/academic-paper-reviewer/agents/devils_advocate_reviewer_agent.md +443 -0
- package/vendor/ars/academic-paper-reviewer/agents/domain_reviewer_agent.md +412 -0
- package/vendor/ars/academic-paper-reviewer/agents/editorial_synthesizer_agent.md +478 -0
- package/vendor/ars/academic-paper-reviewer/agents/eic_agent.md +339 -0
- package/vendor/ars/academic-paper-reviewer/agents/field_analyst_agent.md +221 -0
- package/vendor/ars/academic-paper-reviewer/agents/methodology_reviewer_agent.md +449 -0
- package/vendor/ars/academic-paper-reviewer/agents/perspective_reviewer_agent.md +427 -0
- package/vendor/ars/academic-paper-reviewer/examples/hei_paper_review_example.md +391 -0
- package/vendor/ars/academic-paper-reviewer/examples/interdisciplinary_review_example.md +299 -0
- package/vendor/ars/academic-paper-reviewer/examples/subclaim_decomposition_example.md +80 -0
- package/vendor/ars/academic-paper-reviewer/references/calibration_mode_protocol.md +256 -0
- package/vendor/ars/academic-paper-reviewer/references/changelog.md +10 -0
- package/vendor/ars/academic-paper-reviewer/references/editorial_decision_standards.md +236 -0
- package/vendor/ars/academic-paper-reviewer/references/guided_mode_protocol.md +34 -0
- package/vendor/ars/academic-paper-reviewer/references/integration_guide.md +15 -0
- package/vendor/ars/academic-paper-reviewer/references/quality_rubrics.md +84 -0
- package/vendor/ars/academic-paper-reviewer/references/re_review_mode_protocol.md +340 -0
- package/vendor/ars/academic-paper-reviewer/references/review_criteria_framework.md +98 -0
- package/vendor/ars/academic-paper-reviewer/references/review_panel_provenance_protocol.md +197 -0
- package/vendor/ars/academic-paper-reviewer/references/review_quality_thinking.md +58 -0
- package/vendor/ars/academic-paper-reviewer/references/reviewer_sprint_prompt_source.md +324 -0
- package/vendor/ars/academic-paper-reviewer/references/sprint_contract_protocol.md +296 -0
- package/vendor/ars/academic-paper-reviewer/references/statistical_reporting_standards.md +505 -0
- package/vendor/ars/academic-paper-reviewer/references/top_journals_by_field.md +206 -0
- package/vendor/ars/academic-paper-reviewer/templates/editorial_decision_template.md +235 -0
- package/vendor/ars/academic-paper-reviewer/templates/peer_review_report_template.md +305 -0
- package/vendor/ars/academic-paper-reviewer/templates/revision_response_template.md +248 -0
- package/vendor/ars/academic-pipeline/SKILL.md +736 -0
- package/vendor/ars/academic-pipeline/agents/claim_ref_alignment_audit_agent.md +382 -0
- package/vendor/ars/academic-pipeline/agents/collaboration_depth_agent.md +164 -0
- package/vendor/ars/academic-pipeline/agents/integrity_verification_agent.md +870 -0
- package/vendor/ars/academic-pipeline/agents/pipeline_orchestrator_agent.md +1379 -0
- package/vendor/ars/academic-pipeline/agents/state_tracker_agent.md +622 -0
- package/vendor/ars/academic-pipeline/examples/full_pipeline_example.md +482 -0
- package/vendor/ars/academic-pipeline/examples/integrity_failure_recovery.md +389 -0
- package/vendor/ars/academic-pipeline/examples/mid_entry_example.md +414 -0
- package/vendor/ars/academic-pipeline/references/adapters/.gitkeep +0 -0
- package/vendor/ars/academic-pipeline/references/adapters/overview.md +153 -0
- package/vendor/ars/academic-pipeline/references/ai_research_failure_modes.md +185 -0
- package/vendor/ars/academic-pipeline/references/changelog.md +14 -0
- package/vendor/ars/academic-pipeline/references/claim_audit_calibration_protocol.md +175 -0
- package/vendor/ars/academic-pipeline/references/claim_verification_protocol.md +282 -0
- package/vendor/ars/academic-pipeline/references/external_review_protocol.md +131 -0
- package/vendor/ars/academic-pipeline/references/integrity_review_protocol.md +110 -0
- package/vendor/ars/academic-pipeline/references/literature_corpus_consumers.md +193 -0
- package/vendor/ars/academic-pipeline/references/mode_advisor.md +135 -0
- package/vendor/ars/academic-pipeline/references/passport_as_reset_boundary.md +132 -0
- package/vendor/ars/academic-pipeline/references/pipeline_state_machine.md +405 -0
- package/vendor/ars/academic-pipeline/references/plagiarism_detection_protocol.md +239 -0
- package/vendor/ars/academic-pipeline/references/process_summary_protocol.md +209 -0
- package/vendor/ars/academic-pipeline/references/progress_dashboard_template.md +38 -0
- package/vendor/ars/academic-pipeline/references/reinforcement_content.md +15 -0
- package/vendor/ars/academic-pipeline/references/reproducibility_audit.md +55 -0
- package/vendor/ars/academic-pipeline/references/score_trajectory_protocol.md +78 -0
- package/vendor/ars/academic-pipeline/references/team_collaboration_protocol.md +261 -0
- package/vendor/ars/academic-pipeline/references/two_stage_review_protocol.md +27 -0
- package/vendor/ars/academic-pipeline/templates/pipeline_status_template.md +146 -0
- package/vendor/ars/agents/report_compiler_agent.md +341 -0
- package/vendor/ars/agents/research_architect_agent.md +298 -0
- package/vendor/ars/agents/synthesis_agent.md +356 -0
- package/vendor/ars/commands/ars-3w.md +10 -0
- package/vendor/ars/commands/ars-abstract.md +10 -0
- package/vendor/ars/commands/ars-cache-invalidate.md +20 -0
- package/vendor/ars/commands/ars-citation-check.md +10 -0
- package/vendor/ars/commands/ars-disclosure.md +10 -0
- package/vendor/ars/commands/ars-format-convert.md +10 -0
- package/vendor/ars/commands/ars-full.md +9 -0
- package/vendor/ars/commands/ars-lit-review.md +12 -0
- package/vendor/ars/commands/ars-mark-read.md +18 -0
- package/vendor/ars/commands/ars-outline.md +10 -0
- package/vendor/ars/commands/ars-plan.md +10 -0
- package/vendor/ars/commands/ars-rebuttal-audit.md +12 -0
- package/vendor/ars/commands/ars-reviewer.md +9 -0
- package/vendor/ars/commands/ars-revision-coach.md +9 -0
- package/vendor/ars/commands/ars-revision.md +10 -0
- package/vendor/ars/commands/ars-unmark-read.md +16 -0
- package/vendor/ars/deep-research/SKILL.md +600 -0
- package/vendor/ars/deep-research/agents/bibliography_agent.md +473 -0
- package/vendor/ars/deep-research/agents/devils_advocate_agent.md +192 -0
- package/vendor/ars/deep-research/agents/editor_in_chief_agent.md +167 -0
- package/vendor/ars/deep-research/agents/ethics_review_agent.md +267 -0
- package/vendor/ars/deep-research/agents/meta_analysis_agent.md +325 -0
- package/vendor/ars/deep-research/agents/monitoring_agent.md +209 -0
- package/vendor/ars/deep-research/agents/report_compiler_agent.md +341 -0
- package/vendor/ars/deep-research/agents/research_architect_agent.md +298 -0
- package/vendor/ars/deep-research/agents/research_question_agent.md +216 -0
- package/vendor/ars/deep-research/agents/risk_of_bias_agent.md +231 -0
- package/vendor/ars/deep-research/agents/socratic_mentor_agent.md +764 -0
- package/vendor/ars/deep-research/agents/source_verification_agent.md +219 -0
- package/vendor/ars/deep-research/agents/synthesis_agent.md +356 -0
- package/vendor/ars/deep-research/agents/timeline_extraction_agent.md +99 -0
- package/vendor/ars/deep-research/examples/exploratory_research.md +157 -0
- package/vendor/ars/deep-research/examples/fact_check_mode.md +173 -0
- package/vendor/ars/deep-research/examples/handoff_to_paper.md +318 -0
- package/vendor/ars/deep-research/examples/idea_diversity_coverage_gap_advisory.md +64 -0
- package/vendor/ars/deep-research/examples/policy_analysis.md +161 -0
- package/vendor/ars/deep-research/examples/review_mode.md +253 -0
- package/vendor/ars/deep-research/examples/socratic_guided_research.md +331 -0
- package/vendor/ars/deep-research/examples/systematic_review.md +133 -0
- package/vendor/ars/deep-research/references/apa7_style_guide.md +162 -0
- package/vendor/ars/deep-research/references/argumentation_reasoning_framework.md +68 -0
- package/vendor/ars/deep-research/references/arxiv_api_protocol.md +76 -0
- package/vendor/ars/deep-research/references/changelog.md +22 -0
- package/vendor/ars/deep-research/references/chinese_literature_api_protocol.md +317 -0
- package/vendor/ars/deep-research/references/cross_agent_quality_definitions.md +14 -0
- package/vendor/ars/deep-research/references/crossref_api_protocol.md +84 -0
- package/vendor/ars/deep-research/references/equator_reporting_guidelines.md +482 -0
- package/vendor/ars/deep-research/references/ethics_checklist.md +282 -0
- package/vendor/ars/deep-research/references/failure_paths.md +355 -0
- package/vendor/ars/deep-research/references/interdisciplinary_bridges.md +292 -0
- package/vendor/ars/deep-research/references/irb_decision_tree.md +315 -0
- package/vendor/ars/deep-research/references/literature_monitoring_strategies.md +263 -0
- package/vendor/ars/deep-research/references/logical_fallacies.md +192 -0
- package/vendor/ars/deep-research/references/methodology_patterns.md +462 -0
- package/vendor/ars/deep-research/references/mode_selection_guide.md +331 -0
- package/vendor/ars/deep-research/references/openalex_api_protocol.md +82 -0
- package/vendor/ars/deep-research/references/preregistration_guide.md +324 -0
- package/vendor/ars/deep-research/references/semantic_scholar_api_protocol.md +107 -0
- package/vendor/ars/deep-research/references/socratic_mode_protocol.md +99 -0
- package/vendor/ars/deep-research/references/socratic_questioning_framework.md +232 -0
- package/vendor/ars/deep-research/references/source_quality_hierarchy.md +188 -0
- package/vendor/ars/deep-research/references/systematic_review_protocol.md +95 -0
- package/vendor/ars/deep-research/references/systematic_review_toolkit.md +353 -0
- package/vendor/ars/deep-research/templates/evidence_assessment_template.md +127 -0
- package/vendor/ars/deep-research/templates/literature_matrix_template.md +85 -0
- package/vendor/ars/deep-research/templates/preregistration_template.md +318 -0
- package/vendor/ars/deep-research/templates/prisma_protocol_template.md +248 -0
- package/vendor/ars/deep-research/templates/prisma_report_template.md +415 -0
- package/vendor/ars/deep-research/templates/research_brief_template.md +93 -0
- package/vendor/ars/package.json +24 -0
- package/vendor/ars/pi/README.md +161 -0
- package/vendor/ars/pi/package.json +26 -0
- package/vendor/ars/pi/wrapper.js +193 -0
- package/vendor/ars/pi/wrapper.test.mjs +201 -0
- package/vendor/ars/pyproject.toml +2 -0
- package/vendor/ars/requirements-pdf-content-classifier.txt +5 -0
- package/vendor/ars/scripts/_block_parser.py +396 -0
- package/vendor/ars/scripts/_ci_pytest_manifest.toml +661 -0
- package/vendor/ars/scripts/_claim_audit_constants.py +268 -0
- package/vendor/ars/scripts/_e4_evidence.py +110 -0
- package/vendor/ars/scripts/_eval_threshold_gate.py +73 -0
- package/vendor/ars/scripts/_markdown_lint_util.py +224 -0
- package/vendor/ars/scripts/_next_verified_at_ms.py +176 -0
- package/vendor/ars/scripts/_passport_yaml.py +53 -0
- package/vendor/ars/scripts/_skill_lint.py +254 -0
- package/vendor/ars/scripts/_text_similarity.py +141 -0
- package/vendor/ars/scripts/adapters/README.md +89 -0
- package/vendor/ars/scripts/adapters/_common.py +209 -0
- package/vendor/ars/scripts/adapters/examples/folder_scan/expected_passport.yaml +25 -0
- package/vendor/ars/scripts/adapters/examples/folder_scan/expected_rejection_log.yaml +18 -0
- package/vendor/ars/scripts/adapters/examples/folder_scan/input_fixture/Chen2024_AIAssessment.pdf +0 -0
- package/vendor/ars/scripts/adapters/examples/folder_scan/input_fixture/Wang_2023_formative_feedback.pdf +0 -0
- package/vendor/ars/scripts/adapters/examples/folder_scan/input_fixture/paper1.pdf +0 -0
- 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
- package/vendor/ars/scripts/adapters/examples/obsidian/expected_passport.yaml +40 -0
- package/vendor/ars/scripts/adapters/examples/obsidian/expected_rejection_log.yaml +13 -0
- package/vendor/ars/scripts/adapters/examples/obsidian/input_fixture/vault/.gitkeep +0 -0
- package/vendor/ars/scripts/adapters/examples/obsidian/input_fixture/vault/.obsidian/app.json +1 -0
- package/vendor/ars/scripts/adapters/examples/obsidian/input_fixture/vault/_templates/tmpl.md +7 -0
- package/vendor/ars/scripts/adapters/examples/obsidian/input_fixture/vault/chen2024ai.md +13 -0
- package/vendor/ars/scripts/adapters/examples/obsidian/input_fixture/vault/invalid.md +1 -0
- package/vendor/ars/scripts/adapters/examples/obsidian/input_fixture/vault/wang2023formative.md +10 -0
- package/vendor/ars/scripts/adapters/examples/zotero/expected_passport.yaml +34 -0
- package/vendor/ars/scripts/adapters/examples/zotero/expected_rejection_log.yaml +34 -0
- package/vendor/ars/scripts/adapters/examples/zotero/input_fixture/.gitkeep +0 -0
- package/vendor/ars/scripts/adapters/examples/zotero/input_fixture/export.json +43 -0
- package/vendor/ars/scripts/adapters/folder_scan.py +214 -0
- package/vendor/ars/scripts/adapters/obsidian.py +336 -0
- package/vendor/ars/scripts/adapters/tests/.gitkeep +0 -0
- package/vendor/ars/scripts/adapters/tests/conftest.py +77 -0
- package/vendor/ars/scripts/adapters/tests/test_check_corpus_consumer_protocol.py +632 -0
- package/vendor/ars/scripts/adapters/tests/test_check_literature_corpus_schema.py +631 -0
- package/vendor/ars/scripts/adapters/tests/test_common.py +365 -0
- package/vendor/ars/scripts/adapters/tests/test_conftest.py +96 -0
- package/vendor/ars/scripts/adapters/tests/test_folder_scan.py +260 -0
- package/vendor/ars/scripts/adapters/tests/test_literature_corpus_entry_schema.py +745 -0
- package/vendor/ars/scripts/adapters/tests/test_obsidian.py +357 -0
- package/vendor/ars/scripts/adapters/tests/test_rejection_log_schema.py +271 -0
- package/vendor/ars/scripts/adapters/tests/test_sync_adapter_docs.py +88 -0
- package/vendor/ars/scripts/adapters/tests/test_zotero.py +454 -0
- package/vendor/ars/scripts/adapters/zotero.py +318 -0
- package/vendor/ars/scripts/adjudication_activity.py +1592 -0
- package/vendor/ars/scripts/announce-ars-loaded.sh +144 -0
- package/vendor/ars/scripts/ars_anchorize_draft.py +170 -0
- package/vendor/ars/scripts/ars_apply_revision_patch.py +912 -0
- package/vendor/ars/scripts/ars_cache_invalidate.py +40 -0
- package/vendor/ars/scripts/ars_mark_read.py +521 -0
- package/vendor/ars/scripts/ars_phase_scope_manifest.json +33 -0
- package/vendor/ars/scripts/ars_update_check.sh +215 -0
- package/vendor/ars/scripts/ars_write_scope_guard.py +506 -0
- package/vendor/ars/scripts/arxiv_client.py +222 -0
- package/vendor/ars/scripts/audit_snapshot.py +572 -0
- package/vendor/ars/scripts/bibliographic_integrity_signals.py +800 -0
- package/vendor/ars/scripts/bootstrap_timeline_yaml.py +146 -0
- package/vendor/ars/scripts/build_claim_standing_candidate_ledger.py +1238 -0
- package/vendor/ars/scripts/build_claim_standing_query_plan.py +643 -0
- package/vendor/ars/scripts/build_content_coverage_advisory.py +1205 -0
- package/vendor/ars/scripts/build_cross_document_consistency_advisory.py +2332 -0
- package/vendor/ars/scripts/build_review_pathway_rule_trace.py +830 -0
- package/vendor/ars/scripts/build_submission_packet_manifest.py +2310 -0
- package/vendor/ars/scripts/check_215_field_norm.py +173 -0
- package/vendor/ars/scripts/check_216_surface_form.py +250 -0
- package/vendor/ars/scripts/check_268_nested_commitment_ledger.py +180 -0
- package/vendor/ars/scripts/check_390_revision_patch_discipline.py +296 -0
- package/vendor/ars/scripts/check_392_citation_verification_intake.py +126 -0
- package/vendor/ars/scripts/check_394_submission_policy.py +178 -0
- package/vendor/ars/scripts/check_439_format_profile.py +307 -0
- package/vendor/ars/scripts/check_619_disclosure_closeout.py +237 -0
- package/vendor/ars/scripts/check_630_codex_subscription_transport.py +456 -0
- package/vendor/ars/scripts/check_669_review_pathway_rule_trace.py +662 -0
- package/vendor/ars/scripts/check_670_revision_roadmap_integration.py +518 -0
- package/vendor/ars/scripts/check_673_adjudication_activity.py +684 -0
- package/vendor/ars/scripts/check_684_review_criteria_binding.py +557 -0
- package/vendor/ars/scripts/check_agents_mirror_sync.py +115 -0
- package/vendor/ars/scripts/check_audit_artifact_consistency.py +2313 -0
- package/vendor/ars/scripts/check_benchmark_report.py +79 -0
- package/vendor/ars/scripts/check_bibliographic_integrity_signals.py +831 -0
- package/vendor/ars/scripts/check_calibration_tiers.py +235 -0
- package/vendor/ars/scripts/check_changelog_covers_merges.py +289 -0
- package/vendor/ars/scripts/check_ci_pytest_manifest.py +204 -0
- package/vendor/ars/scripts/check_claim_audit_consistency.py +1664 -0
- package/vendor/ars/scripts/check_claim_standing_candidate_ledger_integration.py +500 -0
- package/vendor/ars/scripts/check_claim_standing_freshness.py +253 -0
- package/vendor/ars/scripts/check_claim_standing_transmissions.py +449 -0
- package/vendor/ars/scripts/check_collaboration_depth_rubric.py +180 -0
- package/vendor/ars/scripts/check_command_frontmatter_name.py +116 -0
- package/vendor/ars/scripts/check_committee_correspondence.py +333 -0
- package/vendor/ars/scripts/check_compliance_report.py +108 -0
- package/vendor/ars/scripts/check_content_coverage_advisory_integration.py +796 -0
- package/vendor/ars/scripts/check_control_availability.py +172 -0
- package/vendor/ars/scripts/check_corpus_consumer_protocol.py +404 -0
- package/vendor/ars/scripts/check_cross_document_consistency_advisory_integration.py +1191 -0
- package/vendor/ars/scripts/check_cross_model_handoff_contract.py +234 -0
- package/vendor/ars/scripts/check_cross_model_verification_sync.py +261 -0
- package/vendor/ars/scripts/check_data_access_level.py +131 -0
- package/vendor/ars/scripts/check_data_flows.py +252 -0
- package/vendor/ars/scripts/check_decision_contract.py +464 -0
- package/vendor/ars/scripts/check_degradation_registry.py +326 -0
- package/vendor/ars/scripts/check_distribution_surface_claims.py +226 -0
- package/vendor/ars/scripts/check_domain_evidence_profile.py +538 -0
- package/vendor/ars/scripts/check_e4_promotion.py +195 -0
- package/vendor/ars/scripts/check_evals_gold_set.py +279 -0
- package/vendor/ars/scripts/check_evidence_row_integration.py +396 -0
- package/vendor/ars/scripts/check_experiment_provenance.py +117 -0
- package/vendor/ars/scripts/check_field_norm_severity.py +144 -0
- package/vendor/ars/scripts/check_firm_rules_sync.py +375 -0
- package/vendor/ars/scripts/check_heldout_measurement_report.py +1179 -0
- package/vendor/ars/scripts/check_human_subjects_output_contract.py +139 -0
- package/vendor/ars/scripts/check_human_subjects_reference_migration.py +844 -0
- package/vendor/ars/scripts/check_indirect_prompt_injection_no_call.py +328 -0
- package/vendor/ars/scripts/check_instruction_data_boundary.py +236 -0
- package/vendor/ars/scripts/check_judge_prompt_version.py +125 -0
- package/vendor/ars/scripts/check_literature_corpus_schema.py +402 -0
- package/vendor/ars/scripts/check_model_tiering.py +223 -0
- package/vendor/ars/scripts/check_panel_synthesis.py +1331 -0
- package/vendor/ars/scripts/check_passport_reset_contract.py +214 -0
- package/vendor/ars/scripts/check_pattern_eval_manifest.py +422 -0
- package/vendor/ars/scripts/check_persuasion_invariance_fixtures.py +637 -0
- package/vendor/ars/scripts/check_phase_conformance.py +2180 -0
- package/vendor/ars/scripts/check_pipeline_boundary_semantics.py +600 -0
- package/vendor/ars/scripts/check_pipeline_integrity.py +340 -0
- package/vendor/ars/scripts/check_policy_anchor_protocol.py +159 -0
- package/vendor/ars/scripts/check_policy_anchor_table.py +286 -0
- package/vendor/ars/scripts/check_preprint_venues_consistency.py +123 -0
- package/vendor/ars/scripts/check_prisma_trAIce_freshness.py +84 -0
- package/vendor/ars/scripts/check_promotion_bakeoff_preregistration.py +1303 -0
- package/vendor/ars/scripts/check_ranking_lift.py +323 -0
- package/vendor/ars/scripts/check_re_review_synthesis.py +2719 -0
- package/vendor/ars/scripts/check_receipt_enum_sync.py +203 -0
- package/vendor/ars/scripts/check_repro_lock.py +85 -0
- package/vendor/ars/scripts/check_review_pathway_output.py +276 -0
- package/vendor/ars/scripts/check_reviewer_data_fences.py +224 -0
- package/vendor/ars/scripts/check_reviewer_finding_contract.py +783 -0
- package/vendor/ars/scripts/check_reviewer_role_label.py +447 -0
- package/vendor/ars/scripts/check_reviewer_scoring_honesty.py +292 -0
- package/vendor/ars/scripts/check_reviewer_sprint_prompt_sync.py +409 -0
- package/vendor/ars/scripts/check_revision_claim_drift_suite_v2.py +1622 -0
- package/vendor/ars/scripts/check_revision_token_conservation.py +263 -0
- package/vendor/ars/scripts/check_risk_register.py +280 -0
- package/vendor/ars/scripts/check_role_scoped_contract.py +702 -0
- package/vendor/ars/scripts/check_rq_framing_patterns.py +184 -0
- package/vendor/ars/scripts/check_rubric_weight_consistency.py +32 -0
- package/vendor/ars/scripts/check_seeded_defect_fixtures.py +425 -0
- package/vendor/ars/scripts/check_setup_cross_model_parity.py +139 -0
- package/vendor/ars/scripts/check_spec_consistency.py +1249 -0
- package/vendor/ars/scripts/check_sprint_contract.py +371 -0
- package/vendor/ars/scripts/check_stage_capability_matrix.py +784 -0
- package/vendor/ars/scripts/check_submission_packet_manifest_integration.py +358 -0
- package/vendor/ars/scripts/check_surface_form_parity.py +445 -0
- package/vendor/ars/scripts/check_task_type.py +22 -0
- package/vendor/ars/scripts/check_tools_allowlist.py +538 -0
- package/vendor/ars/scripts/check_tortured_phrase_screening_integration.py +1974 -0
- package/vendor/ars/scripts/check_v3_10_134_write_scope.py +286 -0
- package/vendor/ars/scripts/check_v3_10_policy.py +656 -0
- package/vendor/ars/scripts/check_v3_6_6_ab_manifest.py +364 -0
- package/vendor/ars/scripts/check_v3_6_7_pattern_protection.py +1366 -0
- package/vendor/ars/scripts/check_v3_6_8_audit_scope_block.py +464 -0
- package/vendor/ars/scripts/check_v3_6_8_cite_provenance_pipeline.py +231 -0
- package/vendor/ars/scripts/check_v3_6_8_frontmatter_trust_schema.py +248 -0
- package/vendor/ars/scripts/check_v3_6_8_mark_read_commands.py +79 -0
- package/vendor/ars/scripts/check_v3_6_8_pattern_protection.py +941 -0
- package/vendor/ars/scripts/check_v3_7_3_three_layer_citation.py +318 -0
- package/vendor/ars/scripts/check_v3_8_annotation_literal_sync.py +228 -0
- package/vendor/ars/scripts/check_v3_9_0_triangulation.py +366 -0
- package/vendor/ars/scripts/check_v3_9_2_phase_boundary.py +270 -0
- package/vendor/ars/scripts/check_v3_9_4_temporal_verification.py +139 -0
- package/vendor/ars/scripts/check_venue_disclosure_policies.py +63 -0
- package/vendor/ars/scripts/check_version_consistency.py +826 -0
- package/vendor/ars/scripts/check_workflow_classification.py +223 -0
- package/vendor/ars/scripts/chinese_literature_client.py +1938 -0
- package/vendor/ars/scripts/citation_verification_summary.py +85 -0
- package/vendor/ars/scripts/claim_audit_calibration.py +517 -0
- package/vendor/ars/scripts/claim_audit_finalizer.py +456 -0
- package/vendor/ars/scripts/claim_audit_pipeline.py +1594 -0
- package/vendor/ars/scripts/claim_registry_coverage.py +493 -0
- package/vendor/ars/scripts/claim_standing_discovery.py +784 -0
- package/vendor/ars/scripts/claim_standing_stance_runner.py +758 -0
- package/vendor/ars/scripts/claim_standing_stance_scorer.py +239 -0
- package/vendor/ars/scripts/claim_strength_drift_disposition.py +666 -0
- package/vendor/ars/scripts/contamination_signals.py +689 -0
- package/vendor/ars/scripts/corpus_consumer_manifest.json +19 -0
- package/vendor/ars/scripts/cross_model_codex_transport.py +1374 -0
- package/vendor/ars/scripts/cross_model_codex_verify.sh +6 -0
- package/vendor/ars/scripts/cross_model_handoff.py +359 -0
- package/vendor/ars/scripts/cross_model_smoke_test.sh +183 -0
- package/vendor/ars/scripts/cross_model_smoke_test_codex.sh +35 -0
- package/vendor/ars/scripts/cross_model_verification/gemini_is_grounded.jq +45 -0
- package/vendor/ars/scripts/cross_model_verification/gemini_sources.jq +45 -0
- package/vendor/ars/scripts/cross_model_verification/normalize_compat_verdict.py +57 -0
- package/vendor/ars/scripts/cross_model_verification/openai_has_completed_web_search.jq +15 -0
- package/vendor/ars/scripts/cross_model_verification/openai_sources.jq +17 -0
- package/vendor/ars/scripts/cross_model_verification/openai_text.jq +11 -0
- package/vendor/ars/scripts/crossref_client.py +225 -0
- package/vendor/ars/scripts/dispatch_e4_panel.py +2731 -0
- package/vendor/ars/scripts/evidence_rows.py +2043 -0
- package/vendor/ars/scripts/fixtures/adjudication_activity/author_stage3.json +32 -0
- package/vendor/ars/scripts/fixtures/adjudication_activity/author_stage3_input.json +27 -0
- package/vendor/ars/scripts/fixtures/adjudication_activity/author_stage3_prime.json +32 -0
- package/vendor/ars/scripts/fixtures/adjudication_activity/author_stage3_prime_input.json +27 -0
- package/vendor/ars/scripts/fixtures/adjudication_activity/compliance_override.json +50 -0
- package/vendor/ars/scripts/fixtures/adjudication_activity/compliance_override_action.json +14 -0
- package/vendor/ars/scripts/fixtures/adjudication_activity/compliance_pass.json +44 -0
- package/vendor/ars/scripts/fixtures/adjudication_activity/explicit_user_request_log.json +26 -0
- package/vendor/ars/scripts/fixtures/adjudication_activity/mandatory_checkpoint_log.json +116 -0
- package/vendor/ars/scripts/fixtures/audit_artifact_consistency/README.md +56 -0
- 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
- package/vendor/ars/scripts/fixtures/audit_artifact_consistency/negative/a1_pass_with_p1/2026-04-30T15-22-04Z-d8f3.jsonl +4 -0
- package/vendor/ars/scripts/fixtures/audit_artifact_consistency/negative/a1_pass_with_p1/2026-04-30T15-22-04Z-d8f3.meta.json +43 -0
- package/vendor/ars/scripts/fixtures/audit_artifact_consistency/negative/a1_pass_with_p1/2026-04-30T15-22-04Z-d8f3.verdict.yaml +19 -0
- package/vendor/ars/scripts/fixtures/audit_artifact_consistency/negative/a7_orphan_completion/2026-04-30T15-22-04Z-d8f3.jsonl +3 -0
- package/vendor/ars/scripts/fixtures/audit_artifact_consistency/positive/persisted_minor/2026-04-30T15-22-04Z-d8f3.audit_artifact_entry.json +26 -0
- package/vendor/ars/scripts/fixtures/audit_artifact_consistency/positive/persisted_minor/2026-04-30T15-22-04Z-d8f3.jsonl +4 -0
- package/vendor/ars/scripts/fixtures/audit_artifact_consistency/positive/persisted_minor/2026-04-30T15-22-04Z-d8f3.meta.json +43 -0
- package/vendor/ars/scripts/fixtures/audit_artifact_consistency/positive/persisted_minor/2026-04-30T15-22-04Z-d8f3.verdict.yaml +19 -0
- package/vendor/ars/scripts/fixtures/audit_artifact_consistency/positive/proposal_pass/2026-04-30T15-22-04Z-d8f3.audit_artifact_entry.json +24 -0
- package/vendor/ars/scripts/fixtures/audit_artifact_consistency/positive/proposal_pass/2026-04-30T15-22-04Z-d8f3.jsonl +4 -0
- package/vendor/ars/scripts/fixtures/audit_artifact_consistency/positive/proposal_pass/2026-04-30T15-22-04Z-d8f3.meta.json +43 -0
- package/vendor/ars/scripts/fixtures/audit_artifact_consistency/positive/proposal_pass/2026-04-30T15-22-04Z-d8f3.verdict.yaml +12 -0
- package/vendor/ars/scripts/fixtures/bibliographic_integrity_signals/retraction.json +46 -0
- package/vendor/ars/scripts/fixtures/bibliographic_integrity_signals/retraction_check_attestation.json +44 -0
- package/vendor/ars/scripts/fixtures/bibliographic_integrity_signals/tortured_phrase.json +44 -0
- package/vendor/ars/scripts/fixtures/bibliographic_integrity_signals/tortured_phrase_v1_2_abstract_missing.json +107 -0
- package/vendor/ars/scripts/fixtures/bibliographic_integrity_signals/tortured_phrase_v1_2_detected.json +124 -0
- package/vendor/ars/scripts/fixtures/check_evals_gold_set/clean/expected_outcomes.json +77 -0
- package/vendor/ars/scripts/fixtures/check_evals_gold_set/clean/manifest.yaml +37 -0
- package/vendor/ars/scripts/fixtures/check_evals_gold_set/clean/tuples/001-valid-doi-test.json +20 -0
- package/vendor/ars/scripts/fixtures/check_evals_gold_set/clean/tuples/002-valid-arxiv-test.json +19 -0
- package/vendor/ars/scripts/fixtures/check_evals_gold_set/clean/tuples/003-fabricated-test.json +20 -0
- package/vendor/ars/scripts/fixtures/claim_audit_calibration/gold_set.json +344 -0
- package/vendor/ars/scripts/fixtures/claim_standing_candidate_ledger/query_plan.json +108 -0
- package/vendor/ars/scripts/fixtures/claim_standing_candidate_ledger/retrieval_input.json +179 -0
- package/vendor/ars/scripts/fixtures/committee_correspondence/16fd83f6aec7/concern_tracker.json +129 -0
- package/vendor/ars/scripts/fixtures/committee_correspondence/16fd83f6aec7/response_skeleton.md +19 -0
- package/vendor/ars/scripts/fixtures/committee_correspondence/16fd83f6aec7/source_letter.txt +9 -0
- package/vendor/ars/scripts/fixtures/content_coverage_advisory/base_draft.json +48 -0
- package/vendor/ars/scripts/fixtures/content_coverage_advisory/base_inventory.json +38 -0
- package/vendor/ars/scripts/fixtures/content_coverage_advisory/packet/consent.txt +1 -0
- package/vendor/ars/scripts/fixtures/content_coverage_advisory/session_sources.json +3 -0
- package/vendor/ars/scripts/fixtures/cross_document_consistency/README.md +6 -0
- package/vendor/ars/scripts/fixtures/cross_document_consistency/accepted_draft.md +35 -0
- package/vendor/ars/scripts/fixtures/cross_document_consistency/cases.json +75 -0
- package/vendor/ars/scripts/fixtures/cross_document_consistency/preregistration.md +5 -0
- package/vendor/ars/scripts/fixtures/cross_model_codex_transport/forbidden_event.jsonl +4 -0
- package/vendor/ars/scripts/fixtures/cross_model_codex_transport/grounded_verified.jsonl +3 -0
- package/vendor/ars/scripts/fixtures/cross_model_codex_transport/malformed.jsonl +3 -0
- package/vendor/ars/scripts/fixtures/cross_model_codex_transport/missing_search.jsonl +2 -0
- package/vendor/ars/scripts/fixtures/cross_model_codex_transport/multiple_finals.jsonl +4 -0
- package/vendor/ars/scripts/fixtures/cross_model_codex_transport/not_found.jsonl +3 -0
- package/vendor/ars/scripts/fixtures/cross_model_codex_transport/unbound_source.jsonl +3 -0
- package/vendor/ars/scripts/fixtures/cross_model_codex_transport/wrong_search_shape.jsonl +3 -0
- package/vendor/ars/scripts/fixtures/evidence_rows/phase_e_inputs.json +114 -0
- package/vendor/ars/scripts/fixtures/evidence_rows/session_sources.json +5 -0
- package/vendor/ars/scripts/fixtures/human_subjects_authority/cross-border-us-tw-gdpr.json +71 -0
- package/vendor/ars/scripts/fixtures/human_subjects_authority/gdpr-member-state-unresolved.json +62 -0
- package/vendor/ars/scripts/fixtures/human_subjects_authority/missing-data-axis.json +45 -0
- package/vendor/ars/scripts/fixtures/human_subjects_authority/no-profile.json +33 -0
- package/vendor/ars/scripts/fixtures/human_subjects_authority/tw-gdpr-two-axis.json +74 -0
- package/vendor/ars/scripts/fixtures/human_subjects_authority/us-gdpr-two-axis.json +74 -0
- package/vendor/ars/scripts/fixtures/review_pathway_rule_trace/lint-near-misses.json +72 -0
- package/vendor/ars/scripts/fixtures/review_pathway_rule_trace/no-profile-request.json +18 -0
- package/vendor/ars/scripts/fixtures/review_pathway_rule_trace/tw-candidates-request.json +63 -0
- package/vendor/ars/scripts/fixtures/review_pathway_rule_trace/us-candidates-request.json +77 -0
- package/vendor/ars/scripts/fixtures/review_target_context/exact-declaration.json +24 -0
- package/vendor/ars/scripts/fixtures/review_target_context/field-general-declaration.json +24 -0
- package/vendor/ars/scripts/fixtures/review_target_context/msr-2027-technical-full-declaration.json +24 -0
- package/vendor/ars/scripts/fixtures/review_target_context/synthetic-registry.json +92 -0
- package/vendor/ars/scripts/fixtures/revision_claim_drift_v2/README.md +21 -0
- package/vendor/ars/scripts/fixtures/revision_claim_drift_v2/subject_context_attested_only.json +55 -0
- package/vendor/ars/scripts/fixtures/revision_claim_drift_v2/subject_context_machine_supported.json +49 -0
- package/vendor/ars/scripts/fixtures/revision_claim_drift_v2/subject_context_not_isolated.json +56 -0
- package/vendor/ars/scripts/fixtures/revision_claim_drift_v2/subject_context_unknown.json +49 -0
- package/vendor/ars/scripts/fixtures/submission_package/clean/paper.md +16 -0
- package/vendor/ars/scripts/fixtures/submission_package/clean/references.bib +13 -0
- package/vendor/ars/scripts/fixtures/submission_package/fallback_authoryear/paper.md +11 -0
- package/vendor/ars/scripts/fixtures/submission_package/fallback_authoryear/references.bib +13 -0
- package/vendor/ars/scripts/fixtures/submission_package/fallback_latex/paper.tex +9 -0
- package/vendor/ars/scripts/fixtures/submission_package/fallback_latex/references.bib +13 -0
- package/vendor/ars/scripts/fixtures/submission_package/marker_no_join/paper.md +7 -0
- package/vendor/ars/scripts/fixtures/submission_package/orphan_intext/paper.md +8 -0
- package/vendor/ars/scripts/fixtures/submission_package/orphan_intext/references.bib +6 -0
- package/vendor/ars/scripts/fixtures/submission_package/passports/corpus_only.yaml +9 -0
- package/vendor/ars/scripts/fixtures/submission_package/passports/summary_join.yaml +16 -0
- package/vendor/ars/scripts/fixtures/submission_package/profiles/full.yaml +15 -0
- package/vendor/ars/scripts/fixtures/submission_package/profiles/tight.yaml +15 -0
- package/vendor/ars/scripts/fixtures/submission_package/summary_join/paper.md +7 -0
- package/vendor/ars/scripts/fixtures/submission_package/uncited_reference/paper.md +9 -0
- package/vendor/ars/scripts/fixtures/submission_package/uncited_reference/references.bib +13 -0
- package/vendor/ars/scripts/fixtures/submission_package/venue_clean/paper.md +26 -0
- package/vendor/ars/scripts/fixtures/submission_package/venue_clean/references.bib +13 -0
- package/vendor/ars/scripts/fixtures/submission_package/venue_violations/paper.md +20 -0
- package/vendor/ars/scripts/fixtures/submission_package/venue_violations/references.bib +13 -0
- package/vendor/ars/scripts/fixtures/submission_packet_manifest/base_inventory.json +101 -0
- package/vendor/ars/scripts/fixtures/submission_packet_manifest/packet/consent-materials.txt +3 -0
- package/vendor/ars/scripts/fixtures/submission_packet_manifest/packet/training-certificate.txt +2 -0
- package/vendor/ars/scripts/fixtures/submission_packet_manifest/packet/tw-consent-materials.txt +3 -0
- package/vendor/ars/scripts/fixtures/tortured_phrase_screening/corpus_input.yaml +30 -0
- package/vendor/ars/scripts/fixtures/tortured_phrase_screening/own_draft.md +36 -0
- package/vendor/ars/scripts/fixtures/tortured_phrase_screening/own_draft.tex +21 -0
- package/vendor/ars/scripts/fixtures/tortured_phrase_screening/seed_expectations.json +218 -0
- package/vendor/ars/scripts/fixtures/tortured_phrase_screening/snapshot.json +164 -0
- package/vendor/ars/scripts/fixtures/tortured_phrase_screening/snapshot_manifest.json +29 -0
- package/vendor/ars/scripts/fixtures/transport_bodies/README.md +55 -0
- package/vendor/ars/scripts/fixtures/transport_bodies/arxiv/empty_feed.xml +10 -0
- package/vendor/ars/scripts/fixtures/transport_bodies/arxiv/error_5xx.html +7 -0
- package/vendor/ars/scripts/fixtures/transport_bodies/arxiv/id_hit.xml +26 -0
- package/vendor/ars/scripts/fixtures/transport_bodies/chinese_literature/README.md +69 -0
- package/vendor/ars/scripts/fixtures/transport_bodies/chinese_literature/cnki_landing_page.html +13 -0
- package/vendor/ars/scripts/fixtures/transport_bodies/chinese_literature/error_5xx.html +2 -0
- package/vendor/ars/scripts/fixtures/transport_bodies/chinese_literature/esearch_coordinate_ambiguous.json +16 -0
- package/vendor/ars/scripts/fixtures/transport_bodies/chinese_literature/esearch_coordinate_hit.json +16 -0
- package/vendor/ars/scripts/fixtures/transport_bodies/chinese_literature/esearch_coordinate_zero.json +14 -0
- package/vendor/ars/scripts/fixtures/transport_bodies/chinese_literature/esearch_coverage_hit.json +15 -0
- package/vendor/ars/scripts/fixtures/transport_bodies/chinese_literature/esearch_coverage_zero.json +13 -0
- package/vendor/ars/scripts/fixtures/transport_bodies/chinese_literature/esummary_hit.json +43 -0
- package/vendor/ars/scripts/fixtures/transport_bodies/chinese_literature/esummary_issn_mismatch.json +31 -0
- package/vendor/ars/scripts/fixtures/transport_bodies/chinese_literature/esummary_no_doi.json +31 -0
- package/vendor/ars/scripts/fixtures/transport_bodies/chinese_literature/esummary_unknown_ra.json +34 -0
- package/vendor/ars/scripts/fixtures/transport_bodies/chinese_literature/esummary_year_mismatch.json +31 -0
- package/vendor/ars/scripts/fixtures/transport_bodies/chinese_literature/handle_absent.json +4 -0
- package/vendor/ars/scripts/fixtures/transport_bodies/chinese_literature/handle_exists.json +16 -0
- package/vendor/ars/scripts/fixtures/transport_bodies/chinese_literature/handle_internal_error.json +4 -0
- package/vendor/ars/scripts/fixtures/transport_bodies/chinese_literature/istic_csl_hit.json +25 -0
- package/vendor/ars/scripts/fixtures/transport_bodies/chinese_literature/istic_csl_other_title.json +18 -0
- package/vendor/ars/scripts/fixtures/transport_bodies/chinese_literature/ra_cnki.json +6 -0
- package/vendor/ars/scripts/fixtures/transport_bodies/chinese_literature/ra_crossref.json +6 -0
- package/vendor/ars/scripts/fixtures/transport_bodies/chinese_literature/ra_istic.json +6 -0
- package/vendor/ars/scripts/fixtures/transport_bodies/chinese_literature/ra_unknown_prefix.json +6 -0
- package/vendor/ars/scripts/fixtures/transport_bodies/crossref/doi_hit.json +24 -0
- package/vendor/ars/scripts/fixtures/transport_bodies/crossref/error_5xx.html +7 -0
- package/vendor/ars/scripts/fixtures/transport_bodies/crossref/title_search_miss.json +15 -0
- package/vendor/ars/scripts/fixtures/transport_bodies/openalex/doi_hit.json +29 -0
- package/vendor/ars/scripts/fixtures/transport_bodies/openalex/error_5xx.json +4 -0
- package/vendor/ars/scripts/fixtures/transport_bodies/openalex/title_search_miss.json +11 -0
- package/vendor/ars/scripts/fixtures/transport_bodies/semantic_scholar/doi_hit.json +14 -0
- package/vendor/ars/scripts/fixtures/transport_bodies/semantic_scholar/error_5xx.json +3 -0
- package/vendor/ars/scripts/fixtures/transport_bodies/semantic_scholar/title_search_miss.json +5 -0
- package/vendor/ars/scripts/human_read_attestation_resolver.py +467 -0
- package/vendor/ars/scripts/ideation_diversity_assignment_gate.py +430 -0
- package/vendor/ars/scripts/inquiry_branch_ledger.py +2540 -0
- package/vendor/ars/scripts/legacy/ars_apply_revision_patch_v1_0.py +715 -0
- package/vendor/ars/scripts/legacy/check_re_review_synthesis_v1_0.py +2215 -0
- package/vendor/ars/scripts/migrate_literature_corpus_to_v3_10.py +223 -0
- package/vendor/ars/scripts/migrate_literature_corpus_to_v3_7_3.py +277 -0
- package/vendor/ars/scripts/migrate_literature_corpus_to_v3_9_0.py +304 -0
- package/vendor/ars/scripts/model_tiering_manifest.json +46 -0
- package/vendor/ars/scripts/openalex_client.py +232 -0
- package/vendor/ars/scripts/parse_audit_verdict.py +802 -0
- package/vendor/ars/scripts/pdf_content_classifier_worker.py +176 -0
- package/vendor/ars/scripts/pdf_read_preflight.py +1455 -0
- package/vendor/ars/scripts/policy_anchor_disclosure_referee.py +354 -0
- package/vendor/ars/scripts/recompute_receipts.py +1414 -0
- package/vendor/ars/scripts/render_claim_standing_view.py +374 -0
- package/vendor/ars/scripts/render_eval_comment.py +130 -0
- package/vendor/ars/scripts/render_harness_retirement_issue.py +167 -0
- package/vendor/ars/scripts/repro_lock_validation.py +90 -0
- package/vendor/ars/scripts/research_workflow_profile.py +1079 -0
- package/vendor/ars/scripts/resolve_human_subjects_authority.py +1158 -0
- package/vendor/ars/scripts/resolve_review_target_context.py +683 -0
- package/vendor/ars/scripts/resume_e4_record.py +509 -0
- package/vendor/ars/scripts/retraction_status.py +484 -0
- package/vendor/ars/scripts/review_criteria_binding.py +889 -0
- package/vendor/ars/scripts/review_panel_provenance.py +744 -0
- package/vendor/ars/scripts/revision_roadmap.py +1967 -0
- package/vendor/ars/scripts/run_ci_pytest_manifest.py +116 -0
- package/vendor/ars/scripts/run_codex_audit.sh +1191 -0
- package/vendor/ars/scripts/run_evals.py +513 -0
- package/vendor/ars/scripts/run_ideation_diversity_no_call.py +3505 -0
- package/vendor/ars/scripts/run_indirect_prompt_injection_no_call.py +3330 -0
- package/vendor/ars/scripts/run_indirect_prompt_injection_probe.py +399 -0
- package/vendor/ars/scripts/run_review_criteria_constructive_value.py +1895 -0
- package/vendor/ars/scripts/run_role_topology_utility_dry_run.py +606 -0
- package/vendor/ars/scripts/score_review_criteria_constructive_value.py +617 -0
- package/vendor/ars/scripts/semantic_scholar_client.py +291 -0
- package/vendor/ars/scripts/slr_lineage.py +59 -0
- package/vendor/ars/scripts/sync_adapter_docs.py +118 -0
- package/vendor/ars/scripts/temporal_integrity_audit.py +840 -0
- package/vendor/ars/scripts/test_431_exact_or_bust.py +253 -0
- package/vendor/ars/scripts/test__eval_threshold_gate.py +125 -0
- package/vendor/ars/scripts/test__markdown_lint_util.py +129 -0
- package/vendor/ars/scripts/test__next_verified_at_ms.py +256 -0
- package/vendor/ars/scripts/test_adjacent_framing_probe_lint.py +171 -0
- package/vendor/ars/scripts/test_adjudication_activity.py +1515 -0
- package/vendor/ars/scripts/test_ars_anchorize_draft.py +178 -0
- package/vendor/ars/scripts/test_ars_apply_revision_patch.py +1335 -0
- package/vendor/ars/scripts/test_ars_cache_invalidate.py +51 -0
- package/vendor/ars/scripts/test_ars_mark_read.py +910 -0
- package/vendor/ars/scripts/test_ars_update_check.py +816 -0
- package/vendor/ars/scripts/test_ars_write_scope_guard.py +790 -0
- package/vendor/ars/scripts/test_arxiv_client.py +374 -0
- package/vendor/ars/scripts/test_audit_schemas.py +560 -0
- package/vendor/ars/scripts/test_audit_snapshot_render_section_0.py +105 -0
- package/vendor/ars/scripts/test_block_parser.py +259 -0
- package/vendor/ars/scripts/test_bootstrap_timeline_yaml.py +148 -0
- package/vendor/ars/scripts/test_build_claim_standing_candidate_ledger.py +1203 -0
- package/vendor/ars/scripts/test_build_claim_standing_query_plan.py +791 -0
- package/vendor/ars/scripts/test_build_submission_packet_manifest.py +2644 -0
- package/vendor/ars/scripts/test_check_215_field_norm.py +238 -0
- package/vendor/ars/scripts/test_check_216_surface_form.py +341 -0
- package/vendor/ars/scripts/test_check_268_nested_commitment_ledger.py +194 -0
- package/vendor/ars/scripts/test_check_390_revision_patch_discipline.py +279 -0
- package/vendor/ars/scripts/test_check_392_citation_verification_intake.py +144 -0
- package/vendor/ars/scripts/test_check_394_submission_policy.py +200 -0
- package/vendor/ars/scripts/test_check_439_format_profile.py +252 -0
- package/vendor/ars/scripts/test_check_619_disclosure_closeout.py +158 -0
- package/vendor/ars/scripts/test_check_630_codex_subscription_transport.py +245 -0
- package/vendor/ars/scripts/test_check_669_review_pathway_rule_trace.py +304 -0
- package/vendor/ars/scripts/test_check_670_revision_roadmap_integration.py +260 -0
- package/vendor/ars/scripts/test_check_673_adjudication_activity.py +367 -0
- package/vendor/ars/scripts/test_check_684_review_criteria_binding.py +274 -0
- package/vendor/ars/scripts/test_check_agents_mirror_sync.py +137 -0
- package/vendor/ars/scripts/test_check_audit_artifact_consistency.py +2133 -0
- package/vendor/ars/scripts/test_check_benchmark_report.py +117 -0
- package/vendor/ars/scripts/test_check_bibliographic_integrity_signals.py +609 -0
- package/vendor/ars/scripts/test_check_calibration_tiers.py +376 -0
- package/vendor/ars/scripts/test_check_changelog_covers_merges.py +509 -0
- package/vendor/ars/scripts/test_check_ci_pytest_manifest.py +425 -0
- package/vendor/ars/scripts/test_check_claim_standing_candidate_ledger_integration.py +256 -0
- package/vendor/ars/scripts/test_check_claim_standing_freshness.py +277 -0
- package/vendor/ars/scripts/test_check_collaboration_depth_rubric.py +239 -0
- package/vendor/ars/scripts/test_check_command_frontmatter_name.py +178 -0
- package/vendor/ars/scripts/test_check_committee_correspondence.py +298 -0
- package/vendor/ars/scripts/test_check_compliance_report.py +381 -0
- package/vendor/ars/scripts/test_check_content_coverage_advisory_integration.py +308 -0
- package/vendor/ars/scripts/test_check_control_availability.py +361 -0
- package/vendor/ars/scripts/test_check_cross_document_consistency_advisory_integration.py +698 -0
- package/vendor/ars/scripts/test_check_cross_model_handoff_contract.py +301 -0
- package/vendor/ars/scripts/test_check_cross_model_verification_sync.py +203 -0
- package/vendor/ars/scripts/test_check_data_access_level.py +227 -0
- package/vendor/ars/scripts/test_check_data_flows.py +382 -0
- package/vendor/ars/scripts/test_check_decision_contract.py +387 -0
- package/vendor/ars/scripts/test_check_degradation_registry.py +270 -0
- package/vendor/ars/scripts/test_check_distribution_surface_claims.py +225 -0
- package/vendor/ars/scripts/test_check_domain_evidence_profile.py +439 -0
- package/vendor/ars/scripts/test_check_e4_promotion.py +163 -0
- package/vendor/ars/scripts/test_check_evals_gold_set.py +312 -0
- package/vendor/ars/scripts/test_check_evidence_row_integration.py +187 -0
- package/vendor/ars/scripts/test_check_field_norm_severity.py +173 -0
- package/vendor/ars/scripts/test_check_firm_rules_sync.py +342 -0
- package/vendor/ars/scripts/test_check_heldout_measurement_report.py +1508 -0
- package/vendor/ars/scripts/test_check_human_subjects_output_contract.py +129 -0
- package/vendor/ars/scripts/test_check_human_subjects_reference_migration.py +756 -0
- package/vendor/ars/scripts/test_check_instruction_data_boundary.py +204 -0
- package/vendor/ars/scripts/test_check_judge_prompt_version.py +90 -0
- package/vendor/ars/scripts/test_check_model_tiering.py +236 -0
- package/vendor/ars/scripts/test_check_panel_synthesis.py +1658 -0
- package/vendor/ars/scripts/test_check_passport_reset_contract.py +249 -0
- package/vendor/ars/scripts/test_check_pattern_eval_manifest.py +381 -0
- package/vendor/ars/scripts/test_check_persuasion_invariance_fixtures.py +591 -0
- package/vendor/ars/scripts/test_check_phase_conformance.py +4366 -0
- package/vendor/ars/scripts/test_check_pipeline_boundary_semantics.py +931 -0
- package/vendor/ars/scripts/test_check_pipeline_integrity.py +243 -0
- package/vendor/ars/scripts/test_check_policy_anchor_protocol.py +236 -0
- package/vendor/ars/scripts/test_check_policy_anchor_table.py +295 -0
- package/vendor/ars/scripts/test_check_prisma_trAIce_freshness.py +68 -0
- package/vendor/ars/scripts/test_check_promotion_bakeoff_preregistration.py +799 -0
- package/vendor/ars/scripts/test_check_ranking_lift.py +377 -0
- package/vendor/ars/scripts/test_check_re_review_synthesis.py +3398 -0
- package/vendor/ars/scripts/test_check_receipt_enum_sync.py +176 -0
- package/vendor/ars/scripts/test_check_repro_lock.py +107 -0
- package/vendor/ars/scripts/test_check_reviewer_data_fences.py +334 -0
- package/vendor/ars/scripts/test_check_reviewer_finding_contract.py +1107 -0
- package/vendor/ars/scripts/test_check_reviewer_role_label.py +491 -0
- package/vendor/ars/scripts/test_check_reviewer_scoring_honesty.py +222 -0
- package/vendor/ars/scripts/test_check_reviewer_sprint_prompt_sync.py +373 -0
- package/vendor/ars/scripts/test_check_revision_claim_drift_suite_v2.py +1925 -0
- package/vendor/ars/scripts/test_check_revision_token_conservation.py +398 -0
- package/vendor/ars/scripts/test_check_risk_register.py +336 -0
- package/vendor/ars/scripts/test_check_role_scoped_contract.py +1104 -0
- package/vendor/ars/scripts/test_check_rq_framing_patterns.py +110 -0
- package/vendor/ars/scripts/test_check_rubric_weight_consistency.py +32 -0
- package/vendor/ars/scripts/test_check_seeded_defect_fixtures.py +392 -0
- package/vendor/ars/scripts/test_check_setup_cross_model_parity.py +121 -0
- package/vendor/ars/scripts/test_check_spec_consistency.py +1081 -0
- package/vendor/ars/scripts/test_check_sprint_contract.py +458 -0
- package/vendor/ars/scripts/test_check_stage_capability_matrix.py +698 -0
- package/vendor/ars/scripts/test_check_submission_packet_manifest_integration.py +177 -0
- package/vendor/ars/scripts/test_check_surface_form_parity.py +417 -0
- package/vendor/ars/scripts/test_check_task_type.py +116 -0
- package/vendor/ars/scripts/test_check_tools_allowlist.py +835 -0
- package/vendor/ars/scripts/test_check_tortured_phrase_screening_integration.py +1306 -0
- package/vendor/ars/scripts/test_check_v3_10_134_write_scope.py +251 -0
- package/vendor/ars/scripts/test_check_v3_10_policy.py +547 -0
- package/vendor/ars/scripts/test_check_v3_6_7_pattern_protection.py +960 -0
- package/vendor/ars/scripts/test_check_v3_6_8_audit_scope_block.py +1000 -0
- package/vendor/ars/scripts/test_check_v3_6_8_cite_provenance_pipeline.py +454 -0
- package/vendor/ars/scripts/test_check_v3_6_8_frontmatter_trust_schema.py +581 -0
- package/vendor/ars/scripts/test_check_v3_6_8_mark_read_commands.py +120 -0
- package/vendor/ars/scripts/test_check_v3_6_8_pattern_protection.py +1138 -0
- package/vendor/ars/scripts/test_check_v3_7_3_three_layer_citation.py +566 -0
- package/vendor/ars/scripts/test_check_v3_8_annotation_literal_sync.py +262 -0
- package/vendor/ars/scripts/test_check_v3_9_0_triangulation.py +321 -0
- package/vendor/ars/scripts/test_check_v3_9_2_phase_boundary.py +190 -0
- package/vendor/ars/scripts/test_check_v3_9_4_temporal_verification.py +471 -0
- package/vendor/ars/scripts/test_check_version_consistency.py +1462 -0
- package/vendor/ars/scripts/test_check_workflow_classification.py +225 -0
- package/vendor/ars/scripts/test_chinese_literature_client.py +1889 -0
- package/vendor/ars/scripts/test_citation_existence_policy.py +480 -0
- package/vendor/ars/scripts/test_citation_verification_summary.py +342 -0
- package/vendor/ars/scripts/test_claim_audit_calibration.py +882 -0
- package/vendor/ars/scripts/test_claim_audit_finalizer.py +979 -0
- package/vendor/ars/scripts/test_claim_audit_pipeline.py +2398 -0
- package/vendor/ars/scripts/test_claim_audit_schema.py +1778 -0
- package/vendor/ars/scripts/test_claim_intent_manifest.py +666 -0
- package/vendor/ars/scripts/test_claim_registry_coverage.py +246 -0
- package/vendor/ars/scripts/test_claim_standing_discovery.py +579 -0
- package/vendor/ars/scripts/test_claim_standing_pipeline_wiring.py +290 -0
- package/vendor/ars/scripts/test_claim_standing_stance_assets.py +399 -0
- package/vendor/ars/scripts/test_claim_standing_stance_contracts.py +383 -0
- package/vendor/ars/scripts/test_claim_standing_stance_runner.py +349 -0
- package/vendor/ars/scripts/test_claim_standing_transmissions.py +605 -0
- package/vendor/ars/scripts/test_claim_strength_drift_disposition.py +517 -0
- package/vendor/ars/scripts/test_claim_verification_coverage_contract.py +104 -0
- package/vendor/ars/scripts/test_contamination_signals.py +1086 -0
- package/vendor/ars/scripts/test_content_coverage_advisory.py +1767 -0
- package/vendor/ars/scripts/test_cross_document_consistency_advisory.py +1270 -0
- package/vendor/ars/scripts/test_cross_model_codex_transport.py +1152 -0
- package/vendor/ars/scripts/test_cross_model_handoff.py +571 -0
- package/vendor/ars/scripts/test_cross_model_verification_guards.py +792 -0
- package/vendor/ars/scripts/test_crossref_client.py +393 -0
- package/vendor/ars/scripts/test_dispatch_e4_panel.py +4235 -0
- package/vendor/ars/scripts/test_e2e_claim_audit.py +540 -0
- package/vendor/ars/scripts/test_eval_harness_workflow.py +140 -0
- package/vendor/ars/scripts/test_evals_citation_extraction.py +150 -0
- package/vendor/ars/scripts/test_evals_lift_report_schema.py +108 -0
- package/vendor/ars/scripts/test_evidence_rows.py +2593 -0
- package/vendor/ars/scripts/test_experiment_provenance.py +915 -0
- package/vendor/ars/scripts/test_human_read_attestation_resolver.py +477 -0
- package/vendor/ars/scripts/test_ideation_diversity_assignment_gate.py +615 -0
- package/vendor/ars/scripts/test_indirect_prompt_injection_behavior_probe.py +250 -0
- package/vendor/ars/scripts/test_inquiry_branch_ledger.py +2296 -0
- package/vendor/ars/scripts/test_migrate_literature_corpus_to_v3_10.py +248 -0
- package/vendor/ars/scripts/test_migrate_literature_corpus_to_v3_7_3.py +545 -0
- package/vendor/ars/scripts/test_migrate_literature_corpus_to_v3_9_0.py +497 -0
- package/vendor/ars/scripts/test_normalize_compat_verdict.py +149 -0
- package/vendor/ars/scripts/test_openalex_client.py +490 -0
- package/vendor/ars/scripts/test_passport_yaml.py +104 -0
- package/vendor/ars/scripts/test_pattern_eval_runtime.py +1295 -0
- package/vendor/ars/scripts/test_pdf_read_preflight.py +1943 -0
- package/vendor/ars/scripts/test_policy_anchor_disclosure.py +666 -0
- package/vendor/ars/scripts/test_reading_probe_lint.py +218 -0
- package/vendor/ars/scripts/test_recompute_receipts.py +778 -0
- package/vendor/ars/scripts/test_render_claim_standing_view.py +192 -0
- package/vendor/ars/scripts/test_render_eval_comment.py +162 -0
- package/vendor/ars/scripts/test_render_harness_retirement_issue.py +110 -0
- package/vendor/ars/scripts/test_repro_lock_validation_drift.py +100 -0
- package/vendor/ars/scripts/test_research_workflow_profile.py +734 -0
- package/vendor/ars/scripts/test_resolve_human_subjects_authority.py +1219 -0
- package/vendor/ars/scripts/test_resolve_review_target_context.py +703 -0
- package/vendor/ars/scripts/test_resume_e4_record.py +315 -0
- package/vendor/ars/scripts/test_retraction_status.py +456 -0
- package/vendor/ars/scripts/test_review_criteria_binding.py +629 -0
- package/vendor/ars/scripts/test_review_panel_provenance.py +565 -0
- package/vendor/ars/scripts/test_review_pathway_rule_trace.py +821 -0
- package/vendor/ars/scripts/test_revision_roadmap.py +1255 -0
- package/vendor/ars/scripts/test_run_ci_pytest_manifest.py +186 -0
- package/vendor/ars/scripts/test_run_codex_audit_e2e.py +369 -0
- package/vendor/ars/scripts/test_run_evals.py +430 -0
- package/vendor/ars/scripts/test_run_guard_launcher.py +500 -0
- package/vendor/ars/scripts/test_run_ideation_diversity_no_call.py +1833 -0
- package/vendor/ars/scripts/test_run_indirect_prompt_injection_no_call.py +1889 -0
- package/vendor/ars/scripts/test_run_review_criteria_constructive_value.py +586 -0
- package/vendor/ars/scripts/test_run_role_topology_utility_dry_run.py +428 -0
- package/vendor/ars/scripts/test_score_review_criteria_constructive_value.py +340 -0
- package/vendor/ars/scripts/test_semantic_scholar_client.py +554 -0
- package/vendor/ars/scripts/test_slr_lineage_emission.py +230 -0
- package/vendor/ars/scripts/test_socratic_rq_non_generation_contract.py +173 -0
- package/vendor/ars/scripts/test_temporal_integrity_audit.py +438 -0
- package/vendor/ars/scripts/test_text_similarity.py +95 -0
- package/vendor/ars/scripts/test_title_fuzzy_false_positive.py +111 -0
- package/vendor/ars/scripts/test_tortured_phrase_screening.py +2959 -0
- package/vendor/ars/scripts/test_transport_fixture_citation_gate.py +338 -0
- package/vendor/ars/scripts/test_uncited_assertion.py +558 -0
- package/vendor/ars/scripts/test_v3_6_7_phase_6_6.py +1279 -0
- package/vendor/ars/scripts/test_validate_compliance_fixtures.py +36 -0
- package/vendor/ars/scripts/test_validate_ideation_diversity_assets.py +230 -0
- package/vendor/ars/scripts/test_venue_disclosure_contract.py +755 -0
- package/vendor/ars/scripts/test_verification_cache.py +280 -0
- package/vendor/ars/scripts/test_verification_gate.py +461 -0
- package/vendor/ars/scripts/test_verify_passport_cli.py +123 -0
- package/vendor/ars/scripts/test_verify_submission_package.py +1407 -0
- package/vendor/ars/scripts/test_version_records_schema.py +211 -0
- package/vendor/ars/scripts/tortured_phrase_screening.py +3502 -0
- package/vendor/ars/scripts/uncited_assertion_detector.py +254 -0
- package/vendor/ars/scripts/v3_6_7_inversion_manifest.json +9 -0
- package/vendor/ars/scripts/v3_6_8_inversion_manifest.json +10 -0
- package/vendor/ars/scripts/validate_claim_standing_stance_assets.py +249 -0
- package/vendor/ars/scripts/validate_compliance_fixtures.py +56 -0
- package/vendor/ars/scripts/validate_ideation_diversity_assets.py +303 -0
- package/vendor/ars/scripts/venue_disclosure_contract_harness.py +837 -0
- package/vendor/ars/scripts/verification_cache.py +276 -0
- package/vendor/ars/scripts/verification_gate/__init__.py +345 -0
- package/vendor/ars/scripts/verify_passport.py +133 -0
- package/vendor/ars/scripts/verify_submission_package.py +1657 -0
- package/vendor/ars/shared/agents/compliance_agent.md +136 -0
- package/vendor/ars/shared/artifact_reproducibility_pattern.md +173 -0
- package/vendor/ars/shared/benchmark_report.schema.json +81 -0
- package/vendor/ars/shared/benchmark_report_pattern.md +180 -0
- package/vendor/ars/shared/bibliographic_integrity_signals.md +142 -0
- package/vendor/ars/shared/collaboration_depth_rubric.md +154 -0
- package/vendor/ars/shared/compliance_checkpoint_protocol.md +162 -0
- package/vendor/ars/shared/compliance_report.schema.json +187 -0
- package/vendor/ars/shared/contracts/README.md +938 -0
- package/vendor/ars/shared/contracts/activity/adjudication_activity_input.schema.json +555 -0
- package/vendor/ars/shared/contracts/activity/adjudication_activity_store.schema.json +560 -0
- package/vendor/ars/shared/contracts/audit/audit_jsonl.schema.json +128 -0
- package/vendor/ars/shared/contracts/audit/audit_sidecar.schema.json +169 -0
- package/vendor/ars/shared/contracts/audit/audit_verdict.schema.json +133 -0
- package/vendor/ars/shared/contracts/audit/cross_document_consistency_advisory.schema.json +480 -0
- package/vendor/ars/shared/contracts/audit/cross_document_consistency_advisory_draft.schema.json +564 -0
- package/vendor/ars/shared/contracts/audit/cross_document_source_manifest.schema.json +202 -0
- package/vendor/ars/shared/contracts/audit/tortured_phrase_advisory.schema.json +1362 -0
- package/vendor/ars/shared/contracts/audit/tortured_phrase_snapshot.schema.json +208 -0
- package/vendor/ars/shared/contracts/audit/tortured_phrase_snapshot_manifest.schema.json +335 -0
- package/vendor/ars/shared/contracts/capability/stage_capability_matrix.json +434 -0
- package/vendor/ars/shared/contracts/claim_standing/candidate_ledger.schema.json +705 -0
- package/vendor/ars/shared/contracts/claim_standing/query_plan.schema.json +389 -0
- package/vendor/ars/shared/contracts/claim_standing/query_plan_v1_1.schema.json +782 -0
- package/vendor/ars/shared/contracts/claim_standing/retrieval_input.schema.json +440 -0
- package/vendor/ars/shared/contracts/claim_standing/stance_record.schema.json +460 -0
- package/vendor/ars/shared/contracts/claim_standing/transmission_ledger.schema.json +282 -0
- package/vendor/ars/shared/contracts/cross_model/codex_citation_receipt.schema.json +157 -0
- package/vendor/ars/shared/contracts/cross_model/codex_citation_request.schema.json +23 -0
- package/vendor/ars/shared/contracts/cross_model/promotion_bakeoff_sealed_commitment.schema.json +55 -0
- package/vendor/ars/shared/contracts/cross_model/promotion_bakeoff_sealed_reveal.schema.json +50 -0
- package/vendor/ars/shared/contracts/degradation_registry.json +428 -0
- package/vendor/ars/shared/contracts/evaluator/full.json +126 -0
- package/vendor/ars/shared/contracts/evidence/claim_registry.schema.json +50 -0
- package/vendor/ars/shared/contracts/evidence/claim_registry_coverage_report.schema.json +79 -0
- package/vendor/ars/shared/contracts/evidence/evidence_row.schema.json +504 -0
- package/vendor/ars/shared/contracts/evidence/evidence_row_v1_1.schema.json +364 -0
- package/vendor/ars/shared/contracts/evidence/evidence_row_v1_2.schema.json +714 -0
- package/vendor/ars/shared/contracts/evidence/evidence_row_v1_3.schema.json +524 -0
- package/vendor/ars/shared/contracts/human_subjects/authority_profile_registry.schema.json +497 -0
- package/vendor/ars/shared/contracts/human_subjects/committee_correspondence.schema.json +253 -0
- package/vendor/ars/shared/contracts/human_subjects/content_coverage_advisory.schema.json +620 -0
- package/vendor/ars/shared/contracts/human_subjects/irb_context_record.schema.json +329 -0
- package/vendor/ars/shared/contracts/human_subjects/resolved_authority_context.schema.json +347 -0
- package/vendor/ars/shared/contracts/human_subjects/review_pathway_rule_trace.schema.json +265 -0
- package/vendor/ars/shared/contracts/human_subjects/review_pathway_trace_request.schema.json +127 -0
- package/vendor/ars/shared/contracts/human_subjects/submission_packet_inventory.schema.json +240 -0
- package/vendor/ars/shared/contracts/human_subjects/submission_packet_manifest.schema.json +999 -0
- package/vendor/ars/shared/contracts/passport/audit_artifact_entry.schema.json +266 -0
- package/vendor/ars/shared/contracts/passport/bibliographic_integrity_signal.schema.json +1676 -0
- package/vendor/ars/shared/contracts/passport/citation_provenance.schema.json +107 -0
- package/vendor/ars/shared/contracts/passport/citation_verification_summary.schema.json +164 -0
- package/vendor/ars/shared/contracts/passport/claim_audit_result.schema.json +124 -0
- package/vendor/ars/shared/contracts/passport/claim_drift.schema.json +58 -0
- package/vendor/ars/shared/contracts/passport/claim_intent_manifest.schema.json +107 -0
- package/vendor/ars/shared/contracts/passport/constraint_violation.schema.json +65 -0
- package/vendor/ars/shared/contracts/passport/experiment_alignment_result.schema.json +69 -0
- package/vendor/ars/shared/contracts/passport/experiment_provenance_entry.schema.json +169 -0
- package/vendor/ars/shared/contracts/passport/human_read_log.schema.json +86 -0
- package/vendor/ars/shared/contracts/passport/inquiry_ledger_ref.schema.json +22 -0
- package/vendor/ars/shared/contracts/passport/literature_corpus_entry.schema.json +650 -0
- package/vendor/ars/shared/contracts/passport/preregistration_artifact.schema.json +132 -0
- package/vendor/ars/shared/contracts/passport/rejection_log.schema.json +89 -0
- package/vendor/ars/shared/contracts/passport/reset_ledger_entry.schema.json +158 -0
- package/vendor/ars/shared/contracts/passport/temporal_audit_results.schema.json +208 -0
- package/vendor/ars/shared/contracts/passport/terminal_policies.schema.json +50 -0
- package/vendor/ars/shared/contracts/passport/timeline.schema.json +102 -0
- package/vendor/ars/shared/contracts/passport/uncited_assertion.schema.json +56 -0
- package/vendor/ars/shared/contracts/passport/uncited_audit_failure.schema.json +72 -0
- package/vendor/ars/shared/contracts/passport/user_attested_read_resolution.schema.json +87 -0
- package/vendor/ars/shared/contracts/passport/version_records.schema.json +138 -0
- package/vendor/ars/shared/contracts/patch/block_manifest.schema.json +45 -0
- package/vendor/ars/shared/contracts/patch/legacy/v1_0/revision_patch.schema.json +110 -0
- package/vendor/ars/shared/contracts/patch/revision_patch.schema.json +250 -0
- package/vendor/ars/shared/contracts/pdf/pdf_content_classifier_diagnostic.schema.json +39 -0
- package/vendor/ars/shared/contracts/pdf/pdf_content_classifier_worker.schema.json +88 -0
- package/vendor/ars/shared/contracts/pdf/pdf_read_preflight.schema.json +227 -0
- package/vendor/ars/shared/contracts/re_review/input_manifest.schema.json +161 -0
- package/vendor/ars/shared/contracts/re_review/legacy/v1_0/input_manifest.schema.json +134 -0
- package/vendor/ars/shared/contracts/re_review/legacy/v1_0/precommitment.schema.json +193 -0
- package/vendor/ars/shared/contracts/re_review/legacy/v1_0/traceability.schema.json +841 -0
- package/vendor/ars/shared/contracts/re_review/legacy/v1_0/verdict_record.schema.json +244 -0
- package/vendor/ars/shared/contracts/re_review/precommitment.schema.json +193 -0
- package/vendor/ars/shared/contracts/re_review/traceability.schema.json +916 -0
- package/vendor/ars/shared/contracts/re_review/verdict_record.schema.json +245 -0
- package/vendor/ars/shared/contracts/research_workflow/inquiry_branch_ledger.schema.json +449 -0
- package/vendor/ars/shared/contracts/research_workflow/research_workflow_profile.schema.json +222 -0
- package/vendor/ars/shared/contracts/research_workflow/research_workflow_profile_selection_receipt.schema.json +111 -0
- package/vendor/ars/shared/contracts/review_target/constructive_review_findings.schema.json +172 -0
- package/vendor/ars/shared/contracts/review_target/criteria_registry.schema.json +97 -0
- package/vendor/ars/shared/contracts/review_target/review_criteria_binding_manifest.schema.json +235 -0
- package/vendor/ars/shared/contracts/review_target/review_criteria_source_receipt.schema.json +158 -0
- package/vendor/ars/shared/contracts/review_target/review_target_context.schema.json +106 -0
- package/vendor/ars/shared/contracts/review_target/review_target_declaration.schema.json +118 -0
- package/vendor/ars/shared/contracts/reviewer/full.json +114 -0
- package/vendor/ars/shared/contracts/reviewer/methodology_focus.json +75 -0
- package/vendor/ars/shared/contracts/reviewer/review_panel_provenance.schema.json +263 -0
- package/vendor/ars/shared/contracts/reviewer/review_panel_provenance_carrier.schema.json +122 -0
- package/vendor/ars/shared/contracts/reviewer/review_panel_provenance_input.schema.json +120 -0
- package/vendor/ars/shared/contracts/revision/author_adjudication.schema.json +251 -0
- package/vendor/ars/shared/contracts/revision/author_adjudication_input.schema.json +25 -0
- package/vendor/ars/shared/contracts/revision/claim_strength_drift_disposition.schema.json +97 -0
- package/vendor/ars/shared/contracts/revision/claim_strength_drift_disposition_input.schema.json +80 -0
- package/vendor/ars/shared/contracts/revision/claim_strength_drift_findings.schema.json +139 -0
- package/vendor/ars/shared/contracts/revision/claim_surface_manifest.schema.json +99 -0
- package/vendor/ars/shared/contracts/revision/integrity_correction_authorization.schema.json +140 -0
- package/vendor/ars/shared/contracts/revision/integrity_correction_authorization_input.schema.json +28 -0
- package/vendor/ars/shared/contracts/revision/integrity_correction_list.schema.json +48 -0
- package/vendor/ars/shared/contracts/revision/integrity_pass_receipt.schema.json +16 -0
- package/vendor/ars/shared/contracts/revision/revision_evidence_bundle.schema.json +134 -0
- package/vendor/ars/shared/contracts/revision/revision_roadmap.schema.json +334 -0
- package/vendor/ars/shared/contracts/submission/format_profile.example.yaml +33 -0
- package/vendor/ars/shared/contracts/submission/format_profile.schema.json +102 -0
- package/vendor/ars/shared/contracts/submission/submission_verification_report.schema.json +233 -0
- package/vendor/ars/shared/contracts/submission/venue_profile.schema.json +114 -0
- package/vendor/ars/shared/contracts/writer/full.json +87 -0
- package/vendor/ars/shared/cross_model_verification.md +714 -0
- package/vendor/ars/shared/evals_lift_report.schema.json +141 -0
- package/vendor/ars/shared/ground_truth_isolation_pattern.md +275 -0
- package/vendor/ars/shared/handoff_schemas.md +1209 -0
- package/vendor/ars/shared/human_subjects_authority_registry.json +1278 -0
- package/vendor/ars/shared/mode_spectrum.md +57 -0
- package/vendor/ars/shared/model_tiering.md +83 -0
- package/vendor/ars/shared/policy_data/nature_policy.md +56 -0
- package/vendor/ars/shared/prisma_trAIce_protocol.md +157 -0
- package/vendor/ars/shared/raise_framework.md +129 -0
- package/vendor/ars/shared/references/authority_content_coverage_advisory_protocol.md +275 -0
- package/vendor/ars/shared/references/claim_standing_candidate_ledger_protocol.md +66 -0
- package/vendor/ars/shared/references/claim_strength_ladder.md +93 -0
- package/vendor/ars/shared/references/cross_document_consistency_advisory_protocol.md +263 -0
- package/vendor/ars/shared/references/evidence_row_protocol.md +260 -0
- package/vendor/ars/shared/references/firm_rules.md +90 -0
- package/vendor/ars/shared/references/human_subjects_authority_protocol.md +274 -0
- package/vendor/ars/shared/references/intent_clarification_protocol.md +168 -0
- package/vendor/ars/shared/references/irb_terminology_glossary.md +229 -0
- package/vendor/ars/shared/references/protected_hedging_phrases.md +118 -0
- package/vendor/ars/shared/references/psychometric_terminology_glossary.md +109 -0
- package/vendor/ars/shared/references/review_criteria_consumer_protocol.md +238 -0
- package/vendor/ars/shared/references/review_pathway_rule_trace_protocol.md +166 -0
- package/vendor/ars/shared/references/submission_packet_manifest_protocol.md +292 -0
- package/vendor/ars/shared/references/word_count_conventions.md +124 -0
- package/vendor/ars/shared/research_workflow_profiles/field_general.json +1 -0
- package/vendor/ars/shared/review_criteria_registry.json +207 -0
- package/vendor/ars/shared/review_criteria_sources/msr-2027-technical-papers.2026-08-24.json +46 -0
- package/vendor/ars/shared/review_criteria_sources/sigsoft-empirical-standards.2026-08-24.json +31 -0
- package/vendor/ars/shared/sprint_contract.schema.json +482 -0
- package/vendor/ars/shared/style_calibration_protocol.md +151 -0
- package/vendor/ars/shared/templates/codex_audit_multifile_template.md +263 -0
- package/vendor/ars/tools/release-discipline/.toolkit-version +1 -0
- package/vendor/ars/tools/release-discipline/README.md +4 -0
- package/vendor/ars/tools/release-discipline/scripts/_release_doc_alignment_schema.py +1011 -0
- package/vendor/ars/tools/release-discipline/scripts/check_command_invariants.py +497 -0
- package/vendor/ars/tools/release-discipline/scripts/check_release_doc_alignment.py +263 -0
- package/vendor/ars/tools/release-discipline/scripts/sync-toolkit.sh +147 -0
- package/vendor/windows/NOTICE.md +12 -0
- package/vendor/windows/arm64/fd.exe +0 -0
- package/vendor/windows/arm64/licenses/fd/LICENSE-APACHE +201 -0
- package/vendor/windows/arm64/licenses/fd/LICENSE-MIT +21 -0
- package/vendor/windows/arm64/licenses/ripgrep/COPYING +3 -0
- package/vendor/windows/arm64/licenses/ripgrep/LICENSE-MIT +21 -0
- package/vendor/windows/arm64/licenses/ripgrep/UNLICENSE +24 -0
- package/vendor/windows/arm64/rg.exe +0 -0
- package/vendor/windows/x64/fd.exe +0 -0
- package/vendor/windows/x64/licenses/fd/LICENSE-APACHE +201 -0
- package/vendor/windows/x64/licenses/fd/LICENSE-MIT +21 -0
- package/vendor/windows/x64/licenses/ripgrep/COPYING +3 -0
- package/vendor/windows/x64/licenses/ripgrep/LICENSE-MIT +21 -0
- package/vendor/windows/x64/licenses/ripgrep/UNLICENSE +24 -0
- package/vendor/windows/x64/rg.exe +0 -0
|
@@ -0,0 +1,1658 @@
|
|
|
1
|
+
"""Schema 13.2 panel checker tests, including exhaustive decision profiles."""
|
|
2
|
+
from __future__ import annotations
|
|
3
|
+
|
|
4
|
+
import itertools
|
|
5
|
+
import json
|
|
6
|
+
from pathlib import Path
|
|
7
|
+
|
|
8
|
+
import pytest
|
|
9
|
+
|
|
10
|
+
from scripts import check_panel_synthesis as cps
|
|
11
|
+
|
|
12
|
+
REPO = Path(__file__).resolve().parents[1]
|
|
13
|
+
FULL_PATH = REPO / "shared/contracts/reviewer/full.json"
|
|
14
|
+
MF_PATH = REPO / "shared/contracts/reviewer/methodology_focus.json"
|
|
15
|
+
FULL = json.loads(FULL_PATH.read_text(encoding="utf-8"))
|
|
16
|
+
ROLES = ("eic", "methodology", "domain", "perspective", "da")
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
@pytest.mark.parametrize(
|
|
20
|
+
"anchor",
|
|
21
|
+
(
|
|
22
|
+
"absence: x",
|
|
23
|
+
"absence: Methods — expected ethics;checked appendix",
|
|
24
|
+
"absence: Methods — expected ethics; checked appendix",
|
|
25
|
+
"absence: Methods — expected ; checked appendix — expected ethics; checked supplement",
|
|
26
|
+
"absence: Methods; checked appendix — expected ethics",
|
|
27
|
+
"equation: Eq. ]3[",
|
|
28
|
+
"absence: Methods — expected ethics; checked appendix]",
|
|
29
|
+
"[absence: Methods — expected ethics; checked appendix",
|
|
30
|
+
"text: §References, six DOI strings in list order",
|
|
31
|
+
'[ text: §5 "short exact quote" ]',
|
|
32
|
+
'` text: §5 "short exact quote" `',
|
|
33
|
+
'`text: §5 "short exact quote"',
|
|
34
|
+
'text: §5 "short exact quote"`',
|
|
35
|
+
'text: §5 "short exact quote"]',
|
|
36
|
+
'text: §5 "short exact quote"`]',
|
|
37
|
+
'[text: §5 "short exact quote"] trailing]',
|
|
38
|
+
'[[text: §5 "short exact quote"]]',
|
|
39
|
+
'``text: §5 "short exact quote"``',
|
|
40
|
+
'text: §5 "short exact quote”',
|
|
41
|
+
'text: §5 “short exact quote"',
|
|
42
|
+
'text: §5 "outer “inner”',
|
|
43
|
+
'text: §5 “outer "inner”"',
|
|
44
|
+
"text: §5 “outer “” tail”",
|
|
45
|
+
),
|
|
46
|
+
)
|
|
47
|
+
def test_shared_anchor_validator_rejects_incomplete_or_unpaired_shapes(anchor):
|
|
48
|
+
with pytest.raises(cps.ReportError, match="ANCHOR-INVALID"):
|
|
49
|
+
cps.validate_evidence_anchor(anchor, "probe")
|
|
50
|
+
|
|
51
|
+
|
|
52
|
+
@pytest.mark.parametrize(
|
|
53
|
+
"anchor",
|
|
54
|
+
(
|
|
55
|
+
"absence: Methods — expected an ethics statement; checked Methods, appendix",
|
|
56
|
+
'`text: §5 "short exact quote"`',
|
|
57
|
+
"text: §5 “short exact quote”",
|
|
58
|
+
"equation: Eq. [3]",
|
|
59
|
+
"table: Table 2 [Panel B]",
|
|
60
|
+
"[equation: Eq. [3]]",
|
|
61
|
+
'text: §4 "short quote" [emphasis added]',
|
|
62
|
+
'text: §3 "short quote" per `df`',
|
|
63
|
+
'`text: §3 "short quote" per `df``',
|
|
64
|
+
"text: §2 “the term “quality culture” is undefined”",
|
|
65
|
+
'text: §2 "he said “quality culture” often"',
|
|
66
|
+
),
|
|
67
|
+
)
|
|
68
|
+
def test_shared_anchor_validator_accepts_complete_paired_shapes(anchor):
|
|
69
|
+
cps.validate_evidence_anchor(anchor, "inverse")
|
|
70
|
+
|
|
71
|
+
|
|
72
|
+
def test_shared_anchor_validator_checks_nested_quote_word_limit_per_pair():
|
|
73
|
+
words_25 = " ".join(["word"] * 25)
|
|
74
|
+
words_26 = " ".join(["word"] * 26)
|
|
75
|
+
cps.validate_evidence_anchor(
|
|
76
|
+
f"text: §2 ““{words_25}””",
|
|
77
|
+
"nested-25-word-boundary",
|
|
78
|
+
)
|
|
79
|
+
with pytest.raises(cps.ReportError, match="at most 25 words"):
|
|
80
|
+
cps.validate_evidence_anchor(
|
|
81
|
+
f"text: §2 ““{words_26}””",
|
|
82
|
+
"nested-26-word-boundary",
|
|
83
|
+
)
|
|
84
|
+
outer_words = " ".join(["outer"] * 24)
|
|
85
|
+
with pytest.raises(cps.ReportError, match="at most 25 words"):
|
|
86
|
+
cps.validate_evidence_anchor(
|
|
87
|
+
f"text: §2 “{outer_words} “inner” tail”",
|
|
88
|
+
"nested-differential-outer-26-inner-1",
|
|
89
|
+
)
|
|
90
|
+
|
|
91
|
+
|
|
92
|
+
def state(value: str) -> cps.DimensionScore:
|
|
93
|
+
if value == "fatal":
|
|
94
|
+
return cps.DimensionScore("block", "fatal", "fatal trigger")
|
|
95
|
+
if value == "block":
|
|
96
|
+
return cps.DimensionScore("block", "repairable", "block trigger")
|
|
97
|
+
if value == "warn":
|
|
98
|
+
return cps.DimensionScore("warn", trigger="warn trigger")
|
|
99
|
+
if value == "abstain":
|
|
100
|
+
return cps.DimensionScore("not_assessed", abstain_reason="not applicable")
|
|
101
|
+
return cps.DimensionScore(value)
|
|
102
|
+
|
|
103
|
+
|
|
104
|
+
def report_text(role: str, overrides=None, da_ids=()) -> str:
|
|
105
|
+
overrides = overrides or {}
|
|
106
|
+
lines = [f"contract_role: {role}", "", "## Dimension Scores", ""]
|
|
107
|
+
for dim in FULL["acceptance_dimensions"]:
|
|
108
|
+
did = dim["id"]
|
|
109
|
+
lines.append(f"### {did}: {dim['name']}")
|
|
110
|
+
if role not in dim["eligible_roles"]:
|
|
111
|
+
lines.append("score: not_assessed")
|
|
112
|
+
else:
|
|
113
|
+
value = overrides.get(did, "pass")
|
|
114
|
+
if value == "warn":
|
|
115
|
+
lines += ["score: warn", 'trigger: "warn trigger"']
|
|
116
|
+
elif value == "block":
|
|
117
|
+
lines += [
|
|
118
|
+
"score: block", "block_class: repairable",
|
|
119
|
+
'trigger: "block trigger"',
|
|
120
|
+
]
|
|
121
|
+
elif value == "fatal":
|
|
122
|
+
lines += [
|
|
123
|
+
"score: block", "block_class: fatal",
|
|
124
|
+
'trigger: "fatal trigger"',
|
|
125
|
+
]
|
|
126
|
+
elif value == "abstain":
|
|
127
|
+
lines += [
|
|
128
|
+
"score: not_assessed",
|
|
129
|
+
"abstain_reason: materially inapplicable",
|
|
130
|
+
]
|
|
131
|
+
else:
|
|
132
|
+
lines.append("score: pass")
|
|
133
|
+
lines.append("")
|
|
134
|
+
lines += ["## Review Body", "", "No scored findings.", ""]
|
|
135
|
+
if role == "methodology":
|
|
136
|
+
# #610: a methodology card without its Arithmetic Receipts section
|
|
137
|
+
# stopped being phase-conformant; the synthesis parser itself
|
|
138
|
+
# tolerates the extra H2 either way.
|
|
139
|
+
lines += [
|
|
140
|
+
"## Arithmetic Receipts",
|
|
141
|
+
"",
|
|
142
|
+
"no_recomputable_statistics: the fixture manuscript reports no "
|
|
143
|
+
"statistic covered by a bounded procedure",
|
|
144
|
+
"",
|
|
145
|
+
]
|
|
146
|
+
if role == "da":
|
|
147
|
+
lines += [
|
|
148
|
+
"#### CRITICAL",
|
|
149
|
+
"| # | Issue | Evidence Anchor |",
|
|
150
|
+
"|---|-------|-----------------|",
|
|
151
|
+
]
|
|
152
|
+
for finding_id in da_ids:
|
|
153
|
+
lines.append(
|
|
154
|
+
f'| {finding_id} | Issue | text: "quoted evidence" p. 1 |'
|
|
155
|
+
)
|
|
156
|
+
lines += [
|
|
157
|
+
"",
|
|
158
|
+
"#### MAJOR",
|
|
159
|
+
"| # | Issue | Evidence Anchor |",
|
|
160
|
+
"|---|-------|-----------------|",
|
|
161
|
+
]
|
|
162
|
+
return "\n".join(lines)
|
|
163
|
+
|
|
164
|
+
|
|
165
|
+
def reports(overrides=None, da_ids=()):
|
|
166
|
+
overrides = overrides or {}
|
|
167
|
+
return [
|
|
168
|
+
cps.parse_report(
|
|
169
|
+
f"{role}.md",
|
|
170
|
+
report_text(role, overrides.get(role), da_ids if role == "da" else ()),
|
|
171
|
+
FULL,
|
|
172
|
+
)
|
|
173
|
+
for role in ROLES
|
|
174
|
+
]
|
|
175
|
+
|
|
176
|
+
|
|
177
|
+
def synthesis_for(
|
|
178
|
+
panel_reports, adjudications=None, decision_override=None,
|
|
179
|
+
marker_count=None, rationales=None,
|
|
180
|
+
):
|
|
181
|
+
contract, expressions = cps.load_contract(FULL_PATH)
|
|
182
|
+
assessed, fired, decision = cps.recompute_panel(
|
|
183
|
+
panel_reports, contract, expressions, []
|
|
184
|
+
)
|
|
185
|
+
verdicts = cps.compute_dimension_verdicts(assessed)
|
|
186
|
+
adjudications = adjudications or {}
|
|
187
|
+
rationales = rationales or {}
|
|
188
|
+
lines = [
|
|
189
|
+
"dimension_verdicts: [" + ", ".join(
|
|
190
|
+
f"{did}={value}" for did, value in verdicts.items()
|
|
191
|
+
) + "]",
|
|
192
|
+
"fired_conditions: [" + ", ".join(fired) + "]",
|
|
193
|
+
"da_critical_adjudications: [" + ", ".join(
|
|
194
|
+
f"{finding_id}={value}"
|
|
195
|
+
for finding_id, value in adjudications.items()
|
|
196
|
+
) + "]",
|
|
197
|
+
]
|
|
198
|
+
lines += [
|
|
199
|
+
f"{finding_id} rejection rationale: {text}"
|
|
200
|
+
for finding_id, text in rationales.items()
|
|
201
|
+
]
|
|
202
|
+
lines.append(decision_override or decision)
|
|
203
|
+
if marker_count is not None:
|
|
204
|
+
lines.append(
|
|
205
|
+
f"[DA-CRITICAL-VS-ACCEPT: {marker_count} validated/unresolved]"
|
|
206
|
+
)
|
|
207
|
+
return "\n".join(lines), expressions
|
|
208
|
+
|
|
209
|
+
|
|
210
|
+
def test_majority_n1_is_owner_decides():
|
|
211
|
+
assert cps.quantifier_fires("majority", [True], []) is True
|
|
212
|
+
assert cps.quantifier_fires("majority", [False], []) is False
|
|
213
|
+
|
|
214
|
+
|
|
215
|
+
def test_majority_n2_requires_both_eligible_seats():
|
|
216
|
+
assert cps.quantifier_fires("majority", [True, False], []) is False
|
|
217
|
+
assert cps.quantifier_fires("majority", [True, True], []) is True
|
|
218
|
+
|
|
219
|
+
|
|
220
|
+
@pytest.mark.parametrize(
|
|
221
|
+
"actions",
|
|
222
|
+
(
|
|
223
|
+
("editorial_decision=minor_revision", "editorial_decision=reject"),
|
|
224
|
+
("editorial_decision=reject", "editorial_decision=minor_revision"),
|
|
225
|
+
),
|
|
226
|
+
)
|
|
227
|
+
def test_equal_severity_tie_uses_earliest_condition(actions):
|
|
228
|
+
conditions = [
|
|
229
|
+
{"condition_id": "F1", "severity": 50, "action": actions[0]},
|
|
230
|
+
{"condition_id": "F2", "severity": 50, "action": actions[1]},
|
|
231
|
+
]
|
|
232
|
+
assert cps.resolve_decision(conditions, {"F1", "F2"}) == actions[0]
|
|
233
|
+
|
|
234
|
+
|
|
235
|
+
@pytest.mark.parametrize(
|
|
236
|
+
"expression",
|
|
237
|
+
[
|
|
238
|
+
"any mandatory dimension scores 'block'",
|
|
239
|
+
"two or more mandatory dimensions score 'warn' or worse",
|
|
240
|
+
"every mandatory dimension scores 'pass'",
|
|
241
|
+
"D1 scores 'block'",
|
|
242
|
+
"D1 scores 'warn' AND every high dimension scores 'pass'",
|
|
243
|
+
"any mandatory dimension has a fatal block",
|
|
244
|
+
"D1 has a fatal block",
|
|
245
|
+
"any dimension scores 'warn' or worse",
|
|
246
|
+
"D2 scores 'warn' or worse",
|
|
247
|
+
"every dimension scores 'pass'",
|
|
248
|
+
],
|
|
249
|
+
)
|
|
250
|
+
def test_expression_patterns_parse(expression):
|
|
251
|
+
dimensions = {d["id"]: d for d in FULL["acceptance_dimensions"]}
|
|
252
|
+
assert cps.parse_expression(expression, dimensions, "Fx")
|
|
253
|
+
|
|
254
|
+
|
|
255
|
+
@pytest.mark.parametrize(
|
|
256
|
+
"expression",
|
|
257
|
+
["some dimension fails", "D99 scores 'pass'",
|
|
258
|
+
"any high dimension has a fatal block", "D4 has a fatal block"],
|
|
259
|
+
)
|
|
260
|
+
def test_expression_fail_closed(expression):
|
|
261
|
+
dimensions = {d["id"]: d for d in FULL["acceptance_dimensions"]}
|
|
262
|
+
with pytest.raises(cps.ContractError):
|
|
263
|
+
cps.parse_expression(expression, dimensions, "Fx")
|
|
264
|
+
|
|
265
|
+
|
|
266
|
+
def test_parse_report_role_scope_and_structural_abstention():
|
|
267
|
+
report = cps.parse_report("eic.md", report_text("eic"), FULL)
|
|
268
|
+
assert report.scores["D1"].score == "not_assessed"
|
|
269
|
+
assert report.scores["D5"].score == "pass"
|
|
270
|
+
|
|
271
|
+
|
|
272
|
+
def test_out_of_role_real_score_rejected():
|
|
273
|
+
text = report_text("eic").replace(
|
|
274
|
+
"### D1: methodology_rigor\nscore: not_assessed",
|
|
275
|
+
"### D1: methodology_rigor\nscore: pass",
|
|
276
|
+
)
|
|
277
|
+
with pytest.raises(cps.ReportError, match="OUT-OF-ROLE"):
|
|
278
|
+
cps.parse_report("eic.md", text, FULL)
|
|
279
|
+
|
|
280
|
+
|
|
281
|
+
def test_eligible_abstention_requires_reason():
|
|
282
|
+
text = report_text("eic", {"D5": "abstain"}).replace(
|
|
283
|
+
"\nabstain_reason: materially inapplicable", "", 1
|
|
284
|
+
)
|
|
285
|
+
with pytest.raises(cps.ReportError, match="abstain_reason"):
|
|
286
|
+
cps.parse_report("eic.md", text, FULL)
|
|
287
|
+
|
|
288
|
+
|
|
289
|
+
def test_v1_sections_fail_loudly():
|
|
290
|
+
text = report_text("eic") + "\n## Failure Condition Checks\n"
|
|
291
|
+
with pytest.raises(cps.ReportError, match="V1-GRAMMAR-RETIRED"):
|
|
292
|
+
cps.parse_report("eic.md", text, FULL)
|
|
293
|
+
|
|
294
|
+
|
|
295
|
+
@pytest.mark.parametrize(
|
|
296
|
+
"action",
|
|
297
|
+
(
|
|
298
|
+
"reject", "Reject", "reject-or-major-revision", "unknown_v1_value",
|
|
299
|
+
"mixed_key_case",
|
|
300
|
+
),
|
|
301
|
+
)
|
|
302
|
+
def test_v1_bare_decision_line_fails_loudly(action):
|
|
303
|
+
key = "Editorial_Decision" if action == "mixed_key_case" else "editorial_decision"
|
|
304
|
+
text = report_text("eic") + f"\n{key}={action}\n"
|
|
305
|
+
with pytest.raises(cps.ReportError, match="V1-GRAMMAR-RETIRED"):
|
|
306
|
+
cps.parse_report("eic.md", text, FULL)
|
|
307
|
+
|
|
308
|
+
|
|
309
|
+
@pytest.mark.parametrize("indent", (" ", "\t"))
|
|
310
|
+
def test_indented_v1_bare_decision_line_fails_loudly(indent):
|
|
311
|
+
text = report_text("eic") + f"\n{indent}editorial_decision=accept\n"
|
|
312
|
+
with pytest.raises(cps.ReportError, match="V1-GRAMMAR-RETIRED"):
|
|
313
|
+
cps.parse_report("eic.md", text, FULL)
|
|
314
|
+
|
|
315
|
+
|
|
316
|
+
def test_fenced_v1_bare_decision_decoy_is_ignored():
|
|
317
|
+
text = (
|
|
318
|
+
report_text("eic")
|
|
319
|
+
+ "\n```text\neditorial_decision=Reject\n```\n"
|
|
320
|
+
)
|
|
321
|
+
cps.parse_report("eic.md", text, FULL)
|
|
322
|
+
|
|
323
|
+
|
|
324
|
+
@pytest.mark.parametrize("fence", ("```", "~~~"))
|
|
325
|
+
def test_malformed_fence_closer_does_not_expose_bare_decision(fence):
|
|
326
|
+
text = (
|
|
327
|
+
report_text("eic")
|
|
328
|
+
+ f"\n{fence}text\n{fence}not-a-close\n"
|
|
329
|
+
"editorial_decision=accept\n"
|
|
330
|
+
f"{fence}\n"
|
|
331
|
+
)
|
|
332
|
+
cps.parse_report("eic.md", text, FULL)
|
|
333
|
+
|
|
334
|
+
|
|
335
|
+
def test_malformed_fence_closer_keeps_reviewer_report_hidden():
|
|
336
|
+
text = "```text\n```not-a-close\n" + report_text("eic") + "\n```\n"
|
|
337
|
+
with pytest.raises(cps.ReportError, match="Dimension Scores"):
|
|
338
|
+
cps.parse_report("eic.md", text, FULL)
|
|
339
|
+
|
|
340
|
+
|
|
341
|
+
def test_malformed_fence_closer_synthesis_parses_as_fenced_content():
|
|
342
|
+
"""The fence never closes (`~~~not-a-close` is content, not a closer),
|
|
343
|
+
so the whole synthesis stays fenced — and fenced audit lines are
|
|
344
|
+
candidates since #637. Fence-STATE correctness stays pinned by the
|
|
345
|
+
parse_report twins above, whose grammars remain fence-blind."""
|
|
346
|
+
synthesis, _ = synthesis_for(reports())
|
|
347
|
+
text = "~~~text\n~~~not-a-close\n" + synthesis + "\n~~~\n"
|
|
348
|
+
parsed = cps.parse_synthesis("s.md", text, FULL)
|
|
349
|
+
assert parsed.decision == "editorial_decision=accept"
|
|
350
|
+
|
|
351
|
+
|
|
352
|
+
@pytest.mark.parametrize("separator", ("\x85", "\u2028", "\u2029"))
|
|
353
|
+
def test_unicode_separator_cannot_close_commonmark_fence(separator):
|
|
354
|
+
text = (
|
|
355
|
+
"```text\n```"
|
|
356
|
+
+ separator
|
|
357
|
+
+ report_text("methodology", {"D1": "fatal"})
|
|
358
|
+
+ "\n```\n"
|
|
359
|
+
)
|
|
360
|
+
with pytest.raises(cps.ReportError, match="Dimension Scores"):
|
|
361
|
+
cps.parse_report("hidden-methodology.md", text, FULL)
|
|
362
|
+
|
|
363
|
+
|
|
364
|
+
@pytest.mark.parametrize("separator", ("\x85", "\u2028", "\u2029"))
|
|
365
|
+
def test_unicode_separator_synthesis_parses_as_fenced_content(separator):
|
|
366
|
+
"""A Unicode separator is not a CommonMark line end: it can neither
|
|
367
|
+
close the fence nor split the line, so the glued `~~~<sep>note` stays
|
|
368
|
+
one content line. The rest of the synthesis is ordinary fenced content \u2014
|
|
369
|
+
a candidate since #637 \u2014 and parses."""
|
|
370
|
+
synthesis, _ = synthesis_for(reports())
|
|
371
|
+
text = "~~~text\n~~~" + separator + "note\n" + synthesis + "\n~~~\n"
|
|
372
|
+
parsed = cps.parse_synthesis("fenced-synthesis.md", text, FULL)
|
|
373
|
+
assert parsed.decision == "editorial_decision=accept"
|
|
374
|
+
|
|
375
|
+
|
|
376
|
+
def test_fenced_audit_block_parses_as_observed_in_637_cohort():
|
|
377
|
+
"""Every synthesis first attempt of the 2026-08-03 baseline cohort (6/6)
|
|
378
|
+
emitted the four audit lines inside a plain code fence."""
|
|
379
|
+
synthesis, _ = synthesis_for(reports())
|
|
380
|
+
parsed = cps.parse_synthesis(
|
|
381
|
+
"s.md", "```\n" + synthesis + "\n```\n", FULL
|
|
382
|
+
)
|
|
383
|
+
assert parsed.fired == ["F0"]
|
|
384
|
+
assert parsed.decision == "editorial_decision=accept"
|
|
385
|
+
|
|
386
|
+
|
|
387
|
+
def test_inline_code_wrapped_audit_lines_parse():
|
|
388
|
+
"""ms01_quant baseline r2's a2 retry wrapped each audit line whole in an
|
|
389
|
+
inline code span, defeating the line-anchored grammar (#637)."""
|
|
390
|
+
synthesis, _ = synthesis_for(reports())
|
|
391
|
+
text = "\n".join(f"`{line}`" for line in synthesis.split("\n"))
|
|
392
|
+
parsed = cps.parse_synthesis("s.md", text, FULL)
|
|
393
|
+
assert parsed.decision == "editorial_decision=accept"
|
|
394
|
+
|
|
395
|
+
|
|
396
|
+
def test_identical_duplicate_audit_lines_collapse():
|
|
397
|
+
"""A byte-identical re-statement (plain line plus its fenced copy) is
|
|
398
|
+
one candidate, not a duplicate abort."""
|
|
399
|
+
synthesis, _ = synthesis_for(reports())
|
|
400
|
+
fired_line = next(line for line in synthesis.split("\n")
|
|
401
|
+
if line.startswith("fired_conditions:"))
|
|
402
|
+
text = synthesis + "\n```\n" + fired_line + "\n```\n"
|
|
403
|
+
parsed = cps.parse_synthesis("s.md", text, FULL)
|
|
404
|
+
assert parsed.fired == ["F0"]
|
|
405
|
+
|
|
406
|
+
|
|
407
|
+
def test_conflicting_fenced_audit_line_still_aborts():
|
|
408
|
+
"""A fenced decoy that disagrees with the operative line stays a loud
|
|
409
|
+
abort \u2014 tolerance collapses identical values only."""
|
|
410
|
+
synthesis, _ = synthesis_for(reports())
|
|
411
|
+
text = synthesis + "\n```\nfired_conditions: [F1]\n```\n"
|
|
412
|
+
with pytest.raises(cps.SynthesisError, match="found 2"):
|
|
413
|
+
cps.parse_synthesis("s.md", text, FULL)
|
|
414
|
+
|
|
415
|
+
|
|
416
|
+
def test_prose_quoted_checker_diagnostic_is_not_a_candidate():
|
|
417
|
+
"""The a2 remediation notes of the #637 cohort quote the checker error
|
|
418
|
+
inside longer prose lines; anchored grammars must not see those."""
|
|
419
|
+
synthesis, _ = synthesis_for(reports())
|
|
420
|
+
note = (
|
|
421
|
+
"**Checker remediation:** the prior emission failed "
|
|
422
|
+
"`[SYNTHESIS-PARSE: expected exactly one fired_conditions line, "
|
|
423
|
+
"found 0]` and the canonical block is re-emitted plainly above."
|
|
424
|
+
)
|
|
425
|
+
parsed = cps.parse_synthesis(
|
|
426
|
+
"s.md", synthesis + "\n" + note + "\n", FULL
|
|
427
|
+
)
|
|
428
|
+
assert parsed.fired == ["F0"]
|
|
429
|
+
|
|
430
|
+
|
|
431
|
+
def test_blockquoted_audit_line_documents_an_accepted_miss():
|
|
432
|
+
"""Documents an ACCEPTED miss: a blockquoted audit line renders as
|
|
433
|
+
quotation and is deliberately not a candidate. Change deliberately."""
|
|
434
|
+
synthesis, _ = synthesis_for(reports())
|
|
435
|
+
text = synthesis.replace("fired_conditions:", "> fired_conditions:", 1)
|
|
436
|
+
with pytest.raises(cps.SynthesisError, match="fired_conditions"):
|
|
437
|
+
cps.parse_synthesis("s.md", text, FULL)
|
|
438
|
+
|
|
439
|
+
|
|
440
|
+
def test_inline_span_inside_fence_documents_an_accepted_miss():
|
|
441
|
+
"""Documents an ACCEPTED miss: backticks inside a fence are literal
|
|
442
|
+
rendered content, so a wrapped line there is not unwrapped. Change
|
|
443
|
+
deliberately."""
|
|
444
|
+
synthesis, _ = synthesis_for(reports())
|
|
445
|
+
fenced = "\n".join(f"`{line}`" for line in synthesis.split("\n"))
|
|
446
|
+
with pytest.raises(cps.SynthesisError, match="fired_conditions"):
|
|
447
|
+
cps.parse_synthesis("s.md", "```\n" + fenced + "\n```\n", FULL)
|
|
448
|
+
|
|
449
|
+
|
|
450
|
+
def test_fenced_rationale_and_marker_document_an_accepted_miss():
|
|
451
|
+
"""Documents an ACCEPTED miss: rationales and the DA marker keep the
|
|
452
|
+
plain-line source \u2014 their fenced occurrences read as quotation. Change
|
|
453
|
+
deliberately."""
|
|
454
|
+
synthesis, _ = synthesis_for(reports())
|
|
455
|
+
text = (
|
|
456
|
+
synthesis
|
|
457
|
+
+ "\n```\nC9 rejection rationale: quoted example\n"
|
|
458
|
+
"[DA-CRITICAL-VS-ACCEPT: 2 validated/unresolved]\n```\n"
|
|
459
|
+
)
|
|
460
|
+
parsed = cps.parse_synthesis("s.md", text, FULL)
|
|
461
|
+
assert "C9" not in parsed.rejection_rationales
|
|
462
|
+
assert parsed.marker_count is None
|
|
463
|
+
# The forbidden-marker asymmetry is part of the same accepted boundary:
|
|
464
|
+
# with no active DA-critical adjudications a stated marker is forbidden,
|
|
465
|
+
# and this fenced one stays invisible rather than aborting — the
|
|
466
|
+
# decision channel is pinned independently by the layer-2 recompute.
|
|
467
|
+
assert not any(
|
|
468
|
+
"marker forbidden" in diag
|
|
469
|
+
for diag in cps.check_da_terminal_gate(reports(), parsed)
|
|
470
|
+
)
|
|
471
|
+
|
|
472
|
+
|
|
473
|
+
def test_padded_inline_code_wrapped_audit_lines_parse():
|
|
474
|
+
"""CommonMark renders `` ` body ` `` with one padding space stripped
|
|
475
|
+
from each side, so a padded span displays the audit line verbatim and
|
|
476
|
+
must be a candidate in its DISPLAYED form."""
|
|
477
|
+
synthesis, _ = synthesis_for(reports())
|
|
478
|
+
text = "\n".join(f"` {line} `" for line in synthesis.split("\n"))
|
|
479
|
+
parsed = cps.parse_synthesis("s.md", text, FULL)
|
|
480
|
+
assert parsed.decision == "editorial_decision=accept"
|
|
481
|
+
|
|
482
|
+
|
|
483
|
+
def test_padded_span_conflicting_value_still_aborts():
|
|
484
|
+
"""Rendering normalization must not weaken the distinct-value guard: a
|
|
485
|
+
padded-span decoy that disagrees with the operative line still aborts."""
|
|
486
|
+
synthesis, _ = synthesis_for(reports())
|
|
487
|
+
text = synthesis + "\n` fired_conditions: [F1] `\n"
|
|
488
|
+
with pytest.raises(cps.SynthesisError, match="found 2"):
|
|
489
|
+
cps.parse_synthesis("s.md", text, FULL)
|
|
490
|
+
|
|
491
|
+
|
|
492
|
+
def test_all_space_span_body_is_not_stripped():
|
|
493
|
+
"""CommonMark strips padding only when the body is not all spaces; an
|
|
494
|
+
all-space span stays as-is and is simply a non-candidate."""
|
|
495
|
+
synthesis, _ = synthesis_for(reports())
|
|
496
|
+
parsed = cps.parse_synthesis(
|
|
497
|
+
"s.md", synthesis + "\n` `\n", FULL
|
|
498
|
+
)
|
|
499
|
+
assert parsed.decision == "editorial_decision=accept"
|
|
500
|
+
|
|
501
|
+
|
|
502
|
+
def test_indented_fence_content_parses_dedented():
|
|
503
|
+
"""A fence opened with up to 3 leading spaces renders its content
|
|
504
|
+
dedented by the opener's indent, so indented fenced audit lines are
|
|
505
|
+
candidates in their displayed (dedented) form."""
|
|
506
|
+
synthesis, _ = synthesis_for(reports())
|
|
507
|
+
indented = "\n".join(" " + line for line in synthesis.split("\n"))
|
|
508
|
+
text = " ```\n" + indented + "\n ```\n"
|
|
509
|
+
parsed = cps.parse_synthesis("s.md", text, FULL)
|
|
510
|
+
assert parsed.decision == "editorial_decision=accept"
|
|
511
|
+
|
|
512
|
+
|
|
513
|
+
def test_crlf_fenced_audit_block_parses():
|
|
514
|
+
"""CRLF line endings are CommonMark line ends; the fenced audit block
|
|
515
|
+
parses identically under them."""
|
|
516
|
+
synthesis, _ = synthesis_for(reports())
|
|
517
|
+
text = ("```\n" + synthesis + "\n```\n").replace("\n", "\r\n")
|
|
518
|
+
parsed = cps.parse_synthesis("s.md", text, FULL)
|
|
519
|
+
assert parsed.decision == "editorial_decision=accept"
|
|
520
|
+
|
|
521
|
+
|
|
522
|
+
def test_malformed_closer_fence_state_pins_wrapped_decoy_hidden():
|
|
523
|
+
"""Pins fence STATE through the candidate walker: `~~~not-a-close` does
|
|
524
|
+
not close the fence, so a wrapped decoy after it is fenced — backticks
|
|
525
|
+
render literally, the decoy is never unwrapped, and the plain synthesis
|
|
526
|
+
before the fence parses. A mutation that accepts the malformed closer
|
|
527
|
+
unwraps the decoy and flips this to a found-2 abort."""
|
|
528
|
+
synthesis, _ = synthesis_for(reports())
|
|
529
|
+
text = (
|
|
530
|
+
synthesis
|
|
531
|
+
+ "\n~~~text\n~~~not-a-close\n`fired_conditions: [F1]`\n~~~\n"
|
|
532
|
+
)
|
|
533
|
+
parsed = cps.parse_synthesis("s.md", text, FULL)
|
|
534
|
+
assert parsed.fired == ["F0"]
|
|
535
|
+
|
|
536
|
+
|
|
537
|
+
def test_short_closer_fence_state_pins_wrapped_decoy_hidden():
|
|
538
|
+
"""A prospective closer shorter than the opener does not close the
|
|
539
|
+
fence (CommonMark length rule), so the wrapped decoy after it stays
|
|
540
|
+
fenced and hidden."""
|
|
541
|
+
synthesis, _ = synthesis_for(reports())
|
|
542
|
+
text = (
|
|
543
|
+
synthesis
|
|
544
|
+
+ "\n````\n```\n`fired_conditions: [F1]`\n````\n"
|
|
545
|
+
)
|
|
546
|
+
parsed = cps.parse_synthesis("s.md", text, FULL)
|
|
547
|
+
assert parsed.fired == ["F0"]
|
|
548
|
+
|
|
549
|
+
|
|
550
|
+
def test_mismatched_closer_fence_state_pins_wrapped_decoy_hidden():
|
|
551
|
+
"""A backtick closer cannot close a tilde fence; the wrapped decoy
|
|
552
|
+
after it stays fenced and hidden."""
|
|
553
|
+
synthesis, _ = synthesis_for(reports())
|
|
554
|
+
text = (
|
|
555
|
+
synthesis
|
|
556
|
+
+ "\n~~~\n```\n`fired_conditions: [F1]`\n~~~\n"
|
|
557
|
+
)
|
|
558
|
+
parsed = cps.parse_synthesis("s.md", text, FULL)
|
|
559
|
+
assert parsed.fired == ["F0"]
|
|
560
|
+
|
|
561
|
+
|
|
562
|
+
@pytest.mark.parametrize("separator", ("\x85", "\u2028", "\u2029"))
|
|
563
|
+
def test_unicode_separator_fence_state_pins_wrapped_decoy_hidden(separator):
|
|
564
|
+
"""A Unicode separator is not a CommonMark line end: `~~~<sep>note`
|
|
565
|
+
stays one content line and cannot close the fence, so the wrapped
|
|
566
|
+
decoy after it stays fenced and hidden. A mutation that splits on the
|
|
567
|
+
separator closes the fence and flips this to a found-2 abort."""
|
|
568
|
+
synthesis, _ = synthesis_for(reports())
|
|
569
|
+
text = (
|
|
570
|
+
synthesis
|
|
571
|
+
+ "\n~~~text\n~~~" + separator + "note\n"
|
|
572
|
+
"`fired_conditions: [F1]`\n~~~\n"
|
|
573
|
+
)
|
|
574
|
+
parsed = cps.parse_synthesis("s.md", text, FULL)
|
|
575
|
+
assert parsed.fired == ["F0"]
|
|
576
|
+
|
|
577
|
+
|
|
578
|
+
def test_unterminated_fence_content_stays_candidate():
|
|
579
|
+
"""An unterminated fence retains (not grows) its content, and fenced
|
|
580
|
+
audit lines remain candidates to end-of-input."""
|
|
581
|
+
synthesis, _ = synthesis_for(reports())
|
|
582
|
+
parsed = cps.parse_synthesis("s.md", "```\n" + synthesis, FULL)
|
|
583
|
+
assert parsed.decision == "editorial_decision=accept"
|
|
584
|
+
|
|
585
|
+
|
|
586
|
+
@pytest.mark.parametrize("score", ("warn", "block"))
|
|
587
|
+
def test_eligible_nonpass_score_requires_trigger(score):
|
|
588
|
+
text = report_text("methodology", {"D1": score}).replace(
|
|
589
|
+
f'trigger: "{score} trigger"\n', "", 1
|
|
590
|
+
)
|
|
591
|
+
with pytest.raises(cps.ReportError, match="TRIGGER-GRAMMAR"):
|
|
592
|
+
cps.parse_report("methodology.md", text, FULL)
|
|
593
|
+
|
|
594
|
+
|
|
595
|
+
@pytest.mark.parametrize(
|
|
596
|
+
"role,did,score_line",
|
|
597
|
+
(
|
|
598
|
+
("methodology", "D1", "score: pass"),
|
|
599
|
+
("eic", "D1", "score: not_assessed"),
|
|
600
|
+
),
|
|
601
|
+
)
|
|
602
|
+
def test_nontriggering_score_forbids_trigger(role, did, score_line):
|
|
603
|
+
text = report_text(role).replace(
|
|
604
|
+
f"### {did}:", f'### {did}:', 1
|
|
605
|
+
).replace(
|
|
606
|
+
score_line, score_line + '\ntrigger: "post hoc trigger"', 1
|
|
607
|
+
)
|
|
608
|
+
with pytest.raises(cps.ReportError, match="TRIGGER-GRAMMAR"):
|
|
609
|
+
cps.parse_report(f"{role}.md", text, FULL)
|
|
610
|
+
|
|
611
|
+
|
|
612
|
+
def test_nonmandatory_block_cannot_carry_block_class():
|
|
613
|
+
text = report_text("perspective", {"D4": "pass"}).replace(
|
|
614
|
+
"### D4: cross_disciplinary_relevance\nscore: pass",
|
|
615
|
+
"### D4: cross_disciplinary_relevance\nscore: block\n"
|
|
616
|
+
"block_class: repairable\ntrigger: \"block trigger\"",
|
|
617
|
+
)
|
|
618
|
+
with pytest.raises(cps.ReportError, match="BLOCK-CLASS"):
|
|
619
|
+
cps.parse_report("p.md", text, FULL)
|
|
620
|
+
|
|
621
|
+
|
|
622
|
+
def test_denominator_excludes_ineligible_seats():
|
|
623
|
+
panel_reports = reports({"methodology": {"D1": "warn"}})
|
|
624
|
+
_, expressions = cps.load_contract(FULL_PATH)
|
|
625
|
+
_, fired, decision = cps.recompute_panel(
|
|
626
|
+
panel_reports, FULL, expressions, []
|
|
627
|
+
)
|
|
628
|
+
assert "F5" in fired
|
|
629
|
+
assert decision == "editorial_decision=minor_revision"
|
|
630
|
+
|
|
631
|
+
|
|
632
|
+
def test_denominator_exclusion_ignores_decision_flipping_ineligible_score():
|
|
633
|
+
panel_reports = reports()
|
|
634
|
+
eic_report = next(report for report in panel_reports if report.role == "eic")
|
|
635
|
+
eic_report.scores["D1"] = state("fatal")
|
|
636
|
+
contract, expressions = cps.load_contract(FULL_PATH)
|
|
637
|
+
assessed, fired, decision = cps.recompute_panel(
|
|
638
|
+
panel_reports, contract, expressions, []
|
|
639
|
+
)
|
|
640
|
+
assert len(assessed["D1"]) == 1
|
|
641
|
+
assert assessed["D1"][0].score == "pass"
|
|
642
|
+
assert fired == ["F0"]
|
|
643
|
+
assert decision == "editorial_decision=accept"
|
|
644
|
+
|
|
645
|
+
|
|
646
|
+
def test_roles_cross_check_rejects_dispatch_role_swap(tmp_path, capsys):
|
|
647
|
+
report_path = tmp_path / "eic.md"
|
|
648
|
+
report_path.write_text(report_text("eic"), encoding="utf-8")
|
|
649
|
+
result = cps.main([
|
|
650
|
+
"--contract", str(FULL_PATH),
|
|
651
|
+
"--report", str(report_path),
|
|
652
|
+
"--roles", "methodology",
|
|
653
|
+
"--layer1-only",
|
|
654
|
+
])
|
|
655
|
+
assert result == cps.EXIT_REVIEWER
|
|
656
|
+
assert "[ROLE-BINDING:" in capsys.readouterr().out
|
|
657
|
+
|
|
658
|
+
|
|
659
|
+
def test_roles_cross_check_accepts_matching_dispatch_role(tmp_path, capsys):
|
|
660
|
+
report_path = tmp_path / "eic.md"
|
|
661
|
+
report_path.write_text(report_text("eic"), encoding="utf-8")
|
|
662
|
+
result = cps.main([
|
|
663
|
+
"--contract", str(FULL_PATH),
|
|
664
|
+
"--report", str(report_path),
|
|
665
|
+
"--roles", "eic",
|
|
666
|
+
"--layer1-only",
|
|
667
|
+
])
|
|
668
|
+
assert result == cps.EXIT_PASS
|
|
669
|
+
assert "LAYER1-ONLY: PASS" in capsys.readouterr().out
|
|
670
|
+
|
|
671
|
+
|
|
672
|
+
def test_dimension_unassessed_aborts():
|
|
673
|
+
panel_reports = reports({
|
|
674
|
+
"methodology": {"D3": "abstain"},
|
|
675
|
+
"da": {"D3": "abstain"},
|
|
676
|
+
})
|
|
677
|
+
_, expressions = cps.load_contract(FULL_PATH)
|
|
678
|
+
with pytest.raises(cps.ContractError, match="DIMENSION-UNASSESSED: D3"):
|
|
679
|
+
cps.recompute_panel(panel_reports, FULL, expressions, [])
|
|
680
|
+
|
|
681
|
+
|
|
682
|
+
def test_dimension_verdict_mismatch_is_synthesis_failure():
|
|
683
|
+
panel_reports = reports()
|
|
684
|
+
text, expressions = synthesis_for(panel_reports)
|
|
685
|
+
text = text.replace("D1=pass", "D1=warn")
|
|
686
|
+
synthesis = cps.parse_synthesis("s.md", text, FULL)
|
|
687
|
+
assert any("PANEL-SYNTHESIS-MISMATCH" in item for item in
|
|
688
|
+
cps.layer2_check(panel_reports, FULL, expressions, synthesis, []))
|
|
689
|
+
|
|
690
|
+
|
|
691
|
+
def test_fatal_precedence_over_repairable():
|
|
692
|
+
panel_reports = reports({
|
|
693
|
+
"methodology": {"D1": "fatal"},
|
|
694
|
+
"domain": {"D2": "block"},
|
|
695
|
+
})
|
|
696
|
+
text, expressions = synthesis_for(panel_reports)
|
|
697
|
+
synthesis = cps.parse_synthesis("s.md", text, FULL)
|
|
698
|
+
assert synthesis.fired[:2] == ["F1", "F2"]
|
|
699
|
+
assert synthesis.decision == "editorial_decision=reject"
|
|
700
|
+
assert cps.layer2_check(panel_reports, FULL, expressions, synthesis, []) == []
|
|
701
|
+
|
|
702
|
+
|
|
703
|
+
@pytest.mark.parametrize("adjudication", ["VALIDATED", "UNRESOLVED"])
|
|
704
|
+
def test_da_accept_conflict_requires_counted_marker(adjudication):
|
|
705
|
+
panel_reports = reports(da_ids=("C1",))
|
|
706
|
+
text, expressions = synthesis_for(
|
|
707
|
+
panel_reports, {"C1": adjudication}, marker_count=1
|
|
708
|
+
)
|
|
709
|
+
synthesis = cps.parse_synthesis("s.md", text, FULL)
|
|
710
|
+
assert cps.layer2_check(panel_reports, FULL, expressions, synthesis, []) == []
|
|
711
|
+
missing = cps.parse_synthesis(
|
|
712
|
+
"s.md", text.replace(
|
|
713
|
+
"\n[DA-CRITICAL-VS-ACCEPT: 1 validated/unresolved]", ""
|
|
714
|
+
), FULL
|
|
715
|
+
)
|
|
716
|
+
assert any("MARKER" in item for item in
|
|
717
|
+
cps.layer2_check(panel_reports, FULL, expressions, missing, []))
|
|
718
|
+
|
|
719
|
+
|
|
720
|
+
def test_da_rejected_with_rationale_accepts_without_marker():
|
|
721
|
+
panel_reports = reports(da_ids=("C1",))
|
|
722
|
+
text, expressions = synthesis_for(
|
|
723
|
+
panel_reports,
|
|
724
|
+
{"C1": "REJECTED"},
|
|
725
|
+
rationales={"C1": "The quoted sentence does not support the claim."},
|
|
726
|
+
)
|
|
727
|
+
synthesis = cps.parse_synthesis("s.md", text, FULL)
|
|
728
|
+
assert cps.layer2_check(panel_reports, FULL, expressions, synthesis, []) == []
|
|
729
|
+
|
|
730
|
+
|
|
731
|
+
@pytest.mark.parametrize(
|
|
732
|
+
"adjudications,rationales,marker,fragment",
|
|
733
|
+
[
|
|
734
|
+
({}, {}, None, "MISMATCH"), # omitted C1
|
|
735
|
+
({"C1": "REJECTED", "C3": "VALIDATED"},
|
|
736
|
+
{"C1": "rationale"}, 1, "MISMATCH"), # phantom C3
|
|
737
|
+
({"C1": "REJECTED"}, {}, None, "RATIONALE"),
|
|
738
|
+
({"C1": "VALIDATED"}, {}, 2, "MARKER"),
|
|
739
|
+
],
|
|
740
|
+
)
|
|
741
|
+
def test_da_gate_negative_fixtures(
|
|
742
|
+
adjudications, rationales, marker, fragment
|
|
743
|
+
):
|
|
744
|
+
panel_reports = reports(da_ids=("C1",))
|
|
745
|
+
text, expressions = synthesis_for(
|
|
746
|
+
panel_reports, adjudications, marker_count=marker,
|
|
747
|
+
rationales=rationales,
|
|
748
|
+
)
|
|
749
|
+
synthesis = cps.parse_synthesis("s.md", text, FULL)
|
|
750
|
+
assert any(fragment in item for item in
|
|
751
|
+
cps.layer2_check(panel_reports, FULL, expressions, synthesis, []))
|
|
752
|
+
|
|
753
|
+
|
|
754
|
+
@pytest.mark.parametrize(
|
|
755
|
+
"mutation",
|
|
756
|
+
[
|
|
757
|
+
lambda text: text.replace("#### CRITICAL", "#### Critical", 1),
|
|
758
|
+
lambda text: text.replace("#### CRITICAL", "#### CRITICAL ISSUES", 1),
|
|
759
|
+
lambda text: text.replace(
|
|
760
|
+
"#### CRITICAL",
|
|
761
|
+
"#### CRITICAL\n"
|
|
762
|
+
"| # | Issue | Evidence Anchor |\n"
|
|
763
|
+
"|---|-------|-----------------|\n\n"
|
|
764
|
+
"#### CRITICAL",
|
|
765
|
+
1,
|
|
766
|
+
),
|
|
767
|
+
],
|
|
768
|
+
)
|
|
769
|
+
def test_da_critical_section_drift_fails_closed(mutation):
|
|
770
|
+
da_report = next(report for report in reports() if report.role == "da")
|
|
771
|
+
with pytest.raises(cps.ReportError, match="exactly one #### CRITICAL"):
|
|
772
|
+
cps.parse_da_critical_table(mutation(da_report.text), da_report.path)
|
|
773
|
+
|
|
774
|
+
|
|
775
|
+
@pytest.mark.parametrize(
|
|
776
|
+
"mutation",
|
|
777
|
+
[
|
|
778
|
+
lambda text: text.replace("#### MAJOR", "#### Major", 1),
|
|
779
|
+
lambda text: text.replace("#### MAJOR", "", 1),
|
|
780
|
+
lambda text: text.replace(
|
|
781
|
+
"#### MAJOR",
|
|
782
|
+
"#### MAJOR\n"
|
|
783
|
+
"| # | Issue | Evidence Anchor |\n"
|
|
784
|
+
"|---|-------|-----------------|\n\n"
|
|
785
|
+
"#### MAJOR",
|
|
786
|
+
1,
|
|
787
|
+
),
|
|
788
|
+
],
|
|
789
|
+
)
|
|
790
|
+
def test_da_major_section_drift_fails_in_synthesis_path(mutation):
|
|
791
|
+
panel_reports = reports()
|
|
792
|
+
da_report = next(report for report in panel_reports if report.role == "da")
|
|
793
|
+
da_report.text = mutation(da_report.text)
|
|
794
|
+
text, expressions = synthesis_for(panel_reports)
|
|
795
|
+
synthesis = cps.parse_synthesis("s.md", text, FULL)
|
|
796
|
+
with pytest.raises(cps.ReportError, match="DA-MAJOR-PARSE"):
|
|
797
|
+
cps.layer2_check(panel_reports, FULL, expressions, synthesis, [])
|
|
798
|
+
|
|
799
|
+
|
|
800
|
+
@pytest.mark.parametrize(
|
|
801
|
+
"old,new",
|
|
802
|
+
[
|
|
803
|
+
("|---|-------|-----------------|", ""),
|
|
804
|
+
("|---|-------|-----------------|", "|--|-------|-----------------|"),
|
|
805
|
+
("|---|-------|-----------------|", "|---|-------|"),
|
|
806
|
+
],
|
|
807
|
+
)
|
|
808
|
+
def test_da_separator_drift_fails_in_synthesis_path(old, new):
|
|
809
|
+
panel_reports = reports(da_ids=("C1",))
|
|
810
|
+
da_report = next(report for report in panel_reports if report.role == "da")
|
|
811
|
+
da_report.text = da_report.text.replace(old, new, 1)
|
|
812
|
+
text, expressions = synthesis_for(
|
|
813
|
+
panel_reports, {"C1": "VALIDATED"}, marker_count=1
|
|
814
|
+
)
|
|
815
|
+
synthesis = cps.parse_synthesis("s.md", text, FULL)
|
|
816
|
+
with pytest.raises(cps.ReportError, match="separator"):
|
|
817
|
+
cps.layer2_check(panel_reports, FULL, expressions, synthesis, [])
|
|
818
|
+
|
|
819
|
+
|
|
820
|
+
def test_da_trailing_row_without_outer_pipes_fails_in_synthesis_path():
|
|
821
|
+
panel_reports = reports(da_ids=("C1", "C2"))
|
|
822
|
+
da_report = next(report for report in panel_reports if report.role == "da")
|
|
823
|
+
da_report.text = da_report.text.replace(
|
|
824
|
+
'| C2 | Issue | text: "quoted evidence" p. 1 |',
|
|
825
|
+
'C2 | Issue | text: "quoted evidence" p. 1',
|
|
826
|
+
1,
|
|
827
|
+
)
|
|
828
|
+
synthesis_text, expressions = synthesis_for(
|
|
829
|
+
panel_reports, {"C1": "VALIDATED", "C2": "VALIDATED"}, marker_count=2
|
|
830
|
+
)
|
|
831
|
+
synthesis = cps.parse_synthesis("s.md", synthesis_text, FULL)
|
|
832
|
+
with pytest.raises(cps.ReportError, match="outer-pipe-delimited"):
|
|
833
|
+
cps.layer2_check(panel_reports, FULL, expressions, synthesis, [])
|
|
834
|
+
|
|
835
|
+
|
|
836
|
+
def test_da_pre_table_prose_passes_in_synthesis_path():
|
|
837
|
+
panel_reports = reports(da_ids=("C1",))
|
|
838
|
+
da_report = next(report for report in panel_reports if report.role == "da")
|
|
839
|
+
da_report.text = da_report.text.replace(
|
|
840
|
+
"#### CRITICAL",
|
|
841
|
+
"Ordinary adversarial commentary precedes the terminal tables.\n\n"
|
|
842
|
+
"#### CRITICAL",
|
|
843
|
+
1,
|
|
844
|
+
)
|
|
845
|
+
synthesis_text, expressions = synthesis_for(
|
|
846
|
+
panel_reports, {"C1": "VALIDATED"}, marker_count=1
|
|
847
|
+
)
|
|
848
|
+
synthesis = cps.parse_synthesis("s.md", synthesis_text, FULL)
|
|
849
|
+
assert cps.layer2_check(
|
|
850
|
+
panel_reports, FULL, expressions, synthesis, []
|
|
851
|
+
) == []
|
|
852
|
+
|
|
853
|
+
|
|
854
|
+
def test_da_bare_comment_closer_passes_in_synthesis_path():
|
|
855
|
+
panel_reports = reports(da_ids=("C1",))
|
|
856
|
+
da_report = next(report for report in panel_reports if report.role == "da")
|
|
857
|
+
da_report.text = da_report.text.replace(
|
|
858
|
+
"#### CRITICAL",
|
|
859
|
+
"The reported N moves 41 --> 38 without explanation.\n\n"
|
|
860
|
+
"#### CRITICAL",
|
|
861
|
+
1,
|
|
862
|
+
).replace(
|
|
863
|
+
'text: "quoted evidence" p. 1',
|
|
864
|
+
'text: "N moves 41 --> 38" p. 1',
|
|
865
|
+
1,
|
|
866
|
+
)
|
|
867
|
+
synthesis_text, expressions = synthesis_for(
|
|
868
|
+
panel_reports, {"C1": "VALIDATED"}, marker_count=1
|
|
869
|
+
)
|
|
870
|
+
synthesis = cps.parse_synthesis("s.md", synthesis_text, FULL)
|
|
871
|
+
assert cps.layer2_check(
|
|
872
|
+
panel_reports, FULL, expressions, synthesis, []
|
|
873
|
+
) == []
|
|
874
|
+
|
|
875
|
+
|
|
876
|
+
def test_da_post_critical_table_prose_fails_in_synthesis_path():
|
|
877
|
+
panel_reports = reports()
|
|
878
|
+
da_report = next(report for report in panel_reports if report.role == "da")
|
|
879
|
+
da_report.text = da_report.text.replace(
|
|
880
|
+
"\n\n#### MAJOR",
|
|
881
|
+
"\n\n*None. Ordinary adversarial commentary.*\n\n#### MAJOR",
|
|
882
|
+
1,
|
|
883
|
+
)
|
|
884
|
+
synthesis_text, expressions = synthesis_for(panel_reports)
|
|
885
|
+
synthesis = cps.parse_synthesis("s.md", synthesis_text, FULL)
|
|
886
|
+
with pytest.raises(cps.ReportError, match="issue tables are terminal"):
|
|
887
|
+
cps.layer2_check(panel_reports, FULL, expressions, synthesis, [])
|
|
888
|
+
|
|
889
|
+
|
|
890
|
+
_DA_TERMINAL_LATE_SURFACES = (
|
|
891
|
+
'| C2 | Late issue | text: "late quoted evidence" p. 2 |',
|
|
892
|
+
"| X9 | Bogus issue | |",
|
|
893
|
+
(
|
|
894
|
+
"| # | Issue | Evidence Anchor |\n"
|
|
895
|
+
"|---|-------|-----------------|\n"
|
|
896
|
+
"| C9 | Shadow issue | |"
|
|
897
|
+
),
|
|
898
|
+
'C2 | Late issue | text: "late quoted evidence" p. 2',
|
|
899
|
+
'— | Late issue | text: "late quoted evidence"',
|
|
900
|
+
"# | Issue | Evidence Anchor",
|
|
901
|
+
"C2\nLate issue without pipes\nfigure: Figure 2",
|
|
902
|
+
"- C2\n- Late critical issue\n- figure: Figure 2",
|
|
903
|
+
"> Ordinary post-table commentary",
|
|
904
|
+
"##### Additional commentary",
|
|
905
|
+
"### Closing note\nOrdinary late prose",
|
|
906
|
+
)
|
|
907
|
+
|
|
908
|
+
|
|
909
|
+
@pytest.mark.parametrize(
|
|
910
|
+
"late_surface",
|
|
911
|
+
_DA_TERMINAL_LATE_SURFACES,
|
|
912
|
+
)
|
|
913
|
+
def test_da_post_boundary_table_surfaces_fail_in_synthesis_path(
|
|
914
|
+
late_surface,
|
|
915
|
+
):
|
|
916
|
+
panel_reports = reports(da_ids=("C1",))
|
|
917
|
+
da_report = next(report for report in panel_reports if report.role == "da")
|
|
918
|
+
da_report.text = da_report.text.replace(
|
|
919
|
+
"\n\n#### MAJOR",
|
|
920
|
+
f"\n\n{late_surface}\n\n#### MAJOR",
|
|
921
|
+
1,
|
|
922
|
+
)
|
|
923
|
+
synthesis_text, expressions = synthesis_for(
|
|
924
|
+
panel_reports, {"C1": "VALIDATED"}, marker_count=1
|
|
925
|
+
)
|
|
926
|
+
synthesis = cps.parse_synthesis("s.md", synthesis_text, FULL)
|
|
927
|
+
with pytest.raises(cps.ReportError, match="issue tables are terminal"):
|
|
928
|
+
cps.layer2_check(panel_reports, FULL, expressions, synthesis, [])
|
|
929
|
+
|
|
930
|
+
|
|
931
|
+
@pytest.mark.parametrize("late_surface", _DA_TERMINAL_LATE_SURFACES)
|
|
932
|
+
def test_da_post_major_table_surfaces_fail_in_synthesis_path(
|
|
933
|
+
late_surface,
|
|
934
|
+
):
|
|
935
|
+
panel_reports = reports(da_ids=("C1",))
|
|
936
|
+
da_report = next(report for report in panel_reports if report.role == "da")
|
|
937
|
+
da_report.text += f"\n\n{late_surface}"
|
|
938
|
+
synthesis_text, expressions = synthesis_for(
|
|
939
|
+
panel_reports, {"C1": "VALIDATED"}, marker_count=1
|
|
940
|
+
)
|
|
941
|
+
synthesis = cps.parse_synthesis("s.md", synthesis_text, FULL)
|
|
942
|
+
with pytest.raises(cps.ReportError, match="issue tables are terminal"):
|
|
943
|
+
cps.layer2_check(panel_reports, FULL, expressions, synthesis, [])
|
|
944
|
+
|
|
945
|
+
|
|
946
|
+
def test_da_fenced_payload_after_major_fails_in_synthesis_path():
|
|
947
|
+
panel_reports = reports(da_ids=("C1",))
|
|
948
|
+
da_report = next(report for report in panel_reports if report.role == "da")
|
|
949
|
+
da_report.text += (
|
|
950
|
+
"\n\n```markdown\n"
|
|
951
|
+
'| C2 | Hidden critical issue | text: "hidden evidence" p. 2 |\n'
|
|
952
|
+
"```"
|
|
953
|
+
)
|
|
954
|
+
synthesis_text, expressions = synthesis_for(
|
|
955
|
+
panel_reports, {"C1": "VALIDATED"}, marker_count=1
|
|
956
|
+
)
|
|
957
|
+
synthesis = cps.parse_synthesis("s.md", synthesis_text, FULL)
|
|
958
|
+
with pytest.raises(cps.ReportError, match="issue tables are terminal"):
|
|
959
|
+
cps.layer2_check(panel_reports, FULL, expressions, synthesis, [])
|
|
960
|
+
|
|
961
|
+
|
|
962
|
+
def test_da_html_comment_inside_fence_fails_in_synthesis_path():
|
|
963
|
+
panel_reports = reports()
|
|
964
|
+
da_report = next(report for report in panel_reports if report.role == "da")
|
|
965
|
+
da_report.text += "\n\n```\n<!-- hidden adjudication payload -->\n```"
|
|
966
|
+
synthesis_text, expressions = synthesis_for(panel_reports)
|
|
967
|
+
synthesis = cps.parse_synthesis("s.md", synthesis_text, FULL)
|
|
968
|
+
with pytest.raises(cps.ReportError, match="HTML comments are forbidden"):
|
|
969
|
+
cps.layer2_check(panel_reports, FULL, expressions, synthesis, [])
|
|
970
|
+
|
|
971
|
+
|
|
972
|
+
def test_da_html_commented_tables_fail_in_synthesis_path():
|
|
973
|
+
panel_reports = reports()
|
|
974
|
+
da_report = next(report for report in panel_reports if report.role == "da")
|
|
975
|
+
da_report.text = da_report.text.replace(
|
|
976
|
+
"#### CRITICAL", "<!--\n#### CRITICAL", 1
|
|
977
|
+
)
|
|
978
|
+
da_report.text += "\n-->"
|
|
979
|
+
synthesis_text, expressions = synthesis_for(panel_reports)
|
|
980
|
+
synthesis = cps.parse_synthesis("s.md", synthesis_text, FULL)
|
|
981
|
+
with pytest.raises(cps.ReportError, match="HTML comments are forbidden"):
|
|
982
|
+
cps.layer2_check(panel_reports, FULL, expressions, synthesis, [])
|
|
983
|
+
|
|
984
|
+
|
|
985
|
+
@pytest.mark.parametrize(
|
|
986
|
+
"old,new,fragment",
|
|
987
|
+
[
|
|
988
|
+
(
|
|
989
|
+
"| # | Issue | Evidence Anchor |",
|
|
990
|
+
"| # | # | Evidence Anchor |",
|
|
991
|
+
"exactly one #",
|
|
992
|
+
),
|
|
993
|
+
(
|
|
994
|
+
"| # | Issue | Evidence Anchor |",
|
|
995
|
+
"| # | Evidence Anchor | Evidence Anchor |",
|
|
996
|
+
"exactly one #",
|
|
997
|
+
),
|
|
998
|
+
(
|
|
999
|
+
"| # | Issue | Evidence Anchor |",
|
|
1000
|
+
"| ID | Issue | Anchor |",
|
|
1001
|
+
"missing table header",
|
|
1002
|
+
),
|
|
1003
|
+
(
|
|
1004
|
+
"| C2 | Issue |",
|
|
1005
|
+
"| C1 | Issue |",
|
|
1006
|
+
"duplicate CRITICAL ID",
|
|
1007
|
+
),
|
|
1008
|
+
(
|
|
1009
|
+
"| C2 | Issue |",
|
|
1010
|
+
"| X2 | Issue |",
|
|
1011
|
+
"invalid CRITICAL ID",
|
|
1012
|
+
),
|
|
1013
|
+
],
|
|
1014
|
+
)
|
|
1015
|
+
def test_da_header_and_critical_id_gates_fail_in_synthesis_path(
|
|
1016
|
+
old, new, fragment
|
|
1017
|
+
):
|
|
1018
|
+
panel_reports = reports(da_ids=("C1", "C2"))
|
|
1019
|
+
da_report = next(report for report in panel_reports if report.role == "da")
|
|
1020
|
+
da_report.text = da_report.text.replace(old, new, 1)
|
|
1021
|
+
text, expressions = synthesis_for(
|
|
1022
|
+
panel_reports,
|
|
1023
|
+
{"C1": "VALIDATED", "C2": "VALIDATED"},
|
|
1024
|
+
marker_count=2,
|
|
1025
|
+
)
|
|
1026
|
+
synthesis = cps.parse_synthesis("s.md", text, FULL)
|
|
1027
|
+
with pytest.raises(cps.ReportError, match=fragment):
|
|
1028
|
+
cps.layer2_check(panel_reports, FULL, expressions, synthesis, [])
|
|
1029
|
+
|
|
1030
|
+
|
|
1031
|
+
def test_da_shadow_table_fails_in_synthesis_path():
|
|
1032
|
+
panel_reports = reports(da_ids=("C1",))
|
|
1033
|
+
da_report = next(report for report in panel_reports if report.role == "da")
|
|
1034
|
+
canonical = (
|
|
1035
|
+
'| # | Issue | Evidence Anchor |\n'
|
|
1036
|
+
'|---|-------|-----------------|\n'
|
|
1037
|
+
'| C1 | Issue | text: "quoted evidence" p. 1 |'
|
|
1038
|
+
)
|
|
1039
|
+
shadowed = (
|
|
1040
|
+
'| ID | Issue | Anchor |\n'
|
|
1041
|
+
'|---|-------|--------|\n'
|
|
1042
|
+
'| C1 | Issue | text: "quoted evidence" p. 1 |\n\n'
|
|
1043
|
+
'| # | Issue | Evidence Anchor |\n'
|
|
1044
|
+
'|---|-------|-----------------|'
|
|
1045
|
+
)
|
|
1046
|
+
da_report.text = da_report.text.replace(canonical, shadowed, 1)
|
|
1047
|
+
text, expressions = synthesis_for(panel_reports)
|
|
1048
|
+
synthesis = cps.parse_synthesis("s.md", text, FULL)
|
|
1049
|
+
with pytest.raises(cps.ReportError, match="first nonblank line"):
|
|
1050
|
+
cps.layer2_check(panel_reports, FULL, expressions, synthesis, [])
|
|
1051
|
+
|
|
1052
|
+
|
|
1053
|
+
def test_da_standalone_critical_fails_in_synthesis_path():
|
|
1054
|
+
panel_reports = reports()
|
|
1055
|
+
da_report = next(report for report in panel_reports if report.role == "da")
|
|
1056
|
+
da_report.text = da_report.text.replace(
|
|
1057
|
+
"#### CRITICAL",
|
|
1058
|
+
"### Further adversarial challenge\n"
|
|
1059
|
+
"- **Severity**: Critical | **Confidence**: 5 (statistics)\n\n"
|
|
1060
|
+
"#### CRITICAL",
|
|
1061
|
+
1,
|
|
1062
|
+
)
|
|
1063
|
+
text, expressions = synthesis_for(panel_reports)
|
|
1064
|
+
synthesis = cps.parse_synthesis("s.md", text, FULL)
|
|
1065
|
+
with pytest.raises(cps.ReportError, match="standalone Severity"):
|
|
1066
|
+
cps.layer2_check(panel_reports, FULL, expressions, synthesis, [])
|
|
1067
|
+
|
|
1068
|
+
|
|
1069
|
+
@pytest.mark.parametrize("label", ("severity", "sEvErItY"))
|
|
1070
|
+
def test_da_case_variant_standalone_critical_fails_in_synthesis_path(label):
|
|
1071
|
+
panel_reports = reports()
|
|
1072
|
+
da_report = next(report for report in panel_reports if report.role == "da")
|
|
1073
|
+
da_report.text = da_report.text.replace(
|
|
1074
|
+
"#### CRITICAL",
|
|
1075
|
+
"### Further adversarial challenge\n"
|
|
1076
|
+
f"This is **{label}**: Critical and no revision cures it.\n\n"
|
|
1077
|
+
"#### CRITICAL",
|
|
1078
|
+
1,
|
|
1079
|
+
)
|
|
1080
|
+
text, expressions = synthesis_for(panel_reports)
|
|
1081
|
+
synthesis = cps.parse_synthesis("s.md", text, FULL)
|
|
1082
|
+
with pytest.raises(cps.ReportError, match="standalone Severity"):
|
|
1083
|
+
cps.layer2_check(panel_reports, FULL, expressions, synthesis, [])
|
|
1084
|
+
|
|
1085
|
+
|
|
1086
|
+
def test_da_extra_issue_table_band_fails_in_synthesis_path():
|
|
1087
|
+
panel_reports = reports()
|
|
1088
|
+
da_report = next(report for report in panel_reports if report.role == "da")
|
|
1089
|
+
da_report.text = da_report.text.replace(
|
|
1090
|
+
"#### MAJOR",
|
|
1091
|
+
"#### ADDITIONAL CRITICAL FINDINGS\n"
|
|
1092
|
+
"| # | Issue | Evidence Anchor |\n"
|
|
1093
|
+
"|---|-------|-----------------|\n"
|
|
1094
|
+
'| C1 | impossible df | text: "n=41" p. 4 |\n\n'
|
|
1095
|
+
"#### MAJOR",
|
|
1096
|
+
1,
|
|
1097
|
+
)
|
|
1098
|
+
text, expressions = synthesis_for(panel_reports)
|
|
1099
|
+
synthesis = cps.parse_synthesis("s.md", text, FULL)
|
|
1100
|
+
with pytest.raises(cps.ReportError, match="unexpected issue-table band"):
|
|
1101
|
+
cps.layer2_check(panel_reports, FULL, expressions, synthesis, [])
|
|
1102
|
+
|
|
1103
|
+
|
|
1104
|
+
@pytest.mark.parametrize(
|
|
1105
|
+
("lead_in", "header"),
|
|
1106
|
+
(
|
|
1107
|
+
("The following issues invalidate the claim:\n\n",
|
|
1108
|
+
"| # | Issue | Evidence Anchor |"),
|
|
1109
|
+
("", "| # | Issue | evidence anchor |"),
|
|
1110
|
+
("", "# | Issue | Evidence Anchor"),
|
|
1111
|
+
),
|
|
1112
|
+
)
|
|
1113
|
+
def test_da_disguised_extra_issue_table_band_fails_in_synthesis_path(
|
|
1114
|
+
lead_in, header
|
|
1115
|
+
):
|
|
1116
|
+
panel_reports = reports()
|
|
1117
|
+
da_report = next(report for report in panel_reports if report.role == "da")
|
|
1118
|
+
da_report.text = da_report.text.replace(
|
|
1119
|
+
"#### MAJOR",
|
|
1120
|
+
"#### ADDITIONAL CRITICAL FINDINGS\n"
|
|
1121
|
+
f"{lead_in}{header}\n"
|
|
1122
|
+
"|---|-------|-----------------|\n"
|
|
1123
|
+
'| C9 | impossible df | text: "n=41" p. 4 |\n\n'
|
|
1124
|
+
"#### MAJOR",
|
|
1125
|
+
1,
|
|
1126
|
+
)
|
|
1127
|
+
text, expressions = synthesis_for(panel_reports)
|
|
1128
|
+
synthesis = cps.parse_synthesis("s.md", text, FULL)
|
|
1129
|
+
with pytest.raises(cps.ReportError, match="unexpected issue-table band"):
|
|
1130
|
+
cps.layer2_check(panel_reports, FULL, expressions, synthesis, [])
|
|
1131
|
+
|
|
1132
|
+
|
|
1133
|
+
@pytest.mark.parametrize("placement", ("preamble", "extra_h2"))
|
|
1134
|
+
def test_da_issue_table_outside_canonical_bands_fails_synthesis(placement):
|
|
1135
|
+
panel_reports = reports()
|
|
1136
|
+
da_report = next(report for report in panel_reports if report.role == "da")
|
|
1137
|
+
table = (
|
|
1138
|
+
"| # | Issue | Evidence Anchor |\n"
|
|
1139
|
+
"|---|-------|-----------------|\n"
|
|
1140
|
+
'| C9 | impossible df | text: "n=41" p. 4 |\n'
|
|
1141
|
+
)
|
|
1142
|
+
if placement == "preamble":
|
|
1143
|
+
da_report.text = da_report.text.replace(
|
|
1144
|
+
"#### CRITICAL", table + "\n#### CRITICAL", 1
|
|
1145
|
+
)
|
|
1146
|
+
else:
|
|
1147
|
+
da_report.text += "\n## Appendix\n" + table
|
|
1148
|
+
text, expressions = synthesis_for(panel_reports)
|
|
1149
|
+
synthesis = cps.parse_synthesis("s.md", text, FULL)
|
|
1150
|
+
with pytest.raises(cps.ReportError, match="unexpected issue-table"):
|
|
1151
|
+
cps.layer2_check(panel_reports, FULL, expressions, synthesis, [])
|
|
1152
|
+
|
|
1153
|
+
|
|
1154
|
+
def test_da_internal_header_whitespace_fails_in_synthesis_path():
|
|
1155
|
+
panel_reports = reports()
|
|
1156
|
+
da_report = next(report for report in panel_reports if report.role == "da")
|
|
1157
|
+
da_report.text = da_report.text.replace(
|
|
1158
|
+
"#### MAJOR",
|
|
1159
|
+
"#### ADDITIONAL CRITICAL FINDINGS\n"
|
|
1160
|
+
"# | Issue | Evidence Anchor\n"
|
|
1161
|
+
"---|-------|-----------------\n"
|
|
1162
|
+
'C9 | impossible df | text: "n=41" p. 4\n\n'
|
|
1163
|
+
"#### MAJOR",
|
|
1164
|
+
1,
|
|
1165
|
+
)
|
|
1166
|
+
text, expressions = synthesis_for(panel_reports)
|
|
1167
|
+
synthesis = cps.parse_synthesis("s.md", text, FULL)
|
|
1168
|
+
with pytest.raises(cps.ReportError, match="unexpected issue-table"):
|
|
1169
|
+
cps.layer2_check(panel_reports, FULL, expressions, synthesis, [])
|
|
1170
|
+
|
|
1171
|
+
|
|
1172
|
+
@pytest.mark.parametrize(
|
|
1173
|
+
"header",
|
|
1174
|
+
(
|
|
1175
|
+
"| ID | Issue | Evidence Anchor |",
|
|
1176
|
+
"| # | Issue | Evidence |",
|
|
1177
|
+
"| **#** | Issue | **Evidence Anchor** |",
|
|
1178
|
+
"| `#` | Issue | `Evidence Anchor` |",
|
|
1179
|
+
),
|
|
1180
|
+
)
|
|
1181
|
+
def test_da_partial_or_formatted_issue_header_fails_synthesis(header):
|
|
1182
|
+
panel_reports = reports()
|
|
1183
|
+
da_report = next(report for report in panel_reports if report.role == "da")
|
|
1184
|
+
da_report.text = da_report.text.replace(
|
|
1185
|
+
"#### MAJOR",
|
|
1186
|
+
"#### ADDITIONAL CRITICAL FINDINGS\n"
|
|
1187
|
+
f"{header}\n"
|
|
1188
|
+
"|---|-------|-----------------|\n"
|
|
1189
|
+
'| C9 | impossible df | text: "n=41" p. 4 |\n\n'
|
|
1190
|
+
"#### MAJOR",
|
|
1191
|
+
1,
|
|
1192
|
+
)
|
|
1193
|
+
text, expressions = synthesis_for(panel_reports)
|
|
1194
|
+
synthesis = cps.parse_synthesis("s.md", text, FULL)
|
|
1195
|
+
with pytest.raises(cps.ReportError, match="unexpected issue-table"):
|
|
1196
|
+
cps.layer2_check(panel_reports, FULL, expressions, synthesis, [])
|
|
1197
|
+
|
|
1198
|
+
|
|
1199
|
+
@pytest.mark.parametrize(
|
|
1200
|
+
"header",
|
|
1201
|
+
(
|
|
1202
|
+
"| ID | Issue | [Evidence Anchor][anchor] |",
|
|
1203
|
+
r"| \# | Issue | Evidence |",
|
|
1204
|
+
'| ID | Issue | <span title="x>y">Evidence Anchor</span> |',
|
|
1205
|
+
),
|
|
1206
|
+
)
|
|
1207
|
+
def test_da_commonmark_visible_issue_header_fails_synthesis(header):
|
|
1208
|
+
panel_reports = reports()
|
|
1209
|
+
da_report = next(report for report in panel_reports if report.role == "da")
|
|
1210
|
+
da_report.text = da_report.text.replace(
|
|
1211
|
+
"#### MAJOR",
|
|
1212
|
+
"#### ADDITIONAL CRITICAL FINDINGS\n"
|
|
1213
|
+
f"{header}\n"
|
|
1214
|
+
"|---|-------|-----------------|\n"
|
|
1215
|
+
'| C9 | impossible df | text: "n=41" p. 4 |\n\n'
|
|
1216
|
+
"#### MAJOR",
|
|
1217
|
+
1,
|
|
1218
|
+
)
|
|
1219
|
+
text, expressions = synthesis_for(panel_reports)
|
|
1220
|
+
synthesis = cps.parse_synthesis("s.md", text, FULL)
|
|
1221
|
+
with pytest.raises(cps.ReportError, match="unexpected issue-table"):
|
|
1222
|
+
cps.layer2_check(panel_reports, FULL, expressions, synthesis, [])
|
|
1223
|
+
|
|
1224
|
+
|
|
1225
|
+
def test_da_balanced_link_destination_header_fails_synthesis():
|
|
1226
|
+
panel_reports = reports()
|
|
1227
|
+
da_report = next(report for report in panel_reports if report.role == "da")
|
|
1228
|
+
header = (
|
|
1229
|
+
r"| [\#](<https://x.test/a(b)>) | Issue | "
|
|
1230
|
+
r"[Evidence Anchor](<https://x.test/a(b)>) |"
|
|
1231
|
+
)
|
|
1232
|
+
da_report.text = da_report.text.replace(
|
|
1233
|
+
"#### MAJOR",
|
|
1234
|
+
"#### ADDITIONAL CRITICAL FINDINGS\n"
|
|
1235
|
+
f"{header}\n"
|
|
1236
|
+
"|---|-------|-----------------|\n"
|
|
1237
|
+
'| C9 | impossible df | text: "n=41" p. 4 |\n\n'
|
|
1238
|
+
"#### MAJOR",
|
|
1239
|
+
1,
|
|
1240
|
+
)
|
|
1241
|
+
text, expressions = synthesis_for(panel_reports)
|
|
1242
|
+
synthesis = cps.parse_synthesis("s.md", text, FULL)
|
|
1243
|
+
with pytest.raises(cps.ReportError, match="unexpected issue-table"):
|
|
1244
|
+
cps.layer2_check(panel_reports, FULL, expressions, synthesis, [])
|
|
1245
|
+
|
|
1246
|
+
|
|
1247
|
+
def test_da_typed_anchor_payload_alone_fails_synthesis():
|
|
1248
|
+
panel_reports = reports()
|
|
1249
|
+
da_report = next(report for report in panel_reports if report.role == "da")
|
|
1250
|
+
header = (
|
|
1251
|
+
r"| [\#](<https://x.test/a(b)>) | Issue | "
|
|
1252
|
+
r"[Evidence Anchor](<https://x.test/a(b)>) |"
|
|
1253
|
+
)
|
|
1254
|
+
da_report.text = da_report.text.replace(
|
|
1255
|
+
"#### MAJOR",
|
|
1256
|
+
"#### ADDITIONAL CRITICAL FINDINGS\n"
|
|
1257
|
+
f"{header}\n"
|
|
1258
|
+
"|---|-------|-----------------|\n"
|
|
1259
|
+
'| 1 | impossible df | `text: "n=41" p. 4` |\n\n'
|
|
1260
|
+
"#### MAJOR",
|
|
1261
|
+
1,
|
|
1262
|
+
)
|
|
1263
|
+
text, expressions = synthesis_for(panel_reports)
|
|
1264
|
+
synthesis = cps.parse_synthesis("s.md", text, FULL)
|
|
1265
|
+
with pytest.raises(cps.ReportError, match="unexpected issue-table"):
|
|
1266
|
+
cps.layer2_check(panel_reports, FULL, expressions, synthesis, [])
|
|
1267
|
+
|
|
1268
|
+
|
|
1269
|
+
def test_da_escaped_pipe_cell_evasion_fails_synthesis():
|
|
1270
|
+
panel_reports = reports()
|
|
1271
|
+
da_report = next(report for report in panel_reports if report.role == "da")
|
|
1272
|
+
block = (
|
|
1273
|
+
"#### ADDITIONAL CRITICAL FINDINGS\n"
|
|
1274
|
+
r"| [\#<!--\|-->](https://x.test) | Issue | "
|
|
1275
|
+
r"[Evidence<!--\|--> Anchor](https://x.test) |" "\n"
|
|
1276
|
+
"|---|---|---|\n"
|
|
1277
|
+
r"| [C<!--\|-->9](https://x.test) | impossible df | "
|
|
1278
|
+
r'[text<!--\|-->: "n=41" p. 4](https://x.test) |' "\n\n"
|
|
1279
|
+
)
|
|
1280
|
+
da_report.text = da_report.text.replace(
|
|
1281
|
+
"#### MAJOR", block + "#### MAJOR", 1
|
|
1282
|
+
)
|
|
1283
|
+
text, expressions = synthesis_for(panel_reports)
|
|
1284
|
+
synthesis = cps.parse_synthesis("s.md", text, FULL)
|
|
1285
|
+
with pytest.raises(cps.ReportError, match="HTML comments are forbidden"):
|
|
1286
|
+
cps.layer2_check(panel_reports, FULL, expressions, synthesis, [])
|
|
1287
|
+
|
|
1288
|
+
|
|
1289
|
+
def test_da_canonical_rows_allow_escaped_pipes():
|
|
1290
|
+
text = report_text("da", da_ids=("C1",)).replace(
|
|
1291
|
+
"| C1 | Issue |",
|
|
1292
|
+
r"| C1 | Issue \| detail |",
|
|
1293
|
+
1,
|
|
1294
|
+
)
|
|
1295
|
+
text += "\n" + r'| M1 | Issue \| detail | text: "quoted evidence" p. 1 |'
|
|
1296
|
+
critical, major = cps.parse_da_tables(text, "da.md")
|
|
1297
|
+
assert list(critical) == ["C1"]
|
|
1298
|
+
assert major == ['text: "quoted evidence" p. 1']
|
|
1299
|
+
|
|
1300
|
+
|
|
1301
|
+
def test_da_repeated_absence_separators_fail_in_synthesis_path():
|
|
1302
|
+
malformed = (
|
|
1303
|
+
"absence: Methods — expected ; checked appendix "
|
|
1304
|
+
"— expected ethics; checked supplement"
|
|
1305
|
+
)
|
|
1306
|
+
text = report_text("da", da_ids=("C1",)).replace(
|
|
1307
|
+
'text: "quoted evidence" p. 1',
|
|
1308
|
+
malformed,
|
|
1309
|
+
1,
|
|
1310
|
+
)
|
|
1311
|
+
with pytest.raises(cps.ReportError, match="ANCHOR-INVALID"):
|
|
1312
|
+
cps.parse_da_tables(text, "da.md")
|
|
1313
|
+
|
|
1314
|
+
|
|
1315
|
+
@pytest.mark.parametrize(
|
|
1316
|
+
"malformed",
|
|
1317
|
+
(
|
|
1318
|
+
"absence: Methods; checked appendix — expected ethics",
|
|
1319
|
+
'[ text: §5 "short exact quote" ]',
|
|
1320
|
+
"equation: Eq. ]3[",
|
|
1321
|
+
),
|
|
1322
|
+
)
|
|
1323
|
+
def test_da_misordered_absence_or_padded_wrapper_fails_synthesis(malformed):
|
|
1324
|
+
text = report_text("da", da_ids=("C1",)).replace(
|
|
1325
|
+
'text: "quoted evidence" p. 1',
|
|
1326
|
+
malformed,
|
|
1327
|
+
1,
|
|
1328
|
+
)
|
|
1329
|
+
with pytest.raises(cps.ReportError, match="ANCHOR-INVALID"):
|
|
1330
|
+
cps.parse_da_tables(text, "da.md")
|
|
1331
|
+
|
|
1332
|
+
|
|
1333
|
+
@pytest.mark.parametrize(
|
|
1334
|
+
"invisible", ("\u0600", "\u200b", "\u034f", "\ufe0e", "\u3164", "\ufff0")
|
|
1335
|
+
)
|
|
1336
|
+
def test_da_invisible_issue_payload_fails_synthesis(invisible):
|
|
1337
|
+
panel_reports = reports()
|
|
1338
|
+
da_report = next(report for report in panel_reports if report.role == "da")
|
|
1339
|
+
block = (
|
|
1340
|
+
"#### ADDITIONAL CRITICAL FINDINGS\n"
|
|
1341
|
+
f"| #{invisible} | Issue | Evidence{invisible} Anchor |\n"
|
|
1342
|
+
"|---|---|---|\n"
|
|
1343
|
+
f'| C{invisible}9 | impossible df | text{invisible}: "n=41" p. 4 |\n\n'
|
|
1344
|
+
)
|
|
1345
|
+
da_report.text = da_report.text.replace(
|
|
1346
|
+
"#### MAJOR", block + "#### MAJOR", 1
|
|
1347
|
+
)
|
|
1348
|
+
text, expressions = synthesis_for(panel_reports)
|
|
1349
|
+
synthesis = cps.parse_synthesis("s.md", text, FULL)
|
|
1350
|
+
with pytest.raises(cps.ReportError, match="unexpected issue-table"):
|
|
1351
|
+
cps.layer2_check(panel_reports, FULL, expressions, synthesis, [])
|
|
1352
|
+
|
|
1353
|
+
|
|
1354
|
+
def test_da_fullwidth_issue_payload_fails_synthesis():
|
|
1355
|
+
panel_reports = reports()
|
|
1356
|
+
da_report = next(report for report in panel_reports if report.role == "da")
|
|
1357
|
+
block = (
|
|
1358
|
+
"#### ADDITIONAL CRITICAL FINDINGS\n"
|
|
1359
|
+
"| # | Issue | Evidence Anchor |\n"
|
|
1360
|
+
"|---|---|---|\n"
|
|
1361
|
+
'| C9 | impossible df | text: "n=41" p. 4 |\n\n'
|
|
1362
|
+
)
|
|
1363
|
+
da_report.text = da_report.text.replace(
|
|
1364
|
+
"#### MAJOR", block + "#### MAJOR", 1
|
|
1365
|
+
)
|
|
1366
|
+
text, expressions = synthesis_for(panel_reports)
|
|
1367
|
+
synthesis = cps.parse_synthesis("s.md", text, FULL)
|
|
1368
|
+
with pytest.raises(cps.ReportError, match="unexpected issue-table"):
|
|
1369
|
+
cps.layer2_check(panel_reports, FULL, expressions, synthesis, [])
|
|
1370
|
+
|
|
1371
|
+
|
|
1372
|
+
def test_da_raw_html_issue_table_fails_synthesis():
|
|
1373
|
+
panel_reports = reports()
|
|
1374
|
+
da_report = next(report for report in panel_reports if report.role == "da")
|
|
1375
|
+
block = (
|
|
1376
|
+
"#### ADDITIONAL CRITICAL FINDINGS\n"
|
|
1377
|
+
"<table><tr><th>ID</th><th>Evidence</th></tr>"
|
|
1378
|
+
"<tr><td>C9</td><td>text: n=41</td></tr></table>\n\n"
|
|
1379
|
+
)
|
|
1380
|
+
da_report.text = da_report.text.replace(
|
|
1381
|
+
"#### MAJOR", block + "#### MAJOR", 1
|
|
1382
|
+
)
|
|
1383
|
+
text, expressions = synthesis_for(panel_reports)
|
|
1384
|
+
synthesis = cps.parse_synthesis("s.md", text, FULL)
|
|
1385
|
+
with pytest.raises(cps.ReportError, match="raw HTML issue-table"):
|
|
1386
|
+
cps.layer2_check(panel_reports, FULL, expressions, synthesis, [])
|
|
1387
|
+
|
|
1388
|
+
|
|
1389
|
+
def test_da_nested_html_issue_table_in_canonical_row_fails_synthesis():
|
|
1390
|
+
panel_reports = reports()
|
|
1391
|
+
da_report = next(report for report in panel_reports if report.role == "da")
|
|
1392
|
+
nested = (
|
|
1393
|
+
"real issue <table><tr><th>#</th><th>Evidence Anchor</th></tr>"
|
|
1394
|
+
'<tr><td>C9</td><td>text: "impossible df" p. 4</td></tr></table>'
|
|
1395
|
+
)
|
|
1396
|
+
da_report.text = da_report.text.replace(
|
|
1397
|
+
"#### MAJOR\n"
|
|
1398
|
+
"| # | Issue | Evidence Anchor |\n"
|
|
1399
|
+
"|---|-------|-----------------|",
|
|
1400
|
+
"#### MAJOR\n"
|
|
1401
|
+
"| # | Issue | Evidence Anchor |\n"
|
|
1402
|
+
"|---|-------|-----------------|\n"
|
|
1403
|
+
f'| M1 | {nested} | text: "quote" p. 1 |',
|
|
1404
|
+
1,
|
|
1405
|
+
)
|
|
1406
|
+
text, expressions = synthesis_for(panel_reports)
|
|
1407
|
+
synthesis = cps.parse_synthesis("s.md", text, FULL)
|
|
1408
|
+
with pytest.raises(cps.ReportError, match="raw HTML issue-table"):
|
|
1409
|
+
cps.layer2_check(panel_reports, FULL, expressions, synthesis, [])
|
|
1410
|
+
|
|
1411
|
+
|
|
1412
|
+
def test_da_bare_html_row_fails_synthesis():
|
|
1413
|
+
panel_reports = reports()
|
|
1414
|
+
da_report = next(report for report in panel_reports if report.role == "da")
|
|
1415
|
+
block = (
|
|
1416
|
+
"#### ADDITIONAL CRITICAL FINDINGS\n"
|
|
1417
|
+
"<tr><td>C9</td><td>text: n=41</td></tr>\n\n"
|
|
1418
|
+
)
|
|
1419
|
+
da_report.text = da_report.text.replace(
|
|
1420
|
+
"#### MAJOR", block + "#### MAJOR", 1
|
|
1421
|
+
)
|
|
1422
|
+
text, expressions = synthesis_for(panel_reports)
|
|
1423
|
+
synthesis = cps.parse_synthesis("s.md", text, FULL)
|
|
1424
|
+
with pytest.raises(cps.ReportError, match="raw HTML issue-table"):
|
|
1425
|
+
cps.layer2_check(panel_reports, FULL, expressions, synthesis, [])
|
|
1426
|
+
|
|
1427
|
+
|
|
1428
|
+
def test_da_empty_major_id_fails_in_synthesis_path():
|
|
1429
|
+
panel_reports = reports()
|
|
1430
|
+
da_report = next(report for report in panel_reports if report.role == "da")
|
|
1431
|
+
marker = "|---|-------|-----------------|"
|
|
1432
|
+
before, trailing = da_report.text.rsplit(marker, 1)
|
|
1433
|
+
da_report.text = (
|
|
1434
|
+
before + marker + '\n| | Issue | text: "quote" |' + trailing
|
|
1435
|
+
)
|
|
1436
|
+
text, expressions = synthesis_for(panel_reports)
|
|
1437
|
+
synthesis = cps.parse_synthesis("s.md", text, FULL)
|
|
1438
|
+
with pytest.raises(
|
|
1439
|
+
(cps.ReportError, cps.SynthesisError), match="empty MAJOR # cell"
|
|
1440
|
+
):
|
|
1441
|
+
cps.layer2_check(panel_reports, FULL, expressions, synthesis, [])
|
|
1442
|
+
|
|
1443
|
+
|
|
1444
|
+
def test_da_empty_critical_anchor_fails_in_synthesis_path():
|
|
1445
|
+
panel_reports = reports(da_ids=("C1",))
|
|
1446
|
+
da_report = next(report for report in panel_reports if report.role == "da")
|
|
1447
|
+
da_report.text = da_report.text.replace(
|
|
1448
|
+
'| C1 | Issue | text: "quoted evidence" p. 1 |',
|
|
1449
|
+
"| C1 | Issue | |",
|
|
1450
|
+
1,
|
|
1451
|
+
)
|
|
1452
|
+
text, expressions = synthesis_for(
|
|
1453
|
+
panel_reports, {"C1": "VALIDATED"}, marker_count=1
|
|
1454
|
+
)
|
|
1455
|
+
synthesis = cps.parse_synthesis("s.md", text, FULL)
|
|
1456
|
+
with pytest.raises(cps.ReportError, match="ANCHOR-MISSING"):
|
|
1457
|
+
cps.layer2_check(panel_reports, FULL, expressions, synthesis, [])
|
|
1458
|
+
|
|
1459
|
+
|
|
1460
|
+
@pytest.mark.parametrize(
|
|
1461
|
+
"anchor,fragment",
|
|
1462
|
+
[
|
|
1463
|
+
("", "ANCHOR-MISSING"),
|
|
1464
|
+
("see page 3", "ANCHOR-INVALID"),
|
|
1465
|
+
],
|
|
1466
|
+
)
|
|
1467
|
+
def test_da_major_anchor_fails_in_synthesis_path(anchor, fragment):
|
|
1468
|
+
panel_reports = reports()
|
|
1469
|
+
da_report = next(report for report in panel_reports if report.role == "da")
|
|
1470
|
+
marker = "|---|-------|-----------------|"
|
|
1471
|
+
before, trailing = da_report.text.rsplit(marker, 1)
|
|
1472
|
+
da_report.text = (
|
|
1473
|
+
before + marker + f"\n| M1 | Issue | {anchor} |" + trailing
|
|
1474
|
+
)
|
|
1475
|
+
text, expressions = synthesis_for(panel_reports)
|
|
1476
|
+
synthesis = cps.parse_synthesis("s.md", text, FULL)
|
|
1477
|
+
with pytest.raises(cps.ReportError, match=fragment):
|
|
1478
|
+
cps.layer2_check(panel_reports, FULL, expressions, synthesis, [])
|
|
1479
|
+
|
|
1480
|
+
|
|
1481
|
+
def test_da_valid_major_anchor_passes_in_synthesis_path():
|
|
1482
|
+
panel_reports = reports()
|
|
1483
|
+
da_report = next(report for report in panel_reports if report.role == "da")
|
|
1484
|
+
marker = "|---|-------|-----------------|"
|
|
1485
|
+
before, trailing = da_report.text.rsplit(marker, 1)
|
|
1486
|
+
da_report.text = (
|
|
1487
|
+
before + marker
|
|
1488
|
+
+ '\n| M1 | Issue | text: "short quote" |'
|
|
1489
|
+
+ trailing
|
|
1490
|
+
)
|
|
1491
|
+
text, expressions = synthesis_for(panel_reports)
|
|
1492
|
+
synthesis = cps.parse_synthesis("s.md", text, FULL)
|
|
1493
|
+
assert cps.layer2_check(
|
|
1494
|
+
panel_reports, FULL, expressions, synthesis, []
|
|
1495
|
+
) == []
|
|
1496
|
+
|
|
1497
|
+
|
|
1498
|
+
def test_marker_forbidden_under_nonaccept():
|
|
1499
|
+
panel_reports = reports({"methodology": {"D1": "warn"}}, da_ids=("C1",))
|
|
1500
|
+
text, expressions = synthesis_for(
|
|
1501
|
+
panel_reports, {"C1": "VALIDATED"}, marker_count=1
|
|
1502
|
+
)
|
|
1503
|
+
synthesis = cps.parse_synthesis("s.md", text, FULL)
|
|
1504
|
+
assert synthesis.decision == "editorial_decision=minor_revision"
|
|
1505
|
+
assert any("forbidden" in item for item in
|
|
1506
|
+
cps.layer2_check(panel_reports, FULL, expressions, synthesis, []))
|
|
1507
|
+
|
|
1508
|
+
|
|
1509
|
+
def _evaluate_profile(contract, expressions, assessed):
|
|
1510
|
+
fired = [
|
|
1511
|
+
condition["condition_id"]
|
|
1512
|
+
for condition in contract["failure_conditions"]
|
|
1513
|
+
if cps.evaluate_expression(
|
|
1514
|
+
expressions[condition["condition_id"]],
|
|
1515
|
+
assessed,
|
|
1516
|
+
condition["cross_reviewer_quantifier"],
|
|
1517
|
+
[],
|
|
1518
|
+
)
|
|
1519
|
+
]
|
|
1520
|
+
return fired, cps.resolve_decision(
|
|
1521
|
+
contract["failure_conditions"], set(fired)
|
|
1522
|
+
)
|
|
1523
|
+
|
|
1524
|
+
|
|
1525
|
+
def test_full_contract_exhaustive_13824_profiles():
|
|
1526
|
+
contract, expressions = cps.load_contract(FULL_PATH)
|
|
1527
|
+
mandatory_single = ("pass", "warn", "block", "fatal")
|
|
1528
|
+
nonmandatory_single = ("pass", "warn", "block")
|
|
1529
|
+
d3_states = [
|
|
1530
|
+
pair for pair in itertools.product(
|
|
1531
|
+
("pass", "warn", "block", "fatal", "abstain"), repeat=2
|
|
1532
|
+
) if pair != ("abstain", "abstain")
|
|
1533
|
+
]
|
|
1534
|
+
count = 0
|
|
1535
|
+
decisions = set()
|
|
1536
|
+
for d1, d2, d6, d3, d4, d5 in itertools.product(
|
|
1537
|
+
mandatory_single, mandatory_single, mandatory_single, d3_states,
|
|
1538
|
+
nonmandatory_single, nonmandatory_single,
|
|
1539
|
+
):
|
|
1540
|
+
assessed = {
|
|
1541
|
+
"D1": [state(d1)],
|
|
1542
|
+
"D2": [state(d2)],
|
|
1543
|
+
"D3": [state(value) for value in d3 if value != "abstain"],
|
|
1544
|
+
"D4": [state(d4)],
|
|
1545
|
+
"D5": [state(d5)],
|
|
1546
|
+
"D6": [state(d6)],
|
|
1547
|
+
}
|
|
1548
|
+
fired, decision = _evaluate_profile(contract, expressions, assessed)
|
|
1549
|
+
assert fired
|
|
1550
|
+
assert decision in cps.ACTION_ENUM
|
|
1551
|
+
decisions.add(decision)
|
|
1552
|
+
count += 1
|
|
1553
|
+
assert count == 13_824
|
|
1554
|
+
assert decisions == cps.ACTION_ENUM
|
|
1555
|
+
|
|
1556
|
+
|
|
1557
|
+
def test_methodology_focus_exhaustive_12_profiles():
|
|
1558
|
+
contract, expressions = cps.load_contract(MF_PATH)
|
|
1559
|
+
count = 0
|
|
1560
|
+
decisions = set()
|
|
1561
|
+
for d1, d2 in itertools.product(
|
|
1562
|
+
("pass", "warn", "block", "fatal"),
|
|
1563
|
+
("pass", "warn", "block"),
|
|
1564
|
+
):
|
|
1565
|
+
fired, decision = _evaluate_profile(
|
|
1566
|
+
contract, expressions, {"D1": [state(d1)], "D2": [state(d2)]}
|
|
1567
|
+
)
|
|
1568
|
+
assert fired
|
|
1569
|
+
decisions.add(decision)
|
|
1570
|
+
count += 1
|
|
1571
|
+
assert count == 12
|
|
1572
|
+
assert decisions == cps.ACTION_ENUM
|
|
1573
|
+
|
|
1574
|
+
|
|
1575
|
+
def test_methodology_focus_d1_warn_is_major_revision():
|
|
1576
|
+
contract, expressions = cps.load_contract(MF_PATH)
|
|
1577
|
+
fired, decision = _evaluate_profile(
|
|
1578
|
+
contract,
|
|
1579
|
+
expressions,
|
|
1580
|
+
{"D1": [state("warn")], "D2": [state("pass")]},
|
|
1581
|
+
)
|
|
1582
|
+
assert fired == ["F3"]
|
|
1583
|
+
assert decision == "editorial_decision=major_revision"
|
|
1584
|
+
|
|
1585
|
+
|
|
1586
|
+
def test_methodology_focus_layer2_has_empty_da_gate():
|
|
1587
|
+
contract, expressions = cps.load_contract(MF_PATH)
|
|
1588
|
+
panel_reports = []
|
|
1589
|
+
for role in ("eic", "methodology"):
|
|
1590
|
+
lines = [f"contract_role: {role}", "", "## Dimension Scores", ""]
|
|
1591
|
+
for dim in contract["acceptance_dimensions"]:
|
|
1592
|
+
lines += [
|
|
1593
|
+
f"### {dim['id']}: {dim['name']}",
|
|
1594
|
+
"score: pass" if role in dim["eligible_roles"]
|
|
1595
|
+
else "score: not_assessed",
|
|
1596
|
+
"",
|
|
1597
|
+
]
|
|
1598
|
+
lines += ["## Review Body", "", "No scored findings.", ""]
|
|
1599
|
+
panel_reports.append(cps.parse_report(
|
|
1600
|
+
f"{role}.md", "\n".join(lines), contract
|
|
1601
|
+
))
|
|
1602
|
+
synthesis = cps.parse_synthesis(
|
|
1603
|
+
"s.md",
|
|
1604
|
+
"dimension_verdicts: [D1=pass, D2=pass]\n"
|
|
1605
|
+
"fired_conditions: [F0]\n"
|
|
1606
|
+
"da_critical_adjudications: []\n"
|
|
1607
|
+
"editorial_decision=accept\n",
|
|
1608
|
+
contract,
|
|
1609
|
+
)
|
|
1610
|
+
assert cps.layer2_check(
|
|
1611
|
+
panel_reports, contract, expressions, synthesis, []
|
|
1612
|
+
) == []
|
|
1613
|
+
|
|
1614
|
+
|
|
1615
|
+
def test_boundary_decisions_and_d3_split_dynamic_majority():
|
|
1616
|
+
contract, expressions = cps.load_contract(FULL_PATH)
|
|
1617
|
+
base = {did: [state("pass")] for did in ("D1", "D2", "D4", "D5", "D6")}
|
|
1618
|
+
base["D3"] = [state("pass"), state("pass")]
|
|
1619
|
+
|
|
1620
|
+
one_warn = {**base, "D1": [state("warn")]}
|
|
1621
|
+
assert _evaluate_profile(contract, expressions, one_warn)[1] == \
|
|
1622
|
+
"editorial_decision=minor_revision"
|
|
1623
|
+
|
|
1624
|
+
normal_block = {**base, "D5": [state("block")]}
|
|
1625
|
+
assert _evaluate_profile(contract, expressions, normal_block)[1] == \
|
|
1626
|
+
"editorial_decision=minor_revision"
|
|
1627
|
+
|
|
1628
|
+
high_block = {**base, "D4": [state("block")]}
|
|
1629
|
+
assert _evaluate_profile(contract, expressions, high_block)[1] == \
|
|
1630
|
+
"editorial_decision=major_revision"
|
|
1631
|
+
|
|
1632
|
+
fatal_venue = {**base, "D6": [state("fatal")]}
|
|
1633
|
+
assert _evaluate_profile(contract, expressions, fatal_venue)[1] == \
|
|
1634
|
+
"editorial_decision=reject"
|
|
1635
|
+
|
|
1636
|
+
split = {**base, "D3": [state("block"), state("pass")]}
|
|
1637
|
+
fired, _ = _evaluate_profile(contract, expressions, split)
|
|
1638
|
+
assert "F2" in fired and "F3" not in fired
|
|
1639
|
+
|
|
1640
|
+
for assessed_d3 in ([state("warn")], [state("pass")]):
|
|
1641
|
+
dynamic = {**base, "D3": assessed_d3}
|
|
1642
|
+
fired, _ = _evaluate_profile(contract, expressions, dynamic)
|
|
1643
|
+
assert ("F5" in fired) == (assessed_d3[0].score == "warn")
|
|
1644
|
+
|
|
1645
|
+
|
|
1646
|
+
def test_n2_majority_split_cannot_harden_the_decision():
|
|
1647
|
+
contract, expressions = cps.load_contract(FULL_PATH)
|
|
1648
|
+
assessed = {
|
|
1649
|
+
"D1": [state("warn")],
|
|
1650
|
+
"D2": [state("pass")],
|
|
1651
|
+
"D3": [state("warn"), state("pass")],
|
|
1652
|
+
"D4": [state("pass")],
|
|
1653
|
+
"D5": [state("pass")],
|
|
1654
|
+
"D6": [state("pass")],
|
|
1655
|
+
}
|
|
1656
|
+
fired, decision = _evaluate_profile(contract, expressions, assessed)
|
|
1657
|
+
assert fired == ["F5"]
|
|
1658
|
+
assert decision == "editorial_decision=minor_revision"
|