psyclaw 0.27.23 → 0.28.1
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/agents/recommended/catalog.json +99 -0
- package/dist/apps/panel/index.html +5 -5
- package/dist/src/adapters/pi/extension.js +339 -94
- package/dist/src/adapters/pi/extension.js.map +1 -1
- package/dist/src/adapters/pi/rpc.d.ts +2 -0
- package/dist/src/adapters/pi/rpc.js +9 -2
- package/dist/src/adapters/pi/rpc.js.map +1 -1
- package/dist/src/agents/import.js +44 -32
- package/dist/src/agents/import.js.map +1 -1
- package/dist/src/agents/recommended-personas.d.ts +42 -0
- package/dist/src/agents/recommended-personas.js +135 -0
- package/dist/src/agents/recommended-personas.js.map +1 -0
- 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/cli.js +6 -3
- package/dist/src/cli.js.map +1 -1
- package/dist/src/creation/contracts.d.ts +41 -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 +208 -0
- package/dist/src/creation/service.js.map +1 -0
- package/dist/src/index.d.ts +11 -0
- package/dist/src/index.js +11 -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/bundled-personas.d.ts +16 -0
- package/dist/src/orchestration/bundled-personas.js +101 -0
- package/dist/src/orchestration/bundled-personas.js.map +1 -0
- package/dist/src/orchestration/effects.d.ts +8 -0
- package/dist/src/orchestration/effects.js +39 -0
- package/dist/src/orchestration/effects.js.map +1 -0
- package/dist/src/orchestration/personas.d.ts +16 -0
- package/dist/src/orchestration/personas.js +64 -0
- package/dist/src/orchestration/personas.js.map +1 -0
- package/dist/src/orchestration/pi-executor.d.ts +9 -4
- package/dist/src/orchestration/pi-executor.js +55 -22
- package/dist/src/orchestration/pi-executor.js.map +1 -1
- package/dist/src/orchestration/research-agents.d.ts +3 -7
- package/dist/src/orchestration/research-agents.js +5 -69
- package/dist/src/orchestration/research-agents.js.map +1 -1
- package/dist/src/panel/server.js +19 -4
- 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.d.ts +14 -0
- package/dist/src/style/cli-ui.js +45 -1
- package/dist/src/style/cli-ui.js.map +1 -1
- package/dist/src/tui/skill-manager.js +1 -1
- package/dist/src/tui/skill-manager.js.map +1 -1
- package/dist/src/updates/update.js +9 -3
- package/dist/src/updates/update.js.map +1 -1
- package/package.json +15 -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,1366 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
"""Static audit for ARS v3.6.7 downstream-agent pattern protection.
|
|
3
|
+
|
|
4
|
+
Spec: docs/design/2026-04-29-ars-v3.6.7-downstream-agent-pattern-protection-spec.md
|
|
5
|
+
|
|
6
|
+
Greps the v3.6.7 reference files, audit template, and downstream agent prompts
|
|
7
|
+
for the keywords and obligation phrases that make each pattern-protection
|
|
8
|
+
clause detectable. Static only — does not validate runtime behaviour.
|
|
9
|
+
Behavioural validation belongs to spec §9 step 8 (live pipeline evaluation
|
|
10
|
+
case) and is out of scope here.
|
|
11
|
+
|
|
12
|
+
Falsifiability discipline (per feedback_lint_passes_but_prompt_silent.md):
|
|
13
|
+
- Agent-prompt checks scope grep to the `PATTERN PROTECTION (v3.6.7)` block
|
|
14
|
+
via `block_marker`. A keyword that lands outside the block in unrelated
|
|
15
|
+
prose does not count toward passing.
|
|
16
|
+
- Obligation-bearing patterns (forbidden / required / only-if) are enforced
|
|
17
|
+
via `must_contain_regex` so the prohibition is grep-detectable as a
|
|
18
|
+
contiguous fragment, not as two unrelated nouns elsewhere in the file.
|
|
19
|
+
|
|
20
|
+
Exit codes: 0 on pass, 1 on any failure.
|
|
21
|
+
"""
|
|
22
|
+
|
|
23
|
+
from __future__ import annotations
|
|
24
|
+
|
|
25
|
+
import os
|
|
26
|
+
import re
|
|
27
|
+
import sys
|
|
28
|
+
from dataclasses import dataclass, field
|
|
29
|
+
from pathlib import Path
|
|
30
|
+
|
|
31
|
+
REPO_ROOT = Path(__file__).resolve().parent.parent
|
|
32
|
+
|
|
33
|
+
REF_DIR = REPO_ROOT / "shared" / "references"
|
|
34
|
+
TPL_DIR = REPO_ROOT / "shared" / "templates"
|
|
35
|
+
AGENT_DIR = REPO_ROOT / "deep-research" / "agents"
|
|
36
|
+
|
|
37
|
+
SYNTHESIS_AGENT = AGENT_DIR / "synthesis_agent.md"
|
|
38
|
+
ARCHITECT_AGENT = AGENT_DIR / "research_architect_agent.md"
|
|
39
|
+
COMPILER_AGENT = AGENT_DIR / "report_compiler_agent.md"
|
|
40
|
+
|
|
41
|
+
# Markdown heading pattern that closes a `block_marker` scope. A check's scope
|
|
42
|
+
# starts at the marker and ends at the next H1/H2/H3 heading or EOF.
|
|
43
|
+
_HEADING_RE = re.compile(r"^#{1,3} ", re.MULTILINE)
|
|
44
|
+
|
|
45
|
+
# Negation / weakening patterns that, if present in the sentence containing
|
|
46
|
+
# an obligation match, indicate the obligation is being denied or weakened
|
|
47
|
+
# rather than asserted. R2-004 flagged "does not enumerate fully" / "not non-
|
|
48
|
+
# negotiable"; R3-002 expanded the list with should not / fails to / instead
|
|
49
|
+
# of / rarely / sometimes / is unable to. The patterns split into two groups:
|
|
50
|
+
#
|
|
51
|
+
# - _GENERAL_NEGATION_PATTERNS: DO NOT-style imperative prohibitions and
|
|
52
|
+
# weakening modals. These reject most obligations BUT they would also
|
|
53
|
+
# reject a legitimate prohibition like C3's "DO NOT simulate". For
|
|
54
|
+
# prohibition-style obligations, callers pass `allow_prohibition=True` to
|
|
55
|
+
# skip this group.
|
|
56
|
+
# - _ALWAYS_NEGATION_PATTERNS: weakening verbs and adverbs that never
|
|
57
|
+
# constitute a valid prohibition signal (rarely / sometimes / fails to /
|
|
58
|
+
# etc.). These apply regardless of `allow_prohibition`.
|
|
59
|
+
_GENERAL_NEGATION_PATTERNS = [
|
|
60
|
+
# Subject + auxiliary negation that directly weakens an obligation.
|
|
61
|
+
# These are the verb-negation forms most commonly used to undo a rule
|
|
62
|
+
# ("X does not Y", "X must not Y"). They are excluded by default but
|
|
63
|
+
# exempted for prohibition-style obligations like C3 via
|
|
64
|
+
# `allow_prohibition`.
|
|
65
|
+
re.compile(r"\bdoes not\b", re.IGNORECASE),
|
|
66
|
+
re.compile(r"\bdo not\b", re.IGNORECASE),
|
|
67
|
+
re.compile(r"\bDO NOT\b"), # case-sensitive imperative form
|
|
68
|
+
re.compile(r"\bdoesn'?t\b", re.IGNORECASE),
|
|
69
|
+
re.compile(r"\bdon'?t\b", re.IGNORECASE),
|
|
70
|
+
re.compile(r"\bshould not\b", re.IGNORECASE),
|
|
71
|
+
re.compile(r"\bshouldn'?t\b", re.IGNORECASE),
|
|
72
|
+
re.compile(r"\bmust not\b", re.IGNORECASE),
|
|
73
|
+
re.compile(r"\bmustn'?t\b", re.IGNORECASE),
|
|
74
|
+
# Adjective-targeted negations: explicit "not <obligation-adjective>"
|
|
75
|
+
# forms that directly negate the contract vocabulary.
|
|
76
|
+
re.compile(r"\bnot\s+(?:non[- ]negotiable|enumerate|required|mandatory|forbidden|verbatim|reserved)\b", re.IGNORECASE),
|
|
77
|
+
re.compile(r"\bneed not\b", re.IGNORECASE),
|
|
78
|
+
re.compile(r"\bno\s+buffer\b", re.IGNORECASE),
|
|
79
|
+
re.compile(r"\bno\s+enumeration\b", re.IGNORECASE),
|
|
80
|
+
# NOTE: `cannot` and `can't` are intentionally NOT in this list. They
|
|
81
|
+
# are routinely used in benign conditional phrasing ("if X cannot fit,
|
|
82
|
+
# the compiler reports..."), where `cannot` describes a trigger
|
|
83
|
+
# condition rather than weakening an obligation. The other negation
|
|
84
|
+
# patterns are tight enough to catch genuine weakening even without
|
|
85
|
+
# `cannot`.
|
|
86
|
+
]
|
|
87
|
+
# Modal weakeners (`may`, `should`, `can`) downgrade mandatory obligations
|
|
88
|
+
# to advisory. They are scoped to a verb list so the bare token does not
|
|
89
|
+
# match unrelated prose ("you may want to see references/...", "this can
|
|
90
|
+
# be useful"). The verb list covers imperatives the v3.6.7 agent prompts
|
|
91
|
+
# actually use.
|
|
92
|
+
_MODAL_WEAKENED_VERBS = (
|
|
93
|
+
r"(?:invite|enumerate|preserve|drop|skip|substitute|paraphrase"
|
|
94
|
+
r"|wrap|include|default|defaults?|run|use|declare|pass(?:\s+through)?"
|
|
95
|
+
r"|claim|cite|fall\s+back|be\s+quoted|be\s+permitted|use\s+chapter)"
|
|
96
|
+
)
|
|
97
|
+
|
|
98
|
+
_ALWAYS_NEGATION_PATTERNS = [
|
|
99
|
+
re.compile(r"\bisn'?t\b", re.IGNORECASE),
|
|
100
|
+
re.compile(r"\baren'?t\b", re.IGNORECASE),
|
|
101
|
+
# `optional` only counts as a weakener when it directly modifies an
|
|
102
|
+
# obligation noun. The bare token can appear in unrelated context
|
|
103
|
+
# ("optional `approved_synonyms` field"), so we narrow this rule to
|
|
104
|
+
# `optional <obligation-noun>` forms.
|
|
105
|
+
re.compile(r"\boptional\s+(?:buffer|enumeration|preservation|inclusion|verbatim|hedge|hedges|enforcement|requirement|reservation)\b", re.IGNORECASE),
|
|
106
|
+
# B2 R4-001: "X is recommended" / "are recommended" downgrades a
|
|
107
|
+
# mandatory obligation to advisory. The narrowed verb list ensures
|
|
108
|
+
# this only flags weakening of actual contract verbs / nouns.
|
|
109
|
+
re.compile(
|
|
110
|
+
r"\b(?:is|are)\s+recommended\b",
|
|
111
|
+
re.IGNORECASE,
|
|
112
|
+
),
|
|
113
|
+
# B2 R4-002 helper: "are allowed" / "is allowed" turns a forbidden
|
|
114
|
+
# operation into an exception. Covers C2's mutated "deictic phrases
|
|
115
|
+
# are allowed when shorter" and B5's "Over-setting ... are allowed"
|
|
116
|
+
# when those structures slip past the per-rule regex.
|
|
117
|
+
re.compile(r"\b(?:is|are)\s+allowed\b", re.IGNORECASE),
|
|
118
|
+
# Modal/advisory weakener coverage for the obligation verb list.
|
|
119
|
+
# B2 R4-001 added `may`; R5-001 added `should` / `can` /
|
|
120
|
+
# `is/are permitted`; R6-001 added the future/conditional modals
|
|
121
|
+
# (`will`, `would`, `ought to`) and the advisory adverb framings
|
|
122
|
+
# (`ideally`, `preferably`, `We recommend that`).
|
|
123
|
+
re.compile(rf"\bmay\s+(?:not\s+)?{_MODAL_WEAKENED_VERBS}\b", re.IGNORECASE),
|
|
124
|
+
re.compile(rf"\bshould\s+(?:not\s+)?{_MODAL_WEAKENED_VERBS}\b", re.IGNORECASE),
|
|
125
|
+
re.compile(rf"\bcan\s+(?:not\s+)?{_MODAL_WEAKENED_VERBS}\b", re.IGNORECASE),
|
|
126
|
+
# B2 R6-001: future-tense `will` / `will not` directly contradicts a
|
|
127
|
+
# mandatory obligation when paired with the obligation verb.
|
|
128
|
+
re.compile(rf"\bwill\s+(?:not\s+)?{_MODAL_WEAKENED_VERBS}\b", re.IGNORECASE),
|
|
129
|
+
# B2 R6-001: conditional `would` framings turn an imperative into a
|
|
130
|
+
# hypothetical ("Compression would preserve" instead of "must preserve").
|
|
131
|
+
re.compile(rf"\bwould\s+(?:not\s+)?{_MODAL_WEAKENED_VERBS}\b", re.IGNORECASE),
|
|
132
|
+
# B2 R6-001: `ought to` is a modal-equivalent advisory.
|
|
133
|
+
re.compile(rf"\bought\s+to\s+(?:not\s+)?{_MODAL_WEAKENED_VERBS}\b", re.IGNORECASE),
|
|
134
|
+
# B2 R6-001: advisory adverb framings. "Ideally include X" or
|
|
135
|
+
# "Preferably enumerate fully" downgrades the obligation. The verb
|
|
136
|
+
# boundary is required so bare adverbs in unrelated context don't
|
|
137
|
+
# trigger.
|
|
138
|
+
re.compile(rf"\bideally\s+{_MODAL_WEAKENED_VERBS}\b", re.IGNORECASE),
|
|
139
|
+
re.compile(rf"\bpreferably\s+{_MODAL_WEAKENED_VERBS}\b", re.IGNORECASE),
|
|
140
|
+
# B2 R6-001: "We recommend that ..." reframing makes the obligation
|
|
141
|
+
# advisory. Anchor on the recommend-that structure to avoid false
|
|
142
|
+
# positives on legitimate references that just contain "recommend".
|
|
143
|
+
re.compile(r"\bWe\s+recommend\s+that\b", re.IGNORECASE),
|
|
144
|
+
# B2 R5-001: "is/are permitted" turns a forbidden operation into an
|
|
145
|
+
# exception ("over-setting is permitted when concise"). Mirrors the
|
|
146
|
+
# `is/are allowed` pattern.
|
|
147
|
+
re.compile(r"\b(?:is|are)\s+permitted\b", re.IGNORECASE),
|
|
148
|
+
re.compile(r"\bfails? to\b", re.IGNORECASE),
|
|
149
|
+
re.compile(r"\binstead of\b", re.IGNORECASE),
|
|
150
|
+
# `rarely` / `sometimes` / `occasionally` similarly need to be near
|
|
151
|
+
# an obligation verb to count as weakeners.
|
|
152
|
+
re.compile(r"\brarely\s+(?:enumerate|enforce|invoke|reserve|preserve|verify)", re.IGNORECASE),
|
|
153
|
+
re.compile(r"\bsometimes\s+(?:enumerate|enforce|invoke|reserve|preserve|verify)", re.IGNORECASE),
|
|
154
|
+
re.compile(r"\boccasionally\s+(?:enumerate|enforce|invoke|reserve|preserve|verify)", re.IGNORECASE),
|
|
155
|
+
re.compile(r"\bis unable to\b", re.IGNORECASE),
|
|
156
|
+
re.compile(r"\bare unable to\b", re.IGNORECASE),
|
|
157
|
+
re.compile(r"\bonly when convenient\b", re.IGNORECASE),
|
|
158
|
+
re.compile(r"\bif (?:space|time) (?:allows|permits)\b", re.IGNORECASE),
|
|
159
|
+
# Feasibility qualifiers (R6-001). "when possible" / "where possible"
|
|
160
|
+
# /etc. tail-attached to an obligation phrase silently downgrades it
|
|
161
|
+
# from mandatory to best-effort.
|
|
162
|
+
re.compile(r"\bwhen\s+possible\b", re.IGNORECASE),
|
|
163
|
+
re.compile(r"\bwhere\s+possible\b", re.IGNORECASE),
|
|
164
|
+
re.compile(r"\bwherever\s+feasible\b", re.IGNORECASE),
|
|
165
|
+
re.compile(r"\bif\s+practical\b", re.IGNORECASE),
|
|
166
|
+
re.compile(r"\bif\s+feasible\b", re.IGNORECASE),
|
|
167
|
+
re.compile(r"\bbest[- ]effort\b", re.IGNORECASE),
|
|
168
|
+
# Exception qualifiers (B2 R3-003). "except" / "unless" / "save when"
|
|
169
|
+
# carve out a hole in an otherwise-mandatory rule. Mutation evidence:
|
|
170
|
+
# "No subsetting except when concise" silently weakens B5. These are
|
|
171
|
+
# treated as always-rejecting because no legitimate v3.6.7 contract
|
|
172
|
+
# rule carries an opt-out clause; if a future spec rule needs a
|
|
173
|
+
# genuine exception (e.g. "X is forbidden, except in mode Y"), the
|
|
174
|
+
# check for that rule should structure the obligation regex to
|
|
175
|
+
# demand both halves explicitly rather than relying on free prose.
|
|
176
|
+
re.compile(r"\bexcept\s+(?:when|if|in|for|as|where)\b", re.IGNORECASE),
|
|
177
|
+
re.compile(r"\bunless\b", re.IGNORECASE),
|
|
178
|
+
re.compile(r"\bsave\s+when\b", re.IGNORECASE),
|
|
179
|
+
]
|
|
180
|
+
|
|
181
|
+
|
|
182
|
+
# Imperative/auxiliary verb-negation tokens that, when allow_prohibition is
|
|
183
|
+
# set, MAY appear in the matched obligation span but must still be rejected
|
|
184
|
+
# anywhere else in the bullet window. This is the "span-restricted exemption"
|
|
185
|
+
# (B2 R3-001): the obligation's own prohibition vocabulary ("DO NOT simulate",
|
|
186
|
+
# "must not claim audit-passed state", "does not paraphrase") rides verbatim
|
|
187
|
+
# in the matched span; a *second* prohibition elsewhere in the same bullet
|
|
188
|
+
# (e.g. trailing "this must not be enforced") still indicates weakening.
|
|
189
|
+
_PROHIBITION_VERB_PATTERN_TEXTS = {
|
|
190
|
+
r"\bDO NOT\b",
|
|
191
|
+
r"\bdo not\b",
|
|
192
|
+
r"\bdoes not\b",
|
|
193
|
+
r"\bdoesn'?t\b",
|
|
194
|
+
r"\bdon'?t\b",
|
|
195
|
+
r"\bmust not\b",
|
|
196
|
+
r"\bmustn'?t\b",
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
|
|
200
|
+
def _match_excludes_negation(
|
|
201
|
+
text_window: str,
|
|
202
|
+
allow_prohibition: bool = False,
|
|
203
|
+
matched_span: tuple[int, int] | None = None,
|
|
204
|
+
) -> bool:
|
|
205
|
+
"""Return True if the bullet window around an obligation match does NOT
|
|
206
|
+
contain any negation that would weaken it.
|
|
207
|
+
|
|
208
|
+
`allow_prohibition=True` exempts the literal prohibition tokens
|
|
209
|
+
(DO NOT / do not / does not / must not / etc.) **only when they fall
|
|
210
|
+
inside the matched obligation span**. A trailing "this must not be
|
|
211
|
+
enforced" outside the matched span still rejects (B2 R3-001).
|
|
212
|
+
|
|
213
|
+
The `_ALWAYS_NEGATION_PATTERNS` (rarely, sometimes, fails to, optional,
|
|
214
|
+
except, unless, etc.) apply regardless because no legitimate obligation
|
|
215
|
+
framing should rely on those.
|
|
216
|
+
|
|
217
|
+
`matched_span` is `(start, end)` relative to `text_window`. When None
|
|
218
|
+
or `allow_prohibition=False`, prohibition tokens anywhere in the
|
|
219
|
+
window count as weakeners.
|
|
220
|
+
"""
|
|
221
|
+
if any(p.search(text_window) for p in _ALWAYS_NEGATION_PATTERNS):
|
|
222
|
+
return False
|
|
223
|
+
for p in _GENERAL_NEGATION_PATTERNS:
|
|
224
|
+
is_prohibition_pattern = p.pattern in _PROHIBITION_VERB_PATTERN_TEXTS
|
|
225
|
+
for hit in p.finditer(text_window):
|
|
226
|
+
if (
|
|
227
|
+
allow_prohibition
|
|
228
|
+
and is_prohibition_pattern
|
|
229
|
+
and matched_span is not None
|
|
230
|
+
and hit.start() >= matched_span[0]
|
|
231
|
+
and hit.end() <= matched_span[1]
|
|
232
|
+
):
|
|
233
|
+
# Prohibition token sits inside the matched obligation
|
|
234
|
+
# span — it is the obligation's own vocabulary, not a
|
|
235
|
+
# weakener. Skip this hit.
|
|
236
|
+
continue
|
|
237
|
+
return False
|
|
238
|
+
return True
|
|
239
|
+
|
|
240
|
+
|
|
241
|
+
@dataclass
|
|
242
|
+
class Check:
|
|
243
|
+
pattern_id: str
|
|
244
|
+
description: str
|
|
245
|
+
target: Path
|
|
246
|
+
must_contain: list[str] = field(default_factory=list)
|
|
247
|
+
must_contain_regex: list[tuple[str, str] | tuple[str, str, bool]] = field(default_factory=list)
|
|
248
|
+
"""Each entry is `(label, pattern)` or `(label, pattern, allow_prohibition)`.
|
|
249
|
+
`allow_prohibition` is per-regex (not per-Check) so a check can mix
|
|
250
|
+
prohibition-style obligations (REF-3 verbatim preservation, C3 anti-
|
|
251
|
+
fake-audit guard, C3 audit-passed metadata) with assertion-style
|
|
252
|
+
obligations (C1 protected hedges non-negotiable) without the
|
|
253
|
+
prohibition exemption leaking across regexes (B2 codex R2-001)."""
|
|
254
|
+
block_marker: str | None = None
|
|
255
|
+
"""If set, scope all keyword/regex checks to the text between the marker
|
|
256
|
+
and the next H1/H2/H3 heading. Use for agent-prompt checks where the
|
|
257
|
+
PATTERN PROTECTION clause must be inside its own block, not scattered
|
|
258
|
+
elsewhere in the file."""
|
|
259
|
+
|
|
260
|
+
def _scoped_text(self, full_text: str) -> tuple[str | None, str]:
|
|
261
|
+
"""Return (scoped_text, error_message). scoped_text is None on failure."""
|
|
262
|
+
if self.block_marker is None:
|
|
263
|
+
return full_text, ""
|
|
264
|
+
marker_pos = full_text.lower().find(self.block_marker.lower())
|
|
265
|
+
if marker_pos == -1:
|
|
266
|
+
return None, f"block marker missing: {self.block_marker!r}"
|
|
267
|
+
# Find next heading after the marker; scope ends there.
|
|
268
|
+
rest = full_text[marker_pos:]
|
|
269
|
+
match = _HEADING_RE.search(rest, pos=len(self.block_marker))
|
|
270
|
+
scoped_end = marker_pos + (match.start() if match else len(rest))
|
|
271
|
+
return full_text[marker_pos:scoped_end], ""
|
|
272
|
+
|
|
273
|
+
def _display_path(self) -> str:
|
|
274
|
+
try:
|
|
275
|
+
return str(self.target.relative_to(REPO_ROOT))
|
|
276
|
+
except ValueError:
|
|
277
|
+
return str(self.target)
|
|
278
|
+
|
|
279
|
+
def run(self) -> tuple[bool, str]:
|
|
280
|
+
display = self._display_path()
|
|
281
|
+
if not self.target.exists():
|
|
282
|
+
return False, f"target file missing: {display}"
|
|
283
|
+
full = self.target.read_text(encoding="utf-8")
|
|
284
|
+
scoped, err = self._scoped_text(full)
|
|
285
|
+
if scoped is None:
|
|
286
|
+
return False, f"{display}: {err}"
|
|
287
|
+
scoped_lower = scoped.lower()
|
|
288
|
+
missing_substr = [s for s in self.must_contain if s.lower() not in scoped_lower]
|
|
289
|
+
missing_regex = []
|
|
290
|
+
for entry in self.must_contain_regex:
|
|
291
|
+
if len(entry) == 2:
|
|
292
|
+
label, pattern = entry
|
|
293
|
+
allow_prohibition = False
|
|
294
|
+
else:
|
|
295
|
+
label, pattern, allow_prohibition = entry
|
|
296
|
+
# First try to find an obligation match.
|
|
297
|
+
match = re.search(pattern, scoped, re.IGNORECASE | re.DOTALL)
|
|
298
|
+
if match is None:
|
|
299
|
+
missing_regex.append(label)
|
|
300
|
+
continue
|
|
301
|
+
# Reject if the bullet/paragraph containing the match carries
|
|
302
|
+
# a negation that weakens the obligation (per R2-004 + R3-001
|
|
303
|
+
# + R4-001). The check looks backward from the match start to
|
|
304
|
+
# the start of the current bullet (or paragraph start) and
|
|
305
|
+
# forward from the match end to the next bullet (or blank line
|
|
306
|
+
# / EOF). This catches trailing weakeners like
|
|
307
|
+
# "...obligation. This is not required."
|
|
308
|
+
iterator = re.finditer(pattern, scoped, re.IGNORECASE | re.DOTALL)
|
|
309
|
+
accepted = False
|
|
310
|
+
for m in iterator:
|
|
311
|
+
start, end = m.start(), m.end()
|
|
312
|
+
# Lookback to the start of this bullet/paragraph: previous
|
|
313
|
+
# blank line, list-bullet marker on its own line, or start
|
|
314
|
+
# of scoped text. Capped at 400 chars so very long bullets
|
|
315
|
+
# do not pull in unrelated negation from far above.
|
|
316
|
+
lookback_floor = max(0, start - 400)
|
|
317
|
+
lookback = scoped[lookback_floor:start]
|
|
318
|
+
blank_line = lookback.rfind("\n\n")
|
|
319
|
+
bullet_back_match = list(re.finditer(r"\n\s*-\s", lookback))
|
|
320
|
+
bullet_back = bullet_back_match[-1].start() if bullet_back_match else -1
|
|
321
|
+
last_break_back = max(blank_line, bullet_back)
|
|
322
|
+
bullet_start = (
|
|
323
|
+
lookback_floor + last_break_back + 1
|
|
324
|
+
if last_break_back >= 0
|
|
325
|
+
else lookback_floor
|
|
326
|
+
)
|
|
327
|
+
# Lookahead to the start of the next bullet, blank line,
|
|
328
|
+
# or EOF (capped 400 chars).
|
|
329
|
+
lookahead_ceiling = min(len(scoped), end + 400)
|
|
330
|
+
lookahead = scoped[end:lookahead_ceiling]
|
|
331
|
+
blank_fwd = lookahead.find("\n\n")
|
|
332
|
+
bullet_fwd_match = re.search(r"\n\s*-\s", lookahead)
|
|
333
|
+
bullet_fwd = bullet_fwd_match.start() if bullet_fwd_match else -1
|
|
334
|
+
fwd_breaks = [i for i in (blank_fwd, bullet_fwd) if i >= 0]
|
|
335
|
+
next_break = min(fwd_breaks) if fwd_breaks else -1
|
|
336
|
+
bullet_end = end + next_break if next_break >= 0 else lookahead_ceiling
|
|
337
|
+
window = scoped[bullet_start:bullet_end]
|
|
338
|
+
# Span of THIS obligation match within the window, so the
|
|
339
|
+
# negation filter can distinguish prohibition vocabulary
|
|
340
|
+
# that is the obligation itself ("DO NOT simulate") from
|
|
341
|
+
# a SECOND prohibition elsewhere in the bullet that
|
|
342
|
+
# weakens it (B2 R3-001).
|
|
343
|
+
match_in_window = (start - bullet_start, end - bullet_start)
|
|
344
|
+
if _match_excludes_negation(
|
|
345
|
+
window,
|
|
346
|
+
allow_prohibition=allow_prohibition,
|
|
347
|
+
matched_span=match_in_window,
|
|
348
|
+
):
|
|
349
|
+
accepted = True
|
|
350
|
+
break
|
|
351
|
+
if not accepted:
|
|
352
|
+
missing_regex.append(f"{label} (only negated forms found)")
|
|
353
|
+
problems = []
|
|
354
|
+
if missing_substr:
|
|
355
|
+
problems.append(f"missing keywords: {missing_substr}")
|
|
356
|
+
if missing_regex:
|
|
357
|
+
problems.append(f"missing obligation phrases: {missing_regex}")
|
|
358
|
+
if problems:
|
|
359
|
+
scope_note = f" within {self.block_marker!r} block" if self.block_marker else ""
|
|
360
|
+
return False, f"{display}{scope_note}: {'; '.join(problems)}"
|
|
361
|
+
return True, "OK"
|
|
362
|
+
|
|
363
|
+
|
|
364
|
+
def reference_file_checks() -> list[Check]:
|
|
365
|
+
"""Spec §7.1 — 4 reference files. No block scoping; whole-file grep."""
|
|
366
|
+
return [
|
|
367
|
+
Check(
|
|
368
|
+
pattern_id="REF-1 (B1)",
|
|
369
|
+
description="irb_terminology_glossary covers 4 IRB terms with operational distinctions",
|
|
370
|
+
target=REF_DIR / "irb_terminology_glossary.md",
|
|
371
|
+
must_contain=[
|
|
372
|
+
"Anonymity",
|
|
373
|
+
"Confidentiality",
|
|
374
|
+
"De-identification",
|
|
375
|
+
"Pseudonymization",
|
|
376
|
+
],
|
|
377
|
+
),
|
|
378
|
+
Check(
|
|
379
|
+
pattern_id="REF-2 (B2)",
|
|
380
|
+
description="psychometric_terminology_glossary distinguishes true reverse-coded vs contrast",
|
|
381
|
+
target=REF_DIR / "psychometric_terminology_glossary.md",
|
|
382
|
+
must_contain=[
|
|
383
|
+
"true reverse-coded",
|
|
384
|
+
"contrast item",
|
|
385
|
+
"acquiescence",
|
|
386
|
+
"recall bias",
|
|
387
|
+
],
|
|
388
|
+
),
|
|
389
|
+
Check(
|
|
390
|
+
pattern_id="REF-3 (C1)",
|
|
391
|
+
description="protected_hedging_phrases defines upstream-marked hedge protocol with 5 contract rules",
|
|
392
|
+
target=REF_DIR / "protected_hedging_phrases.md",
|
|
393
|
+
must_contain=[
|
|
394
|
+
"protected hedging phrases",
|
|
395
|
+
"upstream calibration",
|
|
396
|
+
"word budget",
|
|
397
|
+
],
|
|
398
|
+
must_contain_regex=[
|
|
399
|
+
# Rule 1: conservative inclusion — "include the phrase" is
|
|
400
|
+
# the operative directive (R5-002 mutation showed
|
|
401
|
+
# "ask upstream for advice" was previously accepted).
|
|
402
|
+
(
|
|
403
|
+
"Rule: Conservative inclusion",
|
|
404
|
+
r"\bConservative inclusion\b.{0,200}\bWhen in doubt\b.{0,150}\binclude\s+the\s+phrase\b",
|
|
405
|
+
),
|
|
406
|
+
# Rule 2: anchor every entry — "where … and why" is the
|
|
407
|
+
# specific obligation; bare "must cite" was previously
|
|
408
|
+
# accepted with weakened content.
|
|
409
|
+
(
|
|
410
|
+
"Rule: Anchor every entry (where + why)",
|
|
411
|
+
r"\bAnchor every entry\b.{0,200}\bmust\s+cite\s+where\b.{0,200}\bwhy\b",
|
|
412
|
+
),
|
|
413
|
+
# Rule 3: no duplicates — bullet body must assert
|
|
414
|
+
# "One entry per phrase" then back-reference the count.
|
|
415
|
+
# R5-002 showed bare "One entry per phrase" alone could be
|
|
416
|
+
# suffixed with "is optional" and still pass; require the
|
|
417
|
+
# full "One entry per phrase. The compiler counts ... once"
|
|
418
|
+
# sequence so a tail weakener cannot land between them.
|
|
419
|
+
# Allow Markdown markup (`**`) between the heading word and
|
|
420
|
+
# the body sentence.
|
|
421
|
+
(
|
|
422
|
+
"Rule: No duplicates",
|
|
423
|
+
r"\bNo duplicates\b[\s.*\-]{0,10}One entry per phrase\.\s+The compiler counts[^.]{0,150}\bonce\b",
|
|
424
|
+
),
|
|
425
|
+
# Rule 4: verbatim preservation — both the title and the
|
|
426
|
+
# imperative body ("does not paraphrase") must appear. The
|
|
427
|
+
# body uses "does not paraphrase / substitute" as the
|
|
428
|
+
# prohibition expressing the obligation, so this specific
|
|
429
|
+
# regex needs prohibition exemption (was per-Check before
|
|
430
|
+
# B2 R2-001; now per-regex so other regexes in this Check
|
|
431
|
+
# still reject inverted forms).
|
|
432
|
+
(
|
|
433
|
+
"Rule: Verbatim preservation",
|
|
434
|
+
r"\bVerbatim preservation\b.{0,250}\brides\s+verbatim\b.{0,300}\bdoes\s+not\s+paraphrase\b",
|
|
435
|
+
True, # allow_prohibition: prohibition-style obligation body
|
|
436
|
+
),
|
|
437
|
+
# Rule 5: failure surface — must say "rather than dropping",
|
|
438
|
+
# not "while dropping" (R5-002 mutation flipped this).
|
|
439
|
+
(
|
|
440
|
+
"Rule: Conflict reporting (no silent drop)",
|
|
441
|
+
r"\breports the conflict\b[^.\n]{0,100}\brather than\s+dropping a protected hedge\b",
|
|
442
|
+
),
|
|
443
|
+
],
|
|
444
|
+
),
|
|
445
|
+
Check(
|
|
446
|
+
pattern_id="REF-4 (word-count)",
|
|
447
|
+
description="word_count_conventions specifies whitespace-split + 3-5% buffer",
|
|
448
|
+
target=REF_DIR / "word_count_conventions.md",
|
|
449
|
+
must_contain=[
|
|
450
|
+
"whitespace",
|
|
451
|
+
"split()",
|
|
452
|
+
"3–5%",
|
|
453
|
+
"hyphenated",
|
|
454
|
+
],
|
|
455
|
+
),
|
|
456
|
+
]
|
|
457
|
+
|
|
458
|
+
|
|
459
|
+
def template_file_checks() -> list[Check]:
|
|
460
|
+
"""Spec §7.2 — audit prompt template."""
|
|
461
|
+
return [
|
|
462
|
+
Check(
|
|
463
|
+
pattern_id="TPL-1 (D1)",
|
|
464
|
+
description="codex_audit_multifile_template enumerates 7 audit dimensions",
|
|
465
|
+
target=TPL_DIR / "codex_audit_multifile_template.md",
|
|
466
|
+
must_contain=[
|
|
467
|
+
"cross-ref",
|
|
468
|
+
"hallucination",
|
|
469
|
+
"primary-source integrity",
|
|
470
|
+
"internal coherence",
|
|
471
|
+
"instrument quality",
|
|
472
|
+
"Round-N framing",
|
|
473
|
+
"COI adequacy",
|
|
474
|
+
],
|
|
475
|
+
),
|
|
476
|
+
# The report_compiler bundle's Section 4(f) is mandatory three-part:
|
|
477
|
+
# (i) word-count cap-minus-buffer, (ii) protected-hedge verbatim,
|
|
478
|
+
# (iii) abstract no less hedged than body. R1-006 upgraded this from
|
|
479
|
+
# an example to a mandatory contract; lint must verify the contract
|
|
480
|
+
# rides verbatim in the template, not just the prose around it.
|
|
481
|
+
# Scoped to the `report_compiler_agent bundle` clause so scattered
|
|
482
|
+
# text elsewhere in the template cannot satisfy the contract (R3-004).
|
|
483
|
+
Check(
|
|
484
|
+
pattern_id="TPL-2 (4f-compiler)",
|
|
485
|
+
description="audit template encodes mandatory three-part (f) check for report_compiler bundles",
|
|
486
|
+
target=TPL_DIR / "codex_audit_multifile_template.md",
|
|
487
|
+
block_marker="report_compiler_agent bundle (mandatory three-part check)",
|
|
488
|
+
must_contain_regex=[
|
|
489
|
+
# Sub-check (i): whitespace-split cap minus 3-5% buffer
|
|
490
|
+
(
|
|
491
|
+
"4f sub-check (i) word-count algorithm + buffer",
|
|
492
|
+
r"len\(body\.split\(\)\).{0,200}\b3[-–]5%\s+buffer\b",
|
|
493
|
+
),
|
|
494
|
+
# Sub-check (ii): protected_hedges appear verbatim
|
|
495
|
+
# unconditionally. R5-003 mutation showed bare
|
|
496
|
+
# "appear verbatim when possible" was previously accepted;
|
|
497
|
+
# the obligation must be unconditional ("appears verbatim
|
|
498
|
+
# in the abstract" without "when possible" / "if space").
|
|
499
|
+
# The negation post-filter already rejects "when convenient"
|
|
500
|
+
# / "if space allows", so the regex requires the
|
|
501
|
+
# imperative-tense phrasing.
|
|
502
|
+
(
|
|
503
|
+
"4f sub-check (ii) protected_hedges verbatim (unconditional)",
|
|
504
|
+
r"every entry of upstream\s+`?protected_hedges`?[^\n]{0,200}\bappears? verbatim in the abstract\b",
|
|
505
|
+
),
|
|
506
|
+
# Sub-check (iii): "no claim in the abstract is less hedged
|
|
507
|
+
# than its anchor in the body" — anchored on "no claim" so
|
|
508
|
+
# an inverted form ("every claim ... is less hedged") fails.
|
|
509
|
+
(
|
|
510
|
+
"4f sub-check (iii) less-hedged-than-body prohibition",
|
|
511
|
+
r"\bno claim in the abstract is less hedged than its anchor in the body\b",
|
|
512
|
+
),
|
|
513
|
+
# P1 severity assignment for any sub-check failure
|
|
514
|
+
(
|
|
515
|
+
"4f failures severity P1",
|
|
516
|
+
r"\bFailure of any sub-check is a P1 finding\b",
|
|
517
|
+
),
|
|
518
|
+
],
|
|
519
|
+
),
|
|
520
|
+
]
|
|
521
|
+
|
|
522
|
+
|
|
523
|
+
# Block marker every agent-prompt check scopes to. Defined once so the value
|
|
524
|
+
# stays in sync across agents.
|
|
525
|
+
PROTECTION_BLOCK = "PATTERN PROTECTION (v3.6.7)"
|
|
526
|
+
|
|
527
|
+
|
|
528
|
+
def synthesis_agent_checks() -> list[Check]:
|
|
529
|
+
"""Spec §6.1 — synthesis_agent A1-A5 protection.
|
|
530
|
+
|
|
531
|
+
Scoped to the PATTERN PROTECTION (v3.6.7) block so keyword presence
|
|
532
|
+
elsewhere in the agent prompt does not count toward passing. All five
|
|
533
|
+
rules use must_contain_regex (not raw must_contain tokens) so the
|
|
534
|
+
weakening filter rejects mutations like "pending verification language
|
|
535
|
+
is optional" (B2 R3-002).
|
|
536
|
+
"""
|
|
537
|
+
return [
|
|
538
|
+
Check(
|
|
539
|
+
pattern_id="A1-A5",
|
|
540
|
+
description="synthesis_agent carries 5 narrative-side protection clauses",
|
|
541
|
+
target=SYNTHESIS_AGENT,
|
|
542
|
+
block_marker=PROTECTION_BLOCK,
|
|
543
|
+
must_contain_regex=[
|
|
544
|
+
# A1 — cross-section consistency self-check. Bullet must
|
|
545
|
+
# carry both the imperative pre-list step and the
|
|
546
|
+
# consistency self-check before output. "are recommended"
|
|
547
|
+
# / "may run" / "optional" weakeners are caught by the
|
|
548
|
+
# negation filter (verb list + `is/are recommended` in
|
|
549
|
+
# _ALWAYS_NEGATION_PATTERNS, B2 R4-001 expansion).
|
|
550
|
+
(
|
|
551
|
+
"A1 effect inventory pre-list + cross-section self-check before output",
|
|
552
|
+
r"\bpre-list\b[^.\n]{0,200}\beffect inventory\b[^.\n]{0,200}\brun\s+a\s+cross-section consistency self-check\b[^.\n]{0,100}\bbefore output\b",
|
|
553
|
+
),
|
|
554
|
+
# A2 — pending-verification hedge. "wrap claims in explicit
|
|
555
|
+
# hedge" is the imperative; mutating to "may wrap" or
|
|
556
|
+
# "pending verification language is optional" trips the
|
|
557
|
+
# may-verb weakener (R4-001) and the optional-noun weakener
|
|
558
|
+
# respectively.
|
|
559
|
+
(
|
|
560
|
+
"A2 pending-verification hedge wrap",
|
|
561
|
+
r"\bpending verification\b[^.\n]{0,200}\bwrap claims\b[^.\n]{0,200}\bexplicit hedge\b",
|
|
562
|
+
),
|
|
563
|
+
# A3 — anchor justification. "include a one-line anchor
|
|
564
|
+
# justification" is the imperative; "may include" trips
|
|
565
|
+
# the may-verb weakener (R4-001).
|
|
566
|
+
(
|
|
567
|
+
"A3 one-line anchor justification (include)",
|
|
568
|
+
r"\binclude\s+a\s+one[- ]line\s+anchor justification\b",
|
|
569
|
+
),
|
|
570
|
+
# A4 — quote scope boundary AND surrounding-context handling.
|
|
571
|
+
# Spec §6.1 says "surrounding context paraphrased and
|
|
572
|
+
# unquoted". Without enforcing the second clause, an agent
|
|
573
|
+
# can satisfy "Verbatim quotes only within ..." while
|
|
574
|
+
# mutating context handling to "may be quoted" (R4-002).
|
|
575
|
+
# Two regexes so dropping either half fails lint.
|
|
576
|
+
(
|
|
577
|
+
"A4 verbatim quotes only within verified phrase boundary",
|
|
578
|
+
r"\bVerbatim quotes\s+only\s+within\s+the\s+verified phrase boundary\b",
|
|
579
|
+
),
|
|
580
|
+
(
|
|
581
|
+
"A4 surrounding context paraphrased and unquoted",
|
|
582
|
+
r"\bsurrounding context\s+paraphrased\s+and\s+unquoted\b",
|
|
583
|
+
),
|
|
584
|
+
# A5 — declarative claims about un-provided documents are
|
|
585
|
+
# forbidden AND the conditional-language fallback is
|
|
586
|
+
# required. Spec §6.1 pairs the two: conditional language
|
|
587
|
+
# / explicit gap acknowledgment is the constructive duty,
|
|
588
|
+
# the prohibition is the negative duty. Both must ride.
|
|
589
|
+
(
|
|
590
|
+
"A5 conditional language fallback for un-provided documents",
|
|
591
|
+
# Bullet contains "e.g., ..." parenthetical, so match
|
|
592
|
+
# across periods within the bullet line.
|
|
593
|
+
r"\bun-provided[^\n]{0,300}\buse\s+conditional language\b[^\n]{0,300}\bexplicit gap acknowledgment\b",
|
|
594
|
+
),
|
|
595
|
+
(
|
|
596
|
+
"A5 sentence-bounded injunction",
|
|
597
|
+
r"declarative claims? about un-provided[^.\n]{0,200}\bare forbidden\b",
|
|
598
|
+
),
|
|
599
|
+
],
|
|
600
|
+
)
|
|
601
|
+
]
|
|
602
|
+
|
|
603
|
+
|
|
604
|
+
def architect_agent_checks() -> list[Check]:
|
|
605
|
+
"""Spec §6.2 — research_architect_agent (survey designer mode) B1-B5
|
|
606
|
+
protection. B1, B2, B5 use must_contain_regex with imperative verbs
|
|
607
|
+
anchored so a mutation like "passing through the IRB glossary is
|
|
608
|
+
optional" or "construct equivalence justification is recommended"
|
|
609
|
+
is rejected by the weakening filter (B2 R3-002).
|
|
610
|
+
"""
|
|
611
|
+
return [
|
|
612
|
+
Check(
|
|
613
|
+
pattern_id="B1-B5",
|
|
614
|
+
description="research_architect_agent (survey designer) carries 5 instrument-side protection clauses",
|
|
615
|
+
target=ARCHITECT_AGENT,
|
|
616
|
+
block_marker=PROTECTION_BLOCK,
|
|
617
|
+
must_contain_regex=[
|
|
618
|
+
# B1 — IRB terminology pass-through. "must pass through ...
|
|
619
|
+
# before output" is the imperative; the glossary back-pointer
|
|
620
|
+
# is part of the obligation.
|
|
621
|
+
(
|
|
622
|
+
"B1 IRB terminology pass-through (must, before output)",
|
|
623
|
+
r"\bmust\s+pass\s+through\b[^.\n]{0,200}\birb_terminology_glossary\.md\b[^.\n]{0,200}\bbefore output\b",
|
|
624
|
+
),
|
|
625
|
+
# B2 — reverse-coded construct equivalence. "include a one-
|
|
626
|
+
# line construct-equivalence justification" is the imperative
|
|
627
|
+
# that survives mutations like "construct-equivalence
|
|
628
|
+
# justification is recommended".
|
|
629
|
+
(
|
|
630
|
+
"B2 reverse-coded construct-equivalence justification",
|
|
631
|
+
r"\breverse-coded\b[^.\n]{0,200}\binclude\s+a\s+one[- ]line\s+construct-equivalence justification\b",
|
|
632
|
+
),
|
|
633
|
+
# B3 — retrospective items default to event-anchored;
|
|
634
|
+
# calendar-anchored is conditional on a shared event date.
|
|
635
|
+
# Spec wording naturally spans two sentences ("default to..."
|
|
636
|
+
# then "calendar... only when..."), so the gap allows one
|
|
637
|
+
# sentence boundary; the 'only when' tail must sit in the
|
|
638
|
+
# same sentence as 'calendar-anchored' to bind the conditional.
|
|
639
|
+
(
|
|
640
|
+
"B3 retrospective default + calendar conditional",
|
|
641
|
+
r"event-anchored[^.\n]{0,200}\.[^.\n]{0,100}\bcalendar[- ]anchored[^.\n]{0,200}\bonly when\b",
|
|
642
|
+
),
|
|
643
|
+
# B4 — three-part obligation per spec §6.2:
|
|
644
|
+
# (i) item phrasing must be neutral/balanced,
|
|
645
|
+
# (ii) chapter argument vocabulary forbidden in items,
|
|
646
|
+
# (iii) open-text prompts invite all valences.
|
|
647
|
+
# Splitting into three regexes so dropping any one half
|
|
648
|
+
# fails lint (R4-002 mutation evidence: "may use chapter
|
|
649
|
+
# argument vocabulary" replaced (i)+(ii) and bare valences
|
|
650
|
+
# match still passed).
|
|
651
|
+
(
|
|
652
|
+
"B4 item phrasing neutral/balanced (must)",
|
|
653
|
+
r"\bItem phrasing\s+must\s+be\s+neutral[/-]balanced\b",
|
|
654
|
+
),
|
|
655
|
+
(
|
|
656
|
+
"B4 chapter argument vocabulary forbidden",
|
|
657
|
+
r"\bChapter argument vocabulary\s+is\s+forbidden\s+in\s+instrument items\b",
|
|
658
|
+
),
|
|
659
|
+
(
|
|
660
|
+
"B4 open-text invites all valences",
|
|
661
|
+
r"\b(?:all valences|positive,? negative,? (?:or|and) neutral)\b",
|
|
662
|
+
),
|
|
663
|
+
# B5 — option lists must declare primary-source list AND
|
|
664
|
+
# enumerate fully AND prohibit subsetting AND prohibit
|
|
665
|
+
# over-setting AND prohibit scope cross-contamination.
|
|
666
|
+
# All five are the contract per spec §6.2; matching any
|
|
667
|
+
# subset is a silent gap (R4-002 mutation: "Over-setting
|
|
668
|
+
# and scope cross-contamination are allowed" passed even
|
|
669
|
+
# though "No subsetting" remained).
|
|
670
|
+
(
|
|
671
|
+
"B5 primary-source list + enumerate fully",
|
|
672
|
+
r"\bprimary-source list\b[^.\n]{0,100}\benumerate(?:s|d)?\s+fully\b",
|
|
673
|
+
),
|
|
674
|
+
(
|
|
675
|
+
"B5 no subsetting prohibition",
|
|
676
|
+
r"\bno\s+subsetting\b",
|
|
677
|
+
),
|
|
678
|
+
(
|
|
679
|
+
"B5 no over-setting prohibition",
|
|
680
|
+
r"\bno\s+over-setting\b",
|
|
681
|
+
),
|
|
682
|
+
(
|
|
683
|
+
"B5 no scope cross-contamination prohibition",
|
|
684
|
+
r"\bno\s+scope cross-contamination\b",
|
|
685
|
+
),
|
|
686
|
+
],
|
|
687
|
+
)
|
|
688
|
+
]
|
|
689
|
+
|
|
690
|
+
|
|
691
|
+
def compiler_agent_checks() -> list[Check]:
|
|
692
|
+
"""Spec §6.3 — report_compiler_agent (abstract-only mode) C1-C3 protection."""
|
|
693
|
+
return [
|
|
694
|
+
Check(
|
|
695
|
+
pattern_id="C1-C3",
|
|
696
|
+
description="report_compiler_agent (abstract-only) carries 3 publication-side protection clauses incl. anti-fake-audit guard",
|
|
697
|
+
target=COMPILER_AGENT,
|
|
698
|
+
block_marker=PROTECTION_BLOCK,
|
|
699
|
+
must_contain_regex=[
|
|
700
|
+
# C1 word-count algorithm + buffer. Spec §6.3 pairs the
|
|
701
|
+
# whitespace-split rule with "Reserve 3–5% buffer below
|
|
702
|
+
# hard cap"; both must ride. R4-002 mutation showed
|
|
703
|
+
# buffer deletion still passed.
|
|
704
|
+
(
|
|
705
|
+
"C1 whitespace-split convention (uses)",
|
|
706
|
+
r"\bWord budget\s+uses\s+whitespace-split\s+convention\b",
|
|
707
|
+
),
|
|
708
|
+
(
|
|
709
|
+
"C1 reserve 3-5% buffer below hard cap",
|
|
710
|
+
r"\bReserve\s+3[-–]5%\s+buffer\s+below\s+hard cap\b",
|
|
711
|
+
),
|
|
712
|
+
# C2 temporal disambiguation: imperative + full triple of
|
|
713
|
+
# acceptable forms (year range, past-tense disambiguating
|
|
714
|
+
# verb, "former" prefix). R4-002 evidence: dropping the
|
|
715
|
+
# past-tense + former prefix still passed because only
|
|
716
|
+
# "explicit year range" was lint-required.
|
|
717
|
+
(
|
|
718
|
+
"C2 reflexivity disclosure must use explicit year range",
|
|
719
|
+
r"\bReflexivity disclosure\s+must\s+use\s+explicit temporal bounds\b[^.\n]{0,200}\bexplicit year range\b",
|
|
720
|
+
),
|
|
721
|
+
(
|
|
722
|
+
"C2 past-tense disambiguating verb form",
|
|
723
|
+
r"\bpast-tense disambiguating verb\b",
|
|
724
|
+
),
|
|
725
|
+
(
|
|
726
|
+
"C2 'former' prefix form",
|
|
727
|
+
r"['\"]former['\"]\s+prefix\b",
|
|
728
|
+
),
|
|
729
|
+
# C2 deictic forbidden — paired with above so a mutation
|
|
730
|
+
# that drops the prohibition still fails.
|
|
731
|
+
(
|
|
732
|
+
"C2 deictic temporal phrases forbidden",
|
|
733
|
+
r"\bDeictic temporal phrases\b[^.\n]{0,200}\bare forbidden\b",
|
|
734
|
+
),
|
|
735
|
+
# C1 — protected hedges are budget-protected / non-negotiable
|
|
736
|
+
# / verbatim. Sentence-bounded; negation post-filter rejects
|
|
737
|
+
# "are not non-negotiable" (R2-004) AND must reject inverted
|
|
738
|
+
# "Compression must not preserve protected hedging phrases"
|
|
739
|
+
# (B2 R2-001), so this regex does NOT take prohibition
|
|
740
|
+
# exemption — it is an assertion-style obligation.
|
|
741
|
+
(
|
|
742
|
+
"C1 protected hedges non-negotiable",
|
|
743
|
+
r"protected\s+hedg(?:e|ing)\s+phrases[^.\n]{0,200}\b(?:budget[- ]protected|non-negotiable|verbatim)\b",
|
|
744
|
+
),
|
|
745
|
+
# C3 — canonical Clause 1 line per Step 6 §6.2. The line is
|
|
746
|
+
# one bullet carrying three prohibitions in fixed order:
|
|
747
|
+
# "DO NOT simulate any audit step. DO NOT claim to have run
|
|
748
|
+
# codex/external review. Output metadata must not claim
|
|
749
|
+
# audit-passed state." Phase 6.7 merged the prior two C3
|
|
750
|
+
# regexes (anti-fake-audit pair + output-metadata) into a
|
|
751
|
+
# single line so the bullet is whole-line verbatim — INV-1
|
|
752
|
+
# below enforces presence/uniqueness across all three
|
|
753
|
+
# in-scope prompts; this regex stays here to keep C1-C3
|
|
754
|
+
# mutation coverage intact (R2-001 inverted-must-not, R3-001
|
|
755
|
+
# trailing weakener, R4-001 advisory framing). Pattern is
|
|
756
|
+
# whole-line so all three prohibition tokens (DO NOT × 2 +
|
|
757
|
+
# must not) sit inside the matched span and the negation
|
|
758
|
+
# post-filter does not flag a sibling prohibition as a
|
|
759
|
+
# weakener (B2 R3-001 span-restricted exemption).
|
|
760
|
+
(
|
|
761
|
+
"C3 canonical Clause 1 line (whole-line verbatim)",
|
|
762
|
+
# Whitespace-tolerant: every inter-token space inside
|
|
763
|
+
# the canonical line accepts `\s+` so a Markdown
|
|
764
|
+
# soft-wrap anywhere inside a sentence (e.g. between
|
|
765
|
+
# `run` and `codex/external`) is treated as the
|
|
766
|
+
# same canonical bullet — matches INV-1's
|
|
767
|
+
# whitespace-normalization contract (codex R5 P2
|
|
768
|
+
# closure). The trailing `\.(?=\s|\Z)` anchor still
|
|
769
|
+
# rejects tail weakeners like ` if feasible.` (R1
|
|
770
|
+
# P2 closure).
|
|
771
|
+
r"\bDO\s+NOT\s+simulate\s+any\s+audit\s+step\.\s+"
|
|
772
|
+
r"DO\s+NOT\s+claim\s+to\s+have\s+run\s+codex/external\s+review\.\s+"
|
|
773
|
+
r"Output\s+metadata\s+must\s+not\s+claim\s+audit-passed\s+state\.(?=\s|\Z)",
|
|
774
|
+
True, # allow_prohibition: this IS the prohibition
|
|
775
|
+
),
|
|
776
|
+
],
|
|
777
|
+
)
|
|
778
|
+
]
|
|
779
|
+
|
|
780
|
+
|
|
781
|
+
# ---------------------------------------------------------------------------
|
|
782
|
+
# Inversion sweep checks (Phase 6.7 — spec §6 partial inversion rule)
|
|
783
|
+
# ---------------------------------------------------------------------------
|
|
784
|
+
#
|
|
785
|
+
# Spec §6.3 defines INV-1/INV-2/INV-3 as the lint enforcement of the
|
|
786
|
+
# §6.2 sweep. These run alongside the keyword/regex Check pipeline above
|
|
787
|
+
# but operate at file-list granularity (manifest-driven) rather than
|
|
788
|
+
# per-Check, so they are implemented as standalone functions returning
|
|
789
|
+
# (pattern_id, description, ok, message) tuples.
|
|
790
|
+
#
|
|
791
|
+
# - INV-1: each manifest file's PATTERN PROTECTION block carries the
|
|
792
|
+
# canonical Clause 1 line exactly once (presence + uniqueness).
|
|
793
|
+
# - INV-2: each manifest file's PATTERN PROTECTION block contains zero
|
|
794
|
+
# sentences matching any of the four Clause 2 violation patterns.
|
|
795
|
+
# - INV-3: no agent prompt file outside the manifest carries the canonical
|
|
796
|
+
# Clause 1 line (defends against accidental sweep widening per §9 L2).
|
|
797
|
+
|
|
798
|
+
INVERSION_MANIFEST = REPO_ROOT / "scripts" / "v3_6_7_inversion_manifest.json"
|
|
799
|
+
|
|
800
|
+
# Canonical Clause 1 line, byte-aligned with spec §6.2 line 1767. Whitespace
|
|
801
|
+
# inside is tolerant (collapse whitespace runs to a single space) so a future
|
|
802
|
+
# Markdown reflow that wraps the bullet across two lines does not break the
|
|
803
|
+
# match; presence is what matters.
|
|
804
|
+
CANONICAL_CLAUSE_1_TEXT = (
|
|
805
|
+
"DO NOT simulate any audit step. "
|
|
806
|
+
"DO NOT claim to have run codex/external review. "
|
|
807
|
+
"Output metadata must not claim audit-passed state."
|
|
808
|
+
)
|
|
809
|
+
|
|
810
|
+
# Spec §6.3 INV-2 regex set (a)-(d). Patterns are written as Python regex
|
|
811
|
+
# literals here (`|` for alternation, no Markdown escaping) — the spec
|
|
812
|
+
# table renders them as `\|` because raw `|` is the Markdown table-column
|
|
813
|
+
# delimiter; the lint reads the underlying regex, not the rendered cell.
|
|
814
|
+
# All four compile with re.IGNORECASE only — DOTALL is not needed because
|
|
815
|
+
# patterns are applied to bullet text after whitespace normalization
|
|
816
|
+
# (newlines collapsed to single spaces), which preserves Markdown
|
|
817
|
+
# soft-wrap tolerance (codex R1 P2 closure) while bounding the `.*`
|
|
818
|
+
# wildcard to a single bullet (codex R2 P2 closure: prior IGNORECASE |
|
|
819
|
+
# DOTALL applied to raw block text let INV-2(a)/(b) match across
|
|
820
|
+
# unrelated bullets).
|
|
821
|
+
INV2_PATTERNS = [
|
|
822
|
+
("INV-2(a)", re.compile(r"\bthe orchestrator\b.*\baudit\b", re.IGNORECASE)),
|
|
823
|
+
(
|
|
824
|
+
"INV-2(b)",
|
|
825
|
+
re.compile(
|
|
826
|
+
r"\bcross-model audit (?:follows|covers)\b.*codex_audit_multifile_template",
|
|
827
|
+
re.IGNORECASE,
|
|
828
|
+
),
|
|
829
|
+
),
|
|
830
|
+
(
|
|
831
|
+
"INV-2(c)",
|
|
832
|
+
re.compile(
|
|
833
|
+
r"\baudit (?:afterwards?|will be run|is dispatched)\b",
|
|
834
|
+
re.IGNORECASE,
|
|
835
|
+
),
|
|
836
|
+
),
|
|
837
|
+
(
|
|
838
|
+
"INV-2(d)",
|
|
839
|
+
re.compile(
|
|
840
|
+
r"\bdownstream audit\b|\bthis output (?:is|will be) audited\b",
|
|
841
|
+
re.IGNORECASE,
|
|
842
|
+
),
|
|
843
|
+
),
|
|
844
|
+
]
|
|
845
|
+
|
|
846
|
+
# Frozen v3.6.7 manifest contents per spec §6.3. The manifest file at
|
|
847
|
+
# scripts/v3_6_7_inversion_manifest.json is the data; this constant is
|
|
848
|
+
# the schema's expected value, used by `_load_inversion_manifest` to
|
|
849
|
+
# refuse drifted manifests at lint time. Spec §6.3 line 1807 reserves
|
|
850
|
+
# manifest widening for explicit v3.6.8+ work that lands "its own
|
|
851
|
+
# version-tagged manifest rather than retroactively widening v3.6.7's";
|
|
852
|
+
# this constant locks the v3.6.7 scope so a copy-paste widening
|
|
853
|
+
# (codex R1 P2 closure: add fourth file + canonical bullet → INV-1
|
|
854
|
+
# passes for all 4, INV-3 skips the new file because it is in
|
|
855
|
+
# manifest_set, full pass) can no longer slip past lint.
|
|
856
|
+
EXPECTED_MANIFEST_FILES = (
|
|
857
|
+
"deep-research/agents/synthesis_agent.md",
|
|
858
|
+
"deep-research/agents/research_architect_agent.md",
|
|
859
|
+
"deep-research/agents/report_compiler_agent.md",
|
|
860
|
+
)
|
|
861
|
+
|
|
862
|
+
|
|
863
|
+
def _load_inversion_manifest() -> tuple[list[str], str | None]:
|
|
864
|
+
"""Return (file_list, error_message). file_list paths are repo-relative.
|
|
865
|
+
|
|
866
|
+
Validates that the manifest carries exactly the three v3.6.7-scoped
|
|
867
|
+
file paths (per spec §6.3 + EXPECTED_MANIFEST_FILES). Drift, addition,
|
|
868
|
+
deletion, or duplication of entries is rejected — widening to a
|
|
869
|
+
fourth file requires landing a v3.6.8+ manifest with its own scope
|
|
870
|
+
tag, not retroactive edits to this manifest (per spec §6.3 line
|
|
871
|
+
1807).
|
|
872
|
+
"""
|
|
873
|
+
if not INVERSION_MANIFEST.exists():
|
|
874
|
+
return [], f"manifest missing: scripts/v3_6_7_inversion_manifest.json"
|
|
875
|
+
try:
|
|
876
|
+
import json
|
|
877
|
+
data = json.loads(INVERSION_MANIFEST.read_text(encoding="utf-8"))
|
|
878
|
+
except (json.JSONDecodeError, OSError) as exc:
|
|
879
|
+
return [], f"manifest unreadable: {exc}"
|
|
880
|
+
if data.get("scope") != "v3.6.7-only":
|
|
881
|
+
return [], f"manifest 'scope' must be 'v3.6.7-only', got {data.get('scope')!r}"
|
|
882
|
+
files = data.get("files")
|
|
883
|
+
if not isinstance(files, list) or not all(isinstance(p, str) for p in files):
|
|
884
|
+
return [], "manifest 'files' must be a list of strings"
|
|
885
|
+
if len(files) != len(set(files)):
|
|
886
|
+
dupes = sorted({p for p in files if files.count(p) > 1})
|
|
887
|
+
return [], f"manifest 'files' contains duplicate entries: {dupes}"
|
|
888
|
+
if set(files) != set(EXPECTED_MANIFEST_FILES):
|
|
889
|
+
expected = sorted(EXPECTED_MANIFEST_FILES)
|
|
890
|
+
actual = sorted(files)
|
|
891
|
+
return [], (
|
|
892
|
+
f"manifest 'files' must match the v3.6.7 frozen scope. "
|
|
893
|
+
f"Expected (sorted): {expected}. Got (sorted): {actual}. "
|
|
894
|
+
f"To widen scope to additional agents, land a v3.6.8+ "
|
|
895
|
+
f"manifest with its own scope tag per spec §6.3 line 1807; "
|
|
896
|
+
f"do not edit v3.6.7's manifest retroactively."
|
|
897
|
+
)
|
|
898
|
+
return files, None
|
|
899
|
+
|
|
900
|
+
|
|
901
|
+
def _extract_block(text: str, marker: str) -> str | None:
|
|
902
|
+
"""Return PATTERN PROTECTION block text, or None if marker missing."""
|
|
903
|
+
pos = text.lower().find(marker.lower())
|
|
904
|
+
if pos == -1:
|
|
905
|
+
return None
|
|
906
|
+
rest = text[pos:]
|
|
907
|
+
match = _HEADING_RE.search(rest, pos=len(marker))
|
|
908
|
+
end = match.start() if match else len(rest)
|
|
909
|
+
return rest[:end]
|
|
910
|
+
|
|
911
|
+
|
|
912
|
+
# Bullet line — Markdown list item starting with `- ` at the start of a
|
|
913
|
+
# line, optionally indented. Captures the bullet text including any
|
|
914
|
+
# soft-wrapped continuation lines (lines indented more than the bullet
|
|
915
|
+
# itself, by Markdown convention typically two spaces). Bullet text ends
|
|
916
|
+
# at the next bullet, blank line, or block boundary.
|
|
917
|
+
_BULLET_START_RE = re.compile(r"^(\s*)-\s+", re.MULTILINE)
|
|
918
|
+
|
|
919
|
+
|
|
920
|
+
def _iter_bullets(block: str) -> list[tuple[int, str]]:
|
|
921
|
+
"""Walk a PATTERN PROTECTION block and yield (line_offset, bullet_text)
|
|
922
|
+
pairs where bullet_text is the bullet's content (without the leading
|
|
923
|
+
`- ` marker) with all whitespace runs (including newlines from soft
|
|
924
|
+
wraps) collapsed to a single space.
|
|
925
|
+
|
|
926
|
+
Bullet boundaries: each bullet runs from its `- ` marker to the next
|
|
927
|
+
bullet, blank line (`\\n\\n`), or end of block. This makes INV-1
|
|
928
|
+
(canonical-line-as-bullet) and INV-2 (no-Clause-2-disclosure) operate
|
|
929
|
+
at bullet granularity, which is what the spec §6.3 means by "exactly
|
|
930
|
+
one bullet whose text matches the canonical Clause 1 line verbatim".
|
|
931
|
+
|
|
932
|
+
`line_offset` is the 0-indexed character position of the bullet's
|
|
933
|
+
`-` marker inside `block` (used to compute file-line diagnostics).
|
|
934
|
+
"""
|
|
935
|
+
starts = list(_BULLET_START_RE.finditer(block))
|
|
936
|
+
bullets: list[tuple[int, str]] = []
|
|
937
|
+
for i, m in enumerate(starts):
|
|
938
|
+
bullet_start = m.start()
|
|
939
|
+
content_start = m.end()
|
|
940
|
+
if i + 1 < len(starts):
|
|
941
|
+
bullet_end = starts[i + 1].start()
|
|
942
|
+
else:
|
|
943
|
+
bullet_end = len(block)
|
|
944
|
+
# Trim at the first blank line within the bullet — a blank line
|
|
945
|
+
# ends the bullet even if no further `- ` appears in the block.
|
|
946
|
+
candidate = block[content_start:bullet_end]
|
|
947
|
+
blank = candidate.find("\n\n")
|
|
948
|
+
if blank >= 0:
|
|
949
|
+
candidate = candidate[:blank]
|
|
950
|
+
normalized = " ".join(candidate.split())
|
|
951
|
+
bullets.append((bullet_start, normalized))
|
|
952
|
+
return bullets
|
|
953
|
+
|
|
954
|
+
|
|
955
|
+
# Audit-specific fragment markers — load-bearing pieces of the canonical
|
|
956
|
+
# Clause 1 sentence that uniquely tie a bullet to the v3.6.7 audit
|
|
957
|
+
# prohibition (not generic anti-fabrication guidance). Any one of these
|
|
958
|
+
# is sufficient to classify a bullet as Clause 1-like.
|
|
959
|
+
_CLAUSE_1_AUDIT_FRAGMENTS = (
|
|
960
|
+
"audit step",
|
|
961
|
+
"audit-passed state",
|
|
962
|
+
"codex/external review",
|
|
963
|
+
)
|
|
964
|
+
|
|
965
|
+
# Generic prohibition fragments that, ALONE, are common anti-fabrication
|
|
966
|
+
# language and DO NOT imply the v3.6.7 audit prohibition (codex R8 P2:
|
|
967
|
+
# `- Do not simulate data or sources.` is legitimate non-audit
|
|
968
|
+
# guidance). A bullet carrying one of these must ALSO carry an
|
|
969
|
+
# audit-specific fragment to be classified as Clause 1-like.
|
|
970
|
+
_CLAUSE_1_GENERIC_FRAGMENTS = (
|
|
971
|
+
"do not simulate",
|
|
972
|
+
"do not claim to have run",
|
|
973
|
+
)
|
|
974
|
+
|
|
975
|
+
|
|
976
|
+
def _is_clause_1_like(bullet_text: str) -> bool:
|
|
977
|
+
"""True if bullet_text reads as a (possibly weakened) variant of
|
|
978
|
+
the canonical Clause 1 line.
|
|
979
|
+
|
|
980
|
+
A bullet is flagged Clause 1-like iff it carries at least one
|
|
981
|
+
audit-specific fragment (audit step / audit-passed state /
|
|
982
|
+
codex/external review). Generic prohibition fragments (`do not
|
|
983
|
+
simulate`, `do not claim to have run`) alone are insufficient —
|
|
984
|
+
they appear in legitimate non-audit anti-fabrication guidance.
|
|
985
|
+
Codex R8 P2 closure: tighten so non-manifest prompts can carry
|
|
986
|
+
`- Do not simulate data or sources.` without tripping INV-3."""
|
|
987
|
+
lowered = bullet_text.lower()
|
|
988
|
+
return any(frag in lowered for frag in _CLAUSE_1_AUDIT_FRAGMENTS)
|
|
989
|
+
|
|
990
|
+
|
|
991
|
+
def _inv1_check_file(rel_path: str) -> tuple[bool, str]:
|
|
992
|
+
"""INV-1: canonical Clause 1 line appears as exactly one bullet in
|
|
993
|
+
the PATTERN PROTECTION block, AND no other Clause 1-like bullet
|
|
994
|
+
exists. The bullet's whitespace-normalized text MUST equal the
|
|
995
|
+
canonical Clause 1 text byte-for-byte; prefix weakeners (`When
|
|
996
|
+
feasible, DO NOT simulate ...`), tail weakeners (`... audit-passed
|
|
997
|
+
state if feasible.`), or any near-canonical duplicate all fail.
|
|
998
|
+
Returns (ok, message).
|
|
999
|
+
|
|
1000
|
+
Codex R2 P2 closure (substring match → bullet-extract + exact
|
|
1001
|
+
compare); R6 P2 closure (weakened-duplicate bypass — keep canonical
|
|
1002
|
+
bullet, add `- When feasible, DO NOT simulate ...` second bullet,
|
|
1003
|
+
exact-count stays 1 and lint passed). The R6 closure flags every
|
|
1004
|
+
Clause 1-like bullet via _CLAUSE_1_LIKE_FRAGMENTS and demands each
|
|
1005
|
+
one is byte-exact canonical."""
|
|
1006
|
+
target = REPO_ROOT / rel_path
|
|
1007
|
+
if not target.exists():
|
|
1008
|
+
return False, f"file missing: {rel_path}"
|
|
1009
|
+
block = _extract_block(target.read_text(encoding="utf-8"), PROTECTION_BLOCK)
|
|
1010
|
+
if block is None:
|
|
1011
|
+
return False, (
|
|
1012
|
+
f"{rel_path}: PATTERN PROTECTION block missing "
|
|
1013
|
+
f"(marker {PROTECTION_BLOCK!r} not found)"
|
|
1014
|
+
)
|
|
1015
|
+
bullets = list(_iter_bullets(block))
|
|
1016
|
+
exact = [t for _o, t in bullets if t == CANONICAL_CLAUSE_1_TEXT]
|
|
1017
|
+
weakened = [
|
|
1018
|
+
t for _o, t in bullets
|
|
1019
|
+
if _is_clause_1_like(t) and t != CANONICAL_CLAUSE_1_TEXT
|
|
1020
|
+
]
|
|
1021
|
+
if weakened:
|
|
1022
|
+
return False, (
|
|
1023
|
+
f"{rel_path}: PATTERN PROTECTION block contains "
|
|
1024
|
+
f"{len(weakened)} Clause 1-like bullet(s) that do not "
|
|
1025
|
+
f"match the canonical text byte-for-byte. Each must equal "
|
|
1026
|
+
f"the canonical wording verbatim or be removed. Offending "
|
|
1027
|
+
f"bullet(s): {weakened!r}. Expected canonical wording: "
|
|
1028
|
+
f"{CANONICAL_CLAUSE_1_TEXT!r}"
|
|
1029
|
+
)
|
|
1030
|
+
if len(exact) != 1:
|
|
1031
|
+
return False, (
|
|
1032
|
+
f"{rel_path}: PATTERN PROTECTION block has {len(exact)} "
|
|
1033
|
+
f"bullet(s) whose normalized text equals the canonical "
|
|
1034
|
+
f"Clause 1 line; expected exactly 1. Expected wording: "
|
|
1035
|
+
f"{CANONICAL_CLAUSE_1_TEXT!r}"
|
|
1036
|
+
)
|
|
1037
|
+
return True, "OK"
|
|
1038
|
+
|
|
1039
|
+
|
|
1040
|
+
def _iter_block_segments(block: str) -> list[tuple[int, str, str]]:
|
|
1041
|
+
"""Yield (offset, kind, normalized_text) tuples for every
|
|
1042
|
+
matched-content segment inside a PATTERN PROTECTION block. `kind`
|
|
1043
|
+
is `"bullet"` for `^- ` list items or `"prose"` for non-bullet
|
|
1044
|
+
paragraphs (intro paragraph, paragraphs interleaved between bullet
|
|
1045
|
+
runs, paragraphs appended after the last bullet — anywhere in the
|
|
1046
|
+
block).
|
|
1047
|
+
|
|
1048
|
+
Whitespace-normalised so soft-wrapped Markdown lines collapse into
|
|
1049
|
+
single-space sentences. Codex R3 + R4 P2 closures: scanning must
|
|
1050
|
+
cover ALL prose in the block, not just the intro paragraph (R3) or
|
|
1051
|
+
just the pre-first-bullet region (R4). The spec §6.2 sweep promises
|
|
1052
|
+
"zero Clause 2 violation in PATTERN PROTECTION block"; carving out
|
|
1053
|
+
any sub-region (post-bullet trailers, between-bullet inserts) gives
|
|
1054
|
+
a regression vector.
|
|
1055
|
+
|
|
1056
|
+
Algorithm: paragraph-split the block on blank lines. Each paragraph
|
|
1057
|
+
starting with `- ` is treated as a bullet group and walked via
|
|
1058
|
+
`_iter_bullets`; each non-bullet paragraph (excluding the section
|
|
1059
|
+
heading) is reported as `"prose"`. This handles bullets-then-prose,
|
|
1060
|
+
prose-then-bullets, and mixed orderings uniformly.
|
|
1061
|
+
"""
|
|
1062
|
+
segments: list[tuple[int, str, str]] = []
|
|
1063
|
+
cursor = 0
|
|
1064
|
+
paragraphs = re.split(r"\n\s*\n", block)
|
|
1065
|
+
for paragraph in paragraphs:
|
|
1066
|
+
offset = block.find(paragraph, cursor)
|
|
1067
|
+
if offset < 0:
|
|
1068
|
+
offset = cursor
|
|
1069
|
+
# Advance the cursor past this paragraph and its trailing
|
|
1070
|
+
# blank-line separator (`\n\n`) for the next find().
|
|
1071
|
+
cursor = offset + len(paragraph) + 2
|
|
1072
|
+
stripped = paragraph.strip()
|
|
1073
|
+
if not stripped:
|
|
1074
|
+
continue
|
|
1075
|
+
# The block heading line (`## PATTERN PROTECTION (v3.6.7)`)
|
|
1076
|
+
# is content marker, not contract content.
|
|
1077
|
+
if stripped.startswith("## "):
|
|
1078
|
+
continue
|
|
1079
|
+
if stripped.startswith("- "):
|
|
1080
|
+
# Bullet group — may be a single bullet or a wrapped multi-
|
|
1081
|
+
# line bullet; delegate to `_iter_bullets` which knows how
|
|
1082
|
+
# to walk `- ` markers and collapse soft wraps.
|
|
1083
|
+
for bullet_local_offset, bullet_text in _iter_bullets(paragraph):
|
|
1084
|
+
segments.append((offset + bullet_local_offset, "bullet", bullet_text))
|
|
1085
|
+
else:
|
|
1086
|
+
normalized = " ".join(stripped.split())
|
|
1087
|
+
segments.append((offset, "prose", normalized))
|
|
1088
|
+
return segments
|
|
1089
|
+
|
|
1090
|
+
|
|
1091
|
+
def _inv2_check_file(rel_path: str) -> tuple[bool, list[str]]:
|
|
1092
|
+
"""INV-2: zero Clause 2 violation hits across the four regex
|
|
1093
|
+
patterns (a)-(d), evaluated per segment (intro prose paragraphs +
|
|
1094
|
+
bullets, both whitespace-normalized). Returns (ok, error_messages).
|
|
1095
|
+
|
|
1096
|
+
Per-segment evaluation closes codex R2 P2 (cross-bullet `.*`
|
|
1097
|
+
over-reach) AND codex R3 P2 (intro-paragraph regression): each
|
|
1098
|
+
pattern runs against a single bullet OR a single prose paragraph,
|
|
1099
|
+
never spanning unrelated text. Soft-wrap tolerance is preserved by
|
|
1100
|
+
pre-normalizing each segment's whitespace."""
|
|
1101
|
+
target = REPO_ROOT / rel_path
|
|
1102
|
+
if not target.exists():
|
|
1103
|
+
return False, [f"file missing: {rel_path}"]
|
|
1104
|
+
full = target.read_text(encoding="utf-8")
|
|
1105
|
+
block = _extract_block(full, PROTECTION_BLOCK)
|
|
1106
|
+
if block is None:
|
|
1107
|
+
return False, [
|
|
1108
|
+
f"{rel_path}: PATTERN PROTECTION block missing "
|
|
1109
|
+
f"(marker {PROTECTION_BLOCK!r} not found)"
|
|
1110
|
+
]
|
|
1111
|
+
errors: list[str] = []
|
|
1112
|
+
block_offset = full.find(block)
|
|
1113
|
+
for segment_offset, kind, normalized in _iter_block_segments(block):
|
|
1114
|
+
# Skip the canonical Clause 1 bullet — it inherently contains
|
|
1115
|
+
# "audit step" / "audit-passed state" tokens but is the
|
|
1116
|
+
# required prohibition, not a disclosure.
|
|
1117
|
+
if kind == "bullet" and normalized == CANONICAL_CLAUSE_1_TEXT:
|
|
1118
|
+
continue
|
|
1119
|
+
for label, pat in INV2_PATTERNS:
|
|
1120
|
+
m = pat.search(normalized)
|
|
1121
|
+
if m is None:
|
|
1122
|
+
continue
|
|
1123
|
+
absolute_pos = (block_offset + segment_offset) if block_offset >= 0 else segment_offset
|
|
1124
|
+
line_no = full.count("\n", 0, absolute_pos) + 1
|
|
1125
|
+
errors.append(
|
|
1126
|
+
f"{rel_path}:{line_no}: {label} Clause 2 violation in {kind}: "
|
|
1127
|
+
f"{normalized!r}. Sentence must be removed per "
|
|
1128
|
+
f"docs/design/2026-04-30-ars-v3.6.7-step-6-orchestrator-hooks-spec.md §6.2."
|
|
1129
|
+
)
|
|
1130
|
+
# One label per segment is enough; further labels on the
|
|
1131
|
+
# same segment would be redundant.
|
|
1132
|
+
break
|
|
1133
|
+
return (len(errors) == 0), errors
|
|
1134
|
+
|
|
1135
|
+
|
|
1136
|
+
# Directories scanned by INV-3. Spec §6.3 limits scope to agent prompt
|
|
1137
|
+
# files under deep-research/agents/ and academic-pipeline/agents/. docs/,
|
|
1138
|
+
# scripts/, and tests/ are excluded — the canonical line legitimately
|
|
1139
|
+
# appears in the spec, the manifest checker, and test fixtures, and
|
|
1140
|
+
# scanning those would self-fail.
|
|
1141
|
+
INV3_SCAN_DIRS = [
|
|
1142
|
+
REPO_ROOT / "deep-research" / "agents",
|
|
1143
|
+
REPO_ROOT / "academic-pipeline" / "agents",
|
|
1144
|
+
]
|
|
1145
|
+
|
|
1146
|
+
|
|
1147
|
+
def _inv3_check(manifest_files: list[str]) -> tuple[bool, list[str]]:
|
|
1148
|
+
"""INV-3: the EXACT canonical Clause 1 line MUST NOT appear in any
|
|
1149
|
+
agent prompt outside the manifest. Detects:
|
|
1150
|
+
(a) Bullets whose whitespace-normalized text equals
|
|
1151
|
+
`CANONICAL_CLAUSE_1_TEXT` byte-for-byte.
|
|
1152
|
+
(b) Prose runs whose whitespace-normalized text equals
|
|
1153
|
+
`CANONICAL_CLAUSE_1_TEXT` byte-for-byte. Prose runs are
|
|
1154
|
+
identified by sliding a 3-sentence window across non-bullet
|
|
1155
|
+
text after stripping `^#` heading lines.
|
|
1156
|
+
Returns (ok, error_messages).
|
|
1157
|
+
|
|
1158
|
+
Codex R9 P2 closures (architectural rewind on R7+R8 over-extension):
|
|
1159
|
+
- The Clause 1-like heuristic is a manifest-internal weakened-
|
|
1160
|
+
duplicate guard (INV-1), NOT a manifest-external detector.
|
|
1161
|
+
Applied to non-manifest agents, it false-positives any bullet
|
|
1162
|
+
mentioning `audit step` for unrelated reasons (e.g. process-
|
|
1163
|
+
flow guidance like `- Review each audit step before
|
|
1164
|
+
finalizing.`). Spec §6.3 INV-3 wording says "canonical Clause 1
|
|
1165
|
+
line found outside the manifest" — that means the actual
|
|
1166
|
+
sentence, not a Clause 1-like variant. Variants outside the
|
|
1167
|
+
manifest are a separate concern that v3.6.7 does not lint.
|
|
1168
|
+
- Prose detection no longer relies on `re.split(r"\\n\\s*\\n", ...)`
|
|
1169
|
+
paragraphs (which mis-handle a heading immediately followed by
|
|
1170
|
+
the canonical sentence with no blank line). Use line-level
|
|
1171
|
+
heading-strip + whitespace-collapse + a 3-sentence sliding
|
|
1172
|
+
window so the canonical sentence is detectable regardless of
|
|
1173
|
+
surrounding Markdown structure.
|
|
1174
|
+
"""
|
|
1175
|
+
manifest_set = {str(REPO_ROOT / p) for p in manifest_files}
|
|
1176
|
+
errors: list[str] = []
|
|
1177
|
+
for d in INV3_SCAN_DIRS:
|
|
1178
|
+
if not d.is_dir():
|
|
1179
|
+
continue
|
|
1180
|
+
for path in sorted(d.glob("*.md")):
|
|
1181
|
+
if str(path) in manifest_set:
|
|
1182
|
+
continue
|
|
1183
|
+
text = path.read_text(encoding="utf-8")
|
|
1184
|
+
offending_bullets = [
|
|
1185
|
+
bt
|
|
1186
|
+
for _o, bt in _iter_bullets(text)
|
|
1187
|
+
if bt == CANONICAL_CLAUSE_1_TEXT
|
|
1188
|
+
]
|
|
1189
|
+
# Line-level heading strip + whitespace collapse on the
|
|
1190
|
+
# rest. Heading lines (start with `#`) and bullet lines
|
|
1191
|
+
# (`- `) are excluded; remaining lines are joined with a
|
|
1192
|
+
# single space. The canonical sentence is detected as a
|
|
1193
|
+
# substring with proper sentence boundaries.
|
|
1194
|
+
non_bullet_non_heading = "\n".join(
|
|
1195
|
+
line for line in text.splitlines()
|
|
1196
|
+
if not line.lstrip().startswith("#")
|
|
1197
|
+
and not line.lstrip().startswith("- ")
|
|
1198
|
+
)
|
|
1199
|
+
normalized_prose = " ".join(non_bullet_non_heading.split())
|
|
1200
|
+
offending_prose: list[str] = []
|
|
1201
|
+
if CANONICAL_CLAUSE_1_TEXT in normalized_prose:
|
|
1202
|
+
offending_prose.append(CANONICAL_CLAUSE_1_TEXT)
|
|
1203
|
+
if offending_bullets or offending_prose:
|
|
1204
|
+
rel = path.relative_to(REPO_ROOT)
|
|
1205
|
+
offenders = []
|
|
1206
|
+
for bt in offending_bullets:
|
|
1207
|
+
offenders.append(f"bullet: {bt!r}")
|
|
1208
|
+
for pr in offending_prose:
|
|
1209
|
+
offenders.append(f"prose: {pr!r}")
|
|
1210
|
+
errors.append(
|
|
1211
|
+
f"{rel}: canonical Clause 1 line found outside the "
|
|
1212
|
+
f"v3.6.7 inversion manifest. If this is intentional "
|
|
1213
|
+
f"widening, land a v3.6.8+ scope-tagged manifest per "
|
|
1214
|
+
f"spec §6.3 line 1807 and open the §9 L2 question; "
|
|
1215
|
+
f"do not retroactively widen v3.6.7's manifest. "
|
|
1216
|
+
f"Offender(s): {offenders!r}"
|
|
1217
|
+
)
|
|
1218
|
+
return (len(errors) == 0), errors
|
|
1219
|
+
|
|
1220
|
+
|
|
1221
|
+
def inversion_sweep_results() -> list[tuple[str, str, bool, str]]:
|
|
1222
|
+
"""Run INV-1/INV-2/INV-3. Returns list of
|
|
1223
|
+
(pattern_id, description, ok, message) tuples — one row per check ID,
|
|
1224
|
+
aggregated across files for INV-2 and INV-3."""
|
|
1225
|
+
results: list[tuple[str, str, bool, str]] = []
|
|
1226
|
+
files, err = _load_inversion_manifest()
|
|
1227
|
+
if err is not None:
|
|
1228
|
+
results.append(("INV-manifest", "v3.6.7 inversion manifest readable", False, err))
|
|
1229
|
+
return results
|
|
1230
|
+
|
|
1231
|
+
# INV-1: per-file presence/uniqueness check, aggregated.
|
|
1232
|
+
inv1_errors: list[str] = []
|
|
1233
|
+
for f in files:
|
|
1234
|
+
ok, msg = _inv1_check_file(f)
|
|
1235
|
+
if not ok:
|
|
1236
|
+
inv1_errors.append(msg)
|
|
1237
|
+
results.append((
|
|
1238
|
+
"INV-1",
|
|
1239
|
+
f"canonical Clause 1 line present exactly once in each of {len(files)} manifest file(s)",
|
|
1240
|
+
len(inv1_errors) == 0,
|
|
1241
|
+
"OK" if not inv1_errors else "; ".join(inv1_errors),
|
|
1242
|
+
))
|
|
1243
|
+
|
|
1244
|
+
# INV-2: aggregate Clause 2 violation hits across all manifest files.
|
|
1245
|
+
inv2_errors: list[str] = []
|
|
1246
|
+
for f in files:
|
|
1247
|
+
ok, errs = _inv2_check_file(f)
|
|
1248
|
+
if not ok:
|
|
1249
|
+
inv2_errors.extend(errs)
|
|
1250
|
+
results.append((
|
|
1251
|
+
"INV-2",
|
|
1252
|
+
"no Clause 2 disclosure phrases (a)-(d) inside PATTERN PROTECTION blocks",
|
|
1253
|
+
len(inv2_errors) == 0,
|
|
1254
|
+
"OK" if not inv2_errors else "; ".join(inv2_errors),
|
|
1255
|
+
))
|
|
1256
|
+
|
|
1257
|
+
# INV-3: canonical line restricted to manifest files.
|
|
1258
|
+
ok, errs = _inv3_check(files)
|
|
1259
|
+
results.append((
|
|
1260
|
+
"INV-3",
|
|
1261
|
+
f"canonical Clause 1 line confined to {len(files)} manifest file(s)",
|
|
1262
|
+
ok,
|
|
1263
|
+
"OK" if ok else "; ".join(errs),
|
|
1264
|
+
))
|
|
1265
|
+
return results
|
|
1266
|
+
|
|
1267
|
+
|
|
1268
|
+
# Environment variable controlling whether agent-prompt checks run.
|
|
1269
|
+
#
|
|
1270
|
+
# Spec §9 ships v3.6.7 across multiple steps. Step 1 (this PR) shipped the
|
|
1271
|
+
# 4 reference files + audit template + this lint. Step 2 (this PR / Step 1+2
|
|
1272
|
+
# bundle) lands the actual PATTERN PROTECTION (v3.6.7) blocks in the three
|
|
1273
|
+
# downstream agent prompts. With Step 2 in, the agent-prompt checks are
|
|
1274
|
+
# default-on so CI enforces the contract.
|
|
1275
|
+
#
|
|
1276
|
+
# Set ARS_V3_6_7_AGENT_CHECKS=0 to skip agent-prompt checks (e.g. for a
|
|
1277
|
+
# repo bisect that crosses a pre-Step-2 commit, or for partial test runs).
|
|
1278
|
+
_AGENT_CHECKS_ENV = "ARS_V3_6_7_AGENT_CHECKS"
|
|
1279
|
+
|
|
1280
|
+
|
|
1281
|
+
def _agent_checks_enabled() -> bool:
|
|
1282
|
+
return os.environ.get(_AGENT_CHECKS_ENV, "1") == "1"
|
|
1283
|
+
|
|
1284
|
+
|
|
1285
|
+
def all_checks() -> list[Check]:
|
|
1286
|
+
checks = [
|
|
1287
|
+
*reference_file_checks(),
|
|
1288
|
+
*template_file_checks(),
|
|
1289
|
+
]
|
|
1290
|
+
if _agent_checks_enabled():
|
|
1291
|
+
checks.extend([
|
|
1292
|
+
*synthesis_agent_checks(),
|
|
1293
|
+
*architect_agent_checks(),
|
|
1294
|
+
*compiler_agent_checks(),
|
|
1295
|
+
])
|
|
1296
|
+
return checks
|
|
1297
|
+
|
|
1298
|
+
|
|
1299
|
+
def main(argv: list[str]) -> int:
|
|
1300
|
+
checks = all_checks()
|
|
1301
|
+
passed: list[tuple[str, str]] = []
|
|
1302
|
+
failed: list[tuple[str, str, str]] = []
|
|
1303
|
+
|
|
1304
|
+
for check in checks:
|
|
1305
|
+
ok, msg = check.run()
|
|
1306
|
+
entry = (check.pattern_id, check.description)
|
|
1307
|
+
if ok:
|
|
1308
|
+
passed.append(entry)
|
|
1309
|
+
else:
|
|
1310
|
+
failed.append((check.pattern_id, check.description, msg))
|
|
1311
|
+
|
|
1312
|
+
inv_results: list[tuple[str, str, bool, str]] = []
|
|
1313
|
+
if _agent_checks_enabled():
|
|
1314
|
+
inv_results = inversion_sweep_results()
|
|
1315
|
+
for pid, desc, ok, msg in inv_results:
|
|
1316
|
+
entry = (pid, desc)
|
|
1317
|
+
if ok:
|
|
1318
|
+
passed.append(entry)
|
|
1319
|
+
else:
|
|
1320
|
+
failed.append((pid, desc, msg))
|
|
1321
|
+
|
|
1322
|
+
total = len(checks) + len(inv_results)
|
|
1323
|
+
deferred_note = ""
|
|
1324
|
+
if not _agent_checks_enabled():
|
|
1325
|
+
deferred_note = " (agent-prompt checks skipped — ARS_V3_6_7_AGENT_CHECKS=0)"
|
|
1326
|
+
summary = (
|
|
1327
|
+
f"v3.6.7 pattern-protection static audit: {len(passed)}/{total} "
|
|
1328
|
+
f"checks passed{deferred_note}"
|
|
1329
|
+
)
|
|
1330
|
+
print(summary)
|
|
1331
|
+
print()
|
|
1332
|
+
|
|
1333
|
+
if passed:
|
|
1334
|
+
print("PASS:")
|
|
1335
|
+
for pid, desc in passed:
|
|
1336
|
+
print(f" [{pid}] {desc}")
|
|
1337
|
+
print()
|
|
1338
|
+
|
|
1339
|
+
if failed:
|
|
1340
|
+
# Failures go to stderr so CI harnesses that route stderr to a failure
|
|
1341
|
+
# channel (matching scripts/check_corpus_consumer_protocol.py) surface
|
|
1342
|
+
# the diagnostics correctly.
|
|
1343
|
+
print("FAIL:", file=sys.stderr)
|
|
1344
|
+
for pid, desc, msg in failed:
|
|
1345
|
+
print(f" [{pid}] {desc}", file=sys.stderr)
|
|
1346
|
+
print(f" → {msg}", file=sys.stderr)
|
|
1347
|
+
print(file=sys.stderr)
|
|
1348
|
+
print(
|
|
1349
|
+
f"{len(failed)} check(s) failed. See spec for protection clause wording:",
|
|
1350
|
+
file=sys.stderr,
|
|
1351
|
+
)
|
|
1352
|
+
print(
|
|
1353
|
+
" docs/design/2026-04-29-ars-v3.6.7-downstream-agent-pattern-protection-spec.md",
|
|
1354
|
+
file=sys.stderr,
|
|
1355
|
+
)
|
|
1356
|
+
print(
|
|
1357
|
+
" docs/design/2026-04-30-ars-v3.6.7-step-6-orchestrator-hooks-spec.md (INV-1/2/3)",
|
|
1358
|
+
file=sys.stderr,
|
|
1359
|
+
)
|
|
1360
|
+
return 1
|
|
1361
|
+
|
|
1362
|
+
return 0
|
|
1363
|
+
|
|
1364
|
+
|
|
1365
|
+
if __name__ == "__main__":
|
|
1366
|
+
sys.exit(main(sys.argv))
|