claude-dev-env 4.3.0 → 7.0.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/agents/pr-description-writer.md +2 -2
- package/.agents/agents/test_agent_frontmatter.py +2 -2
- package/.agents/agents/test_pr_description_writer_style.py +1 -3
- package/.agents/skills/e-code-review/SKILL.md +12 -12
- package/.agents/skills/e-code-review/preflight-proposal.contract.test.mjs +20 -0
- package/.agents/skills/e-code-review/reference/fix.md +15 -17
- package/.agents/skills/e-code-review/reference/loop.md +35 -39
- package/.agents/skills/e-code-review/reference/mode-contract.test.mjs +2 -1
- package/.agents/skills/e-code-review/reference/preflight-proposal.md +44 -9
- package/.agents/skills/e-code-review/reference/runner-selection.md +13 -14
- package/.agents/skills/issue-tracker/SKILL.md +5 -4
- package/.agents/skills/pull-request/SKILL.md +11 -13
- package/.agents/skills/pull-request/reference/publication-tasks.md +3 -3
- package/.agents/skills/pull-request/scripts/github_pr_command_constants/config/constants.py +9 -1
- package/.agents/skills/pull-request/scripts/pull_request.py +33 -44
- package/.agents/skills/pull-request/scripts/test_github_pr_command_constants.py +9 -0
- package/.agents/skills/pull-request/scripts/test_pull_request.py +1 -3
- package/.agents/skills/skill-builder/SKILL.md +3 -196
- package/_shared/pr-loop/scripts/pr_loop_shared_constants/terminology_sweep_constants.py +6 -0
- package/_shared/pr-loop/scripts/terminology_sweep.py +64 -19
- package/_shared/pr-loop/scripts/tests/test_terminology_sweep.py +59 -0
- package/bin/install.agents-home.test.mjs +15 -13
- package/bin/install.mjs +28 -0
- package/bin/install.policy-lint.test.mjs +78 -0
- package/bin/install.prune.test.mjs +59 -20
- package/bin/install.pstack-plugin.test.mjs +114 -0
- package/bin/install.test.mjs +37 -0
- package/bin/refresh-pstack-plugin-skills.test.mjs +211 -0
- package/hooks/advisory/pr_done_reminder.py +342 -0
- package/hooks/advisory/test_pr_done_reminder.py +249 -0
- package/hooks/blocking/bash_post_call_dispatcher.py +53 -6
- package/hooks/blocking/code_rules_paired_test.py +22 -15
- package/hooks/blocking/test_bash_post_call_dispatcher.py +65 -4
- package/hooks/blocking/test_code_rules_enforcer_paired_test.py +36 -29
- package/hooks/blocking/test_code_rules_js_resume_task_enumeration.py +4 -4
- package/hooks/blocking/test_code_rules_js_returns_object_schemaless.py +5 -5
- package/hooks/blocking/test_pre_tool_use_dispatcher.py +68 -133
- package/hooks/blocking/test_pre_tool_use_dispatcher_native.py +20 -51
- package/hooks/blocking/test_precommit_code_rules_gate_native_owner.py +18 -18
- package/hooks/git-hooks/git_hooks_constants/staged_policy_lint.py +12 -0
- package/hooks/git-hooks/pre_commit.py +52 -11
- package/hooks/git-hooks/test_installed_policy_lint.py +159 -0
- package/hooks/git-hooks/test_native_policy_commit.py +87 -0
- package/hooks/git-hooks/test_pre_commit.py +246 -0
- package/hooks/hooks.json +1 -1
- package/hooks/hooks_constants/bash_post_call_dispatcher_constants.py +14 -1
- package/hooks/hooks_constants/pr_done_reminder_constants.py +98 -0
- package/hooks/hooks_constants/pre_tool_use_dispatcher_constants.py +10 -43
- package/hooks/hooks_constants/test_bash_post_call_dispatcher_constants.py +19 -2
- package/hooks/hooks_constants/test_pr_done_reminder_constants.py +40 -0
- package/hooks/hooks_constants/test_pre_tool_use_dispatcher_constants.py +20 -32
- package/package.json +2 -2
- package/rules/durable-post-artifacts.md +2 -1
- package/rules/git-workflow.md +6 -6
- package/scripts/check.ps1 +0 -1
- package/{.agents/skills/run-claude-dev-env/driver.mjs → scripts/ci/installer-lifecycle.mjs} +3 -28
- package/scripts/ci/installer-lifecycle.test.mjs +26 -0
- package/scripts/ci/windows-installer-lifecycle.ps1 +1 -11
- package/scripts/dev_env_scripts_constants/shared_tree_constants.py +4 -5
- package/{.agents/skills/_shared/pr-loop/scripts → scripts}/durable_post_lint.py +5 -41
- package/{.agents/skills/_shared/pr-loop/scripts/skills_pr_loop_constants/durable_post_lint_constants.py → scripts/durable_post_lint_config/config/constants.py} +0 -10
- package/{.agents/skills/_shared/pr-loop/scripts/test_durable_post_lint_constants.py → scripts/durable_post_lint_config/config/test_constants.py} +1 -1
- package/scripts/policy_lint/adapter_detectors.py +13 -6
- package/scripts/policy_lint/adapters.py +7 -4
- package/scripts/policy_lint/config/constants.py +5 -0
- package/scripts/policy_lint/engine.py +48 -4
- package/scripts/policy_lint/model.py +1 -0
- package/scripts/policy_lint/registry.py +1 -1
- package/scripts/policy_lint/selection.py +2 -1
- package/scripts/policy_lint/selection_git.py +2 -0
- package/scripts/refresh_pstack_plugin_skills.mjs +200 -0
- package/scripts/shared_tree_paths.py +32 -3
- package/scripts/test_shared_tree_paths.py +33 -0
- package/scripts/tests/test_policy_lint_rules_archive.py +120 -0
- package/scripts/tests/test_policy_lint_rules_engine.py +25 -4
- package/scripts/tests/test_policy_lint_rules_installed_loader.py +29 -0
- package/scripts/tests/test_policy_lint_rules_registry.py +227 -13
- package/scripts/tests/test_policy_lint_selection.py +25 -2
- package/scripts/tests/test_policy_lint_selection_native_index.py +30 -0
- package/scripts/tests/test_rules.py +3 -7
- package/.agents/skills/_shared/pr-loop/.claude/CLAUDE.md +0 -1
- package/.agents/skills/_shared/pr-loop/AGENTS.md +0 -1
- package/.agents/skills/_shared/pr-loop/audit-contract.md +0 -5
- package/.agents/skills/_shared/pr-loop/audit-reply-template.md +0 -5
- package/.agents/skills/_shared/pr-loop/code-rules-gate.md +0 -5
- package/.agents/skills/_shared/pr-loop/fix-protocol.md +0 -5
- package/.agents/skills/_shared/pr-loop/gh-payloads.md +0 -5
- package/.agents/skills/_shared/pr-loop/portable-driver.md +0 -149
- package/.agents/skills/_shared/pr-loop/post-audit-thread-contract.md +0 -5
- package/.agents/skills/_shared/pr-loop/precatch-rubric.md +0 -5
- package/.agents/skills/_shared/pr-loop/preflight-proposal.contract.test.mjs +0 -119
- package/.agents/skills/_shared/pr-loop/preflight-proposal.md +0 -5
- package/.agents/skills/_shared/pr-loop/prompts/.claude/CLAUDE.md +0 -1
- package/.agents/skills/_shared/pr-loop/prompts/AGENTS.md +0 -1
- package/.agents/skills/_shared/pr-loop/prompts/pr-consistency-audit.xml +0 -324
- package/.agents/skills/_shared/pr-loop/scripts/.claude/CLAUDE.md +0 -1
- package/.agents/skills/_shared/pr-loop/scripts/AGENTS.md +0 -1
- package/.agents/skills/_shared/pr-loop/scripts/RUNTIME_SCRIPTS.md +0 -29
- package/.agents/skills/_shared/pr-loop/scripts/_cli_utils.py +0 -22
- package/.agents/skills/_shared/pr-loop/scripts/_path_resolver.py +0 -186
- package/.agents/skills/_shared/pr-loop/scripts/_xml_utils.py +0 -20
- package/.agents/skills/_shared/pr-loop/scripts/audit_category_schema.py +0 -355
- package/.agents/skills/_shared/pr-loop/scripts/build_audit_prompt.py +0 -289
- package/.agents/skills/_shared/pr-loop/scripts/build_converge_task_list.py +0 -310
- package/.agents/skills/_shared/pr-loop/scripts/build_fix_prompt.py +0 -292
- package/.agents/skills/_shared/pr-loop/scripts/init_loop_state.py +0 -134
- package/.agents/skills/_shared/pr-loop/scripts/portable_converge_driver.py +0 -1646
- package/.agents/skills/_shared/pr-loop/scripts/preflight_worktree.py +0 -392
- package/.agents/skills/_shared/pr-loop/scripts/select_converge_pacer.py +0 -215
- package/.agents/skills/_shared/pr-loop/scripts/skills_pr_loop_constants/.claude/CLAUDE.md +0 -1
- package/.agents/skills/_shared/pr-loop/scripts/skills_pr_loop_constants/AGENTS.md +0 -1
- package/.agents/skills/_shared/pr-loop/scripts/skills_pr_loop_constants/__init__.py +0 -0
- package/.agents/skills/_shared/pr-loop/scripts/skills_pr_loop_constants/audit_category_schema_constants.py +0 -37
- package/.agents/skills/_shared/pr-loop/scripts/skills_pr_loop_constants/converge_task_list_constants.py +0 -56
- package/.agents/skills/_shared/pr-loop/scripts/skills_pr_loop_constants/handoff_constants.py +0 -45
- package/.agents/skills/_shared/pr-loop/scripts/skills_pr_loop_constants/pacer_constants.py +0 -47
- package/.agents/skills/_shared/pr-loop/scripts/skills_pr_loop_constants/path_resolver_constants.py +0 -157
- package/.agents/skills/_shared/pr-loop/scripts/skills_pr_loop_constants/portable_driver_constants.py +0 -177
- package/.agents/skills/_shared/pr-loop/scripts/skills_pr_loop_constants/preflight_constants.py +0 -70
- package/.agents/skills/_shared/pr-loop/scripts/teardown_worktrees.py +0 -172
- package/.agents/skills/_shared/pr-loop/scripts/test__path_resolver.py +0 -106
- package/.agents/skills/_shared/pr-loop/scripts/test_audit_category_schema.py +0 -94
- package/.agents/skills/_shared/pr-loop/scripts/test_build_audit_prompt.py +0 -499
- package/.agents/skills/_shared/pr-loop/scripts/test_build_converge_task_list.py +0 -140
- package/.agents/skills/_shared/pr-loop/scripts/test_build_fix_prompt.py +0 -262
- package/.agents/skills/_shared/pr-loop/scripts/test_init_loop_state.py +0 -71
- package/.agents/skills/_shared/pr-loop/scripts/test_portable_converge_driver.py +0 -1119
- package/.agents/skills/_shared/pr-loop/scripts/test_preflight_worktree.py +0 -287
- package/.agents/skills/_shared/pr-loop/scripts/test_select_converge_pacer.py +0 -207
- package/.agents/skills/_shared/pr-loop/scripts/test_teardown_worktrees.py +0 -59
- package/.agents/skills/_shared/pr-loop/scripts/test_write_handoff.py +0 -201
- package/.agents/skills/_shared/pr-loop/scripts/write_audit_outcomes.py +0 -182
- package/.agents/skills/_shared/pr-loop/scripts/write_fix_outcomes.py +0 -206
- package/.agents/skills/_shared/pr-loop/scripts/write_handoff.py +0 -309
- package/.agents/skills/_shared/pr-loop/state-schema.md +0 -5
- package/.agents/skills/_shared/pr-loop/worker-spawn.md +0 -5
- package/.agents/skills/autoconverge/.claude/CLAUDE.md +0 -1
- package/.agents/skills/autoconverge/AGENTS.md +0 -1
- package/.agents/skills/autoconverge/SKILL.md +0 -431
- package/.agents/skills/autoconverge/reference/.claude/CLAUDE.md +0 -1
- package/.agents/skills/autoconverge/reference/AGENTS.md +0 -1
- package/.agents/skills/autoconverge/reference/closing-report.md +0 -93
- package/.agents/skills/autoconverge/reference/convergence-gates.md +0 -31
- package/.agents/skills/autoconverge/reference/convergence.md +0 -219
- package/.agents/skills/autoconverge/reference/copilot-findings.md +0 -51
- package/.agents/skills/autoconverge/reference/gotchas.md +0 -66
- package/.agents/skills/autoconverge/reference/headless-safety.md +0 -44
- package/.agents/skills/autoconverge/reference/multi-pr.md +0 -128
- package/.agents/skills/autoconverge/reference/self-closing-loop.md +0 -84
- package/.agents/skills/autoconverge/reference/stop-conditions.md +0 -127
- package/.agents/skills/autoconverge/test_portable_pacer_gate.py +0 -54
- package/.agents/skills/autoconverge/workflow/.claude/CLAUDE.md +0 -1
- package/.agents/skills/autoconverge/workflow/AGENTS.md +0 -1
- package/.agents/skills/autoconverge/workflow/aggregate_runs.py +0 -371
- package/.agents/skills/autoconverge/workflow/autoconverge_report_constants/.claude/CLAUDE.md +0 -1
- package/.agents/skills/autoconverge/workflow/autoconverge_report_constants/AGENTS.md +0 -1
- package/.agents/skills/autoconverge/workflow/autoconverge_report_constants/__init__.py +0 -0
- package/.agents/skills/autoconverge/workflow/autoconverge_report_constants/render_report_constants.py +0 -250
- package/.agents/skills/autoconverge/workflow/converge.clean-audit.test.mjs +0 -665
- package/.agents/skills/autoconverge/workflow/converge.codex-gate.test.mjs +0 -472
- package/.agents/skills/autoconverge/workflow/converge.contract.test.mjs +0 -64
- package/.agents/skills/autoconverge/workflow/converge.copilot-gate.test.mjs +0 -1009
- package/.agents/skills/autoconverge/workflow/converge.fix-progress.test.mjs +0 -107
- package/.agents/skills/autoconverge/workflow/converge.fix-recovery.test.mjs +0 -33
- package/.agents/skills/autoconverge/workflow/converge.merge-conflict.test.mjs +0 -15
- package/.agents/skills/autoconverge/workflow/converge.mjs +0 -3132
- package/.agents/skills/autoconverge/workflow/converge.p2-advance.test.mjs +0 -202
- package/.agents/skills/autoconverge/workflow/converge.path-aware.test.mjs +0 -47
- package/.agents/skills/autoconverge/workflow/converge.precatch.test.mjs +0 -152
- package/.agents/skills/autoconverge/workflow/converge.run-input.test.mjs +0 -116
- package/.agents/skills/autoconverge/workflow/converge_multi.mjs +0 -169
- package/.agents/skills/autoconverge/workflow/converge_multi.run-input.test.mjs +0 -173
- package/.agents/skills/autoconverge/workflow/convergence_summary.py +0 -110
- package/.agents/skills/autoconverge/workflow/fixtures/wf_run/subagents/workflows/wf_881252e6-700/agent-a11d903476b803493.jsonl +0 -2
- package/.agents/skills/autoconverge/workflow/fixtures/wf_run/subagents/workflows/wf_881252e6-700/agent-a26213978adeef6fb.jsonl +0 -2
- package/.agents/skills/autoconverge/workflow/fixtures/wf_run/subagents/workflows/wf_881252e6-700/agent-a3def0d15ed9d9110.jsonl +0 -2
- package/.agents/skills/autoconverge/workflow/fixtures/wf_run/subagents/workflows/wf_881252e6-700/agent-a41f41b1b708ee3b7.jsonl +0 -2
- package/.agents/skills/autoconverge/workflow/fixtures/wf_run/subagents/workflows/wf_881252e6-700/agent-a758b880abecc3ff7.jsonl +0 -2
- package/.agents/skills/autoconverge/workflow/fixtures/wf_run/subagents/workflows/wf_881252e6-700/agent-a8897b89656b1bd16.jsonl +0 -2
- package/.agents/skills/autoconverge/workflow/fixtures/wf_run/subagents/workflows/wf_881252e6-700/agent-ab1c2d3e4f5a6b7c8.jsonl +0 -2
- package/.agents/skills/autoconverge/workflow/fixtures/wf_run/subagents/workflows/wf_881252e6-700/agent-abd463d744a1437bc.jsonl +0 -2
- package/.agents/skills/autoconverge/workflow/fixtures/wf_run/subagents/workflows/wf_881252e6-700/agent-ad19d027ae8ee1816.jsonl +0 -2
- package/.agents/skills/autoconverge/workflow/fixtures/wf_run/workflows/wf_881252e6-700.json +0 -266
- package/.agents/skills/autoconverge/workflow/render_report.py +0 -1024
- package/.agents/skills/autoconverge/workflow/test_aggregate_runs.py +0 -134
- package/.agents/skills/autoconverge/workflow/test_convergence_summary.py +0 -149
- package/.agents/skills/autoconverge/workflow/test_render_report.py +0 -812
- package/.agents/skills/hitl/SKILL.md +0 -45
- package/.agents/skills/pr-cleanup/SKILL.md +0 -140
- package/.agents/skills/pr-cleanup/reference/process-inventory.md +0 -17
- package/.agents/skills/pr-cleanup/reference/task-seeds.md +0 -22
- package/.agents/skills/pr-name-by-capability/SKILL.md +0 -73
- package/.agents/skills/pr-name-by-capability/reference/fetch-commands.md +0 -29
- package/.agents/skills/pr-name-by-capability/reference/offense-examples.md +0 -32
- package/.agents/skills/pr-name-by-capability/reference/report-template.md +0 -29
- package/.agents/skills/pr-name-by-capability/reference/rule-checklist.md +0 -38
- package/.agents/skills/pr-name-by-capability/reference/task-seeds.md +0 -10
- package/.agents/skills/pr-plain-language-cleanup/SKILL.md +0 -93
- package/.agents/skills/pr-refinement/SKILL.md +0 -31
- package/.agents/skills/pr-shared-extraction/SKILL.md +0 -177
- package/.agents/skills/pr-shared-extraction/reference/examples.md +0 -46
- package/.agents/skills/pr-shared-extraction/reference/offense-taxonomy.md +0 -100
- package/.agents/skills/pr-small-cl/SKILL.md +0 -52
- package/.agents/skills/pr-title-description/SKILL.md +0 -96
- package/.agents/skills/prototype/SKILL.md +0 -85
- package/.agents/skills/prototype/reference/honest-limitations.md +0 -23
- package/.agents/skills/prototype/reference/promotion-tasks.md +0 -23
- package/.agents/skills/prototype/scripts/build_sandbox_settings.py +0 -249
- package/.agents/skills/prototype/scripts/conftest.py +0 -15
- package/.agents/skills/prototype/scripts/launch_sandbox.py +0 -205
- package/.agents/skills/prototype/scripts/probe_sandbox_safety.py +0 -311
- package/.agents/skills/prototype/scripts/prototype_scripts_constants/__init__.py +0 -1
- package/.agents/skills/prototype/scripts/prototype_scripts_constants/config/__init__.py +0 -0
- package/.agents/skills/prototype/scripts/prototype_scripts_constants/config/build_sandbox_settings_constants.py +0 -41
- package/.agents/skills/prototype/scripts/prototype_scripts_constants/config/launch_sandbox_constants.py +0 -23
- package/.agents/skills/prototype/scripts/prototype_scripts_constants/config/probe_sandbox_safety_constants.py +0 -45
- package/.agents/skills/prototype/scripts/prototype_scripts_constants/config/prototype_common_constants.py +0 -10
- package/.agents/skills/prototype/scripts/test_build_sandbox_settings.py +0 -275
- package/.agents/skills/prototype/scripts/test_launch_sandbox.py +0 -303
- package/.agents/skills/prototype/scripts/test_probe_sandbox_safety.py +0 -312
- package/.agents/skills/prototype/workflows/promotion.md +0 -25
- package/.agents/skills/prototype/workflows/sandbox.md +0 -35
- package/.agents/skills/rebase/.claude/CLAUDE.md +0 -1
- package/.agents/skills/rebase/AGENTS.md +0 -1
- package/.agents/skills/rebase/SKILL.md +0 -178
- package/.agents/skills/review-router/SKILL.md +0 -51
- package/.agents/skills/review-router/reference/route-policy.json +0 -7
- package/.agents/skills/review-router/reference/task-seeds.md +0 -1
- package/.agents/skills/review-router/scripts/conftest.py +0 -4
- package/.agents/skills/review-router/scripts/review_router.py +0 -50
- package/.agents/skills/review-router/scripts/review_router_cli.py +0 -211
- package/.agents/skills/review-router/scripts/review_router_constants/__init__.py +0 -1
- package/.agents/skills/review-router/scripts/review_router_constants/config/__init__.py +0 -0
- package/.agents/skills/review-router/scripts/review_router_constants/config/constants.py +0 -13
- package/.agents/skills/review-router/scripts/test_review_router.py +0 -23
- package/.agents/skills/review-router/scripts/test_review_router_cli.py +0 -47
- package/.agents/skills/review-tier/SKILL.md +0 -56
- package/.agents/skills/review-tier/reference/task-seeds.md +0 -1
- package/.agents/skills/review-tier/reference/tier-policy.json +0 -9
- package/.agents/skills/review-tier/scripts/conftest.py +0 -4
- package/.agents/skills/review-tier/scripts/review_tier.py +0 -359
- package/.agents/skills/review-tier/scripts/review_tier_constants/__init__.py +0 -1
- package/.agents/skills/review-tier/scripts/review_tier_constants/config/__init__.py +0 -0
- package/.agents/skills/review-tier/scripts/review_tier_constants/config/constants.py +0 -29
- package/.agents/skills/review-tier/scripts/test_generation.py +0 -159
- package/.agents/skills/review-tier/scripts/test_review_tier.py +0 -33
- package/.agents/skills/run-claude-dev-env/SKILL.md +0 -84
- package/.agents/skills/session-log/.claude/CLAUDE.md +0 -1
- package/.agents/skills/session-log/AGENTS.md +0 -1
- package/.agents/skills/session-log/SKILL.md +0 -170
- package/.agents/skills/session-log/templates/frontmatter.md +0 -40
- package/.agents/skills/session-tidy/.claude/CLAUDE.md +0 -1
- package/.agents/skills/session-tidy/AGENTS.md +0 -1
- package/.agents/skills/session-tidy/SKILL.md +0 -191
- package/.agents/skills/skill-builder/references/.claude/CLAUDE.md +0 -1
- package/.agents/skills/skill-builder/references/AGENTS.md +0 -1
- package/.agents/skills/skill-builder/references/delegation-map.md +0 -130
- package/.agents/skills/skill-builder/references/description-field.md +0 -111
- package/.agents/skills/skill-builder/references/deterministic-elements.md +0 -218
- package/.agents/skills/skill-builder/references/progressive-disclosure.md +0 -122
- package/.agents/skills/skill-builder/references/self-audit-checklist.md +0 -126
- package/.agents/skills/skill-builder/references/skill-modularity.md +0 -111
- package/.agents/skills/skill-builder/references/skill-types.md +0 -232
- package/.agents/skills/skill-builder/references/thariq-x-post-skills.json +0 -33
- package/.agents/skills/skill-builder/templates/.claude/CLAUDE.md +0 -1
- package/.agents/skills/skill-builder/templates/AGENTS.md +0 -1
- package/.agents/skills/skill-builder/templates/gap-analysis.md +0 -87
- package/.agents/skills/skill-builder/workflows/.claude/CLAUDE.md +0 -1
- package/.agents/skills/skill-builder/workflows/AGENTS.md +0 -1
- package/.agents/skills/skill-builder/workflows/improve-skill.md +0 -136
- package/.agents/skills/skill-builder/workflows/new-skill.md +0 -179
- package/.agents/skills/skill-builder/workflows/polish-skill.md +0 -139
- package/.agents/skills/source-command-sr-loop/SKILL.md +0 -82
- package/.agents/skills/update/.claude/CLAUDE.md +0 -1
- package/.agents/skills/update/AGENTS.md +0 -1
- package/.agents/skills/update/SKILL.md +0 -190
- package/_shared/pr-loop/AGENTS.md +0 -1
- package/_shared/pr-loop/CLAUDE.md +0 -1
- package/_shared/pr-loop/audit-contract.md +0 -183
- package/_shared/pr-loop/audit-reply-template.md +0 -151
- package/_shared/pr-loop/code-rules-gate.md +0 -65
- package/_shared/pr-loop/fix-protocol.md +0 -60
- package/_shared/pr-loop/gh-payloads.md +0 -75
- package/_shared/pr-loop/post-audit-thread-contract.md +0 -51
- package/_shared/pr-loop/precatch-rubric.md +0 -66
- package/_shared/pr-loop/preflight-proposal.md +0 -56
- package/_shared/pr-loop/scripts/post_audit_thread.py +0 -1242
- package/_shared/pr-loop/scripts/pr_loop_shared_constants/post_audit_thread_constants.py +0 -199
- package/_shared/pr-loop/scripts/tests/test_post_audit_thread.py +0 -1115
- package/_shared/pr-loop/scripts/tests/test_post_audit_thread_constants.py +0 -129
- package/_shared/pr-loop/state-schema.md +0 -45
- package/_shared/pr-loop/worker-spawn.md +0 -189
- /package/{.agents/skills/_shared/pr-loop/scripts → scripts}/test_durable_post_lint.py +0 -0
|
@@ -1,219 +0,0 @@
|
|
|
1
|
-
# Convergence — round shape and the ready definition
|
|
2
|
-
|
|
3
|
-
## Pre-flight: clear merge conflicts
|
|
4
|
-
|
|
5
|
-
Before the first round, the workflow checks once whether the PR branch conflicts
|
|
6
|
-
with `origin/main`. When GitHub reports a conflict (`mergeable` false or
|
|
7
|
-
`mergeable_state` dirty), one `clean-coder` rebases the branch onto `origin/main`
|
|
8
|
-
and resolves every conflict — the edit remains in the working tree, review and
|
|
9
|
-
verification follow the [precatch rubric](../../_shared/pr-loop/precatch-rubric.md),
|
|
10
|
-
and the commit step force-pushes with lease. The bug checks then run on a
|
|
11
|
-
conflict-free diff.
|
|
12
|
-
|
|
13
|
-
A PR that merges cleanly skips the rebase. A conflict that surfaces mid-run, when
|
|
14
|
-
`origin/main` advances during a later round, is caught by the convergence repair
|
|
15
|
-
at the end of the loop, which also rebases.
|
|
16
|
-
|
|
17
|
-
## Reuse pass (runs after the conflict pre-flight, before convergence)
|
|
18
|
-
|
|
19
|
-
One reuse lens (`code-quality-agent`) reviews the full `origin/main...HEAD` diff
|
|
20
|
-
for code that re-implements behavior the repository already provides. It reports a
|
|
21
|
-
reuse improvement only when all three criteria hold together, and omits any case
|
|
22
|
-
where even one is in doubt:
|
|
23
|
-
|
|
24
|
-
1. **Certain** — an existing symbol or module unquestionably covers the new
|
|
25
|
-
code's behavior, cited at `file:line`.
|
|
26
|
-
2. **Behaviorally the same** — swapping the new code for the existing one
|
|
27
|
-
changes no observable behavior: same inputs, outputs, side effects, and
|
|
28
|
-
error handling.
|
|
29
|
-
3. **Autonomously implementable** — the replacement is a mechanical edit (import
|
|
30
|
-
and call the existing symbol, drop the duplicate) needing no product
|
|
31
|
-
decision and no human judgment.
|
|
32
|
-
|
|
33
|
-
The lens reports without editing. Each qualifying improvement runs through the
|
|
34
|
-
same edit → verify → commit fix flow the rounds use, landing in one verified
|
|
35
|
-
commit before convergence begins. The pass is best-effort: when no case clears
|
|
36
|
-
all three criteria the run proceeds straight to convergence. Whatever the reuse
|
|
37
|
-
pass surfaces also joins the round findings, so the code-review lens re-checks
|
|
38
|
-
any improvement that did not land. The run result's `reuseNote` records what
|
|
39
|
-
landed.
|
|
40
|
-
|
|
41
|
-
## The round loop
|
|
42
|
-
|
|
43
|
-
The workflow holds five states and moves between them until the PR is ready or
|
|
44
|
-
a blocker ends the run. A single iteration counter increments on every pass
|
|
45
|
-
through any phase and caps the whole run at 20 loop iterations; the round counter
|
|
46
|
-
tracks CONVERGE passes only and is never the cap. The internal lenses drive the
|
|
47
|
-
code to clean first; the external reviewers run only after that, as terminal
|
|
48
|
-
confirmation gates that are expected to return zero.
|
|
49
|
-
|
|
50
|
-
**CONVERGE** (one round = a static sweep then one parallel lens sweep):
|
|
51
|
-
|
|
52
|
-
1. Resolve the current PR HEAD SHA. The same preflight step also fetches
|
|
53
|
-
`origin/main` once for the round and enumerates the diff — the
|
|
54
|
-
`git diff --name-status origin/main...HEAD` changed-file list and the
|
|
55
|
-
`git diff --stat` diffstat — and carries both into the round.
|
|
56
|
-
2. Run the **static-sweep lens** on that HEAD: a deterministic pass that runs the
|
|
57
|
-
CODE_RULES gate (`code_rules_gate.py --base origin/main`), `ruff`, `mypy`, and
|
|
58
|
-
stem-matched `pytest` over the changed files, mapping each failure to a
|
|
59
|
-
finding. It uses local commands only, so it runs in any session. When the sweep
|
|
60
|
-
raises a finding, one `clean-coder` fixes it through the same fix flow below and
|
|
61
|
-
the round re-runs, so the reading lenses only ever review sweep-clean code.
|
|
62
|
-
3. Run three reading lenses in parallel on that HEAD, each over the full
|
|
63
|
-
`origin/main...HEAD` diff. Each lens receives the preflight's changed-file
|
|
64
|
-
list and diffstat and reads only the files it needs from that list rather than
|
|
65
|
-
re-deriving the diff; each lens applies the [precatch rubric](../../_shared/pr-loop/precatch-rubric.md#review-judgment).
|
|
66
|
-
- **Code-review lens** — a correctness-focused review pass (`code-quality-agent`),
|
|
67
|
-
report-only workflow agent — see runCodeReviewLens in workflow/converge.mjs for its configuration.
|
|
68
|
-
The built-in `/code-review` command is a separate surface outside this
|
|
69
|
-
workflow path. On `pacer=workflow`, this lens runs inside `converge.mjs`.
|
|
70
|
-
On `pacer=portable`, the continuous driver uses the CODE_REVIEW phase
|
|
71
|
-
through `invoke_code_review.py` instead of `runCodeReviewLens`
|
|
72
|
-
([`../../_shared/pr-loop/portable-driver.md`](../../_shared/pr-loop/portable-driver.md)).
|
|
73
|
-
- **Bug-audit lens** — the bug-audit (`code-quality-agent`) applying the
|
|
74
|
-
shared A–P rubric from `_shared/pr-loop/audit-contract.md`, then its
|
|
75
|
-
adversarial second pass, and the doc-parity, test-assertion, and
|
|
76
|
-
PR-description lanes from `_shared/pr-loop/precatch-rubric.md`, reporting
|
|
77
|
-
findings without editing.
|
|
78
|
-
- **Self-review lens** — the semantic parity pass (`code-quality-agent`) that
|
|
79
|
-
reads `_shared/pr-loop/precatch-rubric.md` and covers doc-vs-code parity,
|
|
80
|
-
test-assertion completeness, and PR-description-vs-diff parity, reporting
|
|
81
|
-
findings without editing.
|
|
82
|
-
4. Dedup findings across the three lenses by file, line, and title. A collision
|
|
83
|
-
keeps the most severe duplicate's severity (P0 > P1 > P2), unions the detail
|
|
84
|
-
text, and collects every distinct bot thread id so the fix lens resolves all
|
|
85
|
-
colliding threads.
|
|
86
|
-
5. **Any findings** → one `clean-coder` applies every fix per the
|
|
87
|
-
shared [fix protocol](../../_shared/pr-loop/fix-protocol.md): a single
|
|
88
|
-
test-first commit, a push, then a reply and resolve on each finding that
|
|
89
|
-
carries a GitHub review thread. Before its turn ends, the edit step dry-runs
|
|
90
|
-
the CODE_RULES commit gate (`code_rules_gate.py --staged`) over its staged
|
|
91
|
-
changes and keeps fixing until that gate would accept the commit, so the
|
|
92
|
-
later commit step never hits a gate rejection. A round progresses when the
|
|
93
|
-
fix lens lands a push that moves HEAD, or when every finding was already
|
|
94
|
-
addressed so no code change is needed yet each finding thread is still
|
|
95
|
-
resolved (the fix lens reports `resolvedWithoutCommit` and the run
|
|
96
|
-
re-converges on the unchanged HEAD). A round whose fix lens reports neither
|
|
97
|
-
a moved-HEAD push nor a full thread-resolution ends the run with a
|
|
98
|
-
fix-stalled blocker. The next round re-verifies on the current HEAD.
|
|
99
|
-
6. **Zero findings on a stable HEAD** → post the CLEAN bugteam audit artifact
|
|
100
|
-
for that HEAD, then move to the terminal Bugbot gate.
|
|
101
|
-
|
|
102
|
-
A round whose findings are ALL code-standard violations (pure CODE_RULES/style,
|
|
103
|
-
no behavioral impact) passes for convergence purposes: the workflow files a
|
|
104
|
-
follow-up issue listing the findings, opens a draft environment-hardening PR
|
|
105
|
-
(hooks/rules that block those violation classes at Write/Edit time), resolves
|
|
106
|
-
any bot threads with a deferral note, and reports the deferral in
|
|
107
|
-
`standardsNote`. The hardening PRs land in the run result's `deferredPrs` list.
|
|
108
|
-
Standards-only deferral still takes precedence when every finding is category
|
|
109
|
-
`code-standard`.
|
|
110
|
-
|
|
111
|
-
When the already-deduped findings for a phase are all severity P2 (and not
|
|
112
|
-
standards-only), the phase still applies the fixes once. If the fix does **not**
|
|
113
|
-
move HEAD (for example `resolvedWithoutCommit`), the phase treats that HEAD as
|
|
114
|
-
clean and advances forward. If the fix **does** move HEAD, the run re-enters
|
|
115
|
-
CONVERGE on the fixed SHA so the current review state rebuilds before
|
|
116
|
-
FINALIZE. The three CONVERGE reading lenses stay
|
|
117
|
-
parallel; the P2-only decision is a routing branch on the deduped set after
|
|
118
|
-
`resolveRoundOutcome` / gate classification. Mixed P0/P1 findings keep the
|
|
119
|
-
existing fix + re-converge path.
|
|
120
|
-
|
|
121
|
-
**BUGBOT** gate (terminal external confirmation):
|
|
122
|
-
|
|
123
|
-
- Runs once the internal lenses are clean. When Bugbot is off for the run — the
|
|
124
|
-
default unless `CLAUDE_REVIEWS_ENABLED` lists `bugbot` — opted out via
|
|
125
|
-
`CLAUDE_REVIEWS_DISABLED`, or unreachable, the gate spawns no agent and moves
|
|
126
|
-
to the Copilot gate with `bugbotDown` set.
|
|
127
|
-
- Otherwise drive Cursor Bugbot to a verdict on HEAD (trigger and poll its CI
|
|
128
|
-
check run when needed).
|
|
129
|
-
- Bugbot findings that are not standards-only and not P2-only → fix them and
|
|
130
|
-
return to CONVERGE on the new HEAD.
|
|
131
|
-
- Bugbot P2-only findings → fix once; advance to Copilot only when HEAD is
|
|
132
|
-
unchanged, otherwise re-converge on the fixed HEAD.
|
|
133
|
-
- Bugbot clean or approved → move to the Copilot gate.
|
|
134
|
-
- Bugbot down after the poll cap → move to the Copilot gate with `bugbotDown` set.
|
|
135
|
-
|
|
136
|
-
**COPILOT** gate (terminal external confirmation):
|
|
137
|
-
|
|
138
|
-
- Request a Copilot review on HEAD (skipping a duplicate request), then poll up
|
|
139
|
-
to the configured cap, 360 seconds apart.
|
|
140
|
-
- Copilot findings that are not standards-only and not P2-only → fix them and
|
|
141
|
-
return to CONVERGE on the new HEAD.
|
|
142
|
-
- Copilot P2-only findings → fix once; advance to Codex only when HEAD is
|
|
143
|
-
unchanged, otherwise re-converge on the fixed HEAD.
|
|
144
|
-
- Copilot clean or approved → move to the Codex gate.
|
|
145
|
-
- Copilot down or out of quota (an out-of-usage notice, or no review after the
|
|
146
|
-
configured cap) → log a notice and move to the Codex gate with the Copilot gate
|
|
147
|
-
bypassed.
|
|
148
|
-
|
|
149
|
-
**CODEX** gate (conditional-required terminal confirmation):
|
|
150
|
-
|
|
151
|
-
- Runs after Bugbot and Copilot. Honors `reviews_disabled.py --reviewer codex`,
|
|
152
|
-
the weekly usage probe via `is_codex_review_required` (shared threshold
|
|
153
|
-
constant — no inline percent), and the wrapper's `codex_down` class.
|
|
154
|
-
- Missing opt-in (the default), opt-out token, or `codex_down` → set
|
|
155
|
-
`codexDown`, no stamp, move to the
|
|
156
|
-
convergence check with `--codex-down`. A `codex_down` classification also
|
|
157
|
-
records a `codexNote` so the skip stays visible in the final report.
|
|
158
|
-
- Usage at/below threshold or null → skip with no stamp; the machine checklist
|
|
159
|
-
applies the same rule.
|
|
160
|
-
- Above threshold → run the codex-review wrapper against the PR base branch.
|
|
161
|
-
Non–code-standard, non–P2-only findings → fix and return to CONVERGE.
|
|
162
|
-
P2-only findings → fix once; when HEAD is unchanged, stamp `codexCleanAt` and
|
|
163
|
-
move to the convergence check (no re-converge), otherwise re-converge on the
|
|
164
|
-
fixed HEAD.
|
|
165
|
-
Standards-only findings → defer a follow-up, stamp `codexCleanAt`, and move to the
|
|
166
|
-
convergence check (no fix push).
|
|
167
|
-
Clean → stamp `codexCleanAt` and pass `--codex-clean-at` into the convergence check.
|
|
168
|
-
|
|
169
|
-
**Convergence check**:
|
|
170
|
-
|
|
171
|
-
- One agent runs `check_convergence.py` and, on a full pass, marks the PR ready
|
|
172
|
-
(`draft=false`) in the same turn, ending the run. A failure returns to CONVERGE
|
|
173
|
-
so the next round addresses the failing gate; the repair path re-runs this same
|
|
174
|
-
check, and only a passing check marks the PR ready.
|
|
175
|
-
|
|
176
|
-
## Model tiers
|
|
177
|
-
|
|
178
|
-
Each spawned agent runs on the model and effort its role needs, so the run spends
|
|
179
|
-
the strongest model only where judgment is dense:
|
|
180
|
-
|
|
181
|
-
- **sonnet** — the deterministic static-sweep lens, and the verify,
|
|
182
|
-
commit, and recovery steps that clear a commit-gate or verdict rejection.
|
|
183
|
-
- **opus** — the reading lenses (code-review, bug-audit, self-review,
|
|
184
|
-
reuse), the terminal Bugbot gate, and the code-editing steps that fix findings
|
|
185
|
-
(fix-edit, conflict-edit, repair-edit, standards-edit).
|
|
186
|
-
- **haiku** — the mechanical probes: preflight, the Copilot gate, the Codex
|
|
187
|
-
gate, the CLEAN-audit post, and the convergence check.
|
|
188
|
-
|
|
189
|
-
## Full-diff rule
|
|
190
|
-
|
|
191
|
-
Every lens, every round, reviews the full `origin/main...HEAD` diff — every file
|
|
192
|
-
the PR touches. A lens that scopes to recent commits, a single file, or a
|
|
193
|
-
bugbot-flagged path does not satisfy the round; its clean verdict is not a clean.
|
|
194
|
-
|
|
195
|
-
## The ready definition
|
|
196
|
-
|
|
197
|
-
`check_convergence.py` (`packages/claude-dev-env/_shared/pr-loop/scripts/check_convergence.py`) is the single
|
|
198
|
-
source of truth for readiness. Ready means the script exits `0` and prints:
|
|
199
|
-
|
|
200
|
-
```
|
|
201
|
-
All pre-conditions met — PR is ready to mark ready.
|
|
202
|
-
```
|
|
203
|
-
|
|
204
|
-
The script re-derives every condition from GitHub and prints one PASS/FAIL line
|
|
205
|
-
per label. The exact printed labels (script order) live in
|
|
206
|
-
[`convergence-gates.md`](convergence-gates.md).
|
|
207
|
-
|
|
208
|
-
The script has no Claude APPROVED review gate. Agent-side checks (Claude
|
|
209
|
-
reviewer presence, broader unresolved-thread sweeps) sit outside this machine
|
|
210
|
-
checklist.
|
|
211
|
-
|
|
212
|
-
## Audit-trail design
|
|
213
|
-
|
|
214
|
-
Bugbot and Copilot post their own review threads, which the fix lens replies to
|
|
215
|
-
and resolves. Codex findings are local to the gate (no GitHub review thread) and
|
|
216
|
-
enter the same fix path with `replyToCommentId: null`. The bug-audit lens keeps
|
|
217
|
-
its findings in memory across the round and posts only the terminal CLEAN bugteam
|
|
218
|
-
review once every lens is clean on a stable HEAD — that single artifact is what
|
|
219
|
-
gate 3 reads. This keeps thread churn to the threads the bots raise themselves.
|
|
@@ -1,51 +0,0 @@
|
|
|
1
|
-
# Copilot findings — tier, verify, then route
|
|
2
|
-
|
|
3
|
-
How the autoconverge Copilot gate handles each finding. The hub
|
|
4
|
-
([`../SKILL.md`](../SKILL.md)) points here; the orchestrating session's
|
|
5
|
-
user-review hold runs the [`copilot-finding-triage`](../../copilot-finding-triage/SKILL.md)
|
|
6
|
-
skill.
|
|
7
|
-
|
|
8
|
-
The Copilot gate tiers each finding: a **self-healing** finding (style, type
|
|
9
|
-
hints, imports, formatting, magic-value extraction, test-only or doc-vs-code
|
|
10
|
-
fixes — nothing that changes observable runtime behavior) flows into the fix
|
|
11
|
-
round with no user notification. A **code-concern** finding (logic, security,
|
|
12
|
-
data handling, error-handling semantics, concurrency — the tier whenever in
|
|
13
|
-
doubt) goes to a verification stage before any routing.
|
|
14
|
-
|
|
15
|
-
Each code-concern finding gets its own verifier agent, all in parallel, inside
|
|
16
|
-
the workflow. A verdict is conclusive only when an actual check ran: the verifier
|
|
17
|
-
executes a command against the flagged HEAD — running the code path with crafted
|
|
18
|
-
inputs, forcing the claimed error condition, or running a purpose-built test —
|
|
19
|
-
and captures its output. The verdict carries
|
|
20
|
-
`{ verdict, checkCommand, checkOutput, evidence }`; a conclusive verdict with an
|
|
21
|
-
empty `checkCommand` or `checkOutput` downgrades to inconclusive.
|
|
22
|
-
|
|
23
|
-
- **confirmed** — the check reproduces the defect. The finding becomes
|
|
24
|
-
self-healing: it joins the fix round carrying its repro, and the fix re-runs
|
|
25
|
-
that same check, adds a regression test where the suite covers the surface,
|
|
26
|
-
lands in one commit, pushes, and replies on the thread with the fix SHA and the
|
|
27
|
-
before/after output. No page.
|
|
28
|
-
- **refuted** — the check shows the code already behaves correctly in the exact
|
|
29
|
-
scenario the finding claims is broken. The workflow replies on the thread with
|
|
30
|
-
the command and output, resolves it, and counts it clean. No page.
|
|
31
|
-
- **inconclusive** — everything else, and the verifier's default: no runnable
|
|
32
|
-
check exists, the check is infeasible here, the results are ambiguous, or the
|
|
33
|
-
fix needs a product decision. Any doubt sorts here. Only inconclusive findings
|
|
34
|
-
page the user.
|
|
35
|
-
|
|
36
|
-
A round whose code concerns all confirm or refute never returns
|
|
37
|
-
`blocker: "user-review"`. On one or more inconclusive findings, the workflow
|
|
38
|
-
stops with `converged: false`, `blocker: "user-review"`, and a `userReview`
|
|
39
|
-
field carrying
|
|
40
|
-
`{ reviewUrl, findings: [{ file, line, severity, tier, title, evidence }] }` —
|
|
41
|
-
`evidence` is the verifier's one-line note stating what check was attempted and
|
|
42
|
-
why it was not decisive.
|
|
43
|
-
|
|
44
|
-
A background workflow cannot hold for a human, so the wait belongs to the
|
|
45
|
-
orchestrating session. On a `blocker: "user-review"` return, run the
|
|
46
|
-
[`copilot-finding-triage`](../../copilot-finding-triage/SKILL.md) skill: send the
|
|
47
|
-
ntfy notification (the per-finding summary and evidence note plus the `reviewUrl`
|
|
48
|
-
Copilot review link), then hold with a 45-minute `ScheduleWakeup` for the user's
|
|
49
|
-
response. When the user answers within the window, follow their direction. When
|
|
50
|
-
the window closes with no response, run normal teardown and report the
|
|
51
|
-
inconclusive findings un-reviewed.
|
|
@@ -1,66 +0,0 @@
|
|
|
1
|
-
# Gotchas
|
|
2
|
-
|
|
3
|
-
Hard-won lessons for the autoconverge workflow. Append a bullet each time a run
|
|
4
|
-
fails in a new way.
|
|
5
|
-
|
|
6
|
-
- **The workflow script cannot sleep, and neither can an agent's foreground shell.** `Date.now`, `Math.random`, and timers
|
|
7
|
-
are unavailable in the script body, and a foreground `sleep` / `Start-Sleep` is blocked in the headless harness. Every
|
|
8
|
-
reviewer wait lives inside an `agent`'s own poll loop, and that loop waits with the Monitor tool inside the same turn —
|
|
9
|
-
never a foreground sleep, and never backgrounding a wait and ending the turn to await it, which
|
|
10
|
-
leaves a schema-bearing agent with no `StructuredOutput` call. Never try to wait in the script itself.
|
|
11
|
-
|
|
12
|
-
- **Workflow agents start blank.** Spawned agents do not inherit CLAUDE.md,
|
|
13
|
-
rules, or this skill's context. Each agent prompt is self-contained: it names
|
|
14
|
-
the exact scripts and flags, the full `origin/main...HEAD` diff scope, and the
|
|
15
|
-
return contract.
|
|
16
|
-
|
|
17
|
-
- **Only the fix lens writes.** The three converge lenses read and report; they
|
|
18
|
-
never edit, commit, or push. Because only the serial fix step pushes, the
|
|
19
|
-
parallel sweep needs no worktree isolation.
|
|
20
|
-
|
|
21
|
-
- **Fetch origin/main once before the parallel lenses.** The code-review and
|
|
22
|
-
bug-audit lenses both diff against `origin/main`. Concurrent `git fetch` calls
|
|
23
|
-
contend on the worktree `.git` lock and fail intermittently, so the workflow
|
|
24
|
-
runs a single serial `git fetch origin main` inside the merged `preflight-git`
|
|
25
|
-
step — the one git-utility agent that also resolves the PR HEAD SHA, probes
|
|
26
|
-
mergeability, and checks Copilot and Bugbot availability — and the parallel
|
|
27
|
-
lenses run no git fetch of their own; they
|
|
28
|
-
diff against the already-current ref. The workflow threads the resolved HEAD
|
|
29
|
-
through the rounds and re-runs `preflight-git` only after a push or rebase
|
|
30
|
-
invalidates it, so a round on an unchanged HEAD spawns no git agent at all.
|
|
31
|
-
|
|
32
|
-
- **The CLEAN bugteam artifact is HEAD-specific.** `check_convergence.py` reads
|
|
33
|
-
the bugteam review on the current HEAD. Any push moves HEAD and invalidates a
|
|
34
|
-
prior artifact, so post it only when a round is fully clean, and post a fresh
|
|
35
|
-
one after any later fix round.
|
|
36
|
-
|
|
37
|
-
- **Bot login fields differ by endpoint.** `get_reviews` returns `.user.login`
|
|
38
|
-
(an object), while `get_review_comments` returns `.author` (a string). Match
|
|
39
|
-
bot logins with case-insensitive substring tests, not strict equality.
|
|
40
|
-
|
|
41
|
-
- **`scriptPath` takes a real path, not a shell variable.** `$HOME` expands in a
|
|
42
|
-
Bash command but not in the `Workflow` tool's `scriptPath` argument. Pass the
|
|
43
|
-
expanded absolute path to `workflow/converge.mjs`.
|
|
44
|
-
|
|
45
|
-
- **Tilde paths fail on Windows Git Bash.** Inside shell calls, use `$HOME/.claude/...`,
|
|
46
|
-
not `~/.claude/...`; a tilde resolves to the wrong home and gives a
|
|
47
|
-
file-not-found error that looks like a script failure.
|
|
48
|
-
|
|
49
|
-
- **Local identity drift across accounts.** A local run that touches more than
|
|
50
|
-
one GitHub account must use the selected local account. Cloud runs use the
|
|
51
|
-
connected GitHub MCP identity and never use local CLI identity commands.
|
|
52
|
-
|
|
53
|
-
- **Commit or push fails after a repair.** Read the hook or command output,
|
|
54
|
-
repair the named issue, and record the rerun. Apply the
|
|
55
|
-
[precatch rubric](../../_shared/pr-loop/precatch-rubric.md) before retrying.
|
|
56
|
-
|
|
57
|
-
- **A Copilot "down" verdict is valid only after the full poll budget.** A
|
|
58
|
-
successful review request means the review is in flight — Copilot typically
|
|
59
|
-
posts within 10–15 minutes of the request. A gate agent that returns
|
|
60
|
-
`down:true` on a partial poll misreports an in-flight review as reviewer
|
|
61
|
-
unavailability, and the run marks the PR ready moments before the review
|
|
62
|
-
lands. After a successful request the only valid gate outcomes are a
|
|
63
|
-
received review on HEAD, an out-of-usage notice, or the full poll budget
|
|
64
|
-
spent. The teardown re-checks the PR for a late-arriving Copilot review
|
|
65
|
-
whenever the gate was bypassed, and routes its findings through one more
|
|
66
|
-
fix round.
|
|
@@ -1,44 +0,0 @@
|
|
|
1
|
-
# Headless-safety preamble
|
|
2
|
-
|
|
3
|
-
Every agent prompt the workflow authors carries a headless-safety preamble: the
|
|
4
|
-
run is unattended, so agents never inline a destructive-command literal
|
|
5
|
-
(`rm -rf`, `git reset --hard`, `dd`) into a Bash command — the
|
|
6
|
-
`destructive_command_blocker` hook matches those patterns as raw text, and a
|
|
7
|
-
confirmation prompt no human can answer would stall the run.
|
|
8
|
-
|
|
9
|
-
## Two forms
|
|
10
|
-
|
|
11
|
-
The preamble has two forms. Read-only agents — the review, verify, and utility
|
|
12
|
-
spawns that edit nothing — receive a trimmed form that drops the rm-shape rules,
|
|
13
|
-
since a read-only agent never runs `rm`. Edit agents — the fix and commit spawns
|
|
14
|
-
— receive the full form that carries the rm-shape rules below.
|
|
15
|
-
|
|
16
|
-
Agents verify destructive-blocker behavior through the committed test suite
|
|
17
|
-
(`python -m pytest`) and keep scratch work in the OS temp dir.
|
|
18
|
-
|
|
19
|
-
## The rm auto-allow paths (full form)
|
|
20
|
-
|
|
21
|
-
The full preamble describes three auto-allow paths:
|
|
22
|
-
|
|
23
|
-
1. **Standalone path** — a standalone Bash call whose target resolves inside the
|
|
24
|
-
ephemeral namespace (`/tmp`, `/temp`, the OS temp root, or the run worktree).
|
|
25
|
-
It fails closed on `$(...)` substitution and backtick subshells. It declines a
|
|
26
|
-
`$`-bearing target only when the literal path is not already under an
|
|
27
|
-
ephemeral root, so it does not by itself stop a `$VAR` that expands inside an
|
|
28
|
-
ephemeral root.
|
|
29
|
-
2. **Compound path** — accepts an rm joined with benign reporting segments when
|
|
30
|
-
every rm target is an absolute ephemeral path. It fails closed on `$(...)`
|
|
31
|
-
substitution, backtick subshells, and any `$` in the target — including
|
|
32
|
-
`$CLAUDE_JOB_DIR`.
|
|
33
|
-
3. **Cwd-scoped path** — matches only when the command itself declares an
|
|
34
|
-
ephemeral working directory (it `cd`s into one, or runs under one). It
|
|
35
|
-
resolves the target against the declared cwd, fails closed on `$(...)`,
|
|
36
|
-
backticks, and unknown variables, and resolves the known temporary variables
|
|
37
|
-
`TEMP`, `TMP`, `TMPDIR`, and `CLAUDE_JOB_DIR` to the OS temp root. Under a
|
|
38
|
-
declared ephemeral cwd, a bare `$CLAUDE_JOB_DIR/tmp/<name>` target and a
|
|
39
|
-
relative target after a `cd` are auto-allowed.
|
|
40
|
-
|
|
41
|
-
Even so, for any cleanup whose path is variable-built or whose teardown spans
|
|
42
|
-
multiple steps, agents author a Python helper file and run it as
|
|
43
|
-
`python <file>.py` — keeping every destructive literal out of a Bash command
|
|
44
|
-
string entirely and independent of which auto-allow path matches.
|
|
@@ -1,128 +0,0 @@
|
|
|
1
|
-
# Multiple PRs
|
|
2
|
-
|
|
3
|
-
The multi-PR run drives several draft PRs to ready in one launch:
|
|
4
|
-
`workflow/converge_multi.mjs` fans out one `converge.mjs` child run per PR with
|
|
5
|
-
`parallel()`, and every child is pinned to its own PR's worktree through the
|
|
6
|
-
`repoPath` it receives, so the children never share a checkout. Each child run is
|
|
7
|
-
the exact single-PR convergence loop — same rounds, same reuse pass, same Copilot
|
|
8
|
-
gate, same convergence check — one per PR at once. The children share the run's
|
|
9
|
-
concurrency cap, so the fan-out self-throttles rather than spawning every PR's
|
|
10
|
-
lenses at the same instant.
|
|
11
|
-
|
|
12
|
-
## Multi-PR pre-flight (main session)
|
|
13
|
-
|
|
14
|
-
`EnterWorktree` puts the session on one branch only, so the multi-PR path gives
|
|
15
|
-
each PR its own checkout with `git worktree add`. For each PR the user named:
|
|
16
|
-
|
|
17
|
-
1. **Resolve PR scope** as the single-PR pre-flight step 2 in
|
|
18
|
-
[`SKILL.md`](../SKILL.md) does: capture `owner`, `repo`, `prNumber`, and
|
|
19
|
-
`headRefName`; confirm the PR is a draft, and mark it draft
|
|
20
|
-
(`gh pr ready <n> --repo <o>/<r> --undo`) when it is already ready so the
|
|
21
|
-
loop owns the ready transition.
|
|
22
|
-
2. **Create a worktree on the PR's head ref** and capture its absolute path. From
|
|
23
|
-
inside the PR's repository checkout:
|
|
24
|
-
`git worktree add <abs worktree path> <headRefName>` (run `git fetch origin
|
|
25
|
-
<headRefName>` first when the ref is not local). Put each PR's worktree under a
|
|
26
|
-
path carrying its PR number so the fan-out keeps them distinct. Confirm
|
|
27
|
-
`git -C <abs worktree path> rev-parse --abbrev-ref HEAD` equals the head ref
|
|
28
|
-
and its `HEAD` equals the PR head SHA.
|
|
29
|
-
3. **Verify each worktree is the PR's repo (strict pre-flight):**
|
|
30
|
-
`python "$HOME/.claude/skills/_shared/pr-loop/scripts/preflight_worktree.py" --owner <owner> --repo <repo> --mode strict`,
|
|
31
|
-
run with that worktree as the working directory. A non-zero exit prints a
|
|
32
|
-
`PREFLIGHT_OUTCOME` line and an `ABORT` line: report it and drop that PR from
|
|
33
|
-
the run rather than aborting every PR.
|
|
34
|
-
4. **Grant project permissions once per repository** — the single-PR pre-flight
|
|
35
|
-
step 4 grant covers every worktree of the same repo, so run it one time for
|
|
36
|
-
the repo the PRs live in.
|
|
37
|
-
5. **Copilot quota pre-check once for the whole run** — run the single-PR
|
|
38
|
-
pre-flight step 5 check one time:
|
|
39
|
-
`python "$HOME/.claude/_shared/pr-loop/scripts/copilot_quota.py"`. Every PR in
|
|
40
|
-
the run shares one account's Copilot premium-request quota, so one check covers
|
|
41
|
-
them all. Exit 0 sets `copilotDisabled: false` on every PR entry below; any
|
|
42
|
-
non-zero exit sets `copilotDisabled: true` on every entry, so each child skips
|
|
43
|
-
the Copilot gate with no agent spawned.
|
|
44
|
-
|
|
45
|
-
## Launch
|
|
46
|
-
|
|
47
|
-
Select the pacer once for the multi-PR run (same helper as single-PR):
|
|
48
|
-
|
|
49
|
-
```
|
|
50
|
-
python "$HOME/.claude/skills/_shared/pr-loop/scripts/select_converge_pacer.py" \
|
|
51
|
-
--skill autoconverge \
|
|
52
|
-
--has-workflow <0|1> \
|
|
53
|
-
--has-schedule-wakeup <0|1>
|
|
54
|
-
```
|
|
55
|
-
|
|
56
|
-
### `pacer=portable`
|
|
57
|
-
|
|
58
|
-
Do **not** call `Workflow`. For each PR worktree from pre-flight, run the
|
|
59
|
-
continuous portable driver in
|
|
60
|
-
[`../../_shared/pr-loop/portable-driver.md`](../../_shared/pr-loop/portable-driver.md)
|
|
61
|
-
(serial, or host fan-out when the host can isolate workers). One teardown per
|
|
62
|
-
PR after that PR reaches ready or a named blocker. Shared Copilot quota and
|
|
63
|
-
permission grants from multi-PR pre-flight still apply once.
|
|
64
|
-
|
|
65
|
-
### `pacer=workflow`
|
|
66
|
-
|
|
67
|
-
Call the `Workflow` tool against the fan-out script, passing the absolute path of
|
|
68
|
-
`converge.mjs` and one entry per PR:
|
|
69
|
-
|
|
70
|
-
```
|
|
71
|
-
Workflow({
|
|
72
|
-
scriptPath: "<this skill dir>/workflow/converge_multi.mjs",
|
|
73
|
-
args: {
|
|
74
|
-
convergeScriptPath: "<this skill dir>/workflow/converge.mjs",
|
|
75
|
-
homeDirectory: "<HOME>",
|
|
76
|
-
transport: "<cloud|local>",
|
|
77
|
-
prs: [
|
|
78
|
-
{ owner: "<O>", repo: "<R>", prNumber: <N1>, repoPath: "<abs worktree 1>", bugbotDisabled: false, copilotDisabled: false },
|
|
79
|
-
{ owner: "<O>", repo: "<R>", prNumber: <N2>, repoPath: "<abs worktree 2>", bugbotDisabled: false, copilotDisabled: false }
|
|
80
|
-
]
|
|
81
|
-
}
|
|
82
|
-
})
|
|
83
|
-
```
|
|
84
|
-
|
|
85
|
-
`convergeScriptPath` is the absolute path to `workflow/converge.mjs` in this same
|
|
86
|
-
skill directory; each `repoPath` is the absolute path of the worktree that PR is
|
|
87
|
-
checked out in. `homeDirectory` is the absolute path to the directory that holds
|
|
88
|
-
`.claude` (resolve it once from `$HOME`, or `$env:USERPROFILE` on Windows, with
|
|
89
|
-
forward slashes); the fan-out forwards it to every child run, which needs it to
|
|
90
|
-
build the codex-review scripts path because the workflow sandbox has no access to
|
|
91
|
-
environment variables. Set `transport: "cloud"` in a Cloud session and
|
|
92
|
-
`transport: "local"` in a local session. Cloud uses the connected GitHub MCP
|
|
93
|
-
tools and skips local CLI authentication. The workflow runs in the background
|
|
94
|
-
and notifies the session on completion; watch live progress with `/workflows`,
|
|
95
|
-
where each PR's child run
|
|
96
|
-
appears under its own group.
|
|
97
|
-
|
|
98
|
-
The workflow returns
|
|
99
|
-
`{ converged, prCount, convergedCount, results, allDeferredPrs, blocker }`, where
|
|
100
|
-
`results` is one record per PR carrying
|
|
101
|
-
`{ owner, repo, prNumber, converged, rounds, finalSha, blocker, deferredPrs }`.
|
|
102
|
-
Each record's `deferredPrs` is that PR's own list of draft hardening PRs, and
|
|
103
|
-
`allDeferredPrs` is every record's `deferredPrs` flattened into one list. The
|
|
104
|
-
top-level `converged` is true only when every PR converged.
|
|
105
|
-
|
|
106
|
-
## Multi-PR teardown
|
|
107
|
-
|
|
108
|
-
### `pacer=portable`
|
|
109
|
-
|
|
110
|
-
For each PR worktree, run the single-PR **Teardown → pacer=portable** path in
|
|
111
|
-
[`SKILL.md`](../SKILL.md) (`pr-loop-lifecycle` Close, no Workflow journal
|
|
112
|
-
report). Write one durable handoff per PR with that PR's `--pr-number` and
|
|
113
|
-
resume command `/autoconverge <PR URL>`. Revoke project permissions once per
|
|
114
|
-
repository after every PR's close. Print one summary line per PR as
|
|
115
|
-
`#<prNumber>: <converged | blocked> — rounds <N>, final <finalSha>[, blocker <blocker>]`.
|
|
116
|
-
|
|
117
|
-
### `pacer=workflow` (on workflow completion)
|
|
118
|
-
|
|
119
|
-
Run the single-PR Teardown in [`SKILL.md`](../SKILL.md) once per entry in
|
|
120
|
-
`results`, using that PR's `owner`, `repo`, `prNumber`, and `finalSha`, and its
|
|
121
|
-
own worktree as the working directory. Write one durable handoff per PR entry —
|
|
122
|
-
each with that PR's own `--pr-number` — so a fresh session can resume any PR on
|
|
123
|
-
its own. Build and publish a PR's closing report
|
|
124
|
-
only for a PR whose `converged` is true; for a PR that returned a blocker, skip
|
|
125
|
-
its report and carry the blocker into the final summary. Revoke project
|
|
126
|
-
permissions once per repository after every PR's teardown. Then print one summary
|
|
127
|
-
report — a line per PR as
|
|
128
|
-
`#<prNumber>: <converged | blocked> — rounds <N>, final <finalSha>[, blocker <blocker>]`.
|
|
@@ -1,84 +0,0 @@
|
|
|
1
|
-
# Self-closing loop: converge the deferred PRs
|
|
2
|
-
|
|
3
|
-
Every run leaves work behind. When a round holds only code-standard findings, the
|
|
4
|
-
standards-deferral path opens a draft environment-hardening PR and reports it in
|
|
5
|
-
`deferredPrs`. That PR is itself a draft that needs to reach ready, and its own
|
|
6
|
-
convergence can defer more standard findings, opening more hardening PRs. The
|
|
7
|
-
self-closing loop drives that chain to the ground: after teardown, the
|
|
8
|
-
orchestrator (the session that launched the workflow) converges the deferred
|
|
9
|
-
PRs, then the PRs their runs defer, and so on until a generation opens none.
|
|
10
|
-
|
|
11
|
-
This loop runs by default at the end of every autoconverge run — single-PR and
|
|
12
|
-
multi-PR alike. It stops only when a generation's deferred-PR list comes back
|
|
13
|
-
empty.
|
|
14
|
-
|
|
15
|
-
## Seed the loop
|
|
16
|
-
|
|
17
|
-
Collect the first generation of deferred PRs from the run that just finished:
|
|
18
|
-
|
|
19
|
-
- A single-PR run seeds from its `deferredPrs`.
|
|
20
|
-
- A multi-PR run seeds from its `allDeferredPrs`.
|
|
21
|
-
|
|
22
|
-
When the seed list is empty, the loop is already done — the run deferred nothing,
|
|
23
|
-
so there is nothing to converge. Report that and stop.
|
|
24
|
-
|
|
25
|
-
## Each generation
|
|
26
|
-
|
|
27
|
-
Given a non-empty list of deferred PRs `{ owner, repo, prNumber, copilotDisabled, bugbotDisabled }`
|
|
28
|
-
(a generation may span more than one repository — a hardening PR lands in whichever repo owns
|
|
29
|
-
the surface that blocks the deferred class, so `JonEcho/llm-settings` for hooks
|
|
30
|
-
and `jl-cmd/claude-dev-env` for rules and skills both appear):
|
|
31
|
-
|
|
32
|
-
1. **Check out each deferred PR.** Run the
|
|
33
|
-
[multi-PR pre-flight](multi-pr.md#multi-pr-pre-flight-main-session) once per
|
|
34
|
-
deferred PR. Because a deferred PR can live in a repo the first run never
|
|
35
|
-
touched, first find a local checkout of that PR's repo; when none exists,
|
|
36
|
-
clone it under the session temp dir, then add the per-PR worktree on the PR's
|
|
37
|
-
head ref. Drop any PR whose strict pre-flight fails rather than stopping the
|
|
38
|
-
whole generation. Grant project permissions once per repository the
|
|
39
|
-
generation spans.
|
|
40
|
-
2. **Converge the generation.** Launch `workflow/converge_multi.mjs` with one
|
|
41
|
-
entry per checked-out deferred PR, exactly as the
|
|
42
|
-
[multi-PR launch](multi-pr.md#launch-the-multi-pr-workflow) describes. Each
|
|
43
|
-
child run checks Copilot and Bugbot availability through the workflow's own
|
|
44
|
-
preflight-git probe, carried across rounds, so a reviewer that is down or out
|
|
45
|
-
of quota is never spawned in any generation; the
|
|
46
|
-
`copilotDisabled`/`bugbotDisabled` flags each deferred PR carries seed that
|
|
47
|
-
check for the first round.
|
|
48
|
-
3. **Tear down.** Run the [multi-PR teardown](multi-pr.md#multi-pr-teardown-on-workflow-completion)
|
|
49
|
-
over the generation's `results`, and revoke project permissions once per
|
|
50
|
-
repository.
|
|
51
|
-
4. **Take the next seed.** The generation's `allDeferredPrs` is the next
|
|
52
|
-
generation's seed list. When it is empty, the loop is done.
|
|
53
|
-
|
|
54
|
-
Repeat from step 1 with each new seed. The depth is unbounded: the loop keeps
|
|
55
|
-
opening generations until one converges every deferred PR without deferring
|
|
56
|
-
anything new.
|
|
57
|
-
|
|
58
|
-
## Report each generation
|
|
59
|
-
|
|
60
|
-
Log one line as each generation finishes, so a watcher sees the chain close:
|
|
61
|
-
|
|
62
|
-
```
|
|
63
|
-
Self-closing generation <k>: <converged>/<total> deferred PR(s) converged, <new> new deferred PR(s) opened
|
|
64
|
-
```
|
|
65
|
-
|
|
66
|
-
When the loop ends, print a final line naming the generation count and the total
|
|
67
|
-
deferred PRs converged across every generation.
|
|
68
|
-
|
|
69
|
-
## Conventional titles on deferred PRs
|
|
70
|
-
|
|
71
|
-
Each hardening PR the loop opens targets a repo whose CI validates the PR title
|
|
72
|
-
as a Conventional Commit. The commit step's prompt directs the agent to title
|
|
73
|
-
the hardening PR as a Conventional Commit — a type prefix, an optional scope,
|
|
74
|
-
then a colon and a short summary — so a deferred PR carries a conforming title
|
|
75
|
-
(`feat(hooks): …`, `chore(rules): …`) before it exists. That prompt is where the
|
|
76
|
-
conforming title is enforced.
|
|
77
|
-
|
|
78
|
-
The `conventional_pr_title_gate` hook is a best-effort backstop on that title,
|
|
79
|
-
not the guarantee. It blocks a `gh pr create` with a non-conforming `--title`
|
|
80
|
-
only for a repo whose semantic-pull-request workflow leaves the action's
|
|
81
|
-
`types:` input at the default Conventional Commits list. For a repo that pins
|
|
82
|
-
its own explicit `types:` list — which the main target repo does in
|
|
83
|
-
`.github/workflows/pr-check.yml` — the hook fails open and lets the title
|
|
84
|
-
through, and the CI title check on GitHub has the final say.
|