claude-dev-env 2.12.0 → 2.14.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/AGENTS.md +61 -0
- package/CLAUDE.md +1 -57
- package/_shared/AGENTS.md +15 -0
- package/_shared/CLAUDE.md +1 -15
- package/_shared/advisor/AGENTS.md +22 -0
- package/_shared/advisor/CLAUDE.md +1 -22
- package/_shared/pr-loop/AGENTS.md +27 -0
- package/_shared/pr-loop/CLAUDE.md +1 -27
- package/_shared/pr-loop/scripts/AGENTS.md +35 -0
- package/_shared/pr-loop/scripts/CLAUDE.md +1 -35
- package/_shared/pr-loop/scripts/code_rules_gate.py +2 -3
- package/_shared/pr-loop/scripts/code_rules_gate_parts/AGENTS.md +42 -0
- package/_shared/pr-loop/scripts/code_rules_gate_parts/CLAUDE.md +1 -42
- package/_shared/pr-loop/scripts/pr_loop_shared_constants/AGENTS.md +26 -0
- package/_shared/pr-loop/scripts/pr_loop_shared_constants/CLAUDE.md +1 -26
- package/_shared/pr-loop/scripts/test_code_rules_gate.py +0 -26
- package/_shared/pr-loop/scripts/tests/AGENTS.md +44 -0
- package/_shared/pr-loop/scripts/tests/CLAUDE.md +1 -44
- package/_shared/process-tree/AGENTS.md +41 -0
- package/_shared/process-tree/CLAUDE.md +1 -41
- package/agents/AGENTS.md +31 -0
- package/agents/CLAUDE.md +1 -32
- package/agents/clean-coder.md +6 -6
- package/agents/pr-description-writer.md +11 -81
- package/agents/test_agent_frontmatter.py +4 -4
- package/audit-rubrics/AGENTS.md +43 -0
- package/audit-rubrics/CLAUDE.md +1 -43
- package/audit-rubrics/category_rubrics/AGENTS.md +37 -0
- package/audit-rubrics/category_rubrics/CLAUDE.md +1 -37
- package/audit-rubrics/prompts/AGENTS.md +37 -0
- package/audit-rubrics/prompts/CLAUDE.md +1 -37
- package/bin/AGENTS.md +112 -0
- package/bin/CLAUDE.md +1 -112
- package/bin/ever-shipped-skills.mjs +1 -0
- package/bin/install-constants.mjs +6 -7
- package/bin/install.mjs +71 -13
- package/bin/install.prune.test.mjs +26 -0
- package/bin/install.settings-defaults.test.mjs +60 -33
- package/bin/install.test.mjs +36 -4
- package/commands/AGENTS.md +23 -0
- package/commands/CLAUDE.md +1 -23
- package/commands/hook-log-extract.md +3 -3
- package/commands/sr-loop.md +9 -5
- package/docs/AGENTS.md +32 -0
- package/docs/CLAUDE.md +1 -33
- package/docs/CODE_RULES.md +1 -1
- package/docs/imagegen.md +22 -0
- package/docs/references/AGENTS.md +17 -0
- package/docs/references/CLAUDE.md +1 -18
- package/hooks/AGENTS.md +31 -0
- package/hooks/CLAUDE.md +1 -31
- package/hooks/_gh_pr_author_swap_utils.py +14 -0
- package/hooks/advisory/AGENTS.md +16 -0
- package/hooks/advisory/CLAUDE.md +1 -16
- package/hooks/blocking/AGENTS.md +123 -0
- package/hooks/blocking/CLAUDE.md +1 -148
- package/hooks/blocking/claude_md_orphan_file_blocker_parts/AGENTS.md +28 -0
- package/hooks/blocking/claude_md_orphan_file_blocker_parts/CLAUDE.md +1 -28
- package/hooks/blocking/code_rules_banned_identifiers.py +1 -1
- package/hooks/blocking/code_rules_dead_module_constant.py +149 -37
- package/hooks/blocking/code_rules_probe_chains.py +6 -2
- package/hooks/blocking/config/AGENTS.md +10 -0
- package/hooks/blocking/config/CLAUDE.md +1 -22
- package/hooks/blocking/conventional_pr_title_gate.py +1 -2
- package/hooks/blocking/gh_pr_author_restore.py +7 -2
- package/hooks/blocking/intent_only_ending_blocker.py +11 -16
- package/hooks/blocking/inventory_intent_records/AGENTS.md +26 -0
- package/hooks/blocking/inventory_intent_records/CLAUDE.md +1 -26
- package/hooks/blocking/package_inventory_stale_blocker_parts/AGENTS.md +26 -0
- package/hooks/blocking/package_inventory_stale_blocker_parts/CLAUDE.md +1 -26
- package/hooks/blocking/pii_prevention_blocker_parts/AGENTS.md +24 -0
- package/hooks/blocking/pii_prevention_blocker_parts/CLAUDE.md +1 -24
- package/hooks/blocking/send_user_file_open_locally_blocker.py +1 -1
- package/hooks/blocking/stop_dispatcher.py +4 -4
- package/hooks/blocking/tdd_enforcer_parts/AGENTS.md +30 -0
- package/hooks/blocking/tdd_enforcer_parts/CLAUDE.md +1 -30
- package/hooks/blocking/test_bash_pre_tool_use_dispatcher.py +0 -3
- package/hooks/blocking/test_code_rules_enforcer_banned_prefixes.py +1 -1
- package/hooks/blocking/test_code_rules_enforcer_dead_module_constant.py +171 -0
- package/hooks/blocking/test_code_rules_enforcer_magic_allowlist.py +1 -1
- package/hooks/blocking/test_gh_pr_author_restore.py +2 -1
- package/hooks/blocking/test_intent_only_ending_blocker.py +4 -0
- package/hooks/blocking/test_pre_tool_use_dispatcher.py +6 -7
- package/hooks/blocking/test_send_user_file_open_locally_blocker.py +4 -3
- package/hooks/blocking/test_shared_stdin_adoption.py +0 -2
- package/hooks/diagnostic/AGENTS.md +43 -0
- package/hooks/diagnostic/CLAUDE.md +1 -43
- package/hooks/diagnostic/hook_log_extractor.py +4 -38
- package/hooks/diagnostic/hook_log_stop_wrapper.py +6 -155
- package/hooks/diagnostic/migrations/AGENTS.md +16 -0
- package/hooks/diagnostic/migrations/CLAUDE.md +1 -16
- package/hooks/diagnostic/queries/AGENTS.md +19 -0
- package/hooks/diagnostic/queries/CLAUDE.md +1 -19
- package/hooks/diagnostic/test_hook_log_extractor.py +10 -23
- package/hooks/diagnostic/test_hook_log_stop_wrapper.py +3 -331
- package/hooks/git-hooks/AGENTS.md +31 -0
- package/hooks/git-hooks/CLAUDE.md +1 -31
- package/hooks/git-hooks/git_hooks_constants/AGENTS.md +21 -0
- package/hooks/git-hooks/git_hooks_constants/CLAUDE.md +1 -21
- package/hooks/git-hooks/git_hooks_constants/__init__.py +4 -12
- package/hooks/git-hooks/pre_push.py +49 -118
- package/hooks/git-hooks/test_pre_push.py +111 -137
- package/hooks/hooks.json +0 -35
- package/hooks/hooks_constants/AGENTS.md +104 -0
- package/hooks/hooks_constants/CLAUDE.md +1 -113
- package/hooks/hooks_constants/bash_pre_tool_use_dispatcher_constants.py +0 -11
- package/hooks/hooks_constants/convergence_branch_constants.py +0 -1
- package/hooks/hooks_constants/fable_spawn_gate_constants.py +3 -4
- package/hooks/hooks_constants/hook_log_extractor_constants.py +1 -2
- package/hooks/hooks_constants/pre_tool_use_dispatcher_constants.py +0 -8
- package/hooks/hooks_constants/send_user_file_open_locally_blocker_constants.py +1 -6
- package/hooks/hooks_constants/stop_dispatcher_constants.py +0 -1
- package/hooks/hooks_constants/task_list_loop_starter_constants.py +4 -3
- package/hooks/hooks_constants/test_bash_pre_tool_use_dispatcher_constants.py +1 -26
- package/hooks/hooks_constants/test_pre_tool_use_dispatcher_constants.py +0 -5
- package/hooks/hooks_constants/test_stop_dispatcher_constants.py +0 -1
- package/hooks/hooks_constants/working_style_prompt_constants.py +29 -20
- package/hooks/lifecycle/AGENTS.md +18 -0
- package/hooks/lifecycle/CLAUDE.md +1 -20
- package/hooks/observability/AGENTS.md +20 -0
- package/hooks/observability/CLAUDE.md +1 -20
- package/hooks/session/AGENTS.md +33 -0
- package/hooks/session/CLAUDE.md +1 -33
- package/hooks/session/gh_pr_author_session_cleanup.py +7 -2
- package/hooks/session/task_list_loop_starter.py +3 -3
- package/hooks/session/test_gh_pr_author_session_cleanup.py +2 -1
- package/hooks/session/test_task_list_loop_starter.py +10 -2
- package/hooks/session/test_working_style_prompt.py +9 -4
- package/hooks/validation/AGENTS.md +20 -0
- package/hooks/validation/CLAUDE.md +1 -20
- package/hooks/validators/AGENTS.md +51 -0
- package/hooks/validators/CLAUDE.md +1 -51
- package/hooks/validators/health_check.py +52 -19
- package/hooks/validators/python_style_checks.py +1 -1
- package/hooks/validators/test_health_check.py +112 -27
- package/hooks/workflow/AGENTS.md +16 -0
- package/hooks/workflow/CLAUDE.md +1 -16
- package/installable-surfaces.manifest.json +1 -0
- package/output-styles/AGENTS.md +15 -0
- package/output-styles/CLAUDE.md +1 -15
- package/package.json +2 -1
- package/rules/AGENTS.md +61 -0
- package/rules/CLAUDE.md +1 -63
- package/rules/code-standards.md +5 -9
- package/rules/doc-prose-cuts.md +1 -1
- package/rules/gh-cli-conventions.md +0 -1
- package/rules/git-workflow.md +1 -3
- package/scripts/AGENTS.md +62 -0
- package/scripts/CLAUDE.md +1 -63
- package/scripts/_code_review_test_support.py +0 -95
- package/scripts/codex_compat_materializer.py +4 -0
- package/scripts/dev_env_scripts_constants/AGENTS.md +21 -0
- package/scripts/dev_env_scripts_constants/CLAUDE.md +1 -21
- package/scripts/dev_env_scripts_constants/code_review_constants.py +9 -98
- package/scripts/dev_env_scripts_constants/test_code_review_constants.py +1 -44
- package/scripts/invoke_code_review.py +8 -451
- package/scripts/sync_to_cursor/AGENTS.md +23 -0
- package/scripts/sync_to_cursor/CLAUDE.md +1 -23
- package/scripts/test_invoke_code_review.py +5 -61
- package/scripts/test_invoke_code_review_cli.py +1 -45
- package/scripts/test_invoke_code_review_contract.py +1 -118
- package/scripts/test_validate_instruction_pairs.py +90 -0
- package/scripts/test_verify_installable_package.py +5 -1
- package/scripts/tests/AGENTS.md +33 -0
- package/scripts/tests/CLAUDE.md +1 -33
- package/scripts/tests/test_codex_compat_materializer.py +36 -1
- package/scripts/validate_instruction_pairs.py +183 -0
- package/settings.json +1 -10
- package/skills/AGENTS.md +72 -0
- package/skills/CLAUDE.md +1 -64
- package/skills/_shared/AGENTS.md +44 -0
- package/skills/_shared/CLAUDE.md +1 -44
- package/skills/_shared/advisor/AGENTS.md +9 -0
- package/skills/_shared/advisor/CLAUDE.md +1 -9
- package/skills/_shared/pr-loop/AGENTS.md +50 -0
- package/skills/_shared/pr-loop/CLAUDE.md +1 -50
- package/skills/_shared/pr-loop/prompts/AGENTS.md +9 -0
- package/skills/_shared/pr-loop/prompts/CLAUDE.md +1 -9
- package/skills/_shared/pr-loop/scripts/AGENTS.md +35 -0
- package/skills/_shared/pr-loop/scripts/CLAUDE.md +1 -35
- package/skills/_shared/pr-loop/scripts/skills_pr_loop_constants/AGENTS.md +24 -0
- package/skills/_shared/pr-loop/scripts/skills_pr_loop_constants/CLAUDE.md +1 -24
- package/skills/anthropic-plan/AGENTS.md +34 -0
- package/skills/anthropic-plan/CLAUDE.md +1 -34
- package/skills/anthropic-plan/scripts/AGENTS.md +11 -0
- package/skills/anthropic-plan/scripts/CLAUDE.md +1 -11
- package/skills/anthropic-plan/scripts/anthropic_plan_scripts_constants/AGENTS.md +16 -0
- package/skills/anthropic-plan/scripts/anthropic_plan_scripts_constants/CLAUDE.md +1 -16
- package/skills/anthropic-plan/templates/AGENTS.md +13 -0
- package/skills/anthropic-plan/templates/CLAUDE.md +1 -13
- package/skills/anthropic-plan/workflow/AGENTS.md +14 -0
- package/skills/anthropic-plan/workflow/CLAUDE.md +1 -14
- package/skills/auditing-claude-config/AGENTS.md +21 -0
- package/skills/auditing-claude-config/CLAUDE.md +1 -21
- package/skills/autoconverge/AGENTS.md +36 -0
- package/skills/autoconverge/CLAUDE.md +1 -36
- package/skills/autoconverge/reference/AGENTS.md +16 -0
- package/skills/autoconverge/reference/CLAUDE.md +1 -16
- package/skills/autoconverge/reference/convergence.md +7 -7
- package/skills/autoconverge/reference/gotchas.md +3 -10
- package/skills/autoconverge/workflow/AGENTS.md +26 -0
- package/skills/autoconverge/workflow/CLAUDE.md +1 -26
- package/skills/autoconverge/workflow/autoconverge_report_constants/AGENTS.md +16 -0
- package/skills/autoconverge/workflow/autoconverge_report_constants/CLAUDE.md +1 -16
- package/skills/autoconverge/workflow/converge.contract.test.mjs +53 -1388
- package/skills/autoconverge/workflow/converge.copilot-gate.test.mjs +4 -3
- package/skills/autoconverge/workflow/converge.fix-recovery.test.mjs +33 -493
- package/skills/autoconverge/workflow/converge.merge-conflict.test.mjs +15 -97
- package/skills/autoconverge/workflow/converge.mjs +201 -238
- package/skills/autoconverge/workflow/converge.precatch.test.mjs +1 -1
- package/skills/bugteam/AGENTS.md +30 -0
- package/skills/bugteam/CLAUDE.md +1 -30
- package/skills/bugteam/CONSTRAINTS.md +1 -1
- package/skills/bugteam/SKILL.md +9 -0
- package/skills/bugteam/reference/AGENTS.md +20 -0
- package/skills/bugteam/reference/CLAUDE.md +1 -20
- package/skills/bugteam/reference/audit-and-teammates.md +10 -6
- package/skills/bugteam/reference/obstacles/AGENTS.md +24 -0
- package/skills/bugteam/reference/obstacles/CLAUDE.md +1 -24
- package/skills/bugteam/scripts/AGENTS.md +30 -0
- package/skills/bugteam/scripts/CLAUDE.md +1 -30
- package/skills/bugteam/scripts/bugteam_scripts_constants/AGENTS.md +18 -0
- package/skills/bugteam/scripts/bugteam_scripts_constants/CLAUDE.md +1 -18
- package/skills/bugteam/test_skill_additions.py +9 -0
- package/skills/closeout/reference/handoff-prompt-template.md +1 -1
- package/skills/codex-review/AGENTS.md +46 -0
- package/skills/codex-review/CLAUDE.md +1 -46
- package/skills/codex-review/reference/AGENTS.md +15 -0
- package/skills/codex-review/reference/CLAUDE.md +1 -15
- package/skills/codex-review/scripts/codex_review_scripts_constants/AGENTS.md +18 -0
- package/skills/codex-review/scripts/codex_review_scripts_constants/CLAUDE.md +1 -18
- package/skills/codex-review/test_skill_scaffold.py +3 -3
- package/skills/comments/SKILL.md +65 -0
- package/skills/copilot-review/AGENTS.md +18 -0
- package/skills/copilot-review/CLAUDE.md +1 -18
- package/skills/descriptions/SKILL.md +51 -0
- package/skills/emergencies/SKILL.md +42 -0
- package/skills/everything-search/AGENTS.md +17 -0
- package/skills/everything-search/CLAUDE.md +1 -17
- package/skills/fresh-branch/AGENTS.md +14 -0
- package/skills/fresh-branch/CLAUDE.md +1 -14
- package/skills/grok-spawn/AGENTS.md +28 -0
- package/skills/grok-spawn/CLAUDE.md +1 -28
- package/skills/orchestrator/SKILL.md +2 -4
- package/skills/plan-to-pr/SKILL.md +6 -7
- package/skills/plan-to-pr/reference/final-validation-tasks.md +1 -1
- package/skills/plan-to-pr/reference/process-inventory.md +2 -2
- package/skills/plan-to-pr/reference/review-loop.md +2 -2
- package/skills/plan-to-pr/reference/run-record.schema.json +1 -1
- package/skills/plan-to-pr/reference/task-seeds.md +1 -1
- package/skills/plan-to-pr/reference/task-ticket.md +3 -4
- package/skills/plan-to-pr/scripts/config/constants.py +1 -2
- package/skills/plan-to-pr/scripts/test_validate_protocol.py +1 -1
- package/skills/plan-to-pr/test_skill_contract.py +2 -2
- package/skills/pr-converge/AGENTS.md +32 -0
- package/skills/pr-converge/CLAUDE.md +1 -32
- package/skills/pr-converge/SKILL.md +13 -16
- package/skills/pr-converge/pr_converge_skill_constants/AGENTS.md +26 -0
- package/skills/pr-converge/pr_converge_skill_constants/CLAUDE.md +1 -26
- package/skills/pr-converge/reference/AGENTS.md +28 -0
- package/skills/pr-converge/reference/CLAUDE.md +1 -28
- package/skills/pr-converge/reference/obstacles/AGENTS.md +23 -0
- package/skills/pr-converge/reference/obstacles/CLAUDE.md +1 -23
- package/skills/pr-converge/reference/progress-checklist.md +6 -5
- package/skills/pr-converge/reference/state-schema.md +1 -27
- package/skills/pr-converge/scripts/AGENTS.md +46 -0
- package/skills/pr-converge/scripts/CLAUDE.md +1 -46
- package/skills/pr-converge/scripts/pr_converge_scripts_constants/AGENTS.md +18 -0
- package/skills/pr-converge/scripts/pr_converge_scripts_constants/CLAUDE.md +1 -18
- package/skills/pr-converge/workflows/AGENTS.md +16 -0
- package/skills/pr-converge/workflows/CLAUDE.md +1 -16
- package/skills/pr-loop-cloud-transport/SKILL.md +1 -1
- package/skills/pr-loop-cloud-transport/reference/identity-and-hooks.md +3 -3
- package/skills/pr-loop-lifecycle/SKILL.md +1 -1
- package/skills/pr-loop-lifecycle/reference/teardown-publish-permissions.md +1 -1
- package/skills/prototype/SKILL.md +4 -4
- package/skills/prototype/reference/honest-limitations.md +5 -5
- package/skills/prototype/reference/promotion-tasks.md +2 -2
- package/skills/prototype/workflows/promotion.md +4 -6
- package/skills/rebase/AGENTS.md +32 -0
- package/skills/rebase/CLAUDE.md +1 -32
- package/skills/recall/AGENTS.md +30 -0
- package/skills/recall/CLAUDE.md +1 -30
- package/skills/remember/AGENTS.md +31 -0
- package/skills/remember/CLAUDE.md +1 -31
- package/skills/reviews/SKILL.md +85 -0
- package/skills/session-log/AGENTS.md +32 -0
- package/skills/session-log/CLAUDE.md +1 -32
- package/skills/session-tidy/AGENTS.md +36 -0
- package/skills/session-tidy/CLAUDE.md +1 -36
- package/skills/skill-builder/AGENTS.md +49 -0
- package/skills/skill-builder/CLAUDE.md +1 -49
- package/skills/skill-builder/references/AGENTS.md +25 -0
- package/skills/skill-builder/references/CLAUDE.md +1 -25
- package/skills/skill-builder/references/deterministic-elements.md +1 -1
- package/skills/skill-builder/templates/AGENTS.md +14 -0
- package/skills/skill-builder/templates/CLAUDE.md +1 -14
- package/skills/skill-builder/workflows/AGENTS.md +19 -0
- package/skills/skill-builder/workflows/CLAUDE.md +1 -19
- package/skills/small-cl/SKILL.md +52 -0
- package/skills/task-build/AGENTS.md +29 -0
- package/skills/task-build/CLAUDE.md +1 -29
- package/skills/update/AGENTS.md +38 -0
- package/skills/update/CLAUDE.md +1 -38
- package/system-prompts/AGENTS.md +17 -0
- package/system-prompts/CLAUDE.md +1 -17
- package/system-prompts/software-engineer.xml +3 -3
- package/agents/code-verifier.md +0 -74
- package/docs/PR_DESCRIPTION_GUIDE.md +0 -157
- package/docs/references/code-review-enforcement.md +0 -132
- package/hooks/blocking/code_review_enforcement_config_bootstrap.py +0 -53
- package/hooks/blocking/code_review_gate_deny.py +0 -74
- package/hooks/blocking/code_review_pr_create_gate.py +0 -198
- package/hooks/blocking/code_review_push_gate.py +0 -145
- package/hooks/blocking/code_review_stamp_directory_write_blocker.py +0 -348
- package/hooks/blocking/code_review_stamp_store.py +0 -233
- package/hooks/blocking/code_review_stamp_write_blocker_parts/__init__.py +0 -7
- package/hooks/blocking/code_review_stamp_write_blocker_parts/conftest.py +0 -15
- package/hooks/blocking/code_review_stamp_write_blocker_parts/obfuscated_stamp_path_reference.py +0 -212
- package/hooks/blocking/code_review_stamp_write_blocker_parts/split_directory_change_into_stamp.py +0 -138
- package/hooks/blocking/code_review_stamp_write_blocker_parts/test_obfuscated_stamp_path_reference.py +0 -49
- package/hooks/blocking/code_review_stamp_write_blocker_parts/test_split_directory_change_into_stamp.py +0 -38
- package/hooks/blocking/code_verifier_spawn_preflight_gate.py +0 -483
- package/hooks/blocking/config/code_review_enforcement_constants.py +0 -143
- package/hooks/blocking/config/test_code_review_enforcement_constants.py +0 -166
- package/hooks/blocking/config/verified_commit_constants.py +0 -160
- package/hooks/blocking/config/verified_commit_context_constants.py +0 -21
- package/hooks/blocking/config/verified_commit_gate_output_constants.py +0 -14
- package/hooks/blocking/conftest.py +0 -123
- package/hooks/blocking/convergence_gate_blocker.py +0 -310
- package/hooks/blocking/pr_converge_bugteam_enforcer.py +0 -170
- package/hooks/blocking/pr_description_body_audit.py +0 -148
- package/hooks/blocking/pr_description_command_parser.py +0 -237
- package/hooks/blocking/pr_description_enforcer.py +0 -227
- package/hooks/blocking/pr_description_pr_number.py +0 -155
- package/hooks/blocking/pr_description_proof_of_work.py +0 -385
- package/hooks/blocking/pr_description_readability.py +0 -364
- package/hooks/blocking/reviewer_spawn_gate.py +0 -182
- package/hooks/blocking/test_code_review_enforcement_config_bootstrap.py +0 -62
- package/hooks/blocking/test_code_review_gate_deny.py +0 -54
- package/hooks/blocking/test_code_review_pr_create_gate.py +0 -199
- package/hooks/blocking/test_code_review_push_gate.py +0 -205
- package/hooks/blocking/test_code_review_stamp_directory_write_blocker.py +0 -199
- package/hooks/blocking/test_code_review_stamp_store.py +0 -205
- package/hooks/blocking/test_code_verifier_spawn_preflight_gate.py +0 -710
- package/hooks/blocking/test_code_verifier_tools_contract.py +0 -28
- package/hooks/blocking/test_convergence_gate_blocker.py +0 -428
- package/hooks/blocking/test_pr_converge_bugteam_enforcer.py +0 -311
- package/hooks/blocking/test_pr_converge_bugteam_enforcer_state_tolerance.py +0 -184
- package/hooks/blocking/test_pr_description_enforcer.py +0 -221
- package/hooks/blocking/test_pr_description_enforcer_body_audit.py +0 -247
- package/hooks/blocking/test_pr_description_enforcer_body_rules.py +0 -493
- package/hooks/blocking/test_pr_description_enforcer_command_parser.py +0 -366
- package/hooks/blocking/test_pr_description_enforcer_pr_number.py +0 -159
- package/hooks/blocking/test_pr_description_enforcer_proof_gate.py +0 -175
- package/hooks/blocking/test_pr_description_enforcer_readability.py +0 -443
- package/hooks/blocking/test_pr_description_proof_of_work.py +0 -313
- package/hooks/blocking/test_reviewer_spawn_gate.py +0 -230
- package/hooks/blocking/test_verdict_directory_write_blocker.py +0 -804
- package/hooks/blocking/test_verification_verdict_store.py +0 -974
- package/hooks/blocking/test_verified_commit_config_bootstrap.py +0 -67
- package/hooks/blocking/test_verified_commit_docs_delta.py +0 -176
- package/hooks/blocking/test_verified_commit_gate.py +0 -581
- package/hooks/blocking/test_verified_commit_gate_additional_context.py +0 -134
- package/hooks/blocking/test_verified_commit_message_accuracy_blocker.py +0 -131
- package/hooks/blocking/test_verifier_verdict_minter.py +0 -299
- package/hooks/blocking/tests/test_verified_commit_gate.py +0 -41
- package/hooks/blocking/verdict_directory_write_blocker.py +0 -687
- package/hooks/blocking/verification_verdict_store.py +0 -1039
- package/hooks/blocking/verified_commit_config_bootstrap.py +0 -63
- package/hooks/blocking/verified_commit_gate.py +0 -113
- package/hooks/blocking/verified_commit_gate_parts/CLAUDE.md +0 -28
- package/hooks/blocking/verified_commit_gate_parts/__init__.py +0 -1
- package/hooks/blocking/verified_commit_gate_parts/command_tokenization.py +0 -174
- package/hooks/blocking/verified_commit_gate_parts/deny_payload.py +0 -53
- package/hooks/blocking/verified_commit_gate_parts/deny_reason.py +0 -80
- package/hooks/blocking/verified_commit_gate_parts/directory_resolution.py +0 -170
- package/hooks/blocking/verified_commit_gate_parts/gated_invocations.py +0 -217
- package/hooks/blocking/verified_commit_gate_parts/tests/conftest.py +0 -10
- package/hooks/blocking/verified_commit_gate_parts/tests/test_command_tokenization.py +0 -94
- package/hooks/blocking/verified_commit_gate_parts/tests/test_deny_payload.py +0 -17
- package/hooks/blocking/verified_commit_gate_parts/tests/test_deny_reason.py +0 -38
- package/hooks/blocking/verified_commit_gate_parts/tests/test_directory_resolution.py +0 -71
- package/hooks/blocking/verified_commit_gate_parts/tests/test_gated_invocations.py +0 -96
- package/hooks/blocking/verified_commit_message_accuracy_blocker.py +0 -167
- package/hooks/blocking/verifier_verdict_minter.py +0 -280
- package/hooks/hooks_constants/code_verifier_spawn_preflight_gate_constants.py +0 -64
- package/hooks/hooks_constants/convergence_gate_blocker_constants.py +0 -53
- package/hooks/hooks_constants/pr_converge_bugteam_enforcer_constants.py +0 -55
- package/hooks/hooks_constants/pr_converge_bugteam_enforcer_state.py +0 -67
- package/hooks/hooks_constants/pr_description_enforcer_constants.py +0 -167
- package/hooks/hooks_constants/pr_description_proof_of_work_constants.py +0 -107
- package/hooks/hooks_constants/reviewer_spawn_gate_constants.py +0 -41
- package/hooks/hooks_constants/test_pr_description_enforcer_constants.py +0 -292
- package/hooks/lifecycle/pr_converge_bugteam_skill_tracker.py +0 -198
- package/hooks/lifecycle/test_pr_converge_bugteam_skill_tracker.py +0 -283
- package/rules/proof-of-work-pr-comments.md +0 -22
- package/rules/verified-commit-gate-skip.md +0 -4
- package/scripts/Show-Asset.ps1 +0 -106
|
@@ -1,10 +1,4 @@
|
|
|
1
|
-
"""Specifications for
|
|
2
|
-
|
|
3
|
-
Enforcement refuses every push until a clean stamp covers the branch surface,
|
|
4
|
-
and ``invoke_code_review.py --record-stamp`` is the only way to mint one. When
|
|
5
|
-
that call cannot run, the reason it names is the person's only route back to a
|
|
6
|
-
working push.
|
|
7
|
-
"""
|
|
1
|
+
"""Specifications for code-review error reporting and review-loop outcomes."""
|
|
8
2
|
|
|
9
3
|
from __future__ import annotations
|
|
10
4
|
|
|
@@ -13,8 +7,7 @@ from pathlib import Path
|
|
|
13
7
|
import pytest
|
|
14
8
|
|
|
15
9
|
import invoke_code_review as invoker
|
|
16
|
-
from claude_chain_runner import
|
|
17
|
-
from _code_review_test_support import FIXTURE_SESSION_OPUS
|
|
10
|
+
from claude_chain_runner import ChainInvocationOutcome
|
|
18
11
|
from dev_env_scripts_constants.claude_chain_constants import TERMINAL_STATUS_SERVED
|
|
19
12
|
from dev_env_scripts_constants.code_review_constants import (
|
|
20
13
|
ALL_FINDING_SEVERITIES,
|
|
@@ -52,8 +45,7 @@ from dev_env_scripts_constants.code_review_constants import (
|
|
|
52
45
|
def test_review_arguments_carry_the_permission_mode_this_caller_resolves() -> None:
|
|
53
46
|
"""The review command asks for a permission mode the binary accepts here.
|
|
54
47
|
|
|
55
|
-
The binary refuses the bypass mode outright for a root caller
|
|
56
|
-
for it there means no review runs and no stamp is ever minted.
|
|
48
|
+
The binary refuses the bypass mode outright for a root caller.
|
|
57
49
|
"""
|
|
58
50
|
all_arguments = invoker.build_code_review_arguments(DEFAULT_CODE_REVIEW_EFFORT)
|
|
59
51
|
|
|
@@ -104,8 +96,8 @@ def test_failed_review_reports_what_the_served_binary_wrote(
|
|
|
104
96
|
"""A review that a served binary refused names the refusal.
|
|
105
97
|
|
|
106
98
|
The binary can decline for reasons the caller must act on, such as a
|
|
107
|
-
permission mode it will not accept. Dropping its words leaves a bare
|
|
108
|
-
|
|
99
|
+
permission mode it will not accept. Dropping its words leaves a bare exit
|
|
100
|
+
code without a usable recovery step.
|
|
109
101
|
"""
|
|
110
102
|
monkeypatch.setattr(
|
|
111
103
|
invoker, "_run_claude_with_empty_stdin", _serve_a_refusing_binary
|
|
@@ -122,54 +114,6 @@ def test_failed_review_reports_what_the_served_binary_wrote(
|
|
|
122
114
|
assert REVIEW_BINARY_REFUSAL_TEXT in captured_streams.err
|
|
123
115
|
|
|
124
116
|
|
|
125
|
-
def test_missing_chain_config_reports_its_remedy_on_stderr(
|
|
126
|
-
monkeypatch: pytest.MonkeyPatch,
|
|
127
|
-
tmp_path: Path,
|
|
128
|
-
capsys: pytest.CaptureFixture[str],
|
|
129
|
-
) -> None:
|
|
130
|
-
def raise_chain_configuration_error(**_all_keyword_arguments: object) -> None:
|
|
131
|
-
raise ChainConfigurationError(CHAIN_CONFIG_REMEDY_TEXT)
|
|
132
|
-
|
|
133
|
-
monkeypatch.setattr(
|
|
134
|
-
invoker, "invoke_code_review_and_record_stamp", raise_chain_configuration_error
|
|
135
|
-
)
|
|
136
|
-
|
|
137
|
-
outcome = invoker._mint_or_config_outcome(
|
|
138
|
-
working_directory=tmp_path,
|
|
139
|
-
session_model=FIXTURE_SESSION_OPUS,
|
|
140
|
-
timeout_seconds=MINT_TIMEOUT_SECONDS,
|
|
141
|
-
effort=DEFAULT_CODE_REVIEW_EFFORT,
|
|
142
|
-
)
|
|
143
|
-
|
|
144
|
-
captured_streams = capsys.readouterr()
|
|
145
|
-
assert outcome.is_stamp_minted is False
|
|
146
|
-
assert CHAIN_CONFIG_REMEDY_TEXT in captured_streams.err
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
def test_host_profile_failure_reports_its_reason_on_stderr(
|
|
150
|
-
monkeypatch: pytest.MonkeyPatch,
|
|
151
|
-
tmp_path: Path,
|
|
152
|
-
capsys: pytest.CaptureFixture[str],
|
|
153
|
-
) -> None:
|
|
154
|
-
def raise_host_profile_error(**_all_keyword_arguments: object) -> None:
|
|
155
|
-
raise ValueError(HOST_PROFILE_FAILURE_TEXT)
|
|
156
|
-
|
|
157
|
-
monkeypatch.setattr(
|
|
158
|
-
invoker, "invoke_code_review_and_record_stamp", raise_host_profile_error
|
|
159
|
-
)
|
|
160
|
-
|
|
161
|
-
outcome = invoker._mint_or_config_outcome(
|
|
162
|
-
working_directory=tmp_path,
|
|
163
|
-
session_model=FIXTURE_SESSION_OPUS,
|
|
164
|
-
timeout_seconds=MINT_TIMEOUT_SECONDS,
|
|
165
|
-
effort=DEFAULT_CODE_REVIEW_EFFORT,
|
|
166
|
-
)
|
|
167
|
-
|
|
168
|
-
captured_streams = capsys.readouterr()
|
|
169
|
-
assert outcome.is_stamp_minted is False
|
|
170
|
-
assert HOST_PROFILE_FAILURE_TEXT in captured_streams.err
|
|
171
|
-
|
|
172
|
-
|
|
173
117
|
HEAD_SHA_ONE: str = "aaa111"
|
|
174
118
|
HEAD_SHA_TWO: str = "bbb222"
|
|
175
119
|
HEAD_SHA_THREE: str = "ccc333"
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
"""CLI JSON output for in-session, error,
|
|
1
|
+
"""CLI JSON output for in-session, error, and effort paths."""
|
|
2
2
|
|
|
3
3
|
from __future__ import annotations
|
|
4
4
|
|
|
@@ -9,8 +9,6 @@ import pytest
|
|
|
9
9
|
|
|
10
10
|
import invoke_code_review as invoker
|
|
11
11
|
from _code_review_test_support import (
|
|
12
|
-
DriftingReview,
|
|
13
|
-
EFFORT_LOW,
|
|
14
12
|
FIXTURE_CHAIN_CONFIG_ERROR_MESSAGE,
|
|
15
13
|
FIXTURE_HOST_PROFILE_ERROR_MESSAGE,
|
|
16
14
|
FIXTURE_SESSION_OPUS,
|
|
@@ -19,8 +17,6 @@ from _code_review_test_support import (
|
|
|
19
17
|
REJECTED_ULTRA_EFFORT,
|
|
20
18
|
init_git_repository,
|
|
21
19
|
install_seams,
|
|
22
|
-
prepared_surface_repo,
|
|
23
|
-
run_record_stamp_cli,
|
|
24
20
|
run_review_cli,
|
|
25
21
|
)
|
|
26
22
|
from claude_chain_runner import ChainConfigurationError
|
|
@@ -32,17 +28,12 @@ from dev_env_scripts_constants.code_review_constants import (
|
|
|
32
28
|
HOST_PROFILE_ERROR_RETURNCODE,
|
|
33
29
|
IN_SESSION_RETURNCODE,
|
|
34
30
|
INVALID_EFFORT_RETURNCODE,
|
|
35
|
-
MAXIMUM_STAMP_MINT_PASSES,
|
|
36
31
|
MODE_CHAIN,
|
|
37
32
|
MODE_IN_SESSION,
|
|
38
|
-
RESULT_KEY_BOUND_HASH,
|
|
39
33
|
RESULT_KEY_DIRTY_TREE,
|
|
40
34
|
RESULT_KEY_MODE,
|
|
41
|
-
RESULT_KEY_PASS_COUNT,
|
|
42
35
|
RESULT_KEY_RETURNCODE,
|
|
43
36
|
RESULT_KEY_SERVED_COMMAND,
|
|
44
|
-
RESULT_KEY_STAMP_MINTED,
|
|
45
|
-
STAMP_DID_NOT_CONVERGE_RETURNCODE,
|
|
46
37
|
)
|
|
47
38
|
from dev_env_scripts_constants.grok_worker_constants import CWD_FLAG
|
|
48
39
|
|
|
@@ -103,7 +94,6 @@ def test_cli_emits_json_on_chain_configuration_error(
|
|
|
103
94
|
returncode=CHAIN_CONFIG_ERROR_EXIT_CODE,
|
|
104
95
|
is_dirty_tree=False,
|
|
105
96
|
)
|
|
106
|
-
assert invoker.is_code_review_clean_stamp_allowed(config_error_outcome) is False
|
|
107
97
|
|
|
108
98
|
|
|
109
99
|
def test_cli_emits_json_on_host_profile_value_error(
|
|
@@ -156,37 +146,3 @@ def test_cli_rejects_ultra_effort_with_nonzero_exit(
|
|
|
156
146
|
)
|
|
157
147
|
assert exit_code == INVALID_EFFORT_RETURNCODE
|
|
158
148
|
assert REJECTED_ULTRA_EFFORT in capsys.readouterr().err
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
def test_cli_record_stamp_returns_non_convergence_code_on_cap(
|
|
162
|
-
monkeypatch: pytest.MonkeyPatch,
|
|
163
|
-
tmp_path: Path,
|
|
164
|
-
capsys: pytest.CaptureFixture[str],
|
|
165
|
-
) -> None:
|
|
166
|
-
working_directory = prepared_surface_repo(monkeypatch, tmp_path)
|
|
167
|
-
monkeypatch.setattr(invoker, "invoke_code_review", DriftingReview())
|
|
168
|
-
exit_code = run_record_stamp_cli(working_directory, effort=EFFORT_LOW)
|
|
169
|
-
assert exit_code == STAMP_DID_NOT_CONVERGE_RETURNCODE
|
|
170
|
-
parsed_payload = json.loads(capsys.readouterr().out)
|
|
171
|
-
assert parsed_payload[RESULT_KEY_STAMP_MINTED] is False
|
|
172
|
-
assert parsed_payload[RESULT_KEY_PASS_COUNT] == MAXIMUM_STAMP_MINT_PASSES
|
|
173
|
-
assert parsed_payload[RESULT_KEY_BOUND_HASH] is None
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
def test_cli_record_stamp_reports_missing_store_dependency(
|
|
177
|
-
monkeypatch: pytest.MonkeyPatch,
|
|
178
|
-
tmp_path: Path,
|
|
179
|
-
capsys: pytest.CaptureFixture[str],
|
|
180
|
-
) -> None:
|
|
181
|
-
def raise_missing_store(*all_args: object, **all_keywords: object) -> object:
|
|
182
|
-
del all_args, all_keywords
|
|
183
|
-
raise ModuleNotFoundError("store missing", name="code_review_stamp_store")
|
|
184
|
-
|
|
185
|
-
working_directory = prepared_surface_repo(monkeypatch, tmp_path)
|
|
186
|
-
monkeypatch.setattr(invoker, "load_code_review_stamp_store", raise_missing_store)
|
|
187
|
-
exit_code = run_record_stamp_cli(working_directory, effort=EFFORT_LOW)
|
|
188
|
-
assert exit_code == INVALID_EFFORT_RETURNCODE
|
|
189
|
-
captured = capsys.readouterr()
|
|
190
|
-
assert "stamp store" in captured.err
|
|
191
|
-
parsed_payload = json.loads(captured.out)
|
|
192
|
-
assert parsed_payload[RESULT_KEY_STAMP_MINTED] is False
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
"""Argument contract, encoding,
|
|
1
|
+
"""Argument contract, outcome encoding, and effort-token behavior."""
|
|
2
2
|
|
|
3
3
|
from __future__ import annotations
|
|
4
4
|
|
|
@@ -8,40 +8,30 @@ import pytest
|
|
|
8
8
|
|
|
9
9
|
import invoke_code_review as invoker
|
|
10
10
|
from _code_review_test_support import (
|
|
11
|
-
DriftingReview,
|
|
12
11
|
EFFORT_LOW,
|
|
13
12
|
FIXTURE_CHAIN_RETURNCODE,
|
|
14
13
|
FIXTURE_FAILED_RETURNCODE,
|
|
15
14
|
FIXTURE_SERVED_COMMAND,
|
|
16
15
|
FIXTURE_SESSION_OPUS,
|
|
17
16
|
HOST_PROFILE_THIRD_PARTY,
|
|
18
|
-
MISSING_STORE_FILE_NAME,
|
|
19
17
|
REJECTED_ULTRA_EFFORT,
|
|
20
|
-
SINGLE_PASS_CAP,
|
|
21
18
|
claude_failed,
|
|
22
19
|
init_git_repository,
|
|
23
20
|
install_seams,
|
|
24
|
-
prepared_surface_repo,
|
|
25
21
|
run_review,
|
|
26
|
-
stable_clean_review,
|
|
27
|
-
surface_changing_review,
|
|
28
22
|
)
|
|
29
23
|
from dev_env_scripts_constants.code_review_constants import (
|
|
30
24
|
CODE_REVIEW_MODEL_ALIAS,
|
|
31
25
|
DEFAULT_CODE_REVIEW_EFFORT,
|
|
32
26
|
IN_SESSION_RETURNCODE,
|
|
33
|
-
MAXIMUM_STAMP_MINT_PASSES,
|
|
34
27
|
MODE_CHAIN,
|
|
35
28
|
MODE_IN_SESSION,
|
|
36
29
|
REVIEW_PERMISSION_MODE as PERMISSION_MODE_BYPASS,
|
|
37
30
|
PERMISSION_MODE_FLAG,
|
|
38
|
-
RESULT_KEY_BOUND_HASH,
|
|
39
31
|
RESULT_KEY_DIRTY_TREE,
|
|
40
32
|
RESULT_KEY_MODE,
|
|
41
|
-
RESULT_KEY_PASS_COUNT,
|
|
42
33
|
RESULT_KEY_RETURNCODE,
|
|
43
34
|
RESULT_KEY_SERVED_COMMAND,
|
|
44
|
-
RESULT_KEY_STAMP_MINTED,
|
|
45
35
|
)
|
|
46
36
|
from dev_env_scripts_constants.grok_worker_constants import (
|
|
47
37
|
MODEL_FLAG,
|
|
@@ -109,16 +99,6 @@ def test_chain_failure_preserves_returncode(
|
|
|
109
99
|
assert review_outcome.returncode == FIXTURE_FAILED_RETURNCODE
|
|
110
100
|
assert review_outcome.is_dirty_tree is False
|
|
111
101
|
assert invoker.is_successful_code_review(review_outcome) is False
|
|
112
|
-
assert invoker.is_code_review_clean_stamp_allowed(review_outcome) is False
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
def test_clean_stamp_allowed_only_on_successful_clean_serve() -> None:
|
|
116
|
-
assert invoker.is_code_review_clean_stamp_allowed(CLEAN_SUCCESS_OUTCOME) is True
|
|
117
|
-
assert invoker.is_code_review_clean_stamp_allowed(DIRTY_SUCCESS_OUTCOME) is False
|
|
118
|
-
assert invoker.is_code_review_clean_stamp_allowed(FAILED_SERVE_OUTCOME) is False
|
|
119
|
-
assert invoker.is_code_review_clean_stamp_allowed(IN_SESSION_READY_OUTCOME) is True
|
|
120
|
-
assert invoker.is_successful_code_review(FAILED_SERVE_OUTCOME) is False
|
|
121
|
-
assert invoker.is_successful_code_review(CLEAN_SUCCESS_OUTCOME) is True
|
|
122
102
|
|
|
123
103
|
|
|
124
104
|
def test_encode_code_review_outcome_shape() -> None:
|
|
@@ -157,100 +137,3 @@ def test_validate_effort_token_rejects_unknown_token() -> None:
|
|
|
157
137
|
def test_build_code_review_prompt_reads_as_slash_command() -> None:
|
|
158
138
|
assert invoker.build_code_review_prompt(EFFORT_LOW) == "/code-review low --fix"
|
|
159
139
|
assert invoker.build_code_review_prompt("xhigh") == "/code-review xhigh --fix"
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
def test_encode_stamp_mint_outcome_includes_mint_metadata() -> None:
|
|
163
|
-
review_outcome = invoker.CodeReviewOutcome(
|
|
164
|
-
mode=MODE_CHAIN,
|
|
165
|
-
served_command=FIXTURE_SERVED_COMMAND,
|
|
166
|
-
returncode=FIXTURE_CHAIN_RETURNCODE,
|
|
167
|
-
is_dirty_tree=False,
|
|
168
|
-
)
|
|
169
|
-
mint_outcome = invoker.StampMintOutcome(
|
|
170
|
-
review_outcome=review_outcome,
|
|
171
|
-
is_stamp_minted=True,
|
|
172
|
-
pass_count=SINGLE_PASS_CAP,
|
|
173
|
-
bound_hash="abc123",
|
|
174
|
-
)
|
|
175
|
-
encoded_payload = invoker.encode_stamp_mint_outcome(mint_outcome)
|
|
176
|
-
assert encoded_payload[RESULT_KEY_STAMP_MINTED] is True
|
|
177
|
-
assert encoded_payload[RESULT_KEY_PASS_COUNT] == SINGLE_PASS_CAP
|
|
178
|
-
assert encoded_payload[RESULT_KEY_BOUND_HASH] == "abc123"
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
def test_record_stamp_mints_on_surface_stable_clean_pass(
|
|
182
|
-
monkeypatch: pytest.MonkeyPatch, tmp_path: Path
|
|
183
|
-
) -> None:
|
|
184
|
-
working_directory = prepared_surface_repo(monkeypatch, tmp_path)
|
|
185
|
-
monkeypatch.setattr(invoker, "invoke_code_review", stable_clean_review)
|
|
186
|
-
mint_outcome = invoker.invoke_code_review_and_record_stamp(
|
|
187
|
-
working_directory=working_directory,
|
|
188
|
-
session_model=CODE_REVIEW_MODEL_ALIAS,
|
|
189
|
-
timeout_seconds=DEFAULT_CODE_REVIEW_TIMEOUT_SECONDS,
|
|
190
|
-
effort=EFFORT_LOW,
|
|
191
|
-
)
|
|
192
|
-
assert mint_outcome.is_stamp_minted is True
|
|
193
|
-
assert mint_outcome.bound_hash is not None
|
|
194
|
-
store_module = invoker.load_code_review_stamp_store()
|
|
195
|
-
assert store_module.stamp_covers_surface(
|
|
196
|
-
str(working_directory), mint_outcome.bound_hash, EFFORT_LOW
|
|
197
|
-
)
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
def test_record_stamp_does_not_mint_when_review_changes_surface(
|
|
201
|
-
monkeypatch: pytest.MonkeyPatch, tmp_path: Path
|
|
202
|
-
) -> None:
|
|
203
|
-
working_directory = prepared_surface_repo(monkeypatch, tmp_path)
|
|
204
|
-
monkeypatch.setattr(invoker, "invoke_code_review", surface_changing_review)
|
|
205
|
-
mint_outcome = invoker.invoke_code_review_and_record_stamp(
|
|
206
|
-
working_directory=working_directory,
|
|
207
|
-
session_model=CODE_REVIEW_MODEL_ALIAS,
|
|
208
|
-
timeout_seconds=DEFAULT_CODE_REVIEW_TIMEOUT_SECONDS,
|
|
209
|
-
effort=EFFORT_LOW,
|
|
210
|
-
maximum_passes=SINGLE_PASS_CAP,
|
|
211
|
-
)
|
|
212
|
-
assert mint_outcome.is_stamp_minted is False
|
|
213
|
-
assert mint_outcome.pass_count == SINGLE_PASS_CAP
|
|
214
|
-
assert mint_outcome.bound_hash is None
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
def test_record_stamp_hits_cap_without_minting(
|
|
218
|
-
monkeypatch: pytest.MonkeyPatch, tmp_path: Path
|
|
219
|
-
) -> None:
|
|
220
|
-
working_directory = prepared_surface_repo(monkeypatch, tmp_path)
|
|
221
|
-
monkeypatch.setattr(invoker, "invoke_code_review", DriftingReview())
|
|
222
|
-
mint_outcome = invoker.invoke_code_review_and_record_stamp(
|
|
223
|
-
working_directory=working_directory,
|
|
224
|
-
session_model=CODE_REVIEW_MODEL_ALIAS,
|
|
225
|
-
timeout_seconds=DEFAULT_CODE_REVIEW_TIMEOUT_SECONDS,
|
|
226
|
-
effort=EFFORT_LOW,
|
|
227
|
-
maximum_passes=MAXIMUM_STAMP_MINT_PASSES,
|
|
228
|
-
)
|
|
229
|
-
assert mint_outcome.is_stamp_minted is False
|
|
230
|
-
assert mint_outcome.pass_count == MAXIMUM_STAMP_MINT_PASSES
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
def test_load_code_review_stamp_store_records_and_covers_surface(
|
|
234
|
-
monkeypatch: pytest.MonkeyPatch, tmp_path: Path
|
|
235
|
-
) -> None:
|
|
236
|
-
working_directory = prepared_surface_repo(monkeypatch, tmp_path)
|
|
237
|
-
store_module = invoker.load_code_review_stamp_store()
|
|
238
|
-
surface_hash = store_module.live_surface_hash(str(working_directory))
|
|
239
|
-
assert surface_hash is not None
|
|
240
|
-
stamp_path = store_module.record_clean_stamp(
|
|
241
|
-
str(working_directory), surface_hash, EFFORT_LOW
|
|
242
|
-
)
|
|
243
|
-
assert stamp_path.exists()
|
|
244
|
-
assert store_module.stamp_covers_surface(
|
|
245
|
-
str(working_directory), surface_hash, EFFORT_LOW
|
|
246
|
-
)
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
def test_load_code_review_stamp_store_raises_when_file_absent(
|
|
250
|
-
monkeypatch: pytest.MonkeyPatch,
|
|
251
|
-
) -> None:
|
|
252
|
-
monkeypatch.setattr(
|
|
253
|
-
invoker, "STAMP_STORE_MODULE_FILE_NAME", MISSING_STORE_FILE_NAME
|
|
254
|
-
)
|
|
255
|
-
with pytest.raises(ModuleNotFoundError):
|
|
256
|
-
invoker.load_code_review_stamp_store()
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
import subprocess
|
|
2
|
+
from pathlib import Path
|
|
3
|
+
|
|
4
|
+
from validate_instruction_pairs import validate_repository
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
def initialize_repository(repository_root: Path) -> None:
|
|
8
|
+
subprocess.run(["git", "init", "--quiet"], cwd=repository_root, check=True)
|
|
9
|
+
subprocess.run(
|
|
10
|
+
["git", "config", "user.email", "tests@example.com"],
|
|
11
|
+
cwd=repository_root,
|
|
12
|
+
check=True,
|
|
13
|
+
)
|
|
14
|
+
subprocess.run(
|
|
15
|
+
["git", "config", "user.name", "Instruction tests"],
|
|
16
|
+
cwd=repository_root,
|
|
17
|
+
check=True,
|
|
18
|
+
)
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
def stage_instruction_files(repository_root: Path) -> None:
|
|
22
|
+
subprocess.run(["git", "add", "AGENTS.md", "CLAUDE.md"], cwd=repository_root, check=True)
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
def test_exact_import_passes(tmp_path: Path) -> None:
|
|
26
|
+
initialize_repository(tmp_path)
|
|
27
|
+
(tmp_path / "AGENTS.md").write_bytes(b"# Canonical guidance\n")
|
|
28
|
+
(tmp_path / "CLAUDE.md").write_bytes(b"@AGENTS.md\n")
|
|
29
|
+
stage_instruction_files(tmp_path)
|
|
30
|
+
|
|
31
|
+
assert validate_repository(tmp_path) == []
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
def test_claude_context_fails_exact_import_check(tmp_path: Path) -> None:
|
|
35
|
+
initialize_repository(tmp_path)
|
|
36
|
+
(tmp_path / "AGENTS.md").write_bytes(b"# Canonical guidance\n")
|
|
37
|
+
(tmp_path / "CLAUDE.md").write_bytes(b"@AGENTS.md\n\nExtra context\n")
|
|
38
|
+
stage_instruction_files(tmp_path)
|
|
39
|
+
|
|
40
|
+
all_errors = validate_repository(tmp_path)
|
|
41
|
+
|
|
42
|
+
assert any("exactly import" in each_error for each_error in all_errors)
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
def test_nearest_ancestor_import_passes(tmp_path: Path) -> None:
|
|
46
|
+
initialize_repository(tmp_path)
|
|
47
|
+
nested_directory = tmp_path / ".claude"
|
|
48
|
+
nested_directory.mkdir()
|
|
49
|
+
(tmp_path / "AGENTS.md").write_bytes(b"# Canonical guidance\n")
|
|
50
|
+
(nested_directory / "CLAUDE.md").write_bytes(b"@../AGENTS.md\n")
|
|
51
|
+
subprocess.run(["git", "add", "AGENTS.md", ".claude/CLAUDE.md"], cwd=tmp_path, check=True)
|
|
52
|
+
|
|
53
|
+
assert validate_repository(tmp_path) == []
|
|
54
|
+
|
|
55
|
+
|
|
56
|
+
def test_crlf_import_fails_line_ending_check(tmp_path: Path) -> None:
|
|
57
|
+
initialize_repository(tmp_path)
|
|
58
|
+
(tmp_path / "AGENTS.md").write_bytes(b"# Canonical guidance\n")
|
|
59
|
+
(tmp_path / "CLAUDE.md").write_bytes(b"@AGENTS.md\r\n")
|
|
60
|
+
stage_instruction_files(tmp_path)
|
|
61
|
+
|
|
62
|
+
all_errors = validate_repository(tmp_path)
|
|
63
|
+
|
|
64
|
+
assert any("exactly import" in each_error for each_error in all_errors)
|
|
65
|
+
|
|
66
|
+
|
|
67
|
+
def test_executable_import_fails_git_mode_check(tmp_path: Path) -> None:
|
|
68
|
+
initialize_repository(tmp_path)
|
|
69
|
+
(tmp_path / "AGENTS.md").write_bytes(b"# Canonical guidance\n")
|
|
70
|
+
(tmp_path / "CLAUDE.md").write_bytes(b"@AGENTS.md\n")
|
|
71
|
+
stage_instruction_files(tmp_path)
|
|
72
|
+
subprocess.run(
|
|
73
|
+
["git", "update-index", "--chmod=+x", "CLAUDE.md"],
|
|
74
|
+
cwd=tmp_path,
|
|
75
|
+
check=True,
|
|
76
|
+
)
|
|
77
|
+
|
|
78
|
+
all_errors = validate_repository(tmp_path)
|
|
79
|
+
|
|
80
|
+
assert any("Git mode 100644" in each_error for each_error in all_errors)
|
|
81
|
+
|
|
82
|
+
|
|
83
|
+
def test_untracked_import_fails_tracking_check(tmp_path: Path) -> None:
|
|
84
|
+
initialize_repository(tmp_path)
|
|
85
|
+
(tmp_path / "AGENTS.md").write_bytes(b"# Canonical guidance\n")
|
|
86
|
+
(tmp_path / "CLAUDE.md").write_bytes(b"@AGENTS.md\n")
|
|
87
|
+
|
|
88
|
+
all_errors = validate_repository(tmp_path)
|
|
89
|
+
|
|
90
|
+
assert any("Git mode 100644" in each_error for each_error in all_errors)
|
|
@@ -31,6 +31,7 @@ def test_load_manifest_lists_hooks_and_claude_md() -> None:
|
|
|
31
31
|
all_root_files = mod.required_root_file_names(manifest)
|
|
32
32
|
assert "hooks" in all_directories
|
|
33
33
|
assert "output-styles" in all_directories
|
|
34
|
+
assert "AGENTS.md" in all_root_files
|
|
34
35
|
assert "CLAUDE.md" in all_root_files
|
|
35
36
|
assert MANIFEST_FILENAME in all_root_files
|
|
36
37
|
|
|
@@ -58,10 +59,12 @@ def test_surface_appears_in_tarball_members_for_directory_children() -> None:
|
|
|
58
59
|
all_members = frozenset(
|
|
59
60
|
{
|
|
60
61
|
f"{TARBALL_PACKAGE_PREFIX}hooks/hooks.json",
|
|
62
|
+
f"{TARBALL_PACKAGE_PREFIX}AGENTS.md",
|
|
61
63
|
f"{TARBALL_PACKAGE_PREFIX}CLAUDE.md",
|
|
62
64
|
}
|
|
63
65
|
)
|
|
64
66
|
assert mod.surface_appears_in_tarball_members("hooks", all_members)
|
|
67
|
+
assert mod.surface_appears_in_tarball_members("AGENTS.md", all_members)
|
|
65
68
|
assert mod.surface_appears_in_tarball_members("CLAUDE.md", all_members)
|
|
66
69
|
assert not mod.surface_appears_in_tarball_members("missing-dir", all_members)
|
|
67
70
|
|
|
@@ -69,11 +72,12 @@ def test_surface_appears_in_tarball_members_for_directory_children() -> None:
|
|
|
69
72
|
def test_missing_manifest_surfaces_in_tarball_reports_absent_root_file() -> None:
|
|
70
73
|
manifest = {
|
|
71
74
|
"directories": ["hooks"],
|
|
72
|
-
"root_files": ["CLAUDE.md", "codex-capability-map.json"],
|
|
75
|
+
"root_files": ["AGENTS.md", "CLAUDE.md", "codex-capability-map.json"],
|
|
73
76
|
}
|
|
74
77
|
all_members = frozenset(
|
|
75
78
|
{
|
|
76
79
|
f"{TARBALL_PACKAGE_PREFIX}hooks/hooks.json",
|
|
80
|
+
f"{TARBALL_PACKAGE_PREFIX}AGENTS.md",
|
|
77
81
|
f"{TARBALL_PACKAGE_PREFIX}CLAUDE.md",
|
|
78
82
|
}
|
|
79
83
|
)
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
# scripts/tests
|
|
2
|
+
|
|
3
|
+
pytest suite for the Python scripts and Pester suite for the PowerShell scripts in `scripts/`.
|
|
4
|
+
|
|
5
|
+
## Test files
|
|
6
|
+
|
|
7
|
+
| File | Covers |
|
|
8
|
+
|---|---|
|
|
9
|
+
| `test_setup_project_paths.py` | `setup_project_paths.py` — discovery, filtering, and `project-paths.json` writing |
|
|
10
|
+
| `test_setup_project_paths_config.py` | Configuration constants used by `setup_project_paths.py` |
|
|
11
|
+
| `test_sweep_empty_dirs.py` | `sweep_empty_dirs.py` — age check, one-shot mode, and continuous-watch behavior |
|
|
12
|
+
| `test_sync_to_cursor.py` | `sync_to_cursor/` package — mapping, hashing, manifest, and path resolution |
|
|
13
|
+
| `test_grok_worker_constants.py` | `grok_worker_constants.py` — the accepted batch worker-key set stays in step with the worker key constants, and the unknown-key message names both its placeholders |
|
|
14
|
+
|
|
15
|
+
## PowerShell test files
|
|
16
|
+
|
|
17
|
+
| File | Covers |
|
|
18
|
+
|---|---|
|
|
19
|
+
| `Get-SessionAccount.Tests.ps1` | `Get-SessionAccount.ps1` — noise filtering, profile-storage email recovery, CLI-vs-desktop account resolution, and output formatting |
|
|
20
|
+
|
|
21
|
+
## Running
|
|
22
|
+
|
|
23
|
+
Python scripts (pytest):
|
|
24
|
+
|
|
25
|
+
```bash
|
|
26
|
+
python -m pytest packages/claude-dev-env/scripts/tests/
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
PowerShell scripts (Pester 5+, `*.Tests.ps1`):
|
|
30
|
+
|
|
31
|
+
```powershell
|
|
32
|
+
Invoke-Pester -Path packages/claude-dev-env/scripts/tests/
|
|
33
|
+
```
|
package/scripts/tests/CLAUDE.md
CHANGED
|
@@ -1,33 +1 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
pytest suite for the Python scripts and Pester suite for the PowerShell scripts in `scripts/`.
|
|
4
|
-
|
|
5
|
-
## Test files
|
|
6
|
-
|
|
7
|
-
| File | Covers |
|
|
8
|
-
|---|---|
|
|
9
|
-
| `test_setup_project_paths.py` | `setup_project_paths.py` — discovery, filtering, and `project-paths.json` writing |
|
|
10
|
-
| `test_setup_project_paths_config.py` | Configuration constants used by `setup_project_paths.py` |
|
|
11
|
-
| `test_sweep_empty_dirs.py` | `sweep_empty_dirs.py` — age check, one-shot mode, and continuous-watch behavior |
|
|
12
|
-
| `test_sync_to_cursor.py` | `sync_to_cursor/` package — mapping, hashing, manifest, and path resolution |
|
|
13
|
-
| `test_grok_worker_constants.py` | `grok_worker_constants.py` — the accepted batch worker-key set stays in step with the worker key constants, and the unknown-key message names both its placeholders |
|
|
14
|
-
|
|
15
|
-
## PowerShell test files
|
|
16
|
-
|
|
17
|
-
| File | Covers |
|
|
18
|
-
|---|---|
|
|
19
|
-
| `Get-SessionAccount.Tests.ps1` | `Get-SessionAccount.ps1` — noise filtering, profile-storage email recovery, CLI-vs-desktop account resolution, and output formatting |
|
|
20
|
-
|
|
21
|
-
## Running
|
|
22
|
-
|
|
23
|
-
Python scripts (pytest):
|
|
24
|
-
|
|
25
|
-
```bash
|
|
26
|
-
python -m pytest packages/claude-dev-env/scripts/tests/
|
|
27
|
-
```
|
|
28
|
-
|
|
29
|
-
PowerShell scripts (Pester 5+, `*.Tests.ps1`):
|
|
30
|
-
|
|
31
|
-
```powershell
|
|
32
|
-
Invoke-Pester -Path packages/claude-dev-env/scripts/tests/
|
|
33
|
-
```
|
|
1
|
+
@AGENTS.md
|
|
@@ -77,6 +77,42 @@ def test_discover_agents_returns_sorted_parsed_agents(tmp_path: Path) -> None:
|
|
|
77
77
|
assert [agent.name for agent in agents] == ["Alpha", "Zulu"]
|
|
78
78
|
|
|
79
79
|
|
|
80
|
+
def test_discover_agents_skips_instruction_aliases_and_keeps_real_agents(
|
|
81
|
+
tmp_path: Path,
|
|
82
|
+
) -> None:
|
|
83
|
+
source = tmp_path / "source"
|
|
84
|
+
source.mkdir()
|
|
85
|
+
(source / "real-agent.md").write_text(
|
|
86
|
+
"---\nname: Real Agent\ndescription: real\n---\n",
|
|
87
|
+
encoding="utf-8",
|
|
88
|
+
)
|
|
89
|
+
(source / "CLAUDE.md").write_text("# Guidance\n", encoding="utf-8")
|
|
90
|
+
try:
|
|
91
|
+
(source / "AGENTS.md").symlink_to("CLAUDE.md")
|
|
92
|
+
except OSError as error:
|
|
93
|
+
pytest.skip(f"symlinks unavailable: {error}")
|
|
94
|
+
|
|
95
|
+
agents = materializer.discover_agents(MaterializerConfig(source, tmp_path / "target"))
|
|
96
|
+
|
|
97
|
+
assert [agent.name for agent in agents] == ["Real Agent"]
|
|
98
|
+
|
|
99
|
+
|
|
100
|
+
def test_discover_agents_rejects_non_alias_reparse_points(tmp_path: Path) -> None:
|
|
101
|
+
source = tmp_path / "source"
|
|
102
|
+
source.mkdir()
|
|
103
|
+
(source / "real-agent.md").write_text(
|
|
104
|
+
"---\nname: Real Agent\ndescription: real\n---\n",
|
|
105
|
+
encoding="utf-8",
|
|
106
|
+
)
|
|
107
|
+
try:
|
|
108
|
+
(source / "linked-agent.md").symlink_to("real-agent.md")
|
|
109
|
+
except OSError as error:
|
|
110
|
+
pytest.skip(f"symlinks unavailable: {error}")
|
|
111
|
+
|
|
112
|
+
with pytest.raises(MaterializerError, match="source reparse point is not allowed"):
|
|
113
|
+
materializer.discover_agents(MaterializerConfig(source, tmp_path / "target"))
|
|
114
|
+
|
|
115
|
+
|
|
80
116
|
def test_content_to_bytes_preserves_bytes_and_encodes_text() -> None:
|
|
81
117
|
assert content_to_bytes(b"payload") == b"payload"
|
|
82
118
|
assert content_to_bytes("payload") == b"payload"
|
|
@@ -662,4 +698,3 @@ def test_frontmatter_rejects_non_string_name() -> None:
|
|
|
662
698
|
"---\nname: 1\ndescription: y\n---\n",
|
|
663
699
|
"bad.md",
|
|
664
700
|
)
|
|
665
|
-
|