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
|
@@ -22,9 +22,8 @@ object name is the base when no default-branch ref resolves and when the
|
|
|
22
22
|
pushed branch is the default branch. When every remote object name is zero
|
|
23
23
|
(new branch) or stdin is empty, the gate falls back to the remote's default
|
|
24
24
|
branch symbolic ref. When a default-branch ref resolves and git still reports
|
|
25
|
-
no merge base, the base
|
|
26
|
-
a printed reason
|
|
27
|
-
a rebased tip would re-flag replayed commits.
|
|
25
|
+
no merge base, the base stays pending and the hook reports the infrastructure
|
|
26
|
+
status with a printed reason, preserving the scope boundary for rebased tips.
|
|
28
27
|
|
|
29
28
|
Gate scope: the gate process this hook launches diffs its `--base` against the
|
|
30
29
|
current checkout's HEAD, so the surface is the commits between that base and
|
|
@@ -32,40 +31,33 @@ HEAD. A push whose pushed object is HEAD reads as the branch's own work; a
|
|
|
32
31
|
push of any other object is still scoped to HEAD.
|
|
33
32
|
|
|
34
33
|
Exit codes:
|
|
35
|
-
0 - the push destination is allowed and its commits pass the gate
|
|
36
|
-
|
|
37
|
-
default-branch ref resolved and git still reported no merge base).
|
|
34
|
+
0 - the push destination is allowed and its commits pass the gate, or the
|
|
35
|
+
gate is not installed.
|
|
38
36
|
1 - the push would land a non-protected local branch onto a protected
|
|
39
37
|
remote branch, or a commit introduces a blocking violation.
|
|
40
|
-
2 -
|
|
41
|
-
stdin carried no parseable line,
|
|
42
|
-
|
|
38
|
+
2 - infrastructure attention is required because a subprocess could not
|
|
39
|
+
launch, stdin carried no parseable line, a base could not be resolved,
|
|
40
|
+
or a usable commit name could not be produced.
|
|
43
41
|
"""
|
|
44
42
|
|
|
45
43
|
from __future__ import annotations
|
|
46
44
|
|
|
47
|
-
import importlib.util
|
|
48
|
-
import os
|
|
49
45
|
import subprocess
|
|
50
46
|
import sys
|
|
51
47
|
from pathlib import Path
|
|
52
48
|
from typing import NamedTuple
|
|
53
49
|
|
|
50
|
+
from gate_utils import is_safe_regular_file, resolve_gate_script_path
|
|
54
51
|
from git_hooks_constants import (
|
|
55
|
-
|
|
52
|
+
ALL_FALLBACK_REMOTE_DEFAULT_BRANCH_NAMES,
|
|
56
53
|
ALL_GIT_MERGE_BASE_COMMAND_PREFIX,
|
|
57
54
|
ALL_GIT_SYMBOLIC_REFERENCE_COMMAND_PREFIX,
|
|
58
55
|
ALL_GIT_VERIFY_REFERENCE_COMMAND_PREFIX,
|
|
59
56
|
ALL_PROTECTED_BRANCH_PUSH_NAMES,
|
|
60
57
|
ALL_ZEROS_OBJECT_NAME_CHARACTER,
|
|
61
58
|
BASE_REFERENCE_ARGUMENT,
|
|
62
|
-
BLOCKING_DIRECTORY_NAME,
|
|
63
|
-
CODE_REVIEW_DENY_REASON_FUNCTION_NAME,
|
|
64
|
-
CODE_REVIEW_PUSH_GATE_MODULE_NAME,
|
|
65
|
-
CODE_REVIEW_PUSH_GATE_PATH_OVERRIDE_ENV_VAR,
|
|
66
|
-
CODE_REVIEW_PUSH_GATE_SCRIPT_FILENAME,
|
|
67
|
-
CODE_REVIEW_STAMP_BLOCK_EXIT_CODE,
|
|
68
59
|
DEFAULT_REMOTE_BASE_REFERENCE,
|
|
60
|
+
DEFAULT_REMOTE_NAME,
|
|
69
61
|
GATE_INFRASTRUCTURE_FAILURE_EXIT_CODE,
|
|
70
62
|
GIT_COMMAND_TIMEOUT_SECONDS,
|
|
71
63
|
GIT_COMMAND_UNAVAILABLE_MESSAGE,
|
|
@@ -80,11 +72,10 @@ from git_hooks_constants import (
|
|
|
80
72
|
MALFORMED_STDIN_LINE_MESSAGE,
|
|
81
73
|
NO_PARSEABLE_STDIN_LINES_MESSAGE,
|
|
82
74
|
NO_PARSEABLE_STDIN_LINES_SENTINEL,
|
|
83
|
-
ORIGIN_HEAD_SYMBOLIC_REFERENCE,
|
|
84
|
-
ORIGIN_REMOTE_TRACKING_REFERENCE_PREFIX,
|
|
85
75
|
PRE_PUSH_GATE_SCRIPT_NOT_FOUND_MESSAGE,
|
|
86
76
|
PROTECTED_BRANCH_PUSH_BLOCK_EXIT_CODE,
|
|
87
77
|
PROTECTED_BRANCH_PUSH_BLOCK_MESSAGE,
|
|
78
|
+
REMOTE_BRANCH_REFERENCE_TEMPLATE,
|
|
88
79
|
REMOTE_REFERENCE_FIELD_INDEX,
|
|
89
80
|
STDIN_LINE_FIELD_COUNT,
|
|
90
81
|
STDIN_READ_FAILURE_MESSAGE,
|
|
@@ -92,7 +83,6 @@ from git_hooks_constants import (
|
|
|
92
83
|
UNRESOLVABLE_MERGE_BASE_MESSAGE,
|
|
93
84
|
UNRESOLVABLE_MERGE_BASE_SENTINEL,
|
|
94
85
|
)
|
|
95
|
-
from gate_utils import is_safe_regular_file, resolve_gate_script_path
|
|
96
86
|
from pre_push_base_reference import (
|
|
97
87
|
resolve_remote_name_from_arguments,
|
|
98
88
|
resolve_usable_base_reference,
|
|
@@ -302,24 +292,24 @@ def run_git_reference_query(all_git_arguments: tuple[str, ...]) -> str | None:
|
|
|
302
292
|
return decoded_output.strip() or None
|
|
303
293
|
|
|
304
294
|
|
|
305
|
-
def resolve_default_branch_reference() -> str | None:
|
|
295
|
+
def resolve_default_branch_reference(remote_name: str = DEFAULT_REMOTE_NAME) -> str | None:
|
|
306
296
|
"""Return the remote-tracking ref name of the remote's default branch.
|
|
307
297
|
|
|
308
|
-
The remote's HEAD symbolic ref answers first. When it is unset,
|
|
309
|
-
|
|
298
|
+
The remote's HEAD symbolic ref answers first. When it is unset, the
|
|
299
|
+
supported default-branch tracking refs answer in turn.
|
|
310
300
|
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
over ``origin/master``, so a repo whose default is another branch beside a
|
|
314
|
-
legacy ``main`` resolves the wrong base ΓÇö the assumption set tracked at
|
|
315
|
-
~/.claude/orchestrator-runs/falsify-first/parked-items.md row 3.
|
|
301
|
+
Args:
|
|
302
|
+
remote_name: Remote whose default branch provides the gate base.
|
|
316
303
|
|
|
317
304
|
Returns:
|
|
318
305
|
A remote-tracking ref name, or None when no default-branch ref
|
|
319
306
|
resolves.
|
|
320
307
|
"""
|
|
308
|
+
remote_head_reference = REMOTE_BRANCH_REFERENCE_TEMPLATE.format(
|
|
309
|
+
remote=remote_name, branch="HEAD"
|
|
310
|
+
)
|
|
321
311
|
symbolic_reference = run_git_reference_query(
|
|
322
|
-
(*ALL_GIT_SYMBOLIC_REFERENCE_COMMAND_PREFIX,
|
|
312
|
+
(*ALL_GIT_SYMBOLIC_REFERENCE_COMMAND_PREFIX, remote_head_reference)
|
|
323
313
|
)
|
|
324
314
|
if symbolic_reference is not None:
|
|
325
315
|
verified_symbolic_target = run_git_reference_query(
|
|
@@ -327,7 +317,10 @@ def resolve_default_branch_reference() -> str | None:
|
|
|
327
317
|
)
|
|
328
318
|
if verified_symbolic_target is not None:
|
|
329
319
|
return symbolic_reference
|
|
330
|
-
for
|
|
320
|
+
for each_branch_name in ALL_FALLBACK_REMOTE_DEFAULT_BRANCH_NAMES:
|
|
321
|
+
each_candidate_reference = REMOTE_BRANCH_REFERENCE_TEMPLATE.format(
|
|
322
|
+
remote=remote_name, branch=each_branch_name
|
|
323
|
+
)
|
|
331
324
|
verified_reference = run_git_reference_query(
|
|
332
325
|
(*ALL_GIT_VERIFY_REFERENCE_COMMAND_PREFIX, each_candidate_reference)
|
|
333
326
|
)
|
|
@@ -368,7 +361,9 @@ def find_branch_update_push(stdin_text: str) -> PushLine | None:
|
|
|
368
361
|
|
|
369
362
|
|
|
370
363
|
def resolve_default_branch_merge_base(
|
|
371
|
-
remote_branch_name: str,
|
|
364
|
+
remote_branch_name: str,
|
|
365
|
+
pushed_object_name: str,
|
|
366
|
+
remote_name: str = DEFAULT_REMOTE_NAME,
|
|
372
367
|
) -> str | None:
|
|
373
368
|
"""Return the merge base of the pushed object and the default branch.
|
|
374
369
|
|
|
@@ -379,6 +374,7 @@ def resolve_default_branch_merge_base(
|
|
|
379
374
|
Args:
|
|
380
375
|
remote_branch_name: The remote branch the push updates.
|
|
381
376
|
pushed_object_name: The object name the push carries.
|
|
377
|
+
remote_name: The remote whose default branch provides the gate base.
|
|
382
378
|
|
|
383
379
|
Returns:
|
|
384
380
|
The merge-base object name; None when no default-branch ref resolves or
|
|
@@ -386,12 +382,13 @@ def resolve_default_branch_merge_base(
|
|
|
386
382
|
no merge base applies; or the unresolvable-merge-base sentinel when a
|
|
387
383
|
default-branch ref resolves and git still reports no merge base.
|
|
388
384
|
"""
|
|
389
|
-
default_branch_reference = resolve_default_branch_reference()
|
|
385
|
+
default_branch_reference = resolve_default_branch_reference(remote_name)
|
|
390
386
|
if default_branch_reference is None:
|
|
391
387
|
return None
|
|
392
|
-
|
|
393
|
-
|
|
388
|
+
default_branch_prefix = REMOTE_BRANCH_REFERENCE_TEMPLATE.format(
|
|
389
|
+
remote=remote_name, branch=""
|
|
394
390
|
)
|
|
391
|
+
default_branch_name = default_branch_reference.removeprefix(default_branch_prefix)
|
|
395
392
|
if remote_branch_name == default_branch_name:
|
|
396
393
|
return None
|
|
397
394
|
# Anchors to the pushed object; deferring to the gate's HEAD-based merge-base would change behavior on non-HEAD pushes.
|
|
@@ -407,7 +404,9 @@ def resolve_default_branch_merge_base(
|
|
|
407
404
|
return merge_base_object_name
|
|
408
405
|
|
|
409
406
|
|
|
410
|
-
def resolve_gate_base_reference(
|
|
407
|
+
def resolve_gate_base_reference(
|
|
408
|
+
stdin_text: str, remote_name: str = DEFAULT_REMOTE_NAME
|
|
409
|
+
) -> str | None:
|
|
411
410
|
"""Return the reference the gate scopes its changed lines to.
|
|
412
411
|
|
|
413
412
|
A branch update reads from the merge base with the remote default branch,
|
|
@@ -422,20 +421,24 @@ def resolve_gate_base_reference(stdin_text: str) -> str | None:
|
|
|
422
421
|
|
|
423
422
|
Args:
|
|
424
423
|
stdin_text: The pre-push stdin payload.
|
|
424
|
+
remote_name: The remote whose default branch provides the gate base.
|
|
425
425
|
|
|
426
426
|
Returns:
|
|
427
427
|
The gate's base reference, the no-parseable-lines sentinel, the
|
|
428
428
|
unresolvable-merge-base sentinel, or None when the push only deletes
|
|
429
429
|
remote branches.
|
|
430
430
|
"""
|
|
431
|
-
return _resolve_gate_base_from_parsed(_parse_push_stdin(stdin_text))
|
|
431
|
+
return _resolve_gate_base_from_parsed(_parse_push_stdin(stdin_text), remote_name)
|
|
432
432
|
|
|
433
433
|
|
|
434
|
-
def _resolve_gate_base_from_parsed(
|
|
434
|
+
def _resolve_gate_base_from_parsed(
|
|
435
|
+
parsed_stdin: ParsedPushStdin, remote_name: str = DEFAULT_REMOTE_NAME
|
|
436
|
+
) -> str | None:
|
|
435
437
|
"""Return the gate's base reference for an already-parsed stdin payload.
|
|
436
438
|
|
|
437
439
|
Args:
|
|
438
440
|
parsed_stdin: The parsed stdin payload.
|
|
441
|
+
remote_name: The remote whose default branch provides the gate base.
|
|
439
442
|
|
|
440
443
|
Returns:
|
|
441
444
|
The merge base with the remote default branch for a branch update, the
|
|
@@ -448,7 +451,9 @@ def _resolve_gate_base_from_parsed(parsed_stdin: ParsedPushStdin) -> str | None:
|
|
|
448
451
|
if branch_update is None:
|
|
449
452
|
return _resolve_base_reference_from_lines(parsed_stdin)
|
|
450
453
|
merge_base_object_name = resolve_default_branch_merge_base(
|
|
451
|
-
branch_update.remote_branch_name,
|
|
454
|
+
branch_update.remote_branch_name,
|
|
455
|
+
branch_update.local_object_name,
|
|
456
|
+
remote_name,
|
|
452
457
|
)
|
|
453
458
|
if merge_base_object_name is None:
|
|
454
459
|
return branch_update.remote_object_name
|
|
@@ -509,80 +514,6 @@ def invoke_gate(gate_script_path: Path, base_reference: str) -> int:
|
|
|
509
514
|
return completion.returncode
|
|
510
515
|
|
|
511
516
|
|
|
512
|
-
def resolve_code_review_gate_path() -> tuple[Path, Path | None]:
|
|
513
|
-
"""Return the code-review push gate script path and its exact-allow override.
|
|
514
|
-
|
|
515
|
-
The override environment variable, when set, names the only path the trust
|
|
516
|
-
check accepts; otherwise the gate script resolves to the ``blocking``
|
|
517
|
-
directory beside this hook's ``git-hooks`` directory, which holds in both
|
|
518
|
-
the repository layout and the installed ``~/.claude/hooks`` layout.
|
|
519
|
-
|
|
520
|
-
Returns:
|
|
521
|
-
A pair of the resolved gate script path and either the exact override
|
|
522
|
-
path (override set) or None (trust-root case).
|
|
523
|
-
"""
|
|
524
|
-
override_path_raw = os.environ.get(
|
|
525
|
-
CODE_REVIEW_PUSH_GATE_PATH_OVERRIDE_ENV_VAR, ""
|
|
526
|
-
).strip()
|
|
527
|
-
if override_path_raw:
|
|
528
|
-
exact_override = Path(override_path_raw).resolve()
|
|
529
|
-
return exact_override, exact_override
|
|
530
|
-
blocking_directory = Path(__file__).resolve().parent.parent / BLOCKING_DIRECTORY_NAME
|
|
531
|
-
return blocking_directory / CODE_REVIEW_PUSH_GATE_SCRIPT_FILENAME, None
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
def load_code_review_deny_reason(gate_script_path: Path, work_tree_directory: str) -> str | None:
|
|
535
|
-
"""Import the gate script and read its push deny reason for a work tree.
|
|
536
|
-
|
|
537
|
-
Any import or evaluation failure reads as no deny reason.
|
|
538
|
-
|
|
539
|
-
Args:
|
|
540
|
-
gate_script_path: The resolved code-review push gate script path.
|
|
541
|
-
work_tree_directory: The work tree the push targets.
|
|
542
|
-
|
|
543
|
-
Returns:
|
|
544
|
-
The gate's deny reason when the surface lacks a covering low stamp;
|
|
545
|
-
None when the gate allows the push or could not be evaluated.
|
|
546
|
-
"""
|
|
547
|
-
try:
|
|
548
|
-
gate_specification = importlib.util.spec_from_file_location(
|
|
549
|
-
CODE_REVIEW_PUSH_GATE_MODULE_NAME, str(gate_script_path)
|
|
550
|
-
)
|
|
551
|
-
if gate_specification is None or gate_specification.loader is None:
|
|
552
|
-
return None
|
|
553
|
-
gate_module = importlib.util.module_from_spec(gate_specification)
|
|
554
|
-
gate_specification.loader.exec_module(gate_module)
|
|
555
|
-
deny_reason_function = getattr(gate_module, CODE_REVIEW_DENY_REASON_FUNCTION_NAME, None)
|
|
556
|
-
if deny_reason_function is None:
|
|
557
|
-
return None
|
|
558
|
-
deny_reason = deny_reason_function(work_tree_directory)
|
|
559
|
-
except Exception:
|
|
560
|
-
return None
|
|
561
|
-
if isinstance(deny_reason, str) and deny_reason:
|
|
562
|
-
return deny_reason
|
|
563
|
-
return None
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
def code_review_stamp_block_exit_code() -> int:
|
|
567
|
-
"""Block the push when no clean low code-review stamp covers the surface.
|
|
568
|
-
|
|
569
|
-
Runs the gate decision only when the gate script sits at a trusted
|
|
570
|
-
installed location (or the exact override path). When the gate is absent
|
|
571
|
-
from a trusted location, the check is skipped and the push is allowed,
|
|
572
|
-
matching the CODE_RULES gate's fail-open posture.
|
|
573
|
-
|
|
574
|
-
Returns:
|
|
575
|
-
The block exit code when a covering low stamp is missing; 0 when the
|
|
576
|
-
surface is covered or the gate is not installed at a trusted location.
|
|
577
|
-
"""
|
|
578
|
-
gate_script_path, exact_allowed_path = resolve_code_review_gate_path()
|
|
579
|
-
if not is_safe_regular_file(gate_script_path, exact_allowed_path):
|
|
580
|
-
return 0
|
|
581
|
-
deny_reason = load_code_review_deny_reason(gate_script_path, os.getcwd())
|
|
582
|
-
if deny_reason is None:
|
|
583
|
-
return 0
|
|
584
|
-
sys.stderr.write(deny_reason + "\n")
|
|
585
|
-
return CODE_REVIEW_STAMP_BLOCK_EXIT_CODE
|
|
586
517
|
|
|
587
518
|
|
|
588
519
|
def main() -> int:
|
|
@@ -623,8 +554,9 @@ def main() -> int:
|
|
|
623
554
|
pre_push_gate_script_not_found_message.format(path=gate_script_path),
|
|
624
555
|
file=sys.stderr,
|
|
625
556
|
)
|
|
626
|
-
return
|
|
627
|
-
|
|
557
|
+
return 0
|
|
558
|
+
remote_name = resolve_remote_name_from_arguments(sys.argv)
|
|
559
|
+
base_reference = _resolve_gate_base_from_parsed(parsed_stdin, remote_name)
|
|
628
560
|
if base_reference is None:
|
|
629
561
|
return 0
|
|
630
562
|
if base_reference == no_parseable_stdin_lines_sentinel:
|
|
@@ -632,8 +564,7 @@ def main() -> int:
|
|
|
632
564
|
return gate_infrastructure_failure_exit_code
|
|
633
565
|
if base_reference == unresolvable_merge_base_sentinel:
|
|
634
566
|
print(unresolvable_merge_base_message, file=sys.stderr)
|
|
635
|
-
return
|
|
636
|
-
remote_name = resolve_remote_name_from_arguments(sys.argv)
|
|
567
|
+
return gate_infrastructure_failure_exit_code
|
|
637
568
|
try:
|
|
638
569
|
usable_base_reference = resolve_usable_base_reference(
|
|
639
570
|
base_reference, remote_name, run_git_text_command
|
|
@@ -645,7 +576,7 @@ def main() -> int:
|
|
|
645
576
|
code_rules_exit_code = invoke_gate(gate_script_path, usable_base_reference)
|
|
646
577
|
if code_rules_exit_code != 0:
|
|
647
578
|
return code_rules_exit_code
|
|
648
|
-
return
|
|
579
|
+
return 0
|
|
649
580
|
|
|
650
581
|
|
|
651
582
|
if __name__ == "__main__":
|