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,1414 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
"""#610 step-5 deterministic arithmetic-receipt calculator.
|
|
3
|
+
|
|
4
|
+
Consumes one gate-validated ``## Recompute Extraction`` artifact (the
|
|
5
|
+
isolated numeric input surface: typed manuscript values transcribed by the
|
|
6
|
+
methodology seat, never the manuscript itself) and emits the exact
|
|
7
|
+
``## Arithmetic Receipts`` section grammar pinned by
|
|
8
|
+
``check_phase_conformance.py`` — minus ``finding_ref:`` lines, which are
|
|
9
|
+
linkage judgments the seat adds in Phase 2 under the injected-receipt
|
|
10
|
+
identity gate.
|
|
11
|
+
|
|
12
|
+
Determinism contract:
|
|
13
|
+
|
|
14
|
+
- Same extraction bytes -> same receipts bytes ON THE SAME HOST. No clock,
|
|
15
|
+
no randomness, no environment reads, no filesystem access beyond the two
|
|
16
|
+
CLI paths. The scope is per-platform by design: tail probabilities go
|
|
17
|
+
through libm (`lgamma`/`erfc`), whose last-ulp behavior varies across
|
|
18
|
+
platforms, so a value at a 3-significant-digit formatting breakpoint may
|
|
19
|
+
render differently on a different OS. Every #610 cohort is dispatched and
|
|
20
|
+
gated on one host, which is the domain the determinism contract serves;
|
|
21
|
+
exact-rational procedures (GRIM/GRIMMER/n_from_df) are
|
|
22
|
+
platform-independent outright.
|
|
23
|
+
- GRIM / GRIMMER / n_from_df run on exact rational arithmetic
|
|
24
|
+
(``fractions.Fraction``); reported-SD reachability is decided on SD^2 so
|
|
25
|
+
no square root ever enters a verdict.
|
|
26
|
+
- p-values use stdlib-only regularized incomplete beta/gamma
|
|
27
|
+
(continued-fraction forms) plus ``math.erfc``; every verdict comparison
|
|
28
|
+
carries a 1e-9 boundary guard that resolves to a ``not_computable``
|
|
29
|
+
reason, never a float coin-flip.
|
|
30
|
+
- The calculator emits ``consistent`` / ``mismatch`` / ``not_computable``
|
|
31
|
+
only. ``not_applicable`` stays grammar-legal for the self-compute path but
|
|
32
|
+
an RR is by construction an applicability claim, so it is never
|
|
33
|
+
script-emitted.
|
|
34
|
+
|
|
35
|
+
Exit codes: 0 receipts written; 2 the extraction artifact does not parse
|
|
36
|
+
(a should-never state after the ``--extraction`` conformance gate — the
|
|
37
|
+
dispatcher classifies it as a harness infra fault, not a conformance abort).
|
|
38
|
+
"""
|
|
39
|
+
from __future__ import annotations
|
|
40
|
+
|
|
41
|
+
import argparse
|
|
42
|
+
import math
|
|
43
|
+
import re
|
|
44
|
+
import sys
|
|
45
|
+
from dataclasses import dataclass, field
|
|
46
|
+
from fractions import Fraction
|
|
47
|
+
from pathlib import Path
|
|
48
|
+
|
|
49
|
+
EXTRACTION_SECTION = "Recompute Extraction"
|
|
50
|
+
RECEIPT_SECTION = "Arithmetic Receipts"
|
|
51
|
+
ATTESTATION_KEY = "no_recomputable_statistics"
|
|
52
|
+
|
|
53
|
+
PROCEDURES = ("p_from_test_statistic", "grim", "grimmer", "n_from_df")
|
|
54
|
+
TEST_FAMILIES = ("t", "z", "F", "chi_square")
|
|
55
|
+
COMPARATORS = (
|
|
56
|
+
"equals", "less_than", "less_than_or_equal",
|
|
57
|
+
"greater_than", "greater_than_or_equal",
|
|
58
|
+
)
|
|
59
|
+
TAILS = ("two-tailed", "one-tailed", "upper-tail", "unstated")
|
|
60
|
+
ROUNDING_RULES = ("half-up", "half-even", "truncation", "unstated")
|
|
61
|
+
SD_CONVENTIONS = ("sample", "population", "unstated")
|
|
62
|
+
DF_IDENTITIES = ("df=N-1", "df=N1+N2-2", "other_or_corrected", "unavailable")
|
|
63
|
+
N_RELATIONS = ("equals", "at_most", "at_least", "unavailable")
|
|
64
|
+
|
|
65
|
+
COMMON_FIELDS = (
|
|
66
|
+
"procedure_id", "evidence_anchor", "reported_inputs", "assumptions",
|
|
67
|
+
)
|
|
68
|
+
PROCEDURE_FIELDS = {
|
|
69
|
+
"p_from_test_statistic": (
|
|
70
|
+
"test_family", "statistic_value", "df", "reported_p_comparator",
|
|
71
|
+
"reported_p_value", "tail_convention",
|
|
72
|
+
),
|
|
73
|
+
"grim": (
|
|
74
|
+
"n", "reported_mean", "scale_min", "scale_max", "rounding_rule",
|
|
75
|
+
),
|
|
76
|
+
"grimmer": (
|
|
77
|
+
"n", "reported_mean", "scale_min", "scale_max", "rounding_rule",
|
|
78
|
+
"reported_sd", "sd_convention",
|
|
79
|
+
),
|
|
80
|
+
"n_from_df": (
|
|
81
|
+
"df_reported", "df_identity_candidate", "stated_n",
|
|
82
|
+
"stated_n_relation",
|
|
83
|
+
),
|
|
84
|
+
}
|
|
85
|
+
ALL_FIELD_KEYS = frozenset(COMMON_FIELDS) | {
|
|
86
|
+
key for keys in PROCEDURE_FIELDS.values() for key in keys
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
# The verdict boundary guard: a derived float this close to a rounding-
|
|
90
|
+
# interval endpoint or inequality threshold is refused as ambiguous rather
|
|
91
|
+
# than decided. Far below any reported-p precision, far above the special-
|
|
92
|
+
# function error.
|
|
93
|
+
_EPS = 1e-9
|
|
94
|
+
|
|
95
|
+
# GRIMMER reachability is exhaustive or refused; this bounds the memoized
|
|
96
|
+
# (value-index, remaining-count, remaining-sum) state space, beyond which the
|
|
97
|
+
# honest status is `reachability_not_completed`. The seeded MS01 case
|
|
98
|
+
# (N=10, 5-point scale) uses well under 1e3 states.
|
|
99
|
+
_STATE_BUDGET = 200_000
|
|
100
|
+
# The state budget bounds COUNT, not size: each memoized state retains a
|
|
101
|
+
# frozenset of attainable sums of squares, so total retained elements is the
|
|
102
|
+
# real memory bound (security round 1, P1-2). Exceeding it is the same
|
|
103
|
+
# honest refusal, never an approximation.
|
|
104
|
+
_ELEMENT_BUDGET = 2_000_000
|
|
105
|
+
# GRIM's candidate-sum window is ~2n/10^places wide; a zero-decimal mean
|
|
106
|
+
# over a huge N would otherwise iterate without bound. Same honest refusal.
|
|
107
|
+
_SUM_WINDOW_BUDGET = 500_000
|
|
108
|
+
# Total enumeration-loop iterations across one GRIMMER reachability call:
|
|
109
|
+
# the state and element budgets bound what is RETAINED, this bounds what is
|
|
110
|
+
# VISITED (an infeasible prefix retains nothing while it spins).
|
|
111
|
+
_WORK_BUDGET = 5_000_000
|
|
112
|
+
# Numeric-domain bounds shared by the gate and the calculator (they run the
|
|
113
|
+
# same parser, so no accept/refuse divergence is possible). The char cap
|
|
114
|
+
# keeps every token far inside float range; the p-procedure magnitude cap
|
|
115
|
+
# is the domain over which the tail special functions are empirically
|
|
116
|
+
# verified to converge under the iteration ceilings below (a manuscript t,
|
|
117
|
+
# F, chi-square, or df beyond 1e7 is not a plausible transcription).
|
|
118
|
+
_MAX_NUMERIC_CHARS = 18
|
|
119
|
+
_MAX_P_MAGNITUDE = 10_000_000
|
|
120
|
+
# 10 places comfortably exceeds any journal's printed precision while
|
|
121
|
+
# keeping every equality comparison's half-interval (5e-11) resolvable by
|
|
122
|
+
# the exact-rational procedures; p comparisons finer than the float guard
|
|
123
|
+
# degrade to `rounding_boundary_ambiguous` via _EPS rather than deciding.
|
|
124
|
+
# The extraction fragment tells the seat that a value the grammar cannot
|
|
125
|
+
# carry is OUT OF DOMAIN — no RR — so this cap can never trap a faithful
|
|
126
|
+
# transcription in an unsatisfiable retry (codex round 2).
|
|
127
|
+
_MAX_DECIMAL_PLACES = 10
|
|
128
|
+
# Free-text values ride verbatim into receipts and then into the Phase 2
|
|
129
|
+
# card under the identity gate, so tokens that other gates read as machine
|
|
130
|
+
# markup are refused at the source (security round 1, P2-2/P2-3/P2-4):
|
|
131
|
+
# bold spans (the finding grammar's declaration markers), HTML comment
|
|
132
|
+
# markup (banned in the receipt section), and closing-tag shapes (the
|
|
133
|
+
# dispatcher's delimiter fences). Carriage returns are refused line-level —
|
|
134
|
+
# the card-side reader splits on CR, this parser does not, and the identity
|
|
135
|
+
# gate must never straddle two line models.
|
|
136
|
+
_FORBIDDEN_VALUE_TOKENS = ("**", "<!--", "-->", "</")
|
|
137
|
+
|
|
138
|
+
_DECIMAL_RE = re.compile(r"^-?(?:\d+\.\d+|\.\d+|\d+)$")
|
|
139
|
+
_INT_RE = re.compile(r"^-?\d+$")
|
|
140
|
+
_DF_PAIR_RE = re.compile(r"^(\d+)\s*,\s*(\d+)$")
|
|
141
|
+
_H2_RE = re.compile(r"^## (\S.*?)\s*$")
|
|
142
|
+
_H3_RE = re.compile(r"^### (\S.*?)\s*$")
|
|
143
|
+
_RR_TITLE_RE = re.compile(r"^RR[1-9]\d*$")
|
|
144
|
+
_FENCE_OPEN_RE = re.compile(r"^[ ]{0,3}(`{3,}|~{3,})(.*)$")
|
|
145
|
+
_FENCE_CLOSE_RE = re.compile(r"^[ ]{0,3}(`{3,}|~{3,})[ \t]*$")
|
|
146
|
+
# Mirrors the gate's canonical field shape: optional single list marker,
|
|
147
|
+
# balanced-or-absent bold around the key, one space after the colon.
|
|
148
|
+
_FIELD_RE = re.compile(
|
|
149
|
+
r"^(?:[-*] )?(?:\*\*(?P<bkey>[a-z_]+)\*\*|(?P<key>[a-z_]+)): "
|
|
150
|
+
r"(?P<value>\S.*?)\s*$"
|
|
151
|
+
)
|
|
152
|
+
|
|
153
|
+
|
|
154
|
+
class ExtractionError(ValueError):
|
|
155
|
+
"""The extraction artifact violates the RR grammar this module consumes."""
|
|
156
|
+
|
|
157
|
+
|
|
158
|
+
@dataclass
|
|
159
|
+
class Request:
|
|
160
|
+
"""One gate-validated RR subsection."""
|
|
161
|
+
|
|
162
|
+
rr_id: str
|
|
163
|
+
fields: dict[str, str]
|
|
164
|
+
|
|
165
|
+
def __getitem__(self, key: str) -> str:
|
|
166
|
+
return self.fields[key]
|
|
167
|
+
|
|
168
|
+
|
|
169
|
+
@dataclass
|
|
170
|
+
class Extraction:
|
|
171
|
+
attestation: str | None
|
|
172
|
+
requests: list[Request] = field(default_factory=list)
|
|
173
|
+
|
|
174
|
+
|
|
175
|
+
@dataclass
|
|
176
|
+
class Receipt:
|
|
177
|
+
procedure_id: str
|
|
178
|
+
evidence_anchor: str
|
|
179
|
+
reported_inputs: str
|
|
180
|
+
assumptions: str
|
|
181
|
+
derivation: str
|
|
182
|
+
derived_value_or_range: str
|
|
183
|
+
comparison_rule: str
|
|
184
|
+
status: str
|
|
185
|
+
not_computable_reason: str | None = None
|
|
186
|
+
tail_convention: str | None = None
|
|
187
|
+
rounding_interval: str | None = None
|
|
188
|
+
nearest_achievable: str | None = None
|
|
189
|
+
df_identity: str | None = None
|
|
190
|
+
|
|
191
|
+
|
|
192
|
+
# --- extraction parsing ---------------------------------------------------
|
|
193
|
+
|
|
194
|
+
def parse_extraction(text: str) -> Extraction:
|
|
195
|
+
lines = _section_lines(text)
|
|
196
|
+
current: Request | None = None
|
|
197
|
+
requests: list[Request] = []
|
|
198
|
+
attestation: str | None = None
|
|
199
|
+
for line in lines:
|
|
200
|
+
if not line.strip():
|
|
201
|
+
continue
|
|
202
|
+
if "\r" in line:
|
|
203
|
+
raise ExtractionError(
|
|
204
|
+
"carriage return inside a machine line; the card-side "
|
|
205
|
+
"reader and this parser would disagree about line breaks"
|
|
206
|
+
)
|
|
207
|
+
if match := _H3_RE.fullmatch(line):
|
|
208
|
+
title = match.group(1)
|
|
209
|
+
if not _RR_TITLE_RE.fullmatch(title):
|
|
210
|
+
raise ExtractionError(f"invalid subsection heading: {title}")
|
|
211
|
+
expected = f"RR{len(requests) + 1}"
|
|
212
|
+
if title != expected:
|
|
213
|
+
raise ExtractionError(
|
|
214
|
+
f"RR ids must be contiguous: expected {expected}, "
|
|
215
|
+
f"found {title}"
|
|
216
|
+
)
|
|
217
|
+
current = Request(title, {})
|
|
218
|
+
requests.append(current)
|
|
219
|
+
continue
|
|
220
|
+
match = _FIELD_RE.fullmatch(line)
|
|
221
|
+
if not match:
|
|
222
|
+
raise ExtractionError(f"not a machine line: {line!r}")
|
|
223
|
+
key = match.group("bkey") or match.group("key")
|
|
224
|
+
value = match.group("value")
|
|
225
|
+
for token in _FORBIDDEN_VALUE_TOKENS:
|
|
226
|
+
if token in value:
|
|
227
|
+
raise ExtractionError(
|
|
228
|
+
f"forbidden token {token!r} inside a field value; "
|
|
229
|
+
"machine-markup shapes never belong in transcribed "
|
|
230
|
+
"content"
|
|
231
|
+
)
|
|
232
|
+
if key == ATTESTATION_KEY:
|
|
233
|
+
if current is not None or attestation is not None:
|
|
234
|
+
raise ExtractionError(
|
|
235
|
+
"attestation must be the only content of the section"
|
|
236
|
+
)
|
|
237
|
+
attestation = value
|
|
238
|
+
continue
|
|
239
|
+
if current is None:
|
|
240
|
+
raise ExtractionError(
|
|
241
|
+
f"field line outside any RR subsection: {line!r}"
|
|
242
|
+
)
|
|
243
|
+
if key not in ALL_FIELD_KEYS:
|
|
244
|
+
raise ExtractionError(f"unknown field: {key}")
|
|
245
|
+
if key in current.fields:
|
|
246
|
+
raise ExtractionError(f"{current.rr_id}: duplicate field {key}")
|
|
247
|
+
current.fields[key] = value
|
|
248
|
+
if attestation is not None and requests:
|
|
249
|
+
raise ExtractionError("attestation and RR subsections cannot coexist")
|
|
250
|
+
if attestation is None and not requests:
|
|
251
|
+
raise ExtractionError(
|
|
252
|
+
"section carries neither RR subsections nor the attestation"
|
|
253
|
+
)
|
|
254
|
+
for request in requests:
|
|
255
|
+
_validate_request(request)
|
|
256
|
+
return Extraction(attestation, requests)
|
|
257
|
+
|
|
258
|
+
|
|
259
|
+
def _section_lines(text: str) -> list[str]:
|
|
260
|
+
"""The extraction section's content lines, fence-transparently.
|
|
261
|
+
|
|
262
|
+
CommonMark-stateful (codex round 1, P2-3): an opening fence remembers
|
|
263
|
+
its run and only a matching closer ends it, a backtick fence's info
|
|
264
|
+
string may not contain a backtick (so ```` ```bad`tick ```` is a
|
|
265
|
+
paragraph line, not a silently-dropped delimiter), and only an
|
|
266
|
+
UNFENCED H2 delimits — the #637/#638 display-form discipline. Interior
|
|
267
|
+
lines are kept as content, so a fenced machine line is still read and
|
|
268
|
+
the calculator agrees with the gate about what was said.
|
|
269
|
+
"""
|
|
270
|
+
collected: list[str] = []
|
|
271
|
+
inside = False
|
|
272
|
+
found = False
|
|
273
|
+
fence: str | None = None
|
|
274
|
+
for raw in text.split("\n"):
|
|
275
|
+
line = raw.rstrip("\r")
|
|
276
|
+
if fence is not None:
|
|
277
|
+
close = _FENCE_CLOSE_RE.match(line)
|
|
278
|
+
if close and close.group(1)[0] == fence[0] \
|
|
279
|
+
and len(close.group(1)) >= len(fence):
|
|
280
|
+
fence = None
|
|
281
|
+
continue
|
|
282
|
+
if inside:
|
|
283
|
+
collected.append(line)
|
|
284
|
+
continue
|
|
285
|
+
opener = _FENCE_OPEN_RE.match(line)
|
|
286
|
+
if opener and not (opener.group(1)[0] == "`"
|
|
287
|
+
and "`" in opener.group(2)):
|
|
288
|
+
fence = opener.group(1)
|
|
289
|
+
continue
|
|
290
|
+
if match := _H2_RE.fullmatch(line):
|
|
291
|
+
inside = match.group(1) == EXTRACTION_SECTION
|
|
292
|
+
found = found or inside
|
|
293
|
+
continue
|
|
294
|
+
if inside:
|
|
295
|
+
collected.append(line)
|
|
296
|
+
if not found:
|
|
297
|
+
raise ExtractionError(f"no ## {EXTRACTION_SECTION} section")
|
|
298
|
+
return collected
|
|
299
|
+
|
|
300
|
+
|
|
301
|
+
def _validate_request(request: Request) -> None:
|
|
302
|
+
procedure = request.fields.get("procedure_id")
|
|
303
|
+
if procedure not in PROCEDURES:
|
|
304
|
+
raise ExtractionError(
|
|
305
|
+
f"{request.rr_id}: procedure_id must be one of {PROCEDURES}"
|
|
306
|
+
)
|
|
307
|
+
required = COMMON_FIELDS + PROCEDURE_FIELDS[procedure]
|
|
308
|
+
for key in required:
|
|
309
|
+
if key not in request.fields:
|
|
310
|
+
raise ExtractionError(f"{request.rr_id}: missing field {key}")
|
|
311
|
+
extra = set(request.fields) - set(required)
|
|
312
|
+
if extra:
|
|
313
|
+
raise ExtractionError(
|
|
314
|
+
f"{request.rr_id}: fields {sorted(extra)} do not belong to "
|
|
315
|
+
f"{procedure}"
|
|
316
|
+
)
|
|
317
|
+
enums = {
|
|
318
|
+
"test_family": TEST_FAMILIES + ("unavailable",),
|
|
319
|
+
"reported_p_comparator": COMPARATORS,
|
|
320
|
+
"tail_convention": TAILS,
|
|
321
|
+
"rounding_rule": ROUNDING_RULES,
|
|
322
|
+
"sd_convention": SD_CONVENTIONS,
|
|
323
|
+
"df_identity_candidate": DF_IDENTITIES,
|
|
324
|
+
"stated_n_relation": N_RELATIONS,
|
|
325
|
+
}
|
|
326
|
+
for key, allowed in enums.items():
|
|
327
|
+
if key in request.fields and request.fields[key] not in allowed:
|
|
328
|
+
raise ExtractionError(
|
|
329
|
+
f"{request.rr_id}: {key} must be one of {allowed}, "
|
|
330
|
+
f"got {request.fields[key]!r}"
|
|
331
|
+
)
|
|
332
|
+
decimals = {
|
|
333
|
+
"p_from_test_statistic": ("reported_p_value",),
|
|
334
|
+
"grim": ("reported_mean",),
|
|
335
|
+
"grimmer": ("reported_mean", "reported_sd"),
|
|
336
|
+
"n_from_df": (),
|
|
337
|
+
}[procedure]
|
|
338
|
+
for key in decimals:
|
|
339
|
+
if not _DECIMAL_RE.fullmatch(request.fields[key]):
|
|
340
|
+
raise ExtractionError(
|
|
341
|
+
f"{request.rr_id}: {key} must be a plain decimal, "
|
|
342
|
+
f"got {request.fields[key]!r}"
|
|
343
|
+
)
|
|
344
|
+
optional_decimal = {"statistic_value"}
|
|
345
|
+
optional_int = {"n", "scale_min", "scale_max", "stated_n"}
|
|
346
|
+
required_int = {"df_reported"}
|
|
347
|
+
for key in optional_decimal & set(request.fields):
|
|
348
|
+
value = request.fields[key]
|
|
349
|
+
if value != "unavailable" and not _DECIMAL_RE.fullmatch(value):
|
|
350
|
+
raise ExtractionError(
|
|
351
|
+
f"{request.rr_id}: {key} must be a decimal or "
|
|
352
|
+
f"'unavailable', got {value!r}"
|
|
353
|
+
)
|
|
354
|
+
for key in (optional_int | required_int) & set(request.fields):
|
|
355
|
+
value = request.fields[key]
|
|
356
|
+
allow_sentinel = key in optional_int
|
|
357
|
+
if not _INT_RE.fullmatch(value) and not (
|
|
358
|
+
allow_sentinel and value == "unavailable"
|
|
359
|
+
):
|
|
360
|
+
raise ExtractionError(
|
|
361
|
+
f"{request.rr_id}: {key} must be an integer"
|
|
362
|
+
+ (" or 'unavailable'" if allow_sentinel else "")
|
|
363
|
+
+ f", got {value!r}"
|
|
364
|
+
)
|
|
365
|
+
if procedure == "p_from_test_statistic":
|
|
366
|
+
df_value = request.fields["df"]
|
|
367
|
+
if df_value not in ("none", "unavailable") and not (
|
|
368
|
+
_INT_RE.fullmatch(df_value) or _DF_PAIR_RE.fullmatch(df_value)
|
|
369
|
+
):
|
|
370
|
+
raise ExtractionError(
|
|
371
|
+
f"{request.rr_id}: df must be an integer, 'int,int', "
|
|
372
|
+
f"'none', or 'unavailable', got {df_value!r}"
|
|
373
|
+
)
|
|
374
|
+
# Family-consistent df shape (codex round 1, P2-2): a t with an F
|
|
375
|
+
# df pair is a transcription slip, and refusing it HERE makes it a
|
|
376
|
+
# retryable gate diagnostic instead of a misleading not_computable
|
|
377
|
+
# receipt downstream.
|
|
378
|
+
family = request.fields["test_family"]
|
|
379
|
+
shape_rules = {
|
|
380
|
+
"t": (lambda v: _INT_RE.fullmatch(v),
|
|
381
|
+
"a single integer df"),
|
|
382
|
+
"chi_square": (lambda v: _INT_RE.fullmatch(v),
|
|
383
|
+
"a single integer df"),
|
|
384
|
+
"z": (lambda v: v == "none", "df 'none'"),
|
|
385
|
+
"F": (lambda v: _DF_PAIR_RE.fullmatch(v), "df as 'df1,df2'"),
|
|
386
|
+
}
|
|
387
|
+
if family in shape_rules and df_value != "unavailable":
|
|
388
|
+
accepts, description = shape_rules[family]
|
|
389
|
+
if not accepts(df_value):
|
|
390
|
+
raise ExtractionError(
|
|
391
|
+
f"{request.rr_id}: a {family} statistic carries "
|
|
392
|
+
f"{description} (or 'unavailable'), got {df_value!r}"
|
|
393
|
+
)
|
|
394
|
+
_validate_numeric_domain(request, procedure)
|
|
395
|
+
|
|
396
|
+
|
|
397
|
+
def _validate_numeric_domain(request: Request, procedure: str) -> None:
|
|
398
|
+
"""Shared gate/calculator domain bounds (security round 1, P1-2/P2-1).
|
|
399
|
+
|
|
400
|
+
Everything accepted here is verified computable: the char cap keeps
|
|
401
|
+
every token far inside float range, the p-magnitude cap is the
|
|
402
|
+
empirically-verified convergence domain of the tail functions, and the
|
|
403
|
+
decimal-places cap bounds every rounding-interval denominator. GRIM /
|
|
404
|
+
GRIMMER magnitudes are deliberately NOT capped here — their compute
|
|
405
|
+
layer refuses over-budget searches with the honest
|
|
406
|
+
`reachability_not_completed` instead.
|
|
407
|
+
"""
|
|
408
|
+
numeric_keys = (
|
|
409
|
+
"statistic_value", "df", "reported_p_value", "n", "reported_mean",
|
|
410
|
+
"scale_min", "scale_max", "reported_sd", "df_reported", "stated_n",
|
|
411
|
+
)
|
|
412
|
+
for key in numeric_keys:
|
|
413
|
+
value = request.fields.get(key)
|
|
414
|
+
if value is None or value in ("unavailable", "none"):
|
|
415
|
+
continue
|
|
416
|
+
for token in re.split(r"[,\s]+", value):
|
|
417
|
+
if len(token) > _MAX_NUMERIC_CHARS:
|
|
418
|
+
raise ExtractionError(
|
|
419
|
+
f"{request.rr_id}: {key} token {token!r} exceeds "
|
|
420
|
+
f"{_MAX_NUMERIC_CHARS} characters; not a plausible "
|
|
421
|
+
"manuscript value"
|
|
422
|
+
)
|
|
423
|
+
decimal_keys = {
|
|
424
|
+
"p_from_test_statistic": ("reported_p_value",),
|
|
425
|
+
"grim": ("reported_mean",),
|
|
426
|
+
"grimmer": ("reported_mean", "reported_sd"),
|
|
427
|
+
"n_from_df": (),
|
|
428
|
+
}[procedure]
|
|
429
|
+
for key in decimal_keys:
|
|
430
|
+
_, places = _parse_decimal(request.fields[key])
|
|
431
|
+
if places > _MAX_DECIMAL_PLACES:
|
|
432
|
+
raise ExtractionError(
|
|
433
|
+
f"{request.rr_id}: {key} reports more than "
|
|
434
|
+
f"{_MAX_DECIMAL_PLACES} decimal places; not a plausible "
|
|
435
|
+
"manuscript precision"
|
|
436
|
+
)
|
|
437
|
+
if procedure == "p_from_test_statistic":
|
|
438
|
+
statistic = request.fields["statistic_value"]
|
|
439
|
+
if statistic != "unavailable" and abs(
|
|
440
|
+
Fraction(statistic)) > _MAX_P_MAGNITUDE:
|
|
441
|
+
raise ExtractionError(
|
|
442
|
+
f"{request.rr_id}: statistic_value exceeds the verified "
|
|
443
|
+
f"convergence domain (|value| <= {_MAX_P_MAGNITUDE})"
|
|
444
|
+
)
|
|
445
|
+
df_value = request.fields["df"]
|
|
446
|
+
if df_value not in ("none", "unavailable"):
|
|
447
|
+
pair = _DF_PAIR_RE.fullmatch(df_value)
|
|
448
|
+
components = (
|
|
449
|
+
(int(pair.group(1)), int(pair.group(2))) if pair
|
|
450
|
+
else (int(df_value),)
|
|
451
|
+
)
|
|
452
|
+
if any(component > _MAX_P_MAGNITUDE
|
|
453
|
+
for component in components):
|
|
454
|
+
raise ExtractionError(
|
|
455
|
+
f"{request.rr_id}: df exceeds the verified "
|
|
456
|
+
f"convergence domain (df <= {_MAX_P_MAGNITUDE})"
|
|
457
|
+
)
|
|
458
|
+
|
|
459
|
+
|
|
460
|
+
# --- exact rational helpers ----------------------------------------------
|
|
461
|
+
|
|
462
|
+
def _parse_decimal(text: str) -> tuple[Fraction, int]:
|
|
463
|
+
"""Exact value and its reported decimal precision."""
|
|
464
|
+
if not _DECIMAL_RE.fullmatch(text):
|
|
465
|
+
raise ExtractionError(f"not a decimal: {text!r}")
|
|
466
|
+
places = len(text.split(".")[1]) if "." in text else 0
|
|
467
|
+
return Fraction(text), places
|
|
468
|
+
|
|
469
|
+
|
|
470
|
+
def _rounds_to(value: Fraction, reported: Fraction, places: int,
|
|
471
|
+
rule: str) -> bool:
|
|
472
|
+
"""Does ``value`` round to ``reported`` at ``places`` decimals?
|
|
473
|
+
|
|
474
|
+
Exact: ties are decided by the named rule, never by binary floating
|
|
475
|
+
point. ``reported`` must be exactly representable at ``places`` (it is:
|
|
476
|
+
it was parsed from that digit string).
|
|
477
|
+
"""
|
|
478
|
+
scale = 10 ** places
|
|
479
|
+
scaled = value * scale
|
|
480
|
+
target = reported * scale
|
|
481
|
+
if target.denominator != 1:
|
|
482
|
+
raise AssertionError("reported value not exact at stated precision")
|
|
483
|
+
floor = scaled.numerator // scaled.denominator
|
|
484
|
+
frac = scaled - floor
|
|
485
|
+
if rule == "half-up":
|
|
486
|
+
# Round half away from zero.
|
|
487
|
+
if scaled >= 0:
|
|
488
|
+
rounded = floor + (1 if frac >= Fraction(1, 2) else 0)
|
|
489
|
+
else:
|
|
490
|
+
rounded = floor + (1 if frac > Fraction(1, 2) else 0)
|
|
491
|
+
elif rule == "half-even":
|
|
492
|
+
if frac > Fraction(1, 2):
|
|
493
|
+
rounded = floor + 1
|
|
494
|
+
elif frac < Fraction(1, 2):
|
|
495
|
+
rounded = floor
|
|
496
|
+
else:
|
|
497
|
+
rounded = floor if floor % 2 == 0 else floor + 1
|
|
498
|
+
elif rule == "truncation":
|
|
499
|
+
# Toward zero.
|
|
500
|
+
rounded = floor if scaled >= 0 else floor + (1 if frac else 0)
|
|
501
|
+
else:
|
|
502
|
+
raise AssertionError(f"unknown rounding rule {rule!r}")
|
|
503
|
+
return rounded == target.numerator
|
|
504
|
+
|
|
505
|
+
|
|
506
|
+
def _fmt_fraction(value: Fraction, places: int) -> str:
|
|
507
|
+
"""Fixed-point decimal rendering of an exact rational (half-up ties)."""
|
|
508
|
+
sign = "-" if value < 0 else ""
|
|
509
|
+
magnitude = abs(value) * 10 ** places
|
|
510
|
+
units = magnitude.numerator // magnitude.denominator
|
|
511
|
+
if magnitude - units >= Fraction(1, 2):
|
|
512
|
+
units += 1
|
|
513
|
+
digits = str(units).rjust(places + 1, "0")
|
|
514
|
+
if places == 0:
|
|
515
|
+
return sign + digits
|
|
516
|
+
return f"{sign}{digits[:-places]}.{digits[-places:]}"
|
|
517
|
+
|
|
518
|
+
|
|
519
|
+
def _fmt_p(value: float) -> str:
|
|
520
|
+
# Near 1, three significant digits would print a literal "1" beside a
|
|
521
|
+
# verdict that depends on the value being below 1 — an internally
|
|
522
|
+
# contradictory receipt (codex round 2). Show enough digits to keep
|
|
523
|
+
# the displayed value on the same side of 1 as the compared one.
|
|
524
|
+
if 0.999 < value < 1.0:
|
|
525
|
+
return f"{value:.12g}"
|
|
526
|
+
return f"{value:.3g}"
|
|
527
|
+
|
|
528
|
+
|
|
529
|
+
def _interval_text(reported: Fraction, places: int, rules: list[str],
|
|
530
|
+
quantity: str) -> str:
|
|
531
|
+
"""The reporting interval under the operative rounding rule(s), stated
|
|
532
|
+
with its true endpoint behavior (codex round 1, P1-2): a receipt must
|
|
533
|
+
never print a half-up-shaped interval for a truncation or ties-to-even
|
|
534
|
+
verdict — the interval line is part of what adjudication audits.
|
|
535
|
+
"""
|
|
536
|
+
step = Fraction(1, 10 ** places)
|
|
537
|
+
half = step / 2
|
|
538
|
+
decimals = places + 1
|
|
539
|
+
if rules == ["truncation"]:
|
|
540
|
+
# Toward zero: [v, v+step) for v > 0, (v-step, v] for v < 0, and
|
|
541
|
+
# BOTH sides for v == 0 — truncation maps (-step, step) to zero
|
|
542
|
+
# (codex round 2).
|
|
543
|
+
if reported == 0:
|
|
544
|
+
return (f"{_fmt_fraction(-step, decimals)} < {quantity} < "
|
|
545
|
+
f"{_fmt_fraction(step, decimals)} (truncation)")
|
|
546
|
+
if reported > 0:
|
|
547
|
+
return (f"{_fmt_fraction(reported, decimals)} <= {quantity} < "
|
|
548
|
+
f"{_fmt_fraction(reported + step, decimals)} "
|
|
549
|
+
"(truncation)")
|
|
550
|
+
return (f"{_fmt_fraction(reported - step, decimals)} < {quantity} "
|
|
551
|
+
f"<= {_fmt_fraction(reported, decimals)} (truncation)")
|
|
552
|
+
low_text = _fmt_fraction(reported - half, decimals)
|
|
553
|
+
high_text = _fmt_fraction(reported + half, decimals)
|
|
554
|
+
if rules == ["half-up"]:
|
|
555
|
+
# Ties away from zero: the tie endpoint on the zero side is
|
|
556
|
+
# included, the other excluded.
|
|
557
|
+
if reported >= 0:
|
|
558
|
+
return (f"{low_text} <= {quantity} < {high_text} "
|
|
559
|
+
"(half-up, ties away from zero)")
|
|
560
|
+
return (f"{low_text} < {quantity} <= {high_text} "
|
|
561
|
+
"(half-up, ties away from zero)")
|
|
562
|
+
if rules == ["half-even"]:
|
|
563
|
+
# Endpoint membership is the target's parity: an even last digit
|
|
564
|
+
# claims both tie endpoints, an odd one claims neither (codex
|
|
565
|
+
# round 2 — the closed-interval display was wrong for odd
|
|
566
|
+
# targets).
|
|
567
|
+
target_even = (reported * 10 ** places).numerator % 2 == 0
|
|
568
|
+
if target_even:
|
|
569
|
+
return (f"{low_text} <= {quantity} <= {high_text} "
|
|
570
|
+
"(ties-to-even; both endpoint ties round to this even "
|
|
571
|
+
"value)")
|
|
572
|
+
return (f"{low_text} < {quantity} < {high_text} (ties-to-even; "
|
|
573
|
+
"the endpoint ties round to the even neighbors)")
|
|
574
|
+
return (f"{low_text} <= {quantity} <= {high_text} (interval interior; "
|
|
575
|
+
"endpoint ties depend on the unstated rule, and a verdict is "
|
|
576
|
+
"issued only where half-up and ties-to-even agree)")
|
|
577
|
+
|
|
578
|
+
|
|
579
|
+
# --- stdlib distribution tails -------------------------------------------
|
|
580
|
+
|
|
581
|
+
def _reg_inc_beta(a: float, b: float, x: float,
|
|
582
|
+
one_minus_x: float | None = None) -> float:
|
|
583
|
+
"""Regularized incomplete beta I_x(a, b), continued-fraction form.
|
|
584
|
+
|
|
585
|
+
Callers that know the complement analytically pass it explicitly: near
|
|
586
|
+
x = 1 the float subtraction 1.0 - x loses every significant digit and a
|
|
587
|
+
near-zero t/F statistic would collapse to exactly 1.0 (codex round 1,
|
|
588
|
+
P1-1) — a wrong verdict, not just a display error.
|
|
589
|
+
"""
|
|
590
|
+
if one_minus_x is None:
|
|
591
|
+
one_minus_x = 1.0 - x
|
|
592
|
+
if x <= 0.0:
|
|
593
|
+
return 0.0
|
|
594
|
+
if one_minus_x <= 0.0:
|
|
595
|
+
return 1.0
|
|
596
|
+
ln_front = (
|
|
597
|
+
math.lgamma(a + b) - math.lgamma(a) - math.lgamma(b)
|
|
598
|
+
+ a * math.log(x) + b * math.log(one_minus_x)
|
|
599
|
+
)
|
|
600
|
+
front = math.exp(ln_front)
|
|
601
|
+
if x < (a + 1.0) / (a + b + 2.0):
|
|
602
|
+
return front * _betacf(a, b, x) / a
|
|
603
|
+
return 1.0 - front * _betacf(b, a, one_minus_x) / b
|
|
604
|
+
|
|
605
|
+
|
|
606
|
+
def _betacf(a: float, b: float, x: float) -> float:
|
|
607
|
+
"""Lentz continued fraction for the incomplete beta (NR §6.4 form)."""
|
|
608
|
+
tiny = 1e-300
|
|
609
|
+
qab, qap, qam = a + b, a + 1.0, a - 1.0
|
|
610
|
+
c = 1.0
|
|
611
|
+
d = 1.0 - qab * x / qap
|
|
612
|
+
if abs(d) < tiny:
|
|
613
|
+
d = tiny
|
|
614
|
+
d = 1.0 / d
|
|
615
|
+
h = d
|
|
616
|
+
for m in range(1, 20000):
|
|
617
|
+
m2 = 2 * m
|
|
618
|
+
numerator = m * (b - m) * x / ((qam + m2) * (a + m2))
|
|
619
|
+
d = 1.0 + numerator * d
|
|
620
|
+
if abs(d) < tiny:
|
|
621
|
+
d = tiny
|
|
622
|
+
c = 1.0 + numerator / c
|
|
623
|
+
if abs(c) < tiny:
|
|
624
|
+
c = tiny
|
|
625
|
+
d = 1.0 / d
|
|
626
|
+
h *= d * c
|
|
627
|
+
numerator = -(a + m) * (qab + m) * x / ((a + m2) * (qap + m2))
|
|
628
|
+
d = 1.0 + numerator * d
|
|
629
|
+
if abs(d) < tiny:
|
|
630
|
+
d = tiny
|
|
631
|
+
c = 1.0 + numerator / c
|
|
632
|
+
if abs(c) < tiny:
|
|
633
|
+
c = tiny
|
|
634
|
+
d = 1.0 / d
|
|
635
|
+
delta = d * c
|
|
636
|
+
h *= delta
|
|
637
|
+
if abs(delta - 1.0) < 1e-14:
|
|
638
|
+
return h
|
|
639
|
+
raise ArithmeticError("incomplete beta failed to converge")
|
|
640
|
+
|
|
641
|
+
|
|
642
|
+
def _reg_gamma_q(a: float, x: float) -> float:
|
|
643
|
+
"""Regularized upper incomplete gamma Q(a, x)."""
|
|
644
|
+
if x < 0.0 or a <= 0.0:
|
|
645
|
+
raise ArithmeticError("invalid incomplete gamma arguments")
|
|
646
|
+
if x == 0.0:
|
|
647
|
+
return 1.0
|
|
648
|
+
if x < a + 1.0:
|
|
649
|
+
# Series for P, complement for Q.
|
|
650
|
+
term = 1.0 / a
|
|
651
|
+
total = term
|
|
652
|
+
current = a
|
|
653
|
+
for _ in range(20000):
|
|
654
|
+
current += 1.0
|
|
655
|
+
term *= x / current
|
|
656
|
+
total += term
|
|
657
|
+
if abs(term) < abs(total) * 1e-15:
|
|
658
|
+
break
|
|
659
|
+
else:
|
|
660
|
+
raise ArithmeticError("incomplete gamma series did not converge")
|
|
661
|
+
ln_p = -x + a * math.log(x) - math.lgamma(a)
|
|
662
|
+
return 1.0 - total * math.exp(ln_p)
|
|
663
|
+
# Lentz continued fraction for Q directly.
|
|
664
|
+
tiny = 1e-300
|
|
665
|
+
b0 = x + 1.0 - a
|
|
666
|
+
c = 1.0 / tiny
|
|
667
|
+
d = 1.0 / b0
|
|
668
|
+
h = d
|
|
669
|
+
for i in range(1, 20000):
|
|
670
|
+
an = -i * (i - a)
|
|
671
|
+
b0 += 2.0
|
|
672
|
+
d = an * d + b0
|
|
673
|
+
if abs(d) < tiny:
|
|
674
|
+
d = tiny
|
|
675
|
+
c = b0 + an / c
|
|
676
|
+
if abs(c) < tiny:
|
|
677
|
+
c = tiny
|
|
678
|
+
d = 1.0 / d
|
|
679
|
+
delta = d * c
|
|
680
|
+
h *= delta
|
|
681
|
+
if abs(delta - 1.0) < 1e-14:
|
|
682
|
+
break
|
|
683
|
+
else:
|
|
684
|
+
raise ArithmeticError("incomplete gamma fraction did not converge")
|
|
685
|
+
ln_front = -x + a * math.log(x) - math.lgamma(a)
|
|
686
|
+
return math.exp(ln_front) * h
|
|
687
|
+
|
|
688
|
+
|
|
689
|
+
def t_tail_two(t: float, df: int) -> float:
|
|
690
|
+
denominator = df + t * t
|
|
691
|
+
return _reg_inc_beta(df / 2.0, 0.5, df / denominator,
|
|
692
|
+
one_minus_x=(t * t) / denominator)
|
|
693
|
+
|
|
694
|
+
|
|
695
|
+
def t_tail_upper(t: float, df: int) -> float:
|
|
696
|
+
half = t_tail_two(t, df) / 2.0
|
|
697
|
+
return half if t >= 0 else 1.0 - half
|
|
698
|
+
|
|
699
|
+
|
|
700
|
+
def z_tail_two(z: float) -> float:
|
|
701
|
+
return math.erfc(abs(z) / math.sqrt(2.0))
|
|
702
|
+
|
|
703
|
+
|
|
704
|
+
def z_tail_upper(z: float) -> float:
|
|
705
|
+
return math.erfc(z / math.sqrt(2.0)) / 2.0
|
|
706
|
+
|
|
707
|
+
|
|
708
|
+
def f_tail_upper(f_value: float, df1: int, df2: int) -> float:
|
|
709
|
+
denominator = df2 + df1 * f_value
|
|
710
|
+
return _reg_inc_beta(df2 / 2.0, df1 / 2.0, df2 / denominator,
|
|
711
|
+
one_minus_x=(df1 * f_value) / denominator)
|
|
712
|
+
|
|
713
|
+
|
|
714
|
+
def chi2_tail_upper(chi2: float, df: int) -> float:
|
|
715
|
+
return _reg_gamma_q(df / 2.0, chi2 / 2.0)
|
|
716
|
+
|
|
717
|
+
|
|
718
|
+
# --- procedure: p_from_test_statistic ------------------------------------
|
|
719
|
+
|
|
720
|
+
_COMPARATOR_TEXT = {
|
|
721
|
+
"equals": "=", "less_than": "<", "less_than_or_equal": "<=",
|
|
722
|
+
"greater_than": ">", "greater_than_or_equal": ">=",
|
|
723
|
+
}
|
|
724
|
+
|
|
725
|
+
|
|
726
|
+
def _p_receipt(request: Request) -> Receipt:
|
|
727
|
+
base = _base_receipt(request)
|
|
728
|
+
base.tail_convention = request["tail_convention"]
|
|
729
|
+
family = request["test_family"]
|
|
730
|
+
comparator = request["reported_p_comparator"]
|
|
731
|
+
reported, places = _parse_decimal(request["reported_p_value"])
|
|
732
|
+
reported_text = request["reported_p_value"]
|
|
733
|
+
|
|
734
|
+
def stop(reason: str, why: str) -> Receipt:
|
|
735
|
+
return _not_computable(base, reason, why)
|
|
736
|
+
|
|
737
|
+
if family == "unavailable":
|
|
738
|
+
return stop("test_family_ambiguous",
|
|
739
|
+
"the test family is not identifiable from the report")
|
|
740
|
+
if request["statistic_value"] == "unavailable":
|
|
741
|
+
return stop("missing_reported_value",
|
|
742
|
+
"the test statistic is not reported")
|
|
743
|
+
statistic = float(Fraction(request["statistic_value"]))
|
|
744
|
+
df_value = request["df"]
|
|
745
|
+
if df_value == "unavailable":
|
|
746
|
+
return stop("missing_reported_value",
|
|
747
|
+
"the degrees of freedom are not reported")
|
|
748
|
+
tail = request["tail_convention"]
|
|
749
|
+
if family in ("F", "chi_square"):
|
|
750
|
+
if tail not in ("upper-tail", "unstated"):
|
|
751
|
+
return stop(
|
|
752
|
+
"nonstandard_p_procedure",
|
|
753
|
+
f"{family} tests are upper-tail by family; a paper-stated "
|
|
754
|
+
f"{tail} p has no bounded procedure here",
|
|
755
|
+
)
|
|
756
|
+
if statistic < 0:
|
|
757
|
+
return stop("nonstandard_p_procedure",
|
|
758
|
+
f"a negative {family} statistic is not interpretable")
|
|
759
|
+
# Family normalization: the receipt names the operative tail. An
|
|
760
|
+
# unstated extraction stays honest about the paper, but F and
|
|
761
|
+
# chi-square are upper-tail by family (§5.1), so the receipt's
|
|
762
|
+
# tail_convention is the family rule — also what exempts these
|
|
763
|
+
# receipts from the both-tails display rule, which has no second
|
|
764
|
+
# tail to show here.
|
|
765
|
+
base.tail_convention = "upper-tail"
|
|
766
|
+
# Tail probabilities per licensed tail label.
|
|
767
|
+
if family == "t":
|
|
768
|
+
if not _INT_RE.fullmatch(df_value):
|
|
769
|
+
return stop("df_identity_ambiguous",
|
|
770
|
+
"a t statistic needs a single integer df")
|
|
771
|
+
df = int(df_value)
|
|
772
|
+
if df < 1:
|
|
773
|
+
return stop("missing_reported_value", "df must be at least 1")
|
|
774
|
+
tails = {
|
|
775
|
+
"two-tailed": t_tail_two(statistic, df),
|
|
776
|
+
"one-tailed": t_tail_two(statistic, df) / 2.0,
|
|
777
|
+
"upper-tail": t_tail_upper(statistic, df),
|
|
778
|
+
}
|
|
779
|
+
derivation = (
|
|
780
|
+
f"t distribution, df={df}: tail probabilities of |t|={abs(statistic)} "
|
|
781
|
+
"via the regularized incomplete beta; the two-tailed value doubles "
|
|
782
|
+
"the one-tailed"
|
|
783
|
+
)
|
|
784
|
+
elif family == "z":
|
|
785
|
+
if df_value != "none":
|
|
786
|
+
return stop("df_identity_ambiguous",
|
|
787
|
+
"a z statistic carries no df; extraction must say "
|
|
788
|
+
"'none'")
|
|
789
|
+
tails = {
|
|
790
|
+
"two-tailed": z_tail_two(statistic),
|
|
791
|
+
"one-tailed": z_tail_two(statistic) / 2.0,
|
|
792
|
+
"upper-tail": z_tail_upper(statistic),
|
|
793
|
+
}
|
|
794
|
+
derivation = (
|
|
795
|
+
f"standard normal: tail probabilities of |z|={abs(statistic)} via "
|
|
796
|
+
"erfc; the two-tailed value doubles the one-tailed"
|
|
797
|
+
)
|
|
798
|
+
elif family == "F":
|
|
799
|
+
pair = _DF_PAIR_RE.fullmatch(df_value)
|
|
800
|
+
if not pair:
|
|
801
|
+
return stop("df_identity_ambiguous",
|
|
802
|
+
"an F statistic needs df as 'df1,df2'")
|
|
803
|
+
df1, df2 = int(pair.group(1)), int(pair.group(2))
|
|
804
|
+
if df1 < 1 or df2 < 1:
|
|
805
|
+
return stop("missing_reported_value",
|
|
806
|
+
"F dfs must be at least 1")
|
|
807
|
+
tails = {"upper-tail": f_tail_upper(statistic, df1, df2)}
|
|
808
|
+
derivation = (
|
|
809
|
+
f"F distribution, df=({df1},{df2}): upper-tail probability of "
|
|
810
|
+
f"F={statistic} via the regularized incomplete beta"
|
|
811
|
+
)
|
|
812
|
+
else: # chi_square
|
|
813
|
+
if not _INT_RE.fullmatch(df_value):
|
|
814
|
+
return stop("df_identity_ambiguous",
|
|
815
|
+
"a chi-square statistic needs a single integer df")
|
|
816
|
+
df = int(df_value)
|
|
817
|
+
if df < 1:
|
|
818
|
+
return stop("missing_reported_value", "df must be at least 1")
|
|
819
|
+
tails = {"upper-tail": chi2_tail_upper(statistic, df)}
|
|
820
|
+
derivation = (
|
|
821
|
+
f"chi-square distribution, df={df}: upper-tail probability of "
|
|
822
|
+
f"chi2={statistic} via the regularized upper incomplete gamma"
|
|
823
|
+
)
|
|
824
|
+
|
|
825
|
+
if family in ("F", "chi_square"):
|
|
826
|
+
candidates = [("upper-tail", tails["upper-tail"])]
|
|
827
|
+
elif tail == "unstated":
|
|
828
|
+
candidates = [
|
|
829
|
+
("two-tailed", tails["two-tailed"]),
|
|
830
|
+
("one-tailed", tails["one-tailed"]),
|
|
831
|
+
]
|
|
832
|
+
else:
|
|
833
|
+
candidates = [(tail, tails[tail])]
|
|
834
|
+
|
|
835
|
+
verdicts = []
|
|
836
|
+
for _, derived in candidates:
|
|
837
|
+
verdict = _compare_p(derived, comparator, reported, places)
|
|
838
|
+
if verdict == "boundary":
|
|
839
|
+
return stop(
|
|
840
|
+
"rounding_boundary_ambiguous",
|
|
841
|
+
"a derived tail probability sits on the reported value's "
|
|
842
|
+
"rounding-interval boundary within numeric tolerance",
|
|
843
|
+
)
|
|
844
|
+
if verdict == "threshold":
|
|
845
|
+
return stop(
|
|
846
|
+
"inequality_unresolvable",
|
|
847
|
+
"a derived tail probability equals the reported inequality "
|
|
848
|
+
"threshold within numeric tolerance",
|
|
849
|
+
)
|
|
850
|
+
verdicts.append(verdict)
|
|
851
|
+
|
|
852
|
+
shown = "; ".join(
|
|
853
|
+
f"p = {_fmt_p(derived)} ({label})" for label, derived in candidates
|
|
854
|
+
)
|
|
855
|
+
base.derivation = derivation
|
|
856
|
+
base.derived_value_or_range = shown
|
|
857
|
+
if comparator == "equals":
|
|
858
|
+
base.comparison_rule = (
|
|
859
|
+
f"reported p = {reported_text} at {places} decimals: a tail is "
|
|
860
|
+
"compatible only if its derived probability falls in that "
|
|
861
|
+
"rounding interval"
|
|
862
|
+
)
|
|
863
|
+
else:
|
|
864
|
+
base.comparison_rule = (
|
|
865
|
+
f"reported p {_COMPARATOR_TEXT[comparator]} {reported_text}: a "
|
|
866
|
+
"tail is compatible only if its derived probability satisfies "
|
|
867
|
+
"the inequality"
|
|
868
|
+
)
|
|
869
|
+
if len(set(verdicts)) > 1:
|
|
870
|
+
return stop(
|
|
871
|
+
"tail_ambiguous",
|
|
872
|
+
"the verdict depends on an unstated tail choice: "
|
|
873
|
+
+ shown,
|
|
874
|
+
)
|
|
875
|
+
base.status = "consistent" if verdicts[0] == "pass" else "mismatch"
|
|
876
|
+
return base
|
|
877
|
+
|
|
878
|
+
|
|
879
|
+
def _compare_p(derived: float, comparator: str, reported: Fraction,
|
|
880
|
+
places: int) -> str:
|
|
881
|
+
reported_f = float(reported)
|
|
882
|
+
if comparator == "equals":
|
|
883
|
+
half = 0.5 * 10.0 ** (-places)
|
|
884
|
+
low, high = reported_f - half, reported_f + half
|
|
885
|
+
if abs(derived - low) < _EPS or abs(derived - high) < _EPS:
|
|
886
|
+
return "boundary"
|
|
887
|
+
return "pass" if low < derived < high else "fail"
|
|
888
|
+
if abs(derived - reported_f) < _EPS:
|
|
889
|
+
return "threshold"
|
|
890
|
+
satisfied = {
|
|
891
|
+
"less_than": derived < reported_f,
|
|
892
|
+
"less_than_or_equal": derived <= reported_f,
|
|
893
|
+
"greater_than": derived > reported_f,
|
|
894
|
+
"greater_than_or_equal": derived >= reported_f,
|
|
895
|
+
}[comparator]
|
|
896
|
+
return "pass" if satisfied else "fail"
|
|
897
|
+
|
|
898
|
+
|
|
899
|
+
# --- procedure: grim ------------------------------------------------------
|
|
900
|
+
|
|
901
|
+
def _grim_rules(request: Request) -> list[str]:
|
|
902
|
+
rule = request["rounding_rule"]
|
|
903
|
+
return ["half-up", "half-even"] if rule == "unstated" else [rule]
|
|
904
|
+
|
|
905
|
+
|
|
906
|
+
def _grim_ints(request: Request, base: Receipt) -> tuple | Receipt:
|
|
907
|
+
if request["n"] == "unavailable":
|
|
908
|
+
return _not_computable(base, "analytic_n_ambiguous",
|
|
909
|
+
"the item-specific analytic N is not reported")
|
|
910
|
+
if request["scale_min"] == "unavailable" or (
|
|
911
|
+
request["scale_max"] == "unavailable"):
|
|
912
|
+
return _not_computable(base, "scale_support_unknown",
|
|
913
|
+
"the response-scale support is not reported")
|
|
914
|
+
n = int(request["n"])
|
|
915
|
+
lo, hi = int(request["scale_min"]), int(request["scale_max"])
|
|
916
|
+
if n < 1 or lo > hi:
|
|
917
|
+
return _not_computable(base, "scale_support_unknown",
|
|
918
|
+
"N or the scale bounds are not interpretable")
|
|
919
|
+
return n, lo, hi
|
|
920
|
+
|
|
921
|
+
|
|
922
|
+
def _reachable_sums(n: int, lo: int, hi: int, reported: Fraction,
|
|
923
|
+
places: int, rule: str) -> list[int]:
|
|
924
|
+
step = Fraction(1, 10 ** places)
|
|
925
|
+
window_low = max(n * lo, math.floor((reported - step) * n) - 1)
|
|
926
|
+
window_high = min(n * hi, math.ceil((reported + step) * n) + 1)
|
|
927
|
+
if window_high - window_low > _SUM_WINDOW_BUDGET:
|
|
928
|
+
raise _BudgetExceeded
|
|
929
|
+
return [
|
|
930
|
+
total for total in range(window_low, window_high + 1)
|
|
931
|
+
if _rounds_to(Fraction(total, n), reported, places, rule)
|
|
932
|
+
]
|
|
933
|
+
|
|
934
|
+
|
|
935
|
+
def _grim_neighbors(n: int, lo: int, hi: int,
|
|
936
|
+
reported: Fraction) -> list[tuple[int, Fraction]]:
|
|
937
|
+
target = reported * n
|
|
938
|
+
below = math.floor(target)
|
|
939
|
+
above = below + 1
|
|
940
|
+
neighbors = []
|
|
941
|
+
for total in (below, above):
|
|
942
|
+
clamped = min(max(total, n * lo), n * hi)
|
|
943
|
+
neighbors.append((clamped, Fraction(clamped, n)))
|
|
944
|
+
return neighbors
|
|
945
|
+
|
|
946
|
+
|
|
947
|
+
def _grim_receipt(request: Request) -> Receipt:
|
|
948
|
+
base = _base_receipt(request)
|
|
949
|
+
ints = _grim_ints(request, base)
|
|
950
|
+
if isinstance(ints, Receipt):
|
|
951
|
+
return ints
|
|
952
|
+
n, lo, hi = ints
|
|
953
|
+
reported, places = _parse_decimal(request["reported_mean"])
|
|
954
|
+
mean_text = request["reported_mean"]
|
|
955
|
+
rules = _grim_rules(request)
|
|
956
|
+
try:
|
|
957
|
+
reachable = {rule: _reachable_sums(n, lo, hi, reported, places, rule)
|
|
958
|
+
for rule in rules}
|
|
959
|
+
except _BudgetExceeded:
|
|
960
|
+
return _not_computable(
|
|
961
|
+
base, "reachability_not_completed",
|
|
962
|
+
"the candidate-sum search exceeds this calculator's documented "
|
|
963
|
+
"window budget",
|
|
964
|
+
)
|
|
965
|
+
verdicts = {rule: bool(sums) for rule, sums in reachable.items()}
|
|
966
|
+
interval = _interval_text(reported, places, rules, "mean")
|
|
967
|
+
neighbor_places = max(places + 1, 4)
|
|
968
|
+
neighbors = "; ".join(
|
|
969
|
+
f"{total}/{n} = {_fmt_fraction(value, neighbor_places)}"
|
|
970
|
+
for total, value in _grim_neighbors(n, lo, hi, reported)
|
|
971
|
+
)
|
|
972
|
+
base.derivation = (
|
|
973
|
+
f"an unweighted mean of N={n} integer responses on [{lo},{hi}] must "
|
|
974
|
+
f"be an integer sum divided by {n}; candidate sums range over "
|
|
975
|
+
f"[{n * lo},{n * hi}]"
|
|
976
|
+
)
|
|
977
|
+
base.comparison_rule = (
|
|
978
|
+
f"the reported mean {mean_text} at {places} decimals is reachable "
|
|
979
|
+
"only if some integer sum lands in its rounding interval under "
|
|
980
|
+
+ ("the stated rounding rule" if len(rules) == 1
|
|
981
|
+
else "every conventional rounding rule (half-up, half-even)")
|
|
982
|
+
)
|
|
983
|
+
base.rounding_interval = interval
|
|
984
|
+
if len(set(verdicts.values())) > 1:
|
|
985
|
+
return _not_computable(
|
|
986
|
+
base, "rounding_rule_ambiguous",
|
|
987
|
+
"reachability changes with the unstated rounding rule",
|
|
988
|
+
)
|
|
989
|
+
reachable_now = next(iter(verdicts.values()))
|
|
990
|
+
if reachable_now:
|
|
991
|
+
achieving = reachable[rules[0]][0]
|
|
992
|
+
base.derived_value_or_range = (
|
|
993
|
+
f"sum {achieving} gives {achieving}/{n} = "
|
|
994
|
+
f"{_fmt_fraction(Fraction(achieving, n), neighbor_places)}, "
|
|
995
|
+
f"which rounds to {mean_text}"
|
|
996
|
+
)
|
|
997
|
+
base.nearest_achievable = (
|
|
998
|
+
f"achieving sum {achieving}; adjacent sums {neighbors}"
|
|
999
|
+
)
|
|
1000
|
+
base.status = "consistent"
|
|
1001
|
+
else:
|
|
1002
|
+
base.derived_value_or_range = (
|
|
1003
|
+
f"no integer sum in [{n * lo},{n * hi}] rounds to {mean_text} "
|
|
1004
|
+
f"at {places} decimals"
|
|
1005
|
+
)
|
|
1006
|
+
base.nearest_achievable = neighbors
|
|
1007
|
+
base.status = "mismatch"
|
|
1008
|
+
return base
|
|
1009
|
+
|
|
1010
|
+
|
|
1011
|
+
# --- procedure: grimmer ---------------------------------------------------
|
|
1012
|
+
|
|
1013
|
+
class _BudgetExceeded(Exception):
|
|
1014
|
+
pass
|
|
1015
|
+
|
|
1016
|
+
|
|
1017
|
+
def _attainable_sumsq(n: int, lo: int, hi: int, total: int) -> frozenset:
|
|
1018
|
+
"""Every attainable sum of squares over n integers in [lo, hi] summing
|
|
1019
|
+
to ``total``. Memoized exhaustive enumeration; raises when the state
|
|
1020
|
+
budget is exceeded rather than approximating."""
|
|
1021
|
+
values = list(range(lo, hi + 1))
|
|
1022
|
+
cache: dict[tuple[int, int, int], frozenset] = {}
|
|
1023
|
+
retained = 0
|
|
1024
|
+
work = 0
|
|
1025
|
+
|
|
1026
|
+
def rec(index: int, count: int, remaining: int) -> frozenset:
|
|
1027
|
+
nonlocal retained, work
|
|
1028
|
+
if count == 0:
|
|
1029
|
+
return frozenset({0}) if remaining == 0 else frozenset()
|
|
1030
|
+
if index == len(values) - 1:
|
|
1031
|
+
value = values[index]
|
|
1032
|
+
if remaining == value * count:
|
|
1033
|
+
return frozenset({value * value * count})
|
|
1034
|
+
return frozenset()
|
|
1035
|
+
key = (index, count, remaining)
|
|
1036
|
+
if key in cache:
|
|
1037
|
+
return cache[key]
|
|
1038
|
+
if len(cache) > _STATE_BUDGET or retained > _ELEMENT_BUDGET:
|
|
1039
|
+
raise _BudgetExceeded
|
|
1040
|
+
value = values[index]
|
|
1041
|
+
rest_lo, rest_hi = values[index + 1], values[-1]
|
|
1042
|
+
results = set()
|
|
1043
|
+
for chosen in range(count + 1):
|
|
1044
|
+
# The work counter bounds ITERATIONS, not just states: a long
|
|
1045
|
+
# infeasible prefix creates no cache entry, so a state-count
|
|
1046
|
+
# budget alone could spin unbounded before ever firing
|
|
1047
|
+
# (security round 2, NEW-2).
|
|
1048
|
+
work += 1
|
|
1049
|
+
if work > _WORK_BUDGET:
|
|
1050
|
+
raise _BudgetExceeded
|
|
1051
|
+
left = count - chosen
|
|
1052
|
+
leftover = remaining - chosen * value
|
|
1053
|
+
if not left * rest_lo <= leftover <= left * rest_hi:
|
|
1054
|
+
continue
|
|
1055
|
+
for sub in rec(index + 1, left, leftover):
|
|
1056
|
+
results.add(chosen * value * value + sub)
|
|
1057
|
+
frozen = frozenset(results)
|
|
1058
|
+
cache[key] = frozen
|
|
1059
|
+
retained += len(frozen)
|
|
1060
|
+
return frozen
|
|
1061
|
+
|
|
1062
|
+
return rec(0, n, total)
|
|
1063
|
+
|
|
1064
|
+
|
|
1065
|
+
def _sd_reachable(variances: set[Fraction], reported: Fraction, places: int,
|
|
1066
|
+
rule: str) -> bool:
|
|
1067
|
+
"""Is any attainable SD (given as its exact square) reportable as
|
|
1068
|
+
``reported`` at ``places`` decimals under ``rule``? Decided on SD^2, so
|
|
1069
|
+
only a rational SD exactly on an interval endpoint needs the tie rule."""
|
|
1070
|
+
step = Fraction(1, 10 ** places)
|
|
1071
|
+
if rule == "truncation":
|
|
1072
|
+
low, high = reported, reported + step
|
|
1073
|
+
low_closed = True
|
|
1074
|
+
else:
|
|
1075
|
+
half = step / 2
|
|
1076
|
+
low, high = reported - half, reported + half
|
|
1077
|
+
low_closed = None # endpoint membership decided by the tie rule
|
|
1078
|
+
if high <= 0:
|
|
1079
|
+
# A nonpositive reporting interval is unreachable outright: an SD
|
|
1080
|
+
# is nonnegative by definition, and clamping only the lower
|
|
1081
|
+
# endpoint before squaring silently inverted the interval for a
|
|
1082
|
+
# negative reported SD (codex round 1, P1-3).
|
|
1083
|
+
return False
|
|
1084
|
+
low = max(low, Fraction(0))
|
|
1085
|
+
low_sq, high_sq = low * low, high * high
|
|
1086
|
+
for variance in variances:
|
|
1087
|
+
if low_sq < variance < high_sq:
|
|
1088
|
+
return True
|
|
1089
|
+
for endpoint, square in ((low, low_sq), (high, high_sq)):
|
|
1090
|
+
if variance == square:
|
|
1091
|
+
# SD is exactly the rational endpoint; ask the tie rule.
|
|
1092
|
+
if rule == "truncation":
|
|
1093
|
+
if endpoint == low and low_closed:
|
|
1094
|
+
return True
|
|
1095
|
+
elif _rounds_to(endpoint, reported, places, rule):
|
|
1096
|
+
return True
|
|
1097
|
+
return False
|
|
1098
|
+
|
|
1099
|
+
|
|
1100
|
+
def _grimmer_receipt(request: Request) -> Receipt:
|
|
1101
|
+
base = _base_receipt(request)
|
|
1102
|
+
ints = _grim_ints(request, base)
|
|
1103
|
+
if isinstance(ints, Receipt):
|
|
1104
|
+
return ints
|
|
1105
|
+
n, lo, hi = ints
|
|
1106
|
+
convention = request["sd_convention"]
|
|
1107
|
+
if n < 2:
|
|
1108
|
+
# A population SD is defined (zero) for one response; a sample SD
|
|
1109
|
+
# is not (codex round 1, P2-1). Only the genuinely undefined or
|
|
1110
|
+
# convention-dependent cases stop here.
|
|
1111
|
+
if convention == "sample":
|
|
1112
|
+
return _not_computable(
|
|
1113
|
+
base, "analytic_n_ambiguous",
|
|
1114
|
+
"a sample SD is undefined for a single response")
|
|
1115
|
+
if convention == "unstated":
|
|
1116
|
+
return _not_computable(
|
|
1117
|
+
base, "sd_convention_unknown",
|
|
1118
|
+
"with one response a population SD is defined (zero) but "
|
|
1119
|
+
"a sample SD is not; the verdict depends on the unstated "
|
|
1120
|
+
"convention")
|
|
1121
|
+
mean_reported, mean_places = _parse_decimal(request["reported_mean"])
|
|
1122
|
+
sd_reported, sd_places = _parse_decimal(request["reported_sd"])
|
|
1123
|
+
sd_text = request["reported_sd"]
|
|
1124
|
+
rules = _grim_rules(request)
|
|
1125
|
+
conventions = (
|
|
1126
|
+
["sample", "population"] if convention == "unstated"
|
|
1127
|
+
else [convention]
|
|
1128
|
+
)
|
|
1129
|
+
per_rule: dict[str, dict[str, str]] = {}
|
|
1130
|
+
variance_sets: dict[str, dict[str, set[Fraction]]] = {}
|
|
1131
|
+
try:
|
|
1132
|
+
for rule in rules:
|
|
1133
|
+
sums = _reachable_sums(n, lo, hi, mean_reported, mean_places,
|
|
1134
|
+
rule)
|
|
1135
|
+
if not sums:
|
|
1136
|
+
per_rule[rule] = {conv: "mean_fail" for conv in conventions}
|
|
1137
|
+
continue
|
|
1138
|
+
variances: dict[str, set[Fraction]] = {
|
|
1139
|
+
conv: set() for conv in conventions
|
|
1140
|
+
}
|
|
1141
|
+
for total in sums:
|
|
1142
|
+
for sumsq in _attainable_sumsq(n, lo, hi, total):
|
|
1143
|
+
centered = Fraction(sumsq) - Fraction(total * total, n)
|
|
1144
|
+
if "sample" in variances:
|
|
1145
|
+
variances["sample"].add(centered / (n - 1))
|
|
1146
|
+
if "population" in variances:
|
|
1147
|
+
variances["population"].add(centered / n)
|
|
1148
|
+
# n == 1 reaches here only as population-stated, where
|
|
1149
|
+
# centered is identically zero; the sample division
|
|
1150
|
+
# above is guarded by the n < 2 gate.
|
|
1151
|
+
variance_sets[rule] = variances
|
|
1152
|
+
per_rule[rule] = {
|
|
1153
|
+
conv: (
|
|
1154
|
+
"reachable"
|
|
1155
|
+
if _sd_reachable(variances[conv], sd_reported,
|
|
1156
|
+
sd_places, rule)
|
|
1157
|
+
else "unreachable"
|
|
1158
|
+
)
|
|
1159
|
+
for conv in conventions
|
|
1160
|
+
}
|
|
1161
|
+
except _BudgetExceeded:
|
|
1162
|
+
return _not_computable(
|
|
1163
|
+
base, "reachability_not_completed",
|
|
1164
|
+
"the exhaustive feasible-value search exceeds this calculator's "
|
|
1165
|
+
"documented state budget",
|
|
1166
|
+
)
|
|
1167
|
+
|
|
1168
|
+
base.derivation = (
|
|
1169
|
+
f"mean-compatible integer sums are enumerated first (GRIM); for "
|
|
1170
|
+
f"each, every attainable sum of squares over N={n} responses on "
|
|
1171
|
+
f"[{lo},{hi}] is enumerated exhaustively and the implied SD is "
|
|
1172
|
+
"compared exactly on its square"
|
|
1173
|
+
)
|
|
1174
|
+
base.rounding_interval = _interval_text(
|
|
1175
|
+
sd_reported, sd_places, rules, "SD")
|
|
1176
|
+
base.comparison_rule = (
|
|
1177
|
+
f"the reported SD {sd_text} at {sd_places} decimals is reachable "
|
|
1178
|
+
"only if some attainable SD lands in its rounding interval; "
|
|
1179
|
+
+ ("the stated " if len(rules) == 1 else "every conventional ")
|
|
1180
|
+
+ "rounding rule applies to the mean and the SD alike"
|
|
1181
|
+
)
|
|
1182
|
+
# Decision order (documented, deterministic): the mean's own GRIM gate
|
|
1183
|
+
# first; then an unstated rounding rule that changes any verdict; then
|
|
1184
|
+
# an unstated SD convention that does.
|
|
1185
|
+
mean_failed = [
|
|
1186
|
+
rule for rule in rules
|
|
1187
|
+
if per_rule[rule][conventions[0]] == "mean_fail"
|
|
1188
|
+
]
|
|
1189
|
+
if len(mean_failed) == len(rules):
|
|
1190
|
+
return _not_computable(
|
|
1191
|
+
base, "mean_grim_inconsistent",
|
|
1192
|
+
"the reported mean is itself GRIM-inconsistent, so no response "
|
|
1193
|
+
"set exists whose SD could be checked",
|
|
1194
|
+
)
|
|
1195
|
+
if mean_failed:
|
|
1196
|
+
return _not_computable(
|
|
1197
|
+
base, "rounding_rule_ambiguous",
|
|
1198
|
+
"the mean is reachable under one unstated rounding rule and "
|
|
1199
|
+
"unreachable under another",
|
|
1200
|
+
)
|
|
1201
|
+
for conv in conventions:
|
|
1202
|
+
if len({per_rule[rule][conv] for rule in rules}) > 1:
|
|
1203
|
+
return _not_computable(
|
|
1204
|
+
base, "rounding_rule_ambiguous",
|
|
1205
|
+
"reachability changes with the unstated rounding rule",
|
|
1206
|
+
)
|
|
1207
|
+
outcomes = {per_rule[rules[0]][conv] for conv in conventions}
|
|
1208
|
+
if len(outcomes) > 1:
|
|
1209
|
+
return _not_computable(
|
|
1210
|
+
base, "sd_convention_unknown",
|
|
1211
|
+
"the verdict depends on whether the reported SD is the sample "
|
|
1212
|
+
"or the population statistic",
|
|
1213
|
+
)
|
|
1214
|
+
outcome = outcomes.pop()
|
|
1215
|
+
first_rule = rules[0]
|
|
1216
|
+
conv_label = (
|
|
1217
|
+
conventions[0] if len(conventions) == 1
|
|
1218
|
+
else "sample-or-population"
|
|
1219
|
+
)
|
|
1220
|
+
variances = variance_sets[first_rule][conventions[0]]
|
|
1221
|
+
nearest = _nearest_sds(variances, sd_reported)
|
|
1222
|
+
base.nearest_achievable = nearest
|
|
1223
|
+
if outcome == "reachable":
|
|
1224
|
+
base.derived_value_or_range = (
|
|
1225
|
+
f"an attainable {conv_label} SD rounds to {sd_text}; nearest "
|
|
1226
|
+
f"attainable values: {nearest}"
|
|
1227
|
+
)
|
|
1228
|
+
base.status = "consistent"
|
|
1229
|
+
else:
|
|
1230
|
+
base.derived_value_or_range = (
|
|
1231
|
+
f"no attainable {conv_label} SD rounds to {sd_text} at "
|
|
1232
|
+
f"{sd_places} decimals; nearest attainable values: {nearest}"
|
|
1233
|
+
)
|
|
1234
|
+
base.status = "mismatch"
|
|
1235
|
+
return base
|
|
1236
|
+
|
|
1237
|
+
|
|
1238
|
+
def _nearest_sds(variances: set[Fraction], reported: Fraction) -> str:
|
|
1239
|
+
if not variances:
|
|
1240
|
+
return "none (no attainable response set)"
|
|
1241
|
+
reported_sq = reported * reported
|
|
1242
|
+
below = [v for v in variances if v <= reported_sq]
|
|
1243
|
+
above = [v for v in variances if v >= reported_sq]
|
|
1244
|
+
parts = []
|
|
1245
|
+
if below:
|
|
1246
|
+
parts.append(f"SD = {math.sqrt(max(below)):.4f}")
|
|
1247
|
+
if above:
|
|
1248
|
+
parts.append(f"SD = {math.sqrt(min(above)):.4f}")
|
|
1249
|
+
return " and ".join(parts)
|
|
1250
|
+
|
|
1251
|
+
|
|
1252
|
+
# --- procedure: n_from_df -------------------------------------------------
|
|
1253
|
+
|
|
1254
|
+
_IDENTITY_OFFSETS = {"df=N-1": 1, "df=N1+N2-2": 2}
|
|
1255
|
+
|
|
1256
|
+
|
|
1257
|
+
def _n_from_df_receipt(request: Request) -> Receipt:
|
|
1258
|
+
base = _base_receipt(request)
|
|
1259
|
+
identity = request["df_identity_candidate"]
|
|
1260
|
+
if identity == "other_or_corrected":
|
|
1261
|
+
return _not_computable(
|
|
1262
|
+
base, "model_correction_or_pooling",
|
|
1263
|
+
"the analysis uses a corrected, pooled, or model-based df whose "
|
|
1264
|
+
"required inputs are not present",
|
|
1265
|
+
)
|
|
1266
|
+
if identity == "unavailable":
|
|
1267
|
+
return _not_computable(
|
|
1268
|
+
base, "df_identity_ambiguous",
|
|
1269
|
+
"no test-specific df identity is identifiable from the report",
|
|
1270
|
+
)
|
|
1271
|
+
if request["stated_n"] == "unavailable" or (
|
|
1272
|
+
request["stated_n_relation"] == "unavailable"):
|
|
1273
|
+
return _not_computable(
|
|
1274
|
+
base, "missing_reported_value",
|
|
1275
|
+
"no manuscript N claim is available to compare the implied N "
|
|
1276
|
+
"against",
|
|
1277
|
+
)
|
|
1278
|
+
df_reported = int(request["df_reported"])
|
|
1279
|
+
stated_n = int(request["stated_n"])
|
|
1280
|
+
relation = request["stated_n_relation"]
|
|
1281
|
+
implied = df_reported + _IDENTITY_OFFSETS[identity]
|
|
1282
|
+
ceiling_note = (
|
|
1283
|
+
"; Welch-Satterthwaite df cannot exceed the ordinary total-df "
|
|
1284
|
+
"ceiling, so every variant needs at least this N"
|
|
1285
|
+
if identity == "df=N1+N2-2" else ""
|
|
1286
|
+
)
|
|
1287
|
+
base.derivation = (
|
|
1288
|
+
f"{identity} gives implied N = {df_reported} + "
|
|
1289
|
+
f"{_IDENTITY_OFFSETS[identity]} = {implied}{ceiling_note}"
|
|
1290
|
+
)
|
|
1291
|
+
base.derived_value_or_range = f"implied N = {implied}"
|
|
1292
|
+
relation_text = {
|
|
1293
|
+
"equals": f"must equal the stated N = {stated_n}",
|
|
1294
|
+
"at_most": f"must not exceed the stated bound N <= {stated_n}",
|
|
1295
|
+
"at_least": f"must not fall below the stated bound N >= {stated_n}",
|
|
1296
|
+
}[relation]
|
|
1297
|
+
base.comparison_rule = f"the implied N {relation_text}"
|
|
1298
|
+
mismatch = {
|
|
1299
|
+
"equals": implied != stated_n,
|
|
1300
|
+
"at_most": implied > stated_n,
|
|
1301
|
+
"at_least": implied < stated_n,
|
|
1302
|
+
}[relation]
|
|
1303
|
+
base.df_identity = identity
|
|
1304
|
+
base.status = "mismatch" if mismatch else "consistent"
|
|
1305
|
+
return base
|
|
1306
|
+
|
|
1307
|
+
|
|
1308
|
+
# --- receipt assembly -----------------------------------------------------
|
|
1309
|
+
|
|
1310
|
+
def _base_receipt(request: Request) -> Receipt:
|
|
1311
|
+
return Receipt(
|
|
1312
|
+
procedure_id=request["procedure_id"],
|
|
1313
|
+
evidence_anchor=request["evidence_anchor"],
|
|
1314
|
+
reported_inputs=request["reported_inputs"],
|
|
1315
|
+
assumptions=request["assumptions"],
|
|
1316
|
+
derivation="", derived_value_or_range="", comparison_rule="",
|
|
1317
|
+
status="",
|
|
1318
|
+
)
|
|
1319
|
+
|
|
1320
|
+
|
|
1321
|
+
def _not_computable(base: Receipt, reason: str, why: str) -> Receipt:
|
|
1322
|
+
base.status = "not_computable"
|
|
1323
|
+
base.not_computable_reason = reason
|
|
1324
|
+
if not base.derivation:
|
|
1325
|
+
base.derivation = f"stopped before derivation: {why}"
|
|
1326
|
+
if not base.derived_value_or_range:
|
|
1327
|
+
base.derived_value_or_range = "none (procedure stopped)"
|
|
1328
|
+
if not base.comparison_rule:
|
|
1329
|
+
base.comparison_rule = "none (no comparison was licensed)"
|
|
1330
|
+
return base
|
|
1331
|
+
|
|
1332
|
+
|
|
1333
|
+
_PROCEDURE_IMPL = {
|
|
1334
|
+
"p_from_test_statistic": _p_receipt,
|
|
1335
|
+
"grim": _grim_receipt,
|
|
1336
|
+
"grimmer": _grimmer_receipt,
|
|
1337
|
+
"n_from_df": _n_from_df_receipt,
|
|
1338
|
+
}
|
|
1339
|
+
|
|
1340
|
+
|
|
1341
|
+
def compute_receipts(extraction: Extraction) -> str:
|
|
1342
|
+
"""Render the full ``## Arithmetic Receipts`` section, trailing newline
|
|
1343
|
+
included. ``finding_ref:`` is never emitted here — linkage is the seat's
|
|
1344
|
+
Phase 2 judgment, enforced by the injected-receipt identity gate."""
|
|
1345
|
+
lines = [f"## {RECEIPT_SECTION}", ""]
|
|
1346
|
+
if extraction.attestation is not None:
|
|
1347
|
+
lines.append(f"{ATTESTATION_KEY}: {extraction.attestation}")
|
|
1348
|
+
return "\n".join(lines) + "\n"
|
|
1349
|
+
for index, request in enumerate(extraction.requests, start=1):
|
|
1350
|
+
receipt = _PROCEDURE_IMPL[request["procedure_id"]](request)
|
|
1351
|
+
lines.append(f"### AR{index}")
|
|
1352
|
+
lines.append(f"procedure_id: {receipt.procedure_id}")
|
|
1353
|
+
lines.append(f"evidence_anchor: {receipt.evidence_anchor}")
|
|
1354
|
+
lines.append(f"reported_inputs: {receipt.reported_inputs}")
|
|
1355
|
+
lines.append(f"assumptions: {receipt.assumptions}")
|
|
1356
|
+
lines.append(f"derivation: {receipt.derivation}")
|
|
1357
|
+
lines.append(
|
|
1358
|
+
f"derived_value_or_range: {receipt.derived_value_or_range}"
|
|
1359
|
+
)
|
|
1360
|
+
lines.append(f"comparison_rule: {receipt.comparison_rule}")
|
|
1361
|
+
lines.append(f"status: {receipt.status}")
|
|
1362
|
+
if receipt.not_computable_reason is not None:
|
|
1363
|
+
lines.append(
|
|
1364
|
+
f"not_computable_reason: {receipt.not_computable_reason}"
|
|
1365
|
+
)
|
|
1366
|
+
if receipt.tail_convention is not None:
|
|
1367
|
+
lines.append(f"tail_convention: {receipt.tail_convention}")
|
|
1368
|
+
if receipt.rounding_interval is not None and receipt.status in (
|
|
1369
|
+
"consistent", "mismatch"):
|
|
1370
|
+
lines.append(f"rounding_interval: {receipt.rounding_interval}")
|
|
1371
|
+
if receipt.nearest_achievable is not None and receipt.status in (
|
|
1372
|
+
"consistent", "mismatch"):
|
|
1373
|
+
lines.append(f"nearest_achievable: {receipt.nearest_achievable}")
|
|
1374
|
+
if receipt.df_identity is not None:
|
|
1375
|
+
lines.append(f"df_identity: {receipt.df_identity}")
|
|
1376
|
+
lines.append("")
|
|
1377
|
+
while lines and lines[-1] == "":
|
|
1378
|
+
lines.pop()
|
|
1379
|
+
return "\n".join(lines) + "\n"
|
|
1380
|
+
|
|
1381
|
+
|
|
1382
|
+
def main(argv=None) -> int:
|
|
1383
|
+
parser = argparse.ArgumentParser(description=__doc__)
|
|
1384
|
+
parser.add_argument("--extraction", required=True, type=Path)
|
|
1385
|
+
parser.add_argument("--output", required=True, type=Path)
|
|
1386
|
+
args = parser.parse_args(argv)
|
|
1387
|
+
try:
|
|
1388
|
+
text = args.extraction.read_text(encoding="utf-8")
|
|
1389
|
+
except OSError as exc:
|
|
1390
|
+
print(f"cannot read extraction: {exc}", file=sys.stderr)
|
|
1391
|
+
return 2
|
|
1392
|
+
try:
|
|
1393
|
+
extraction = parse_extraction(text)
|
|
1394
|
+
receipts = compute_receipts(extraction)
|
|
1395
|
+
except (ExtractionError, ArithmeticError) as exc:
|
|
1396
|
+
print(f"extraction rejected: {exc}", file=sys.stderr)
|
|
1397
|
+
return 2
|
|
1398
|
+
try:
|
|
1399
|
+
# Exclusive create: the receipts file is bundle evidence and joins
|
|
1400
|
+
# the harness's write-once discipline (security round 1, P3-1).
|
|
1401
|
+
# newline="\n" pins the artifact bytes: default newline translation
|
|
1402
|
+
# would emit CRLF on Windows and the identity gate compares bytes
|
|
1403
|
+
# (codex round 1, P2-5).
|
|
1404
|
+
with args.output.open("x", encoding="utf-8",
|
|
1405
|
+
newline="\n") as stream:
|
|
1406
|
+
stream.write(receipts)
|
|
1407
|
+
except OSError as exc:
|
|
1408
|
+
print(f"cannot write receipts: {exc}", file=sys.stderr)
|
|
1409
|
+
return 2
|
|
1410
|
+
return 0
|
|
1411
|
+
|
|
1412
|
+
|
|
1413
|
+
if __name__ == "__main__":
|
|
1414
|
+
sys.exit(main())
|