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,1622 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
"""Hermetic contract guard for revision_claim_drift suite v2 (#679).
|
|
3
|
+
|
|
4
|
+
This checker never invokes a model, judge, adjudicator, network API, or eval
|
|
5
|
+
runner. It validates repository-owned bytes and prospective record bindings.
|
|
6
|
+
"""
|
|
7
|
+
|
|
8
|
+
from __future__ import annotations
|
|
9
|
+
|
|
10
|
+
import argparse
|
|
11
|
+
import copy
|
|
12
|
+
import datetime as dt
|
|
13
|
+
import hashlib
|
|
14
|
+
import json
|
|
15
|
+
import os
|
|
16
|
+
import re
|
|
17
|
+
import stat
|
|
18
|
+
import sys
|
|
19
|
+
from pathlib import Path
|
|
20
|
+
from typing import Any, Iterable, Mapping, Sequence
|
|
21
|
+
|
|
22
|
+
from jsonschema import Draft202012Validator, FormatChecker
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
REPO_ROOT = Path(__file__).resolve().parents[1]
|
|
26
|
+
SUITE_REL = "evals/heldout/revision_claim_drift"
|
|
27
|
+
SUITE = Path(SUITE_REL)
|
|
28
|
+
RUNS_PREFIX = f"{SUITE_REL}/runs/"
|
|
29
|
+
|
|
30
|
+
V1_RUBRIC_SHA256 = "56e014d5da2c9074afa7d327803caa2de0e16c864cf0374e4cd1f3cf90e35863"
|
|
31
|
+
V2_RUBRIC_SHA256 = "6bb537807f7f0ab02ae2379764551aa0896ca9390919a69cc5812e2f889a315d"
|
|
32
|
+
CLAIM_LADDER_SHA256 = "22f51a6fefb2525e685b6938cc446fa658bdfb6e43157b5d2e6d5051f2212dfe"
|
|
33
|
+
SUBJECT_SCHEMA_SHA256 = "c6c317610958cb72f7370d6c2099b93dfebae77381381122aea70d960799e4ab"
|
|
34
|
+
LAUNCHER_SCHEMA_SHA256 = "897ea22dc64af59e787976e161e687a2b20b52a9ca16f8ef6c22bee8eeba5070"
|
|
35
|
+
CALL_PLAN_SCHEMA_SHA256 = "360ca3f54fa653c79550df61609dc14714d9f628f955376178d30bd75ff4e647"
|
|
36
|
+
HISTORICAL_TREE_SHA256 = "71dcc3bd6a391c80a38fbe504970ac5e0780be9deb3ef8fa2d07e0954044ae61"
|
|
37
|
+
HISTORICAL_TREE_COUNT = 128
|
|
38
|
+
|
|
39
|
+
HISTORICAL_FILES = {
|
|
40
|
+
f"{SUITE_REL}/adjudication_rubric.md": V1_RUBRIC_SHA256,
|
|
41
|
+
f"{SUITE_REL}/heldout_set.json":
|
|
42
|
+
"4b2392e95ae7569907438d9e731ead8eb1db35489b0583a601631d22cdc4eb98",
|
|
43
|
+
f"{SUITE_REL}/measurement-2026-07-22.json":
|
|
44
|
+
"d0c7e5f53d21775d32fb820665cf17f6baec056262765767467e56d1e428bd1f",
|
|
45
|
+
f"{SUITE_REL}/measurement-2026-08-07.json":
|
|
46
|
+
"1af137c798e6cf3a5d0a742e379a8af78fe802cb924b4ece22cdf57cb881f573",
|
|
47
|
+
}
|
|
48
|
+
HISTORICAL_MEASUREMENTS = {
|
|
49
|
+
"measurement-2026-07-22.json",
|
|
50
|
+
"measurement-2026-08-07.json",
|
|
51
|
+
}
|
|
52
|
+
HISTORICAL_TREE_REL = f"{SUITE_REL}/runs/2026-08-07"
|
|
53
|
+
TREE_ALGORITHM = (
|
|
54
|
+
"Recursively select regular files; use POSIX paths relative to this tree; "
|
|
55
|
+
"sort paths by UTF-8 bytes; append for each file: relative-path UTF-8, "
|
|
56
|
+
"one NUL byte, lowercase file sha256 ASCII, one LF byte; sha256 the "
|
|
57
|
+
"concatenated bytes."
|
|
58
|
+
)
|
|
59
|
+
|
|
60
|
+
FIXTURE_HASHES = {
|
|
61
|
+
"README.md": "660ad28ad484cec61aa3d7d5cb47c3119eb75b8a548f9de891e743497732e1c3",
|
|
62
|
+
"subject_context_attested_only.json":
|
|
63
|
+
"d8636dc2d8d8173300e04e211a2411a3e0b1cc644e73c0cf5bc46315b5ae7eca",
|
|
64
|
+
"subject_context_machine_supported.json":
|
|
65
|
+
"7263fd771706d8e407b8ff7f3750bb1558e4d75524f5454bbfeadfb67118f5bc",
|
|
66
|
+
"subject_context_not_isolated.json":
|
|
67
|
+
"24c5d462c9b0184ad2e719dd39cab99d2a08ca598f46ece706fff8e863d6bb5d",
|
|
68
|
+
"subject_context_unknown.json":
|
|
69
|
+
"8b470acdf748b629fefed542c1f3d5578eb72ec44423bf8a98c73fcb6a941727",
|
|
70
|
+
}
|
|
71
|
+
FIXTURE_STATUSES = {
|
|
72
|
+
"subject_context_attested_only.json": "attested_only",
|
|
73
|
+
"subject_context_machine_supported.json": "machine_supported",
|
|
74
|
+
"subject_context_not_isolated.json": "not_isolated",
|
|
75
|
+
"subject_context_unknown.json": "unknown",
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
ROOT_KEYS = {
|
|
79
|
+
"schema_version", "suite", "run_id", "suite_commit", "execution_manifest",
|
|
80
|
+
"subject_call_plan",
|
|
81
|
+
"recorded_at", "status", "neutral_cwd", "cli", "instruction_visibility",
|
|
82
|
+
"context_probe", "attestation", "data_minimization",
|
|
83
|
+
}
|
|
84
|
+
STATUS_VALUES = {"machine_supported", "attested_only", "not_isolated", "unknown"}
|
|
85
|
+
STATUS_CLAIMS = {
|
|
86
|
+
"machine_supported": "repository-instruction isolated (machine-supported)",
|
|
87
|
+
"attested_only": "repository-instruction isolated (operator-attested only)",
|
|
88
|
+
"not_isolated": "repository-instruction isolation not established",
|
|
89
|
+
"unknown": "repository-instruction isolation not established — evidence unknown",
|
|
90
|
+
}
|
|
91
|
+
JUDGE_SUBJECT_INPUT_SEPARATOR = b"\n\n--- ARS SUBJECT INPUT ---\n"
|
|
92
|
+
JUDGE_SUBJECT_OUTPUT_SEPARATOR = b"\n\n--- ARS SUBJECT OUTPUT ---\n"
|
|
93
|
+
|
|
94
|
+
|
|
95
|
+
class ContractError(ValueError):
|
|
96
|
+
"""A fail-closed #679 contract violation."""
|
|
97
|
+
|
|
98
|
+
|
|
99
|
+
def _sha256(path: Path) -> str:
|
|
100
|
+
digest = hashlib.sha256()
|
|
101
|
+
with path.open("rb") as stream:
|
|
102
|
+
for chunk in iter(lambda: stream.read(1024 * 1024), b""):
|
|
103
|
+
digest.update(chunk)
|
|
104
|
+
return digest.hexdigest()
|
|
105
|
+
|
|
106
|
+
|
|
107
|
+
def _canonical_object_sha256(value: Mapping[str, Any]) -> str:
|
|
108
|
+
raw = json.dumps(
|
|
109
|
+
value,
|
|
110
|
+
ensure_ascii=False,
|
|
111
|
+
sort_keys=True,
|
|
112
|
+
separators=(",", ":"),
|
|
113
|
+
).encode("utf-8")
|
|
114
|
+
return hashlib.sha256(raw).hexdigest()
|
|
115
|
+
|
|
116
|
+
|
|
117
|
+
def _strict_json(path: Path) -> Any:
|
|
118
|
+
def pairs(items: list[tuple[str, Any]]) -> dict[str, Any]:
|
|
119
|
+
result: dict[str, Any] = {}
|
|
120
|
+
for key, value in items:
|
|
121
|
+
if key in result:
|
|
122
|
+
raise ContractError(f"{path}: duplicate JSON key {key!r}")
|
|
123
|
+
result[key] = value
|
|
124
|
+
return result
|
|
125
|
+
|
|
126
|
+
def bad_constant(value: str) -> Any:
|
|
127
|
+
raise ContractError(f"{path}: non-finite JSON number {value}")
|
|
128
|
+
|
|
129
|
+
try:
|
|
130
|
+
return json.loads(
|
|
131
|
+
path.read_text(encoding="utf-8"),
|
|
132
|
+
object_pairs_hook=pairs,
|
|
133
|
+
parse_constant=bad_constant,
|
|
134
|
+
)
|
|
135
|
+
except (OSError, UnicodeError, json.JSONDecodeError) as exc:
|
|
136
|
+
raise ContractError(f"{path}: strict JSON parse failed: {exc}") from exc
|
|
137
|
+
|
|
138
|
+
|
|
139
|
+
def _require_object(value: Any, label: str) -> dict[str, Any]:
|
|
140
|
+
if not isinstance(value, dict):
|
|
141
|
+
raise ContractError(f"{label}: expected JSON object")
|
|
142
|
+
return value
|
|
143
|
+
|
|
144
|
+
|
|
145
|
+
def _closed_keys(value: Mapping[str, Any], expected: set[str], label: str) -> None:
|
|
146
|
+
actual = set(value)
|
|
147
|
+
if actual != expected:
|
|
148
|
+
raise ContractError(
|
|
149
|
+
f"{label}: keys mismatch; missing={sorted(expected - actual)}, "
|
|
150
|
+
f"extra={sorted(actual - expected)}"
|
|
151
|
+
)
|
|
152
|
+
|
|
153
|
+
|
|
154
|
+
def _safe_file(root: Path, ref: str, label: str, prefix: str | None = None) -> Path:
|
|
155
|
+
if not isinstance(ref, str) or not ref or "\\" in ref or "\x00" in ref:
|
|
156
|
+
raise ContractError(f"{label}: invalid repository-relative path {ref!r}")
|
|
157
|
+
parts = ref.split("/")
|
|
158
|
+
if ref.startswith("/") or any(part in {"", ".", ".."} for part in parts):
|
|
159
|
+
raise ContractError(f"{label}: path traversal or non-canonical path {ref!r}")
|
|
160
|
+
if prefix is not None and not ref.startswith(prefix):
|
|
161
|
+
raise ContractError(f"{label}: path is outside required prefix {prefix!r}")
|
|
162
|
+
|
|
163
|
+
current = root
|
|
164
|
+
for index, part in enumerate(parts):
|
|
165
|
+
current = current / part
|
|
166
|
+
try:
|
|
167
|
+
mode = current.lstat().st_mode
|
|
168
|
+
except OSError as exc:
|
|
169
|
+
raise ContractError(f"{label}: missing/unreadable path {ref!r}: {exc}") from exc
|
|
170
|
+
if stat.S_ISLNK(mode):
|
|
171
|
+
raise ContractError(f"{label}: symlink component forbidden in {ref!r}")
|
|
172
|
+
final = index == len(parts) - 1
|
|
173
|
+
if final and not stat.S_ISREG(mode):
|
|
174
|
+
raise ContractError(f"{label}: final path is not a regular file: {ref!r}")
|
|
175
|
+
if not final and not stat.S_ISDIR(mode):
|
|
176
|
+
raise ContractError(f"{label}: non-directory path component in {ref!r}")
|
|
177
|
+
|
|
178
|
+
try:
|
|
179
|
+
current.resolve(strict=True).relative_to(root.resolve(strict=True))
|
|
180
|
+
except (OSError, ValueError) as exc:
|
|
181
|
+
raise ContractError(f"{label}: path escapes repository root: {ref!r}") from exc
|
|
182
|
+
return current
|
|
183
|
+
|
|
184
|
+
|
|
185
|
+
def _tree_inventory(root: Path, rel: str) -> tuple[int, str]:
|
|
186
|
+
base = root.joinpath(*rel.split("/"))
|
|
187
|
+
if base.is_symlink() or not base.is_dir():
|
|
188
|
+
raise ContractError(f"historical tree is missing, symlinked, or not a directory: {rel}")
|
|
189
|
+
rows: list[tuple[bytes, str]] = []
|
|
190
|
+
for current, dirnames, filenames in os.walk(base, followlinks=False):
|
|
191
|
+
current_path = Path(current)
|
|
192
|
+
for name in list(dirnames):
|
|
193
|
+
child = current_path / name
|
|
194
|
+
mode = child.lstat().st_mode
|
|
195
|
+
if stat.S_ISLNK(mode) or not stat.S_ISDIR(mode):
|
|
196
|
+
raise ContractError(f"historical tree contains forbidden directory entry: {child}")
|
|
197
|
+
for name in filenames:
|
|
198
|
+
child = current_path / name
|
|
199
|
+
mode = child.lstat().st_mode
|
|
200
|
+
if stat.S_ISLNK(mode) or not stat.S_ISREG(mode):
|
|
201
|
+
raise ContractError(f"historical tree contains non-regular entry: {child}")
|
|
202
|
+
relative = child.relative_to(base).as_posix()
|
|
203
|
+
rows.append((relative.encode("utf-8"), _sha256(child)))
|
|
204
|
+
rows.sort(key=lambda item: item[0])
|
|
205
|
+
payload = b"".join(path + b"\0" + digest.encode("ascii") + b"\n" for path, digest in rows)
|
|
206
|
+
return len(rows), hashlib.sha256(payload).hexdigest()
|
|
207
|
+
|
|
208
|
+
|
|
209
|
+
def _expected_lock() -> dict[str, Any]:
|
|
210
|
+
return {
|
|
211
|
+
"schema_version": "revision-claim-drift-historical-lock/1.0",
|
|
212
|
+
"suite": "revision_claim_drift",
|
|
213
|
+
"baseline_commit": "682b30a200951e058a7ac7848aab600959669198",
|
|
214
|
+
"hash_algorithm": "sha256",
|
|
215
|
+
"readme_exclusion": {
|
|
216
|
+
"path": f"{SUITE_REL}/README.md",
|
|
217
|
+
"reason": (
|
|
218
|
+
"Issue #679 must document the prospective v2 context protocol; the README "
|
|
219
|
+
"is not a scored row, frozen rubric, held-out item set, or retained raw run "
|
|
220
|
+
"artifact."
|
|
221
|
+
),
|
|
222
|
+
},
|
|
223
|
+
"protected_files": [
|
|
224
|
+
{"path": path, "sha256": digest}
|
|
225
|
+
for path, digest in HISTORICAL_FILES.items()
|
|
226
|
+
],
|
|
227
|
+
"protected_trees": [{
|
|
228
|
+
"path": HISTORICAL_TREE_REL,
|
|
229
|
+
"file_count": HISTORICAL_TREE_COUNT,
|
|
230
|
+
"inventory_algorithm": TREE_ALGORITHM,
|
|
231
|
+
"inventory_sha256": HISTORICAL_TREE_SHA256,
|
|
232
|
+
}],
|
|
233
|
+
"mutation_policy": "fail_closed",
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
|
|
237
|
+
def _discover_contract_rows(root: Path) -> list[tuple[Path, dict[str, Any]]]:
|
|
238
|
+
"""Find every exact or near-miss measurement marker under the suite.
|
|
239
|
+
|
|
240
|
+
Discovery is recursive and filename-independent. A future report cannot
|
|
241
|
+
hide under ``runs/``, a nonstandard basename, a case-variant extension, or
|
|
242
|
+
an escaped spelling of the decoded JSON member name.
|
|
243
|
+
"""
|
|
244
|
+
suite_root = root / SUITE
|
|
245
|
+
rows: list[tuple[Path, dict[str, Any]]] = []
|
|
246
|
+
marker_hint = re.compile(r"measurement(?:_|\\u005[fF])contract")
|
|
247
|
+
for current, dirnames, filenames in os.walk(suite_root, followlinks=False):
|
|
248
|
+
current_path = Path(current)
|
|
249
|
+
for name in list(dirnames):
|
|
250
|
+
child = current_path / name
|
|
251
|
+
mode = child.lstat().st_mode
|
|
252
|
+
if stat.S_ISLNK(mode) or not stat.S_ISDIR(mode):
|
|
253
|
+
raise ContractError(
|
|
254
|
+
f"measurement discovery encountered forbidden directory entry: {child}"
|
|
255
|
+
)
|
|
256
|
+
for name in sorted(filenames):
|
|
257
|
+
path = current_path / name
|
|
258
|
+
if path.suffix.casefold() != ".json":
|
|
259
|
+
continue
|
|
260
|
+
mode = path.lstat().st_mode
|
|
261
|
+
if stat.S_ISLNK(mode) or not stat.S_ISREG(mode):
|
|
262
|
+
raise ContractError(
|
|
263
|
+
f"measurement discovery encountered non-regular JSON: {path}"
|
|
264
|
+
)
|
|
265
|
+
try:
|
|
266
|
+
text = path.read_bytes().decode("utf-8")
|
|
267
|
+
except (OSError, UnicodeError) as exc:
|
|
268
|
+
raise ContractError(f"measurement discovery cannot read {path}: {exc}") from exc
|
|
269
|
+
try:
|
|
270
|
+
lenient = json.loads(text)
|
|
271
|
+
except (ValueError, RecursionError) as exc:
|
|
272
|
+
if marker_hint.search(text):
|
|
273
|
+
raise ContractError(
|
|
274
|
+
f"contract-marker JSON does not parse under discovery: {path}: {exc}"
|
|
275
|
+
) from exc
|
|
276
|
+
continue
|
|
277
|
+
if not isinstance(lenient, dict) or "measurement_contract" not in lenient:
|
|
278
|
+
continue
|
|
279
|
+
value = lenient["measurement_contract"]
|
|
280
|
+
if not isinstance(value, str) or not value.startswith("heldout-measurement/"):
|
|
281
|
+
raise ContractError(
|
|
282
|
+
f"near-miss measurement_contract marker fails closed: {path}: {value!r}"
|
|
283
|
+
)
|
|
284
|
+
strict = _strict_json(path)
|
|
285
|
+
if not isinstance(strict, dict):
|
|
286
|
+
raise ContractError(f"contract-marked JSON root is not an object: {path}")
|
|
287
|
+
rows.append((path, strict))
|
|
288
|
+
return rows
|
|
289
|
+
|
|
290
|
+
|
|
291
|
+
def _check_history(root: Path) -> list[tuple[Path, dict[str, Any]]]:
|
|
292
|
+
lock_path = _safe_file(root, f"{SUITE_REL}/historical_artifacts.lock.json", "history lock")
|
|
293
|
+
lock = _strict_json(lock_path)
|
|
294
|
+
if lock != _expected_lock():
|
|
295
|
+
raise ContractError("historical lock differs from hard-coded #679 lock semantics")
|
|
296
|
+
for ref, expected in HISTORICAL_FILES.items():
|
|
297
|
+
path = _safe_file(root, ref, "protected historical file")
|
|
298
|
+
actual = _sha256(path)
|
|
299
|
+
if actual != expected:
|
|
300
|
+
raise ContractError(f"protected historical byte drift: {ref}: {actual} != {expected}")
|
|
301
|
+
count, digest = _tree_inventory(root, HISTORICAL_TREE_REL)
|
|
302
|
+
if (count, digest) != (HISTORICAL_TREE_COUNT, HISTORICAL_TREE_SHA256):
|
|
303
|
+
raise ContractError(
|
|
304
|
+
f"protected historical run-tree drift: count={count}, sha256={digest}"
|
|
305
|
+
)
|
|
306
|
+
measurements = {
|
|
307
|
+
path.name
|
|
308
|
+
for path in (root / SUITE).iterdir()
|
|
309
|
+
if path.name.casefold().startswith("measurement-")
|
|
310
|
+
and path.suffix.casefold() == ".json"
|
|
311
|
+
and (path.is_file() or path.is_symlink())
|
|
312
|
+
}
|
|
313
|
+
if measurements != HISTORICAL_MEASUREMENTS:
|
|
314
|
+
raise ContractError(
|
|
315
|
+
"#679 creates no measurement row; expected only frozen historical rows, "
|
|
316
|
+
f"found {sorted(measurements)}"
|
|
317
|
+
)
|
|
318
|
+
rows = _discover_contract_rows(root)
|
|
319
|
+
expected_marked = {f"{SUITE_REL}/measurement-2026-08-07.json"}
|
|
320
|
+
actual_marked = {path.relative_to(root).as_posix() for path, _ in rows}
|
|
321
|
+
if actual_marked != expected_marked:
|
|
322
|
+
raise ContractError(
|
|
323
|
+
"#679 creates no contract-marked measurement row anywhere under the suite; "
|
|
324
|
+
f"expected {sorted(expected_marked)}, found {sorted(actual_marked)}"
|
|
325
|
+
)
|
|
326
|
+
return rows
|
|
327
|
+
|
|
328
|
+
|
|
329
|
+
def _expected_amendments() -> dict[str, Any]:
|
|
330
|
+
v1_path = f"{SUITE_REL}/adjudication_rubric.md"
|
|
331
|
+
v2_path = f"{SUITE_REL}/adjudication_rubric_v2.md"
|
|
332
|
+
rows = [
|
|
333
|
+
f"{SUITE_REL}/measurement-2026-07-22.json",
|
|
334
|
+
f"{SUITE_REL}/measurement-2026-08-07.json",
|
|
335
|
+
]
|
|
336
|
+
return {
|
|
337
|
+
"schema_version": "revision-claim-drift-rubric-amendments/1.0",
|
|
338
|
+
"suite": "revision_claim_drift",
|
|
339
|
+
"append_only": True,
|
|
340
|
+
"rubrics": [
|
|
341
|
+
{"version": "1.0", "path": v1_path, "sha256": V1_RUBRIC_SHA256,
|
|
342
|
+
"status": "frozen_historical"},
|
|
343
|
+
{"version": "2.0", "path": v2_path, "sha256": V2_RUBRIC_SHA256,
|
|
344
|
+
"status": "prospective"},
|
|
345
|
+
],
|
|
346
|
+
"amendments": [{
|
|
347
|
+
"amendment_id": "RCD-RUBRIC-2026-08-10-001",
|
|
348
|
+
"recorded_on": "2026-08-10",
|
|
349
|
+
"issue": 679,
|
|
350
|
+
"from_version": "1.0",
|
|
351
|
+
"from_sha256": V1_RUBRIC_SHA256,
|
|
352
|
+
"to_version": "2.0",
|
|
353
|
+
"to_sha256": V2_RUBRIC_SHA256,
|
|
354
|
+
"changes": [
|
|
355
|
+
"add_C9_non_control_citation_attachment",
|
|
356
|
+
"replace_ladder_examples_with_canonical_pointers",
|
|
357
|
+
],
|
|
358
|
+
"historical_effect": "none",
|
|
359
|
+
"historical_rows": rows,
|
|
360
|
+
"rescoring_permitted": False,
|
|
361
|
+
}],
|
|
362
|
+
}
|
|
363
|
+
|
|
364
|
+
|
|
365
|
+
def _check_rubric(root: Path) -> None:
|
|
366
|
+
v2_ref = f"{SUITE_REL}/adjudication_rubric_v2.md"
|
|
367
|
+
v2_path = _safe_file(root, v2_ref, "v2 rubric")
|
|
368
|
+
if _sha256(v2_path) != V2_RUBRIC_SHA256:
|
|
369
|
+
raise ContractError("v2 rubric byte identity differs from frozen prospective hash")
|
|
370
|
+
text = v2_path.read_text(encoding="utf-8")
|
|
371
|
+
headings = re.findall(r"^### C([1-9])\s+—\s+(.+)$", text, flags=re.MULTILINE)
|
|
372
|
+
if [number for number, _ in headings] != [str(value) for value in range(1, 10)]:
|
|
373
|
+
raise ContractError("v2 rubric must contain exactly ordered criteria C1 through C9")
|
|
374
|
+
if headings[-1][1].strip().casefold() != "non-control citation-attachment violation":
|
|
375
|
+
raise ContractError("v2 rubric C9 title/authority drift")
|
|
376
|
+
for marker in (
|
|
377
|
+
"../../../shared/references/claim_strength_ladder.md#the-ladder",
|
|
378
|
+
"../../../shared/references/claim_strength_ladder.md#what-counts-as-a-move-and-what-does-not",
|
|
379
|
+
CLAIM_LADDER_SHA256,
|
|
380
|
+
"Status: **prospective only**",
|
|
381
|
+
"C9 is not a retroactive basis",
|
|
382
|
+
):
|
|
383
|
+
if text.count(marker) != 1:
|
|
384
|
+
raise ContractError(f"v2 rubric missing or duplicates frozen marker: {marker}")
|
|
385
|
+
if any(arrow in text for arrow in ("→", "⇒", "->")):
|
|
386
|
+
raise ContractError("v2 rubric must point to, not copy, local ladder-arrow examples")
|
|
387
|
+
|
|
388
|
+
ladder_path = _safe_file(
|
|
389
|
+
root,
|
|
390
|
+
"shared/references/claim_strength_ladder.md",
|
|
391
|
+
"canonical claim-strength ladder",
|
|
392
|
+
)
|
|
393
|
+
if _sha256(ladder_path) != CLAIM_LADDER_SHA256:
|
|
394
|
+
raise ContractError("canonical claim-strength ladder target hash drifted")
|
|
395
|
+
ladder_text = ladder_path.read_text(encoding="utf-8")
|
|
396
|
+
if ladder_text.count("## The ladder") != 1 or ladder_text.count(
|
|
397
|
+
"## What counts as a move (and what does not)"
|
|
398
|
+
) != 1:
|
|
399
|
+
raise ContractError("canonical claim-strength ladder target headings drifted")
|
|
400
|
+
|
|
401
|
+
ledger_path = _safe_file(root, f"{SUITE_REL}/rubric_amendments.json", "rubric ledger")
|
|
402
|
+
ledger = _strict_json(ledger_path)
|
|
403
|
+
if ledger != _expected_amendments():
|
|
404
|
+
raise ContractError("rubric amendment ledger differs from frozen closed amendment")
|
|
405
|
+
for item in ledger["rubrics"]:
|
|
406
|
+
resolved = _safe_file(root, item["path"], "ledger rubric ref")
|
|
407
|
+
if _sha256(resolved) != item["sha256"]:
|
|
408
|
+
raise ContractError(f"ledger rubric hash mismatch: {item['path']}")
|
|
409
|
+
|
|
410
|
+
|
|
411
|
+
_RFC3339 = re.compile(
|
|
412
|
+
r"^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}(?:\.\d{1,6})?(?:Z|[+-]\d{2}:\d{2})$"
|
|
413
|
+
)
|
|
414
|
+
|
|
415
|
+
|
|
416
|
+
def _time(value: str, label: str) -> dt.datetime:
|
|
417
|
+
if not isinstance(value, str) or not _RFC3339.fullmatch(value):
|
|
418
|
+
raise ContractError(f"{label}: expected RFC 3339 date-time")
|
|
419
|
+
try:
|
|
420
|
+
parsed = dt.datetime.fromisoformat(value[:-1] + "+00:00" if value.endswith("Z") else value)
|
|
421
|
+
except ValueError as exc:
|
|
422
|
+
raise ContractError(f"{label}: invalid RFC 3339 date-time") from exc
|
|
423
|
+
if parsed.tzinfo is None:
|
|
424
|
+
raise ContractError(f"{label}: date-time must carry an offset")
|
|
425
|
+
return parsed
|
|
426
|
+
|
|
427
|
+
|
|
428
|
+
def _schema_validator(schema: Mapping[str, Any], label: str) -> Draft202012Validator:
|
|
429
|
+
try:
|
|
430
|
+
Draft202012Validator.check_schema(schema)
|
|
431
|
+
except Exception as exc: # jsonschema exposes version-specific subclasses.
|
|
432
|
+
raise ContractError(f"{label}: invalid Draft 2020-12 schema: {exc}") from exc
|
|
433
|
+
return Draft202012Validator(schema, format_checker=FormatChecker())
|
|
434
|
+
|
|
435
|
+
|
|
436
|
+
def validate_subject_context(
|
|
437
|
+
record: Mapping[str, Any], schema: Mapping[str, Any], label: str = "subject context"
|
|
438
|
+
) -> None:
|
|
439
|
+
errors = sorted(_schema_validator(schema, "subject-context schema").iter_errors(record),
|
|
440
|
+
key=lambda error: tuple(str(part) for part in error.absolute_path))
|
|
441
|
+
if errors:
|
|
442
|
+
first = errors[0]
|
|
443
|
+
location = ".".join(str(part) for part in first.absolute_path) or "<root>"
|
|
444
|
+
raise ContractError(f"{label}.{location}: {first.message}")
|
|
445
|
+
_closed_keys(record, ROOT_KEYS, label)
|
|
446
|
+
if record["status"] not in STATUS_VALUES:
|
|
447
|
+
raise ContractError(f"{label}: status is outside the frozen vocabulary")
|
|
448
|
+
recorded = _time(record["recorded_at"], f"{label}.recorded_at")
|
|
449
|
+
probe = record["context_probe"]
|
|
450
|
+
if probe["started_at"] is not None:
|
|
451
|
+
started = _time(probe["started_at"], f"{label}.context_probe.started_at")
|
|
452
|
+
completed = _time(probe["completed_at"], f"{label}.context_probe.completed_at")
|
|
453
|
+
if started > completed or completed > recorded:
|
|
454
|
+
raise ContractError(f"{label}: probe timestamps are not start <= completion <= record")
|
|
455
|
+
attestation = record["attestation"]
|
|
456
|
+
if attestation is not None:
|
|
457
|
+
attested = _time(attestation["attested_at"], f"{label}.attestation.attested_at")
|
|
458
|
+
if attested > recorded:
|
|
459
|
+
raise ContractError(f"{label}: attestation occurs after the record timestamp")
|
|
460
|
+
if probe["completed_at"] is not None and attested < _time(
|
|
461
|
+
probe["completed_at"], f"{label}.context_probe.completed_at"
|
|
462
|
+
):
|
|
463
|
+
raise ContractError(f"{label}: attestation precedes completed context evidence")
|
|
464
|
+
|
|
465
|
+
|
|
466
|
+
def _pinned_schema(
|
|
467
|
+
root: Path, ref: str, expected_sha256: str, label: str
|
|
468
|
+
) -> dict[str, Any]:
|
|
469
|
+
path = _safe_file(root, ref, label)
|
|
470
|
+
if _sha256(path) != expected_sha256:
|
|
471
|
+
raise ContractError(f"{label} byte identity differs from frozen hash")
|
|
472
|
+
schema = _require_object(_strict_json(path), label)
|
|
473
|
+
_schema_validator(schema, label)
|
|
474
|
+
return schema
|
|
475
|
+
|
|
476
|
+
|
|
477
|
+
def _check_subject_assets(
|
|
478
|
+
root: Path,
|
|
479
|
+
) -> tuple[
|
|
480
|
+
dict[str, Any],
|
|
481
|
+
dict[str, Any],
|
|
482
|
+
dict[str, Any],
|
|
483
|
+
dict[str, dict[str, Any]],
|
|
484
|
+
]:
|
|
485
|
+
schema_ref = f"{SUITE_REL}/subject_context_record.schema.json"
|
|
486
|
+
schema = _pinned_schema(
|
|
487
|
+
root, schema_ref, SUBJECT_SCHEMA_SHA256, "subject-context schema"
|
|
488
|
+
)
|
|
489
|
+
launcher_schema = _pinned_schema(
|
|
490
|
+
root,
|
|
491
|
+
f"{SUITE_REL}/subject_launcher_config.schema.json",
|
|
492
|
+
LAUNCHER_SCHEMA_SHA256,
|
|
493
|
+
"subject-launcher-config schema",
|
|
494
|
+
)
|
|
495
|
+
call_plan_schema = _pinned_schema(
|
|
496
|
+
root,
|
|
497
|
+
f"{SUITE_REL}/subject_call_plan.schema.json",
|
|
498
|
+
CALL_PLAN_SCHEMA_SHA256,
|
|
499
|
+
"subject-call-plan schema",
|
|
500
|
+
)
|
|
501
|
+
if set(schema.get("required", [])) != ROOT_KEYS or set(schema.get("properties", {})) != ROOT_KEYS:
|
|
502
|
+
raise ContractError("subject-context schema root keys differ from the frozen closed grammar")
|
|
503
|
+
status_enum = set(schema["properties"]["status"].get("enum", []))
|
|
504
|
+
if status_enum != STATUS_VALUES:
|
|
505
|
+
raise ContractError("subject-context schema status vocabulary drift")
|
|
506
|
+
|
|
507
|
+
fixture_dir = root / "scripts/fixtures/revision_claim_drift_v2"
|
|
508
|
+
actual_files = {path.name for path in fixture_dir.iterdir() if path.is_file() or path.is_symlink()}
|
|
509
|
+
if actual_files != set(FIXTURE_HASHES):
|
|
510
|
+
raise ContractError(f"subject-context fixture inventory drift: {sorted(actual_files)}")
|
|
511
|
+
records: dict[str, dict[str, Any]] = {}
|
|
512
|
+
for name, expected_hash in FIXTURE_HASHES.items():
|
|
513
|
+
rel = f"scripts/fixtures/revision_claim_drift_v2/{name}"
|
|
514
|
+
path = _safe_file(root, rel, "subject-context fixture")
|
|
515
|
+
if _sha256(path) != expected_hash:
|
|
516
|
+
raise ContractError(f"subject-context fixture byte drift: {name}")
|
|
517
|
+
if name.endswith(".json"):
|
|
518
|
+
record = _require_object(_strict_json(path), name)
|
|
519
|
+
validate_subject_context(record, schema, name)
|
|
520
|
+
if record["status"] != FIXTURE_STATUSES[name]:
|
|
521
|
+
raise ContractError(f"{name}: fixture/status mapping drift")
|
|
522
|
+
records[name] = record
|
|
523
|
+
|
|
524
|
+
# The four checked-in fixtures cover the four public statuses. These
|
|
525
|
+
# derived positive relations pin two additional truthful not-isolated
|
|
526
|
+
# routes without turning them into reusable run artifacts.
|
|
527
|
+
inside = copy.deepcopy(records["subject_context_machine_supported.json"])
|
|
528
|
+
inside["status"] = "not_isolated"
|
|
529
|
+
inside["neutral_cwd"]["repo_membership_probe"] = "inside_suite_repository"
|
|
530
|
+
validate_subject_context(inside, schema, "derived inside-repository record")
|
|
531
|
+
|
|
532
|
+
repository_visible = copy.deepcopy(records["subject_context_unknown.json"])
|
|
533
|
+
repository_visible["status"] = "not_isolated"
|
|
534
|
+
repository_visible["neutral_cwd"]["repo_membership_probe"] = (
|
|
535
|
+
"outside_suite_repository"
|
|
536
|
+
)
|
|
537
|
+
repository_visible["instruction_visibility"]["repository_instructions"] = (
|
|
538
|
+
"visible"
|
|
539
|
+
)
|
|
540
|
+
validate_subject_context(
|
|
541
|
+
repository_visible, schema, "derived repository-visible record"
|
|
542
|
+
)
|
|
543
|
+
return schema, launcher_schema, call_plan_schema, records
|
|
544
|
+
|
|
545
|
+
|
|
546
|
+
def _run_artifact_ref(run_id: str, filename: str) -> str:
|
|
547
|
+
return f"{RUNS_PREFIX}{run_id}/{filename}"
|
|
548
|
+
|
|
549
|
+
|
|
550
|
+
def _validate_launcher_binding(
|
|
551
|
+
root: Path,
|
|
552
|
+
record: Mapping[str, Any],
|
|
553
|
+
config: Mapping[str, Any],
|
|
554
|
+
raw_paths: list[str],
|
|
555
|
+
launcher_schema: Mapping[str, Any],
|
|
556
|
+
) -> dict[str, Any]:
|
|
557
|
+
context_binding = record["cli"]["launcher_config"]
|
|
558
|
+
row_binding = config.get("launcher_config")
|
|
559
|
+
if not isinstance(row_binding, Mapping):
|
|
560
|
+
raise ContractError("subject.config.launcher_config binding is required")
|
|
561
|
+
_closed_keys(row_binding, {"ref", "sha256"}, "subject.config.launcher_config")
|
|
562
|
+
if dict(row_binding) != context_binding:
|
|
563
|
+
raise ContractError("row/context launcher_config binding mismatch")
|
|
564
|
+
expected_ref = _run_artifact_ref(record["run_id"], "launcher-config.json")
|
|
565
|
+
if context_binding["ref"] != expected_ref:
|
|
566
|
+
raise ContractError("launcher-config ref is not the canonical run sibling")
|
|
567
|
+
path = _safe_file(root, expected_ref, "launcher-config artifact", RUNS_PREFIX)
|
|
568
|
+
if _sha256(path) != context_binding["sha256"]:
|
|
569
|
+
raise ContractError("launcher-config artifact hash mismatch")
|
|
570
|
+
if expected_ref not in raw_paths:
|
|
571
|
+
raise ContractError("launcher-config ref must appear in raw_outputs.paths")
|
|
572
|
+
artifact = _require_object(_strict_json(path), "launcher-config artifact")
|
|
573
|
+
errors = list(
|
|
574
|
+
_schema_validator(launcher_schema, "subject-launcher-config schema").iter_errors(
|
|
575
|
+
artifact
|
|
576
|
+
)
|
|
577
|
+
)
|
|
578
|
+
if errors:
|
|
579
|
+
raise ContractError(f"launcher-config artifact fails schema: {errors[0].message}")
|
|
580
|
+
if artifact["suite"] != record["suite"] or artifact["run_id"] != record["run_id"]:
|
|
581
|
+
raise ContractError("launcher-config suite/run_id mismatch")
|
|
582
|
+
invocation = {
|
|
583
|
+
key: artifact[key]
|
|
584
|
+
for key in ("launcher", "working_directory", "instruction_loading")
|
|
585
|
+
}
|
|
586
|
+
if artifact["invocation_sha256"] != _canonical_object_sha256(invocation):
|
|
587
|
+
raise ContractError("launcher-config invocation hash mismatch")
|
|
588
|
+
for key in ("mode", "bare_requested", "bare_used", "authentication_result"):
|
|
589
|
+
if artifact["launcher"][key] != record["cli"][key]:
|
|
590
|
+
raise ContractError(f"launcher-config/context CLI {key} mismatch")
|
|
591
|
+
membership_to_policy = {
|
|
592
|
+
"outside_suite_repository": "fresh_outside_suite_repository",
|
|
593
|
+
"inside_suite_repository": "inside_suite_repository",
|
|
594
|
+
"unresolved": "unresolved",
|
|
595
|
+
}
|
|
596
|
+
if artifact["working_directory"]["policy"] != membership_to_policy[
|
|
597
|
+
record["neutral_cwd"]["repo_membership_probe"]
|
|
598
|
+
]:
|
|
599
|
+
raise ContractError("launcher-config/context working-directory policy mismatch")
|
|
600
|
+
if artifact["working_directory"]["pwd_p_sha256"] != record["neutral_cwd"][
|
|
601
|
+
"pwd_p_sha256"
|
|
602
|
+
]:
|
|
603
|
+
raise ContractError("launcher-config/context pwd -P hash mismatch")
|
|
604
|
+
sealed_at = _time(artifact["sealed_at"], "launcher_config.sealed_at")
|
|
605
|
+
probe_started_at = record["context_probe"]["started_at"]
|
|
606
|
+
launcher_deadline = _time(
|
|
607
|
+
probe_started_at if probe_started_at is not None else record["recorded_at"],
|
|
608
|
+
"launcher-config preflight deadline",
|
|
609
|
+
)
|
|
610
|
+
if sealed_at > launcher_deadline:
|
|
611
|
+
raise ContractError("launcher-config artifact was not sealed before probe/preflight")
|
|
612
|
+
return artifact
|
|
613
|
+
|
|
614
|
+
|
|
615
|
+
def _validate_call_plan_binding(
|
|
616
|
+
root: Path,
|
|
617
|
+
report: Mapping[str, Any],
|
|
618
|
+
record: Mapping[str, Any],
|
|
619
|
+
config: Mapping[str, Any],
|
|
620
|
+
raw_paths: list[str],
|
|
621
|
+
call_plan_schema: Mapping[str, Any],
|
|
622
|
+
) -> dict[str, Any]:
|
|
623
|
+
context_binding = record["subject_call_plan"]
|
|
624
|
+
row_binding = config.get("subject_call_plan")
|
|
625
|
+
if not isinstance(row_binding, Mapping):
|
|
626
|
+
raise ContractError("subject.config.subject_call_plan binding is required")
|
|
627
|
+
_closed_keys(row_binding, {"ref", "sha256"}, "subject.config.subject_call_plan")
|
|
628
|
+
if dict(row_binding) != context_binding:
|
|
629
|
+
raise ContractError("row/context subject_call_plan binding mismatch")
|
|
630
|
+
expected_ref = _run_artifact_ref(record["run_id"], "subject-call-plan.json")
|
|
631
|
+
if context_binding["ref"] != expected_ref:
|
|
632
|
+
raise ContractError("subject-call-plan ref is not the canonical run sibling")
|
|
633
|
+
path = _safe_file(root, expected_ref, "subject-call-plan artifact", RUNS_PREFIX)
|
|
634
|
+
if _sha256(path) != context_binding["sha256"]:
|
|
635
|
+
raise ContractError("subject-call-plan artifact hash mismatch")
|
|
636
|
+
if expected_ref not in raw_paths:
|
|
637
|
+
raise ContractError("subject-call-plan ref must appear in raw_outputs.paths")
|
|
638
|
+
plan = _require_object(_strict_json(path), "subject-call-plan artifact")
|
|
639
|
+
errors = list(
|
|
640
|
+
_schema_validator(call_plan_schema, "subject-call-plan schema").iter_errors(plan)
|
|
641
|
+
)
|
|
642
|
+
if errors:
|
|
643
|
+
raise ContractError(f"subject-call-plan artifact fails schema: {errors[0].message}")
|
|
644
|
+
if (
|
|
645
|
+
plan["suite"] != record["suite"]
|
|
646
|
+
or plan["run_id"] != record["run_id"]
|
|
647
|
+
or plan["suite_commit"] != record["suite_commit"]
|
|
648
|
+
or plan["subject_model_id"] != report.get("subject", {}).get("model_id")
|
|
649
|
+
or plan["launcher_config"] != record["cli"]["launcher_config"]
|
|
650
|
+
):
|
|
651
|
+
raise ContractError("subject-call-plan provenance differs from context record")
|
|
652
|
+
plan_created = _time(plan["created_at"], "subject_call_plan.created_at")
|
|
653
|
+
probe_started_at = record["context_probe"]["started_at"]
|
|
654
|
+
plan_deadline = _time(
|
|
655
|
+
probe_started_at if probe_started_at is not None else record["recorded_at"],
|
|
656
|
+
"subject-call plan preflight deadline",
|
|
657
|
+
)
|
|
658
|
+
if plan_created > plan_deadline:
|
|
659
|
+
raise ContractError("subject-call plan was not frozen before probe/preflight")
|
|
660
|
+
launcher_path = _safe_file(
|
|
661
|
+
root,
|
|
662
|
+
plan["launcher_config"]["ref"],
|
|
663
|
+
"subject-call-plan launcher config",
|
|
664
|
+
RUNS_PREFIX,
|
|
665
|
+
)
|
|
666
|
+
launcher_artifact = _require_object(
|
|
667
|
+
_strict_json(launcher_path), "subject-call-plan launcher config"
|
|
668
|
+
)
|
|
669
|
+
if _time(launcher_artifact["sealed_at"], "launcher_config.sealed_at") > plan_created:
|
|
670
|
+
raise ContractError("launcher config was not sealed before the subject-call plan")
|
|
671
|
+
|
|
672
|
+
heldout_binding = plan["heldout_set"]
|
|
673
|
+
expected_heldout_ref = f"{SUITE_REL}/heldout_set.json"
|
|
674
|
+
if heldout_binding != {
|
|
675
|
+
"ref": expected_heldout_ref,
|
|
676
|
+
"sha256": HISTORICAL_FILES[expected_heldout_ref],
|
|
677
|
+
}:
|
|
678
|
+
raise ContractError("subject-call plan does not bind the frozen held-out set")
|
|
679
|
+
heldout = _require_object(
|
|
680
|
+
_strict_json(_safe_file(root, expected_heldout_ref, "frozen held-out set")),
|
|
681
|
+
"frozen held-out set",
|
|
682
|
+
)
|
|
683
|
+
item_rows = heldout.get("items")
|
|
684
|
+
if not isinstance(item_rows, list):
|
|
685
|
+
raise ContractError("frozen held-out set has no item roster")
|
|
686
|
+
item_ids = [item.get("id") if isinstance(item, Mapping) else None for item in item_rows]
|
|
687
|
+
expected_item_ids = [f"rp-{index:02d}" for index in range(1, 9)]
|
|
688
|
+
if item_ids != expected_item_ids:
|
|
689
|
+
raise ContractError("frozen held-out item roster differs from rp-01 through rp-08")
|
|
690
|
+
control_ids = {"rp-07", "rp-08"}
|
|
691
|
+
|
|
692
|
+
arm_ids = plan["arm_ids"]
|
|
693
|
+
if arm_ids != sorted(set(arm_ids)):
|
|
694
|
+
raise ContractError("subject-call-plan arm_ids must be sorted and unique")
|
|
695
|
+
result_arm_ids = (
|
|
696
|
+
report.get("results", {})
|
|
697
|
+
.get("revision_claim_drift_v2", {})
|
|
698
|
+
.get("arm_ids")
|
|
699
|
+
)
|
|
700
|
+
if result_arm_ids != arm_ids:
|
|
701
|
+
raise ContractError("subject-call plan arm_ids differ from the published v2 layer")
|
|
702
|
+
arm_roles = report.get("results", {}).get("arm_roles", {})
|
|
703
|
+
treatment_arms = arm_roles.get("treatment_or_cohort_arms", [])
|
|
704
|
+
variant_arms = arm_roles.get("variant_packet_arms", [])
|
|
705
|
+
if (
|
|
706
|
+
not isinstance(treatment_arms, list)
|
|
707
|
+
or not isinstance(variant_arms, list)
|
|
708
|
+
or treatment_arms != sorted(set(treatment_arms))
|
|
709
|
+
or variant_arms != sorted(set(variant_arms))
|
|
710
|
+
or set(treatment_arms).intersection(variant_arms)
|
|
711
|
+
or sorted(treatment_arms + variant_arms) != arm_ids
|
|
712
|
+
):
|
|
713
|
+
raise ContractError("published arm roles do not exactly partition call-plan arm_ids")
|
|
714
|
+
replicate_count = report.get("replicates", {}).get("per_item")
|
|
715
|
+
if (
|
|
716
|
+
not isinstance(replicate_count, int)
|
|
717
|
+
or isinstance(replicate_count, bool)
|
|
718
|
+
or not 2 <= replicate_count <= 10
|
|
719
|
+
):
|
|
720
|
+
raise ContractError("future #679 rows require 2..10 replicates per item and arm")
|
|
721
|
+
|
|
722
|
+
expected_subjects = [
|
|
723
|
+
{
|
|
724
|
+
"item_id": item_id,
|
|
725
|
+
"item_replicate_id": f"{item_id}.{arm_id}.r{replicate_index}",
|
|
726
|
+
"replicate_index": replicate_index,
|
|
727
|
+
"arm_id": arm_id,
|
|
728
|
+
"control_item": item_id in control_ids,
|
|
729
|
+
}
|
|
730
|
+
for item_id in item_ids
|
|
731
|
+
for arm_id in arm_ids
|
|
732
|
+
for replicate_index in range(1, replicate_count + 1)
|
|
733
|
+
]
|
|
734
|
+
|
|
735
|
+
calls = plan["calls"]
|
|
736
|
+
indexes = [call["sequence_index"] for call in calls]
|
|
737
|
+
if indexes != list(range(1, len(calls) + 1)):
|
|
738
|
+
raise ContractError("subject-call-plan sequence indexes must be ordered 1..N")
|
|
739
|
+
call_ids = [call["call_id"] for call in calls]
|
|
740
|
+
item_replicates = [call["item_replicate_id"] for call in calls if call["role"] == "subject"]
|
|
741
|
+
if len(call_ids) != len(set(call_ids)):
|
|
742
|
+
raise ContractError("subject-call-plan call_id values must be unique")
|
|
743
|
+
if not item_replicates or len(item_replicates) != len(set(item_replicates)):
|
|
744
|
+
raise ContractError("subject calls must name unique non-empty item-replicates")
|
|
745
|
+
|
|
746
|
+
subject_calls = [call for call in calls if call["role"] == "subject"]
|
|
747
|
+
if len(subject_calls) != len(expected_subjects):
|
|
748
|
+
raise ContractError("subject-call plan does not exactly cover item x arm x replicate")
|
|
749
|
+
for call, expected in zip(subject_calls, expected_subjects, strict=True):
|
|
750
|
+
item_replicate_id = expected["item_replicate_id"]
|
|
751
|
+
expected_call_id = f"subject.{item_replicate_id}"
|
|
752
|
+
if (
|
|
753
|
+
call["call_id"] != expected_call_id
|
|
754
|
+
or call["judge_id"] is not None
|
|
755
|
+
or any(call[key] != value for key, value in expected.items())
|
|
756
|
+
):
|
|
757
|
+
raise ContractError("subject-call roster differs from the frozen run design")
|
|
758
|
+
|
|
759
|
+
subject_by_replicate = {call["item_replicate_id"]: call for call in subject_calls}
|
|
760
|
+
judge_rows = report.get("judges", [])
|
|
761
|
+
judge_ids = [judge.get("judge_id") for judge in judge_rows]
|
|
762
|
+
plan_judges = plan["judges"]
|
|
763
|
+
plan_judge_ids = [judge["judge_id"] for judge in plan_judges]
|
|
764
|
+
if (
|
|
765
|
+
not judge_ids
|
|
766
|
+
or not all(isinstance(judge_id, str) and judge_id for judge_id in judge_ids)
|
|
767
|
+
or judge_ids != sorted(set(judge_ids))
|
|
768
|
+
or not 2 <= len(judge_ids) <= 8
|
|
769
|
+
or judge_ids != plan_judge_ids
|
|
770
|
+
):
|
|
771
|
+
raise ContractError("future #679 row and call plan require the same 2..8 sorted judges")
|
|
772
|
+
if (
|
|
773
|
+
report.get("suite_class") != "llm_judged"
|
|
774
|
+
or report.get("decision_relevant") is not True
|
|
775
|
+
or report.get("judge_plan") != {"exception": "none"}
|
|
776
|
+
):
|
|
777
|
+
raise ContractError("future #679 rows are decision-relevant with no judge exception")
|
|
778
|
+
model_families = [judge.get("model_family") for judge in judge_rows]
|
|
779
|
+
if (
|
|
780
|
+
not all(isinstance(family, str) and family for family in model_families)
|
|
781
|
+
or len(set(model_families)) < 2
|
|
782
|
+
):
|
|
783
|
+
raise ContractError("future #679 rows require at least two judge model families")
|
|
784
|
+
required_blinding = ["arm_identity", "control_status", "mechanism_state"]
|
|
785
|
+
if any(judge.get("blinded_to") != required_blinding for judge in judge_rows):
|
|
786
|
+
raise ContractError("future #679 judges must use the frozen blinding dimensions")
|
|
787
|
+
for plan_judge, row_judge in zip(plan_judges, judge_rows, strict=True):
|
|
788
|
+
if any(
|
|
789
|
+
row_judge.get(key) != plan_judge[key]
|
|
790
|
+
for key in ("judge_id", "model_id", "model_family", "blinded_to")
|
|
791
|
+
) or row_judge.get("prompt_ref") != plan_judge["prompt_template"]["ref"]:
|
|
792
|
+
raise ContractError("published judge identity/template differs from call plan")
|
|
793
|
+
template_ref = plan_judge["prompt_template"]["ref"]
|
|
794
|
+
expected_template_ref = (
|
|
795
|
+
f"{RUNS_PREFIX}{record['run_id']}/raw/"
|
|
796
|
+
f"judge.{plan_judge['judge_id']}.template.txt"
|
|
797
|
+
)
|
|
798
|
+
if template_ref != expected_template_ref:
|
|
799
|
+
raise ContractError("judge prompt-template ref is not canonical")
|
|
800
|
+
template_path = _safe_file(
|
|
801
|
+
root,
|
|
802
|
+
template_ref,
|
|
803
|
+
"judge prompt template",
|
|
804
|
+
f"{RUNS_PREFIX}{record['run_id']}/",
|
|
805
|
+
)
|
|
806
|
+
if _sha256(template_path) != plan_judge["prompt_template"]["sha256"]:
|
|
807
|
+
raise ContractError("judge prompt-template hash mismatch")
|
|
808
|
+
if template_ref not in raw_paths:
|
|
809
|
+
raise ContractError("judge prompt-template ref must appear in raw_outputs.paths")
|
|
810
|
+
plan_judge_by_id = {judge["judge_id"]: judge for judge in plan_judges}
|
|
811
|
+
expected_judges = [
|
|
812
|
+
{
|
|
813
|
+
**subject,
|
|
814
|
+
"call_id": f"judge.{judge_id}.{subject['item_replicate_id']}",
|
|
815
|
+
"judge_id": judge_id,
|
|
816
|
+
}
|
|
817
|
+
for judge_id in judge_ids
|
|
818
|
+
for subject in expected_subjects
|
|
819
|
+
]
|
|
820
|
+
judge_calls = [call for call in calls if call["role"] == "judge"]
|
|
821
|
+
if len(judge_calls) != len(expected_judges):
|
|
822
|
+
raise ContractError("subject-call plan does not exactly cover judge x item-replicate")
|
|
823
|
+
for call, expected in zip(judge_calls, expected_judges, strict=True):
|
|
824
|
+
if call["call_id"] != expected["call_id"] or any(
|
|
825
|
+
call[key] != expected[key]
|
|
826
|
+
for key in (
|
|
827
|
+
"judge_id",
|
|
828
|
+
"item_id",
|
|
829
|
+
"item_replicate_id",
|
|
830
|
+
"replicate_index",
|
|
831
|
+
"arm_id",
|
|
832
|
+
"control_item",
|
|
833
|
+
)
|
|
834
|
+
):
|
|
835
|
+
raise ContractError("judge-call roster differs from the frozen run design")
|
|
836
|
+
expected_call_ids = [
|
|
837
|
+
f"subject.{subject['item_replicate_id']}" for subject in expected_subjects
|
|
838
|
+
] + [judge["call_id"] for judge in expected_judges]
|
|
839
|
+
if call_ids != expected_call_ids:
|
|
840
|
+
raise ContractError("subject-call-plan global order must be subjects then judges")
|
|
841
|
+
|
|
842
|
+
judge_pairs: set[tuple[str, str]] = set()
|
|
843
|
+
prompt_refs: set[str] = set()
|
|
844
|
+
output_refs: set[str] = set()
|
|
845
|
+
run_prefix = f"{RUNS_PREFIX}{record['run_id']}/"
|
|
846
|
+
for index, call in enumerate(calls):
|
|
847
|
+
prompt = call["prompt"]
|
|
848
|
+
prompt_ref = prompt["ref"]
|
|
849
|
+
output_ref = call["output_ref"]
|
|
850
|
+
expected_prompt_ref = f"{run_prefix}raw/{call['call_id']}.prompt.txt"
|
|
851
|
+
expected_output_ref = f"{run_prefix}raw/{call['call_id']}.output.txt"
|
|
852
|
+
if prompt_ref != expected_prompt_ref or output_ref != expected_output_ref:
|
|
853
|
+
raise ContractError("subject-call-plan prompt/output ref is not canonical")
|
|
854
|
+
if prompt_ref in prompt_refs or output_ref in output_refs:
|
|
855
|
+
raise ContractError("subject-call-plan prompt/output refs must be unique")
|
|
856
|
+
prompt_refs.add(prompt_ref)
|
|
857
|
+
output_refs.add(output_ref)
|
|
858
|
+
prompt_path = _safe_file(root, prompt_ref, f"call-plan prompt[{index}]", run_prefix)
|
|
859
|
+
_safe_file(root, output_ref, f"call-plan output[{index}]", run_prefix)
|
|
860
|
+
if call["role"] == "subject":
|
|
861
|
+
if _sha256(prompt_path) != prompt["sha256"]:
|
|
862
|
+
raise ContractError("subject-call-plan subject prompt hash mismatch")
|
|
863
|
+
else:
|
|
864
|
+
expected_template_ref = plan_judge_by_id[call["judge_id"]][
|
|
865
|
+
"prompt_template"
|
|
866
|
+
]["ref"]
|
|
867
|
+
expected_subject_prompt_ref = subject_by_replicate[
|
|
868
|
+
call["item_replicate_id"]
|
|
869
|
+
]["prompt"]["ref"]
|
|
870
|
+
expected_subject_output_ref = subject_by_replicate[
|
|
871
|
+
call["item_replicate_id"]
|
|
872
|
+
]["output_ref"]
|
|
873
|
+
expected_deferred = {
|
|
874
|
+
"ref": expected_prompt_ref,
|
|
875
|
+
"sha256": None,
|
|
876
|
+
"composition": "template_then_subject_input_then_subject_output/1.0",
|
|
877
|
+
"template_ref": expected_template_ref,
|
|
878
|
+
"subject_prompt_ref": expected_subject_prompt_ref,
|
|
879
|
+
"subject_output_ref": expected_subject_output_ref,
|
|
880
|
+
}
|
|
881
|
+
if prompt != expected_deferred:
|
|
882
|
+
raise ContractError("judge prompt dependency differs from frozen plan")
|
|
883
|
+
template_path = _safe_file(
|
|
884
|
+
root,
|
|
885
|
+
expected_template_ref,
|
|
886
|
+
"judge prompt template dependency",
|
|
887
|
+
run_prefix,
|
|
888
|
+
)
|
|
889
|
+
subject_output_path = _safe_file(
|
|
890
|
+
root,
|
|
891
|
+
expected_subject_output_ref,
|
|
892
|
+
"judge subject-output dependency",
|
|
893
|
+
run_prefix,
|
|
894
|
+
)
|
|
895
|
+
subject_prompt_path = _safe_file(
|
|
896
|
+
root,
|
|
897
|
+
expected_subject_prompt_ref,
|
|
898
|
+
"judge subject-input dependency",
|
|
899
|
+
run_prefix,
|
|
900
|
+
)
|
|
901
|
+
expected_prompt_bytes = (
|
|
902
|
+
template_path.read_bytes()
|
|
903
|
+
+ JUDGE_SUBJECT_INPUT_SEPARATOR
|
|
904
|
+
+ subject_prompt_path.read_bytes()
|
|
905
|
+
+ JUDGE_SUBJECT_OUTPUT_SEPARATOR
|
|
906
|
+
+ subject_output_path.read_bytes()
|
|
907
|
+
)
|
|
908
|
+
if prompt_path.read_bytes() != expected_prompt_bytes:
|
|
909
|
+
raise ContractError(
|
|
910
|
+
"judge prompt bytes do not replay template + subject input + subject output"
|
|
911
|
+
)
|
|
912
|
+
if prompt_ref not in raw_paths or output_ref not in raw_paths:
|
|
913
|
+
raise ContractError("every planned prompt/output ref must be retained raw")
|
|
914
|
+
if call["role"] == "judge":
|
|
915
|
+
pair = (call["judge_id"], call["item_replicate_id"])
|
|
916
|
+
if pair in judge_pairs:
|
|
917
|
+
raise ContractError("duplicate judge/item call in subject-call plan")
|
|
918
|
+
judge_pairs.add(pair)
|
|
919
|
+
subject = subject_by_replicate.get(call["item_replicate_id"])
|
|
920
|
+
if subject is None:
|
|
921
|
+
raise ContractError("judge call names an unplanned subject item-replicate")
|
|
922
|
+
for key in ("item_id", "replicate_index", "arm_id", "control_item"):
|
|
923
|
+
if call[key] != subject[key]:
|
|
924
|
+
raise ContractError(f"judge/subject call-plan {key} mismatch")
|
|
925
|
+
|
|
926
|
+
reported_judge_pairs = [
|
|
927
|
+
(judge["judge_id"], item["item_id"])
|
|
928
|
+
for judge in report.get("judges", [])
|
|
929
|
+
for item in judge.get("per_item", [])
|
|
930
|
+
]
|
|
931
|
+
if len(reported_judge_pairs) != len(set(reported_judge_pairs)):
|
|
932
|
+
raise ContractError("prospective row contains duplicate judge/item results")
|
|
933
|
+
expected_judge_pairs = set(reported_judge_pairs)
|
|
934
|
+
if judge_pairs != expected_judge_pairs:
|
|
935
|
+
raise ContractError("subject-call plan does not exactly cover every judge/item pair")
|
|
936
|
+
for judge in report.get("judges", []):
|
|
937
|
+
for item in judge.get("per_item", []):
|
|
938
|
+
raw_c9 = item.get("citation_attachment")
|
|
939
|
+
if not isinstance(raw_c9, Mapping):
|
|
940
|
+
raise ContractError("every raw judge/item row requires a typed C9 verdict")
|
|
941
|
+
_closed_keys(
|
|
942
|
+
raw_c9,
|
|
943
|
+
{"criterion", "flag"},
|
|
944
|
+
"raw judge/item citation_attachment",
|
|
945
|
+
)
|
|
946
|
+
if raw_c9["criterion"] != "C9" or not isinstance(raw_c9["flag"], bool):
|
|
947
|
+
raise ContractError("raw judge/item C9 verdict must be criterion C9 + boolean flag")
|
|
948
|
+
return plan
|
|
949
|
+
|
|
950
|
+
|
|
951
|
+
def _check_manifest_binding(
|
|
952
|
+
root: Path,
|
|
953
|
+
record: Mapping[str, Any],
|
|
954
|
+
row_manifest: Mapping[str, Any],
|
|
955
|
+
plan: Mapping[str, Any],
|
|
956
|
+
raw_paths: list[str],
|
|
957
|
+
) -> dict[str, Any]:
|
|
958
|
+
binding = record["execution_manifest"]
|
|
959
|
+
ref = binding["ref"]
|
|
960
|
+
path = _safe_file(root, ref, "subject-context execution manifest", RUNS_PREFIX)
|
|
961
|
+
if row_manifest.get("ref") != ref:
|
|
962
|
+
raise ContractError("row/context execution-manifest ref mismatch")
|
|
963
|
+
if ref != _run_artifact_ref(record["run_id"], "execution-manifest.json"):
|
|
964
|
+
raise ContractError("execution-manifest ref is not the canonical run sibling")
|
|
965
|
+
if _sha256(path) != row_manifest.get("sha256"):
|
|
966
|
+
raise ContractError("row execution-manifest hash mismatch")
|
|
967
|
+
if ref not in raw_paths:
|
|
968
|
+
raise ContractError("execution-manifest ref must appear in raw_outputs.paths")
|
|
969
|
+
parts = ref.split("/")
|
|
970
|
+
if len(parts) < 2 or parts[-2] != record["run_id"]:
|
|
971
|
+
raise ContractError("subject-context run_id does not match manifest parent directory")
|
|
972
|
+
manifest = _require_object(_strict_json(path), "execution manifest")
|
|
973
|
+
schema_path = _safe_file(root, "evals/heldout/execution_manifest.schema.json",
|
|
974
|
+
"execution-manifest schema")
|
|
975
|
+
manifest_schema = _require_object(_strict_json(schema_path), "execution-manifest schema")
|
|
976
|
+
errors = list(_schema_validator(manifest_schema, "execution-manifest schema").iter_errors(manifest))
|
|
977
|
+
if errors:
|
|
978
|
+
raise ContractError(f"bound execution manifest fails schema: {errors[0].message}")
|
|
979
|
+
if manifest["suite"] != record["suite"]:
|
|
980
|
+
raise ContractError("subject-context and execution manifest suite mismatch")
|
|
981
|
+
calls = manifest["calls"]
|
|
982
|
+
planned_calls = plan["calls"]
|
|
983
|
+
if len(calls) != len(planned_calls):
|
|
984
|
+
raise ContractError("execution manifest does not exactly cover the call plan")
|
|
985
|
+
indexes = [call["sequence_index"] for call in calls]
|
|
986
|
+
if indexes != list(range(1, len(calls) + 1)):
|
|
987
|
+
raise ContractError("execution-manifest sequence indexes must be ordered 1..N")
|
|
988
|
+
call_ids = [call["call_id"] for call in calls]
|
|
989
|
+
if len(call_ids) != len(set(call_ids)):
|
|
990
|
+
raise ContractError("execution-manifest call_id values must be unique")
|
|
991
|
+
starts: list[dt.datetime] = []
|
|
992
|
+
completions: list[dt.datetime] = []
|
|
993
|
+
subject_starts: list[dt.datetime] = []
|
|
994
|
+
subject_completions: list[dt.datetime] = []
|
|
995
|
+
judge_starts: list[dt.datetime] = []
|
|
996
|
+
for index, (call, planned) in enumerate(zip(calls, planned_calls, strict=True)):
|
|
997
|
+
planned_prompt_path = _safe_file(
|
|
998
|
+
root,
|
|
999
|
+
planned["prompt"]["ref"],
|
|
1000
|
+
f"executed prompt[{index}]",
|
|
1001
|
+
f"{RUNS_PREFIX}{record['run_id']}/",
|
|
1002
|
+
)
|
|
1003
|
+
if (
|
|
1004
|
+
call["call_id"] != planned["call_id"]
|
|
1005
|
+
or call["sequence_index"] != planned["sequence_index"]
|
|
1006
|
+
or call["prompt_sha256"] != _sha256(planned_prompt_path)
|
|
1007
|
+
):
|
|
1008
|
+
raise ContractError("execution-manifest call differs from precommitted call plan")
|
|
1009
|
+
output_path = _safe_file(
|
|
1010
|
+
root,
|
|
1011
|
+
planned["output_ref"],
|
|
1012
|
+
f"executed output[{index}]",
|
|
1013
|
+
f"{RUNS_PREFIX}{record['run_id']}/",
|
|
1014
|
+
)
|
|
1015
|
+
if _sha256(output_path) != call["output_sha256"]:
|
|
1016
|
+
raise ContractError("execution-manifest output hash differs from retained bytes")
|
|
1017
|
+
started = _time(call["started_at"], f"execution_manifest.calls[{index}].started_at")
|
|
1018
|
+
completed = _time(call["completed_at"], f"execution_manifest.calls[{index}].completed_at")
|
|
1019
|
+
if started > completed:
|
|
1020
|
+
raise ContractError("execution-manifest call completes before it starts")
|
|
1021
|
+
starts.append(started)
|
|
1022
|
+
completions.append(completed)
|
|
1023
|
+
if planned["role"] == "subject":
|
|
1024
|
+
subject_starts.append(started)
|
|
1025
|
+
subject_completions.append(completed)
|
|
1026
|
+
else:
|
|
1027
|
+
judge_starts.append(started)
|
|
1028
|
+
if _time(manifest["created_at"], "execution_manifest.created_at") < max(completions):
|
|
1029
|
+
raise ContractError("execution manifest was recorded before its final call completed")
|
|
1030
|
+
if "execution_window" in manifest:
|
|
1031
|
+
window = manifest["execution_window"]
|
|
1032
|
+
if window["window_id"] != record["run_id"]:
|
|
1033
|
+
raise ContractError("execution-window ID and subject-context run_id mismatch")
|
|
1034
|
+
window_start = _time(window["started_at"], "execution_window.started_at")
|
|
1035
|
+
window_end = _time(window["completed_at"], "execution_window.completed_at")
|
|
1036
|
+
if window_start > min(starts) or window_end < max(completions) or window_start > window_end:
|
|
1037
|
+
raise ContractError("execution window does not contain all calls")
|
|
1038
|
+
if _time(manifest["created_at"], "execution_manifest.created_at") < window_end:
|
|
1039
|
+
raise ContractError("execution manifest was recorded before its window ended")
|
|
1040
|
+
if any(later < earlier for earlier, later in zip(starts, starts[1:])):
|
|
1041
|
+
raise ContractError("execution-manifest calls are not chronological by plan order")
|
|
1042
|
+
if judge_starts and min(judge_starts) < max(subject_completions):
|
|
1043
|
+
raise ContractError("judge calls began before the subject fleet completed")
|
|
1044
|
+
first_call_start = min(starts)
|
|
1045
|
+
if _time(record["recorded_at"], "subject_context.recorded_at") > first_call_start:
|
|
1046
|
+
raise ContractError("subject-context gate was not sealed before the first planned call")
|
|
1047
|
+
probe_completed = record["context_probe"]["completed_at"]
|
|
1048
|
+
if probe_completed is not None and _time(probe_completed, "context_probe.completed_at") > first_call_start:
|
|
1049
|
+
raise ContractError("context probe was not completed before the first planned call")
|
|
1050
|
+
attestation = record["attestation"]
|
|
1051
|
+
if attestation is not None and _time(attestation["attested_at"], "attestation.attested_at") > first_call_start:
|
|
1052
|
+
raise ContractError("operator attestation was not recorded before the first planned call")
|
|
1053
|
+
return manifest
|
|
1054
|
+
|
|
1055
|
+
|
|
1056
|
+
def _walk_strings(value: Any, path: str = "$") -> Iterable[tuple[str, str]]:
|
|
1057
|
+
if isinstance(value, str):
|
|
1058
|
+
yield path, value
|
|
1059
|
+
elif isinstance(value, Mapping):
|
|
1060
|
+
for key, child in value.items():
|
|
1061
|
+
yield from _walk_strings(child, f"{path}.{key}")
|
|
1062
|
+
elif isinstance(value, Sequence) and not isinstance(value, (str, bytes, bytearray)):
|
|
1063
|
+
for index, child in enumerate(value):
|
|
1064
|
+
yield from _walk_strings(child, f"{path}[{index}]")
|
|
1065
|
+
|
|
1066
|
+
|
|
1067
|
+
def _walk_keys(value: Any, path: str = "$") -> Iterable[tuple[str, str]]:
|
|
1068
|
+
if isinstance(value, Mapping):
|
|
1069
|
+
for key, child in value.items():
|
|
1070
|
+
yield f"{path}.<key:{key}>", str(key)
|
|
1071
|
+
yield from _walk_keys(child, f"{path}.{key}")
|
|
1072
|
+
elif isinstance(value, Sequence) and not isinstance(value, (str, bytes, bytearray)):
|
|
1073
|
+
for index, child in enumerate(value):
|
|
1074
|
+
yield from _walk_keys(child, f"{path}[{index}]")
|
|
1075
|
+
|
|
1076
|
+
|
|
1077
|
+
def _check_claim_language(report: Mapping[str, Any], status: str) -> None:
|
|
1078
|
+
expected = STATUS_CLAIMS[status]
|
|
1079
|
+
actual = report.get("results", {}).get("subject_context_claim")
|
|
1080
|
+
if actual != expected:
|
|
1081
|
+
raise ContractError(
|
|
1082
|
+
"results.subject_context_claim must be the exact status-derived ceiling"
|
|
1083
|
+
)
|
|
1084
|
+
for location, value in _walk_strings(report):
|
|
1085
|
+
if location == "$.results.subject_context_claim":
|
|
1086
|
+
continue
|
|
1087
|
+
lowered = value.casefold()
|
|
1088
|
+
if (
|
|
1089
|
+
"clean context" in lowered
|
|
1090
|
+
or "prompt isolation" in lowered
|
|
1091
|
+
or re.search(r"\b(?:isolated|isolation)\b", lowered)
|
|
1092
|
+
):
|
|
1093
|
+
raise ContractError(
|
|
1094
|
+
f"{location}: isolation wording is allowed only in the exact derived field"
|
|
1095
|
+
)
|
|
1096
|
+
for location, key in _walk_keys(report):
|
|
1097
|
+
normalized = re.sub(r"[_\-/]+", " ", key.casefold())
|
|
1098
|
+
if (
|
|
1099
|
+
"clean context" in normalized
|
|
1100
|
+
or "prompt isolation" in normalized
|
|
1101
|
+
or re.search(r"\b(?:isolated|isolation)\b", normalized)
|
|
1102
|
+
):
|
|
1103
|
+
raise ContractError(
|
|
1104
|
+
f"{location}: claim-shaped isolation keys are forbidden"
|
|
1105
|
+
)
|
|
1106
|
+
|
|
1107
|
+
|
|
1108
|
+
def validate_prospective_measurement(
|
|
1109
|
+
report: Mapping[str, Any], root: Path, schema: Mapping[str, Any] | None = None
|
|
1110
|
+
) -> None:
|
|
1111
|
+
"""Replay #679 bindings for a future heldout-measurement/1.1 row."""
|
|
1112
|
+
measurement_schema_path = _safe_file(
|
|
1113
|
+
root,
|
|
1114
|
+
"evals/heldout/measurement_report.schema.json",
|
|
1115
|
+
"measurement-report schema",
|
|
1116
|
+
)
|
|
1117
|
+
measurement_schema = _require_object(
|
|
1118
|
+
_strict_json(measurement_schema_path), "measurement-report schema"
|
|
1119
|
+
)
|
|
1120
|
+
measurement_errors = sorted(
|
|
1121
|
+
_schema_validator(
|
|
1122
|
+
measurement_schema, "measurement-report schema"
|
|
1123
|
+
).iter_errors(report),
|
|
1124
|
+
key=lambda error: tuple(str(part) for part in error.absolute_path),
|
|
1125
|
+
)
|
|
1126
|
+
if measurement_errors:
|
|
1127
|
+
first = measurement_errors[0]
|
|
1128
|
+
location = ".".join(str(part) for part in first.absolute_path) or "<root>"
|
|
1129
|
+
raise ContractError(f"prospective measurement.{location}: {first.message}")
|
|
1130
|
+
if report.get("measurement_contract") != "heldout-measurement/1.1":
|
|
1131
|
+
raise ContractError("prospective row must use heldout-measurement/1.1")
|
|
1132
|
+
if report.get("suite") != "revision_claim_drift":
|
|
1133
|
+
raise ContractError("prospective row suite mismatch")
|
|
1134
|
+
try:
|
|
1135
|
+
config = report["subject"]["config"]
|
|
1136
|
+
binding = config["subject_context"]
|
|
1137
|
+
except (KeyError, TypeError) as exc:
|
|
1138
|
+
raise ContractError("missing subject.config.subject_context binding") from exc
|
|
1139
|
+
_closed_keys(
|
|
1140
|
+
config,
|
|
1141
|
+
{"suite_commit", "subject_context", "launcher_config", "subject_call_plan"},
|
|
1142
|
+
"subject.config",
|
|
1143
|
+
)
|
|
1144
|
+
_closed_keys(binding, {"ref", "sha256", "status"}, "subject.config.subject_context")
|
|
1145
|
+
if binding["status"] not in STATUS_VALUES:
|
|
1146
|
+
raise ContractError("subject-context binding has unknown status")
|
|
1147
|
+
ref = binding["ref"]
|
|
1148
|
+
context_path = _safe_file(root, ref, "subject-context row ref", RUNS_PREFIX)
|
|
1149
|
+
parts = ref.split("/")
|
|
1150
|
+
if parts[-1] != "subject-context.json":
|
|
1151
|
+
raise ContractError("subject-context ref must end in subject-context.json")
|
|
1152
|
+
if _sha256(context_path) != binding["sha256"]:
|
|
1153
|
+
raise ContractError("subject-context row hash mismatch")
|
|
1154
|
+
if schema is None:
|
|
1155
|
+
schema = _pinned_schema(
|
|
1156
|
+
root,
|
|
1157
|
+
f"{SUITE_REL}/subject_context_record.schema.json",
|
|
1158
|
+
SUBJECT_SCHEMA_SHA256,
|
|
1159
|
+
"subject-context schema",
|
|
1160
|
+
)
|
|
1161
|
+
launcher_schema = _pinned_schema(
|
|
1162
|
+
root,
|
|
1163
|
+
f"{SUITE_REL}/subject_launcher_config.schema.json",
|
|
1164
|
+
LAUNCHER_SCHEMA_SHA256,
|
|
1165
|
+
"subject-launcher-config schema",
|
|
1166
|
+
)
|
|
1167
|
+
call_plan_schema = _pinned_schema(
|
|
1168
|
+
root,
|
|
1169
|
+
f"{SUITE_REL}/subject_call_plan.schema.json",
|
|
1170
|
+
CALL_PLAN_SCHEMA_SHA256,
|
|
1171
|
+
"subject-call-plan schema",
|
|
1172
|
+
)
|
|
1173
|
+
record = _require_object(_strict_json(context_path), "bound subject-context record")
|
|
1174
|
+
validate_subject_context(record, schema, "bound subject-context record")
|
|
1175
|
+
if ref != _run_artifact_ref(record["run_id"], "subject-context.json"):
|
|
1176
|
+
raise ContractError("subject-context ref is not the canonical run sibling")
|
|
1177
|
+
if binding["status"] != record["status"]:
|
|
1178
|
+
raise ContractError("subject-context binding status differs from record")
|
|
1179
|
+
if config.get("suite_commit") != record["suite_commit"]:
|
|
1180
|
+
raise ContractError("subject.config.suite_commit differs from context record")
|
|
1181
|
+
raw_paths = report.get("raw_outputs", {}).get("paths", [])
|
|
1182
|
+
if not isinstance(raw_paths, list) or not all(isinstance(path, str) for path in raw_paths):
|
|
1183
|
+
raise ContractError("raw_outputs.paths must be a string array")
|
|
1184
|
+
if len(raw_paths) != len(set(raw_paths)):
|
|
1185
|
+
raise ContractError("raw_outputs.paths must not contain duplicate refs")
|
|
1186
|
+
for index, raw_ref in enumerate(raw_paths):
|
|
1187
|
+
_safe_file(root, raw_ref, f"raw_outputs.paths[{index}]")
|
|
1188
|
+
if ref not in raw_paths:
|
|
1189
|
+
raise ContractError("subject-context ref must appear verbatim in raw_outputs.paths")
|
|
1190
|
+
_validate_launcher_binding(root, record, config, raw_paths, launcher_schema)
|
|
1191
|
+
plan = _validate_call_plan_binding(
|
|
1192
|
+
root, report, record, config, raw_paths, call_plan_schema
|
|
1193
|
+
)
|
|
1194
|
+
row_manifest = report.get("execution_manifest")
|
|
1195
|
+
if not isinstance(row_manifest, Mapping):
|
|
1196
|
+
raise ContractError("prospective row lacks execution_manifest binding")
|
|
1197
|
+
_closed_keys(
|
|
1198
|
+
row_manifest,
|
|
1199
|
+
{"ref", "sha256", "write_once", "claims"},
|
|
1200
|
+
"execution_manifest",
|
|
1201
|
+
)
|
|
1202
|
+
if row_manifest.get("ref") != record["execution_manifest"]["ref"]:
|
|
1203
|
+
raise ContractError("row/context execution_manifest ref mismatch")
|
|
1204
|
+
_check_manifest_binding(root, record, row_manifest, plan, raw_paths)
|
|
1205
|
+
expected_ref = f"{SUITE_REL}/adjudication_rubric_v2.md"
|
|
1206
|
+
adjudication = report.get("adjudication", {})
|
|
1207
|
+
prereg = report.get("preregistration", {})
|
|
1208
|
+
for label, value in (("adjudication", adjudication), ("preregistration", prereg)):
|
|
1209
|
+
if value.get("rubric_ref") != expected_ref or value.get("rubric_sha256") != V2_RUBRIC_SHA256:
|
|
1210
|
+
raise ContractError(f"{label}: prospective row did not opt into the frozen v2 rubric")
|
|
1211
|
+
if prereg.get("frozen_commit") != record["suite_commit"]:
|
|
1212
|
+
raise ContractError("preregistration frozen_commit differs from context record")
|
|
1213
|
+
if (
|
|
1214
|
+
prereg.get("plan_ref") != config["subject_call_plan"]["ref"]
|
|
1215
|
+
or prereg.get("plan_sha256") != config["subject_call_plan"]["sha256"]
|
|
1216
|
+
):
|
|
1217
|
+
raise ContractError("preregistration plan binding differs from subject-call plan")
|
|
1218
|
+
if adjudication.get("resolution_direction") != "flags_only":
|
|
1219
|
+
raise ContractError("v2 adjudication resolution_direction must be flags_only")
|
|
1220
|
+
headline = report.get("aggregate", {}).get("headline", {})
|
|
1221
|
+
headline_value = headline.get("value")
|
|
1222
|
+
expected_headline = {
|
|
1223
|
+
"metric_name": "claim_strength_hedge_drift_rate",
|
|
1224
|
+
"value": headline_value,
|
|
1225
|
+
"construction_rule": (
|
|
1226
|
+
"Confirmed C1/C2 item-replicate flags divided by evaluated "
|
|
1227
|
+
"item-replicates; flags-only adjudication makes this a lower bound."
|
|
1228
|
+
),
|
|
1229
|
+
"estimand_status": "lower_bound",
|
|
1230
|
+
}
|
|
1231
|
+
if (
|
|
1232
|
+
headline != expected_headline
|
|
1233
|
+
or not isinstance(headline_value, (int, float))
|
|
1234
|
+
or isinstance(headline_value, bool)
|
|
1235
|
+
or not 0 <= headline_value <= 1
|
|
1236
|
+
):
|
|
1237
|
+
raise ContractError("aggregate headline must be the closed C1/C2 lower-bound layer")
|
|
1238
|
+
subject_calls = [call for call in plan["calls"] if call["role"] == "subject"]
|
|
1239
|
+
expected_evaluated = sorted(call["item_replicate_id"] for call in subject_calls)
|
|
1240
|
+
expected_controls = sorted(
|
|
1241
|
+
call["item_replicate_id"] for call in subject_calls if call["control_item"]
|
|
1242
|
+
)
|
|
1243
|
+
expected_v2_results = {
|
|
1244
|
+
"rubric_version": "2.0",
|
|
1245
|
+
"claim_strength_headline_criteria": ["C1", "C2"],
|
|
1246
|
+
"deterministic_token_criterion": "C6",
|
|
1247
|
+
"arm_ids": plan["arm_ids"],
|
|
1248
|
+
"citation_attachment": {
|
|
1249
|
+
"criterion": "C9",
|
|
1250
|
+
"scope": "all_items_including_non_controls",
|
|
1251
|
+
"reported_separately": True,
|
|
1252
|
+
"evaluated_item_replicates": expected_evaluated,
|
|
1253
|
+
"control_item_replicates": expected_controls,
|
|
1254
|
+
"finding_count": report.get("results", {})
|
|
1255
|
+
.get("revision_claim_drift_v2", {})
|
|
1256
|
+
.get("citation_attachment", {})
|
|
1257
|
+
.get("finding_count"),
|
|
1258
|
+
"decisions": report.get("results", {})
|
|
1259
|
+
.get("revision_claim_drift_v2", {})
|
|
1260
|
+
.get("citation_attachment", {})
|
|
1261
|
+
.get("decisions"),
|
|
1262
|
+
"findings": report.get("results", {})
|
|
1263
|
+
.get("revision_claim_drift_v2", {})
|
|
1264
|
+
.get("citation_attachment", {})
|
|
1265
|
+
.get("findings"),
|
|
1266
|
+
},
|
|
1267
|
+
}
|
|
1268
|
+
actual_v2_results = report.get("results", {}).get("revision_claim_drift_v2")
|
|
1269
|
+
if actual_v2_results != expected_v2_results:
|
|
1270
|
+
raise ContractError("prospective row lacks the closed separate C9 result binding")
|
|
1271
|
+
citation_layer = expected_v2_results["citation_attachment"]
|
|
1272
|
+
evaluated = citation_layer["evaluated_item_replicates"]
|
|
1273
|
+
controls = citation_layer["control_item_replicates"]
|
|
1274
|
+
decisions = citation_layer["decisions"]
|
|
1275
|
+
findings = citation_layer["findings"]
|
|
1276
|
+
if (
|
|
1277
|
+
not evaluated
|
|
1278
|
+
or not isinstance(controls, list)
|
|
1279
|
+
or len(controls) != len(set(controls))
|
|
1280
|
+
or not set(controls).issubset(evaluated)
|
|
1281
|
+
or set(controls) == set(evaluated)
|
|
1282
|
+
):
|
|
1283
|
+
raise ContractError(
|
|
1284
|
+
"C9 coverage must include every judged item-replicate and at least one non-control"
|
|
1285
|
+
)
|
|
1286
|
+
if (
|
|
1287
|
+
not isinstance(citation_layer["finding_count"], int)
|
|
1288
|
+
or isinstance(citation_layer["finding_count"], bool)
|
|
1289
|
+
or not isinstance(findings, list)
|
|
1290
|
+
or citation_layer["finding_count"] != len(findings)
|
|
1291
|
+
):
|
|
1292
|
+
raise ContractError("C9 finding_count must equal the findings list length")
|
|
1293
|
+
judge_rows = report.get("judges", [])
|
|
1294
|
+
judge_ids = [judge.get("judge_id") for judge in judge_rows]
|
|
1295
|
+
if (
|
|
1296
|
+
not judge_ids
|
|
1297
|
+
or not all(isinstance(judge_id, str) and judge_id for judge_id in judge_ids)
|
|
1298
|
+
or len(judge_ids) != len(set(judge_ids))
|
|
1299
|
+
):
|
|
1300
|
+
raise ContractError("prospective row judge_id values must be non-empty and unique")
|
|
1301
|
+
reported_judges = {judge["judge_id"]: judge for judge in judge_rows}
|
|
1302
|
+
raw_true_pairs = sorted(
|
|
1303
|
+
(judge["judge_id"], item["item_id"])
|
|
1304
|
+
for judge in judge_rows
|
|
1305
|
+
for item in judge.get("per_item", [])
|
|
1306
|
+
if item.get("citation_attachment") == {"criterion": "C9", "flag": True}
|
|
1307
|
+
)
|
|
1308
|
+
if not isinstance(decisions, list):
|
|
1309
|
+
raise ContractError("C9 decisions must be a closed array")
|
|
1310
|
+
decision_pairs: list[tuple[str, str]] = []
|
|
1311
|
+
confirmed_by_finding: dict[str, list[tuple[str, str]]] = {}
|
|
1312
|
+
for index, decision in enumerate(decisions):
|
|
1313
|
+
if not isinstance(decision, Mapping):
|
|
1314
|
+
raise ContractError(f"C9 decisions[{index}] must be an object")
|
|
1315
|
+
_closed_keys(
|
|
1316
|
+
decision,
|
|
1317
|
+
{
|
|
1318
|
+
"decision_id",
|
|
1319
|
+
"judge_id",
|
|
1320
|
+
"item_replicate_id",
|
|
1321
|
+
"raw_flag",
|
|
1322
|
+
"disposition",
|
|
1323
|
+
"criterion_ref",
|
|
1324
|
+
"reason_code",
|
|
1325
|
+
"finding_id",
|
|
1326
|
+
},
|
|
1327
|
+
f"C9 decisions[{index}]",
|
|
1328
|
+
)
|
|
1329
|
+
judge_id = decision["judge_id"]
|
|
1330
|
+
item_replicate_id = decision["item_replicate_id"]
|
|
1331
|
+
if (
|
|
1332
|
+
not isinstance(judge_id, str)
|
|
1333
|
+
or not isinstance(item_replicate_id, str)
|
|
1334
|
+
or decision["decision_id"] != f"c9d.{judge_id}.{item_replicate_id}"
|
|
1335
|
+
or decision["raw_flag"] is not True
|
|
1336
|
+
):
|
|
1337
|
+
raise ContractError("C9 decision identity/raw flag is not canonical")
|
|
1338
|
+
pair = (judge_id, item_replicate_id)
|
|
1339
|
+
decision_pairs.append(pair)
|
|
1340
|
+
disposition = decision["disposition"]
|
|
1341
|
+
criterion_ref = decision["criterion_ref"]
|
|
1342
|
+
reason_code = decision["reason_code"]
|
|
1343
|
+
finding_id = decision["finding_id"]
|
|
1344
|
+
if disposition == "confirmed":
|
|
1345
|
+
if (
|
|
1346
|
+
criterion_ref != "C9"
|
|
1347
|
+
or reason_code != "violation_confirmed"
|
|
1348
|
+
or not isinstance(finding_id, str)
|
|
1349
|
+
or not finding_id
|
|
1350
|
+
):
|
|
1351
|
+
raise ContractError("confirmed C9 decision has invalid authority/result")
|
|
1352
|
+
confirmed_by_finding.setdefault(finding_id, []).append(pair)
|
|
1353
|
+
elif disposition == "rejected":
|
|
1354
|
+
valid_rejection = (
|
|
1355
|
+
criterion_ref == "C3" and reason_code == "authorized_under_C3"
|
|
1356
|
+
) or (
|
|
1357
|
+
criterion_ref == "C9"
|
|
1358
|
+
and reason_code == "no_citation_attachment_violation"
|
|
1359
|
+
)
|
|
1360
|
+
if not valid_rejection or finding_id is not None:
|
|
1361
|
+
raise ContractError("rejected C9 decision has invalid closed reason")
|
|
1362
|
+
else:
|
|
1363
|
+
raise ContractError("C9 decision disposition is outside the closed vocabulary")
|
|
1364
|
+
if decision_pairs != raw_true_pairs or len(decision_pairs) != len(set(decision_pairs)):
|
|
1365
|
+
raise ContractError("C9 decisions must exactly resolve every typed raw true flag")
|
|
1366
|
+
|
|
1367
|
+
for _location, override_text in _walk_strings(report.get("adjudication", {}).get("overrides", [])):
|
|
1368
|
+
lowered_override = override_text.casefold()
|
|
1369
|
+
if re.search(r"\bc9\b", lowered_override) or "citation_attachment" in lowered_override or "citation-attachment" in lowered_override:
|
|
1370
|
+
raise ContractError("C9 decisions cannot be routed through generic overrides")
|
|
1371
|
+
finding_ids: set[str] = set()
|
|
1372
|
+
for index, finding in enumerate(findings):
|
|
1373
|
+
if not isinstance(finding, Mapping):
|
|
1374
|
+
raise ContractError(f"C9 findings[{index}] must be an object")
|
|
1375
|
+
_closed_keys(
|
|
1376
|
+
finding,
|
|
1377
|
+
{
|
|
1378
|
+
"finding_id",
|
|
1379
|
+
"item_replicate_id",
|
|
1380
|
+
"criterion",
|
|
1381
|
+
"authorization",
|
|
1382
|
+
"citation_tokens_ref",
|
|
1383
|
+
"citation_tokens_sha256",
|
|
1384
|
+
"original_attachment_ref",
|
|
1385
|
+
"original_attachment_sha256",
|
|
1386
|
+
"revised_attachment_ref",
|
|
1387
|
+
"revised_attachment_sha256",
|
|
1388
|
+
"evidence_ref",
|
|
1389
|
+
"evidence_sha256",
|
|
1390
|
+
"raw_flag_judge_ids",
|
|
1391
|
+
"adjudication_disposition",
|
|
1392
|
+
},
|
|
1393
|
+
f"C9 findings[{index}]",
|
|
1394
|
+
)
|
|
1395
|
+
finding_id = finding["finding_id"]
|
|
1396
|
+
if (
|
|
1397
|
+
not isinstance(finding_id, str)
|
|
1398
|
+
or not re.fullmatch(r"[A-Za-z0-9][A-Za-z0-9._-]{0,127}", finding_id)
|
|
1399
|
+
or finding_id in finding_ids
|
|
1400
|
+
):
|
|
1401
|
+
raise ContractError("C9 finding_id values must be non-empty and unique")
|
|
1402
|
+
finding_ids.add(finding_id)
|
|
1403
|
+
if finding["item_replicate_id"] not in evaluated:
|
|
1404
|
+
raise ContractError("C9 finding names an unevaluated item-replicate")
|
|
1405
|
+
if finding["criterion"] != "C9" or finding["authorization"] != "unauthorized_under_C3":
|
|
1406
|
+
raise ContractError("C9 finding authority must be C9 and unauthorized_under_C3")
|
|
1407
|
+
raw_judge_ids = finding["raw_flag_judge_ids"]
|
|
1408
|
+
if (
|
|
1409
|
+
not isinstance(raw_judge_ids, list)
|
|
1410
|
+
or not raw_judge_ids
|
|
1411
|
+
or not all(isinstance(judge_id, str) and judge_id for judge_id in raw_judge_ids)
|
|
1412
|
+
or raw_judge_ids != sorted(set(raw_judge_ids))
|
|
1413
|
+
):
|
|
1414
|
+
raise ContractError("C9 raw_flag_judge_ids must be a sorted non-empty unique list")
|
|
1415
|
+
if finding["adjudication_disposition"] != "confirmed":
|
|
1416
|
+
raise ContractError("published C9 findings must be confirmed raw flags")
|
|
1417
|
+
expected_confirmed_pairs = [
|
|
1418
|
+
(judge_id, finding["item_replicate_id"]) for judge_id in raw_judge_ids
|
|
1419
|
+
]
|
|
1420
|
+
if confirmed_by_finding.get(finding_id) != expected_confirmed_pairs:
|
|
1421
|
+
raise ContractError("C9 finding raw judges differ from confirmed decisions")
|
|
1422
|
+
for judge_id in raw_judge_ids:
|
|
1423
|
+
judge = reported_judges.get(judge_id)
|
|
1424
|
+
if judge is None or not any(
|
|
1425
|
+
item.get("item_id") == finding["item_replicate_id"]
|
|
1426
|
+
and item.get("citation_attachment") == {
|
|
1427
|
+
"criterion": "C9",
|
|
1428
|
+
"flag": True,
|
|
1429
|
+
}
|
|
1430
|
+
for item in judge.get("per_item", [])
|
|
1431
|
+
):
|
|
1432
|
+
raise ContractError(
|
|
1433
|
+
"each confirmed C9 finding must replay to a raw judge flag"
|
|
1434
|
+
)
|
|
1435
|
+
for key in (
|
|
1436
|
+
"citation_tokens_sha256",
|
|
1437
|
+
"original_attachment_sha256",
|
|
1438
|
+
"revised_attachment_sha256",
|
|
1439
|
+
"evidence_sha256",
|
|
1440
|
+
):
|
|
1441
|
+
if not isinstance(finding[key], str) or not re.fullmatch(r"[0-9a-f]{64}", finding[key]):
|
|
1442
|
+
raise ContractError(f"C9 findings[{index}].{key} must be lowercase SHA-256")
|
|
1443
|
+
attachment_specs = (
|
|
1444
|
+
("citation_tokens", "citation-tokens.txt"),
|
|
1445
|
+
("original_attachment", "original-attachment.txt"),
|
|
1446
|
+
("revised_attachment", "revised-attachment.txt"),
|
|
1447
|
+
)
|
|
1448
|
+
attachment_bindings: dict[str, dict[str, str]] = {}
|
|
1449
|
+
for field, suffix in attachment_specs:
|
|
1450
|
+
attachment_ref = finding[f"{field}_ref"]
|
|
1451
|
+
expected_attachment_ref = (
|
|
1452
|
+
f"{RUNS_PREFIX}{record['run_id']}/c9/{finding_id}.{suffix}"
|
|
1453
|
+
)
|
|
1454
|
+
if attachment_ref != expected_attachment_ref:
|
|
1455
|
+
raise ContractError(f"C9 {field}_ref is not the canonical run-local path")
|
|
1456
|
+
attachment_path = _safe_file(
|
|
1457
|
+
root,
|
|
1458
|
+
attachment_ref,
|
|
1459
|
+
f"C9 findings[{index}] {field}",
|
|
1460
|
+
f"{RUNS_PREFIX}{record['run_id']}/",
|
|
1461
|
+
)
|
|
1462
|
+
if not 1 <= attachment_path.stat().st_size <= 65_536:
|
|
1463
|
+
raise ContractError(f"C9 {field} artifact must be 1..65536 bytes")
|
|
1464
|
+
if _sha256(attachment_path) != finding[f"{field}_sha256"]:
|
|
1465
|
+
raise ContractError(f"C9 {field} artifact hash mismatch")
|
|
1466
|
+
if attachment_ref not in raw_paths:
|
|
1467
|
+
raise ContractError(f"C9 {field}_ref must appear in raw_outputs.paths")
|
|
1468
|
+
attachment_bindings[field] = {
|
|
1469
|
+
"ref": attachment_ref,
|
|
1470
|
+
"sha256": finding[f"{field}_sha256"],
|
|
1471
|
+
}
|
|
1472
|
+
evidence_ref = finding["evidence_ref"]
|
|
1473
|
+
expected_evidence_ref = (
|
|
1474
|
+
f"{RUNS_PREFIX}{record['run_id']}/c9/{finding_id}.json"
|
|
1475
|
+
)
|
|
1476
|
+
if evidence_ref != expected_evidence_ref:
|
|
1477
|
+
raise ContractError("C9 evidence_ref is not the canonical run-local path")
|
|
1478
|
+
evidence_path = _safe_file(
|
|
1479
|
+
root,
|
|
1480
|
+
evidence_ref,
|
|
1481
|
+
f"C9 findings[{index}] evidence",
|
|
1482
|
+
f"{RUNS_PREFIX}{record['run_id']}/",
|
|
1483
|
+
)
|
|
1484
|
+
if _sha256(evidence_path) != finding["evidence_sha256"]:
|
|
1485
|
+
raise ContractError("C9 evidence artifact hash mismatch")
|
|
1486
|
+
if evidence_ref not in raw_paths:
|
|
1487
|
+
raise ContractError("C9 evidence_ref must appear in raw_outputs.paths")
|
|
1488
|
+
evidence = _require_object(
|
|
1489
|
+
_strict_json(evidence_path), f"C9 findings[{index}] evidence"
|
|
1490
|
+
)
|
|
1491
|
+
expected_evidence = {
|
|
1492
|
+
"schema_version": "revision-claim-drift-c9-evidence/1.0",
|
|
1493
|
+
"suite": "revision_claim_drift",
|
|
1494
|
+
"run_id": record["run_id"],
|
|
1495
|
+
"finding_id": finding_id,
|
|
1496
|
+
"item_replicate_id": finding["item_replicate_id"],
|
|
1497
|
+
"criterion": "C9",
|
|
1498
|
+
"raw_flags": [
|
|
1499
|
+
{"judge_id": judge_id, "criterion": "C9", "flag": True}
|
|
1500
|
+
for judge_id in raw_judge_ids
|
|
1501
|
+
],
|
|
1502
|
+
"adjudication": {
|
|
1503
|
+
"disposition": "confirmed",
|
|
1504
|
+
"authorization": "unauthorized_under_C3",
|
|
1505
|
+
},
|
|
1506
|
+
"citation_tokens": attachment_bindings["citation_tokens"],
|
|
1507
|
+
"original_attachment": attachment_bindings["original_attachment"],
|
|
1508
|
+
"revised_attachment": attachment_bindings["revised_attachment"],
|
|
1509
|
+
"data_minimization": {"raw_rationale_stored": False},
|
|
1510
|
+
}
|
|
1511
|
+
if evidence != expected_evidence:
|
|
1512
|
+
raise ContractError("C9 evidence artifact differs from its closed replay grammar")
|
|
1513
|
+
if set(confirmed_by_finding) != finding_ids:
|
|
1514
|
+
raise ContractError("confirmed C9 decisions and published findings differ")
|
|
1515
|
+
_check_claim_language(report, record["status"])
|
|
1516
|
+
|
|
1517
|
+
|
|
1518
|
+
def _check_docs(root: Path) -> None:
|
|
1519
|
+
readme_path = _safe_file(root, f"{SUITE_REL}/README.md", "suite README")
|
|
1520
|
+
design_path = _safe_file(
|
|
1521
|
+
root, "docs/design/2026-08-10-679-revision-claim-drift-suite-v2-spec.md", "v2 design"
|
|
1522
|
+
)
|
|
1523
|
+
readme = readme_path.read_text(encoding="utf-8")
|
|
1524
|
+
design = design_path.read_text(encoding="utf-8")
|
|
1525
|
+
readme_markers = (
|
|
1526
|
+
"### v2 subject-context isolation protocol (prospective)",
|
|
1527
|
+
"performs no re-run, creates no new\nmeasurement row, and does not rescore",
|
|
1528
|
+
"repository-instruction isolation",
|
|
1529
|
+
"physical path",
|
|
1530
|
+
"repository-membership probe",
|
|
1531
|
+
"`--bare`",
|
|
1532
|
+
"authentication result",
|
|
1533
|
+
"pre-fleet contamination probe",
|
|
1534
|
+
"prompt/output SHA-256",
|
|
1535
|
+
"subject-call plan",
|
|
1536
|
+
"launcher-config artifact",
|
|
1537
|
+
"subject.config.subject_context={ref,sha256,status}",
|
|
1538
|
+
"`raw_outputs.paths`",
|
|
1539
|
+
"`machine_supported`",
|
|
1540
|
+
"`attested_only`",
|
|
1541
|
+
"`not_isolated`",
|
|
1542
|
+
"`unknown`",
|
|
1543
|
+
"negative probe is evidence, not proof",
|
|
1544
|
+
)
|
|
1545
|
+
for marker in readme_markers:
|
|
1546
|
+
if marker not in readme:
|
|
1547
|
+
raise ContractError(f"suite README missing #679 protocol marker: {marker}")
|
|
1548
|
+
design_markers = (
|
|
1549
|
+
"DESIGN-FROZEN / PROSPECTIVE-ONLY",
|
|
1550
|
+
"creates no measurement row",
|
|
1551
|
+
"subject_context_record.schema.json",
|
|
1552
|
+
"subject.config.subject_context = {",
|
|
1553
|
+
"raw_outputs.paths",
|
|
1554
|
+
"preflight hash cycle",
|
|
1555
|
+
"results.revision_claim_drift_v2 = {",
|
|
1556
|
+
"all_items_including_non_controls",
|
|
1557
|
+
"resolution_direction` is `flags_only`",
|
|
1558
|
+
"inside_suite_repository",
|
|
1559
|
+
"machine_supported",
|
|
1560
|
+
"attested_only",
|
|
1561
|
+
"not_isolated",
|
|
1562
|
+
"unknown",
|
|
1563
|
+
"pwd_p_sha256",
|
|
1564
|
+
"repo_membership_probe",
|
|
1565
|
+
"authentication_result",
|
|
1566
|
+
"launcher-config artifact",
|
|
1567
|
+
"instruction_visibility",
|
|
1568
|
+
"context_probe",
|
|
1569
|
+
"subject_call_plan",
|
|
1570
|
+
"subject-call-plan.json",
|
|
1571
|
+
"launcher-config.json",
|
|
1572
|
+
"raw_flag_judge_ids",
|
|
1573
|
+
"adjudication_disposition",
|
|
1574
|
+
"decisions = [{",
|
|
1575
|
+
"data_minimization",
|
|
1576
|
+
)
|
|
1577
|
+
for marker in design_markers:
|
|
1578
|
+
if marker not in design:
|
|
1579
|
+
raise ContractError(f"v2 design missing frozen marker: {marker}")
|
|
1580
|
+
|
|
1581
|
+
|
|
1582
|
+
def run_checks(root: Path | str = REPO_ROOT) -> list[str]:
|
|
1583
|
+
"""Run every hermetic #679 guard and return human-readable successes."""
|
|
1584
|
+
root_path = Path(root).resolve()
|
|
1585
|
+
measurement_rows = _check_history(root_path)
|
|
1586
|
+
_check_rubric(root_path)
|
|
1587
|
+
schema, _launcher_schema, _call_plan_schema, _ = _check_subject_assets(root_path)
|
|
1588
|
+
_check_docs(root_path)
|
|
1589
|
+
|
|
1590
|
+
# A future row cannot be introduced accidentally. Once the explicit
|
|
1591
|
+
# no-measurement boundary is intentionally revised, every 1.1 row must also
|
|
1592
|
+
# survive the prospective context replay below.
|
|
1593
|
+
for _path, value in measurement_rows:
|
|
1594
|
+
if isinstance(value, Mapping) and value.get("measurement_contract") == "heldout-measurement/1.1":
|
|
1595
|
+
validate_prospective_measurement(value, root_path, schema)
|
|
1596
|
+
|
|
1597
|
+
return [
|
|
1598
|
+
"historical bytes/tree and no-new-measurement boundary",
|
|
1599
|
+
"v2 rubric and closed amendment ledger",
|
|
1600
|
+
"subject-context/launcher/call-plan schemas and four synthetic fixtures",
|
|
1601
|
+
"README/design prospective protocol",
|
|
1602
|
+
"prospective heldout-measurement/1.1 context replay",
|
|
1603
|
+
]
|
|
1604
|
+
|
|
1605
|
+
|
|
1606
|
+
def main(argv: Sequence[str] | None = None) -> int:
|
|
1607
|
+
parser = argparse.ArgumentParser(description=__doc__)
|
|
1608
|
+
parser.add_argument("--root", type=Path, default=REPO_ROOT, help="repository root")
|
|
1609
|
+
args = parser.parse_args(argv)
|
|
1610
|
+
try:
|
|
1611
|
+
checks = run_checks(args.root)
|
|
1612
|
+
except ContractError as exc:
|
|
1613
|
+
print(f"FAIL: {exc}", file=sys.stderr)
|
|
1614
|
+
return 1
|
|
1615
|
+
for check in checks:
|
|
1616
|
+
print(f"PASS: {check}")
|
|
1617
|
+
print("PASS: #679 is hermetic; this guard made no model/API/judge/eval call")
|
|
1618
|
+
return 0
|
|
1619
|
+
|
|
1620
|
+
|
|
1621
|
+
if __name__ == "__main__":
|
|
1622
|
+
raise SystemExit(main())
|