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.
Files changed (293) hide show
  1. package/.agents/agents/pr-description-writer.md +2 -2
  2. package/.agents/agents/test_agent_frontmatter.py +2 -2
  3. package/.agents/agents/test_pr_description_writer_style.py +1 -3
  4. package/.agents/skills/e-code-review/SKILL.md +12 -12
  5. package/.agents/skills/e-code-review/preflight-proposal.contract.test.mjs +20 -0
  6. package/.agents/skills/e-code-review/reference/fix.md +15 -17
  7. package/.agents/skills/e-code-review/reference/loop.md +35 -39
  8. package/.agents/skills/e-code-review/reference/mode-contract.test.mjs +2 -1
  9. package/.agents/skills/e-code-review/reference/preflight-proposal.md +44 -9
  10. package/.agents/skills/e-code-review/reference/runner-selection.md +13 -14
  11. package/.agents/skills/issue-tracker/SKILL.md +5 -4
  12. package/.agents/skills/pull-request/SKILL.md +11 -13
  13. package/.agents/skills/pull-request/reference/publication-tasks.md +3 -3
  14. package/.agents/skills/pull-request/scripts/github_pr_command_constants/config/constants.py +9 -1
  15. package/.agents/skills/pull-request/scripts/pull_request.py +33 -44
  16. package/.agents/skills/pull-request/scripts/test_github_pr_command_constants.py +9 -0
  17. package/.agents/skills/pull-request/scripts/test_pull_request.py +1 -3
  18. package/.agents/skills/skill-builder/SKILL.md +3 -196
  19. package/_shared/pr-loop/scripts/pr_loop_shared_constants/terminology_sweep_constants.py +6 -0
  20. package/_shared/pr-loop/scripts/terminology_sweep.py +64 -19
  21. package/_shared/pr-loop/scripts/tests/test_terminology_sweep.py +59 -0
  22. package/bin/install.agents-home.test.mjs +15 -13
  23. package/bin/install.mjs +28 -0
  24. package/bin/install.policy-lint.test.mjs +78 -0
  25. package/bin/install.prune.test.mjs +59 -20
  26. package/bin/install.pstack-plugin.test.mjs +114 -0
  27. package/bin/install.test.mjs +37 -0
  28. package/bin/refresh-pstack-plugin-skills.test.mjs +211 -0
  29. package/hooks/advisory/pr_done_reminder.py +342 -0
  30. package/hooks/advisory/test_pr_done_reminder.py +249 -0
  31. package/hooks/blocking/bash_post_call_dispatcher.py +53 -6
  32. package/hooks/blocking/code_rules_paired_test.py +22 -15
  33. package/hooks/blocking/test_bash_post_call_dispatcher.py +65 -4
  34. package/hooks/blocking/test_code_rules_enforcer_paired_test.py +36 -29
  35. package/hooks/blocking/test_code_rules_js_resume_task_enumeration.py +4 -4
  36. package/hooks/blocking/test_code_rules_js_returns_object_schemaless.py +5 -5
  37. package/hooks/blocking/test_pre_tool_use_dispatcher.py +68 -133
  38. package/hooks/blocking/test_pre_tool_use_dispatcher_native.py +20 -51
  39. package/hooks/blocking/test_precommit_code_rules_gate_native_owner.py +18 -18
  40. package/hooks/git-hooks/git_hooks_constants/staged_policy_lint.py +12 -0
  41. package/hooks/git-hooks/pre_commit.py +52 -11
  42. package/hooks/git-hooks/test_installed_policy_lint.py +159 -0
  43. package/hooks/git-hooks/test_native_policy_commit.py +87 -0
  44. package/hooks/git-hooks/test_pre_commit.py +246 -0
  45. package/hooks/hooks.json +1 -1
  46. package/hooks/hooks_constants/bash_post_call_dispatcher_constants.py +14 -1
  47. package/hooks/hooks_constants/pr_done_reminder_constants.py +98 -0
  48. package/hooks/hooks_constants/pre_tool_use_dispatcher_constants.py +10 -43
  49. package/hooks/hooks_constants/test_bash_post_call_dispatcher_constants.py +19 -2
  50. package/hooks/hooks_constants/test_pr_done_reminder_constants.py +40 -0
  51. package/hooks/hooks_constants/test_pre_tool_use_dispatcher_constants.py +20 -32
  52. package/package.json +2 -2
  53. package/rules/durable-post-artifacts.md +2 -1
  54. package/rules/git-workflow.md +6 -6
  55. package/scripts/check.ps1 +0 -1
  56. package/{.agents/skills/run-claude-dev-env/driver.mjs → scripts/ci/installer-lifecycle.mjs} +3 -28
  57. package/scripts/ci/installer-lifecycle.test.mjs +26 -0
  58. package/scripts/ci/windows-installer-lifecycle.ps1 +1 -11
  59. package/scripts/dev_env_scripts_constants/shared_tree_constants.py +4 -5
  60. package/{.agents/skills/_shared/pr-loop/scripts → scripts}/durable_post_lint.py +5 -41
  61. 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
  62. package/{.agents/skills/_shared/pr-loop/scripts/test_durable_post_lint_constants.py → scripts/durable_post_lint_config/config/test_constants.py} +1 -1
  63. package/scripts/policy_lint/adapter_detectors.py +13 -6
  64. package/scripts/policy_lint/adapters.py +7 -4
  65. package/scripts/policy_lint/config/constants.py +5 -0
  66. package/scripts/policy_lint/engine.py +48 -4
  67. package/scripts/policy_lint/model.py +1 -0
  68. package/scripts/policy_lint/registry.py +1 -1
  69. package/scripts/policy_lint/selection.py +2 -1
  70. package/scripts/policy_lint/selection_git.py +2 -0
  71. package/scripts/refresh_pstack_plugin_skills.mjs +200 -0
  72. package/scripts/shared_tree_paths.py +32 -3
  73. package/scripts/test_shared_tree_paths.py +33 -0
  74. package/scripts/tests/test_policy_lint_rules_archive.py +120 -0
  75. package/scripts/tests/test_policy_lint_rules_engine.py +25 -4
  76. package/scripts/tests/test_policy_lint_rules_installed_loader.py +29 -0
  77. package/scripts/tests/test_policy_lint_rules_registry.py +227 -13
  78. package/scripts/tests/test_policy_lint_selection.py +25 -2
  79. package/scripts/tests/test_policy_lint_selection_native_index.py +30 -0
  80. package/scripts/tests/test_rules.py +3 -7
  81. package/.agents/skills/_shared/pr-loop/.claude/CLAUDE.md +0 -1
  82. package/.agents/skills/_shared/pr-loop/AGENTS.md +0 -1
  83. package/.agents/skills/_shared/pr-loop/audit-contract.md +0 -5
  84. package/.agents/skills/_shared/pr-loop/audit-reply-template.md +0 -5
  85. package/.agents/skills/_shared/pr-loop/code-rules-gate.md +0 -5
  86. package/.agents/skills/_shared/pr-loop/fix-protocol.md +0 -5
  87. package/.agents/skills/_shared/pr-loop/gh-payloads.md +0 -5
  88. package/.agents/skills/_shared/pr-loop/portable-driver.md +0 -149
  89. package/.agents/skills/_shared/pr-loop/post-audit-thread-contract.md +0 -5
  90. package/.agents/skills/_shared/pr-loop/precatch-rubric.md +0 -5
  91. package/.agents/skills/_shared/pr-loop/preflight-proposal.contract.test.mjs +0 -119
  92. package/.agents/skills/_shared/pr-loop/preflight-proposal.md +0 -5
  93. package/.agents/skills/_shared/pr-loop/prompts/.claude/CLAUDE.md +0 -1
  94. package/.agents/skills/_shared/pr-loop/prompts/AGENTS.md +0 -1
  95. package/.agents/skills/_shared/pr-loop/prompts/pr-consistency-audit.xml +0 -324
  96. package/.agents/skills/_shared/pr-loop/scripts/.claude/CLAUDE.md +0 -1
  97. package/.agents/skills/_shared/pr-loop/scripts/AGENTS.md +0 -1
  98. package/.agents/skills/_shared/pr-loop/scripts/RUNTIME_SCRIPTS.md +0 -29
  99. package/.agents/skills/_shared/pr-loop/scripts/_cli_utils.py +0 -22
  100. package/.agents/skills/_shared/pr-loop/scripts/_path_resolver.py +0 -186
  101. package/.agents/skills/_shared/pr-loop/scripts/_xml_utils.py +0 -20
  102. package/.agents/skills/_shared/pr-loop/scripts/audit_category_schema.py +0 -355
  103. package/.agents/skills/_shared/pr-loop/scripts/build_audit_prompt.py +0 -289
  104. package/.agents/skills/_shared/pr-loop/scripts/build_converge_task_list.py +0 -310
  105. package/.agents/skills/_shared/pr-loop/scripts/build_fix_prompt.py +0 -292
  106. package/.agents/skills/_shared/pr-loop/scripts/init_loop_state.py +0 -134
  107. package/.agents/skills/_shared/pr-loop/scripts/portable_converge_driver.py +0 -1646
  108. package/.agents/skills/_shared/pr-loop/scripts/preflight_worktree.py +0 -392
  109. package/.agents/skills/_shared/pr-loop/scripts/select_converge_pacer.py +0 -215
  110. package/.agents/skills/_shared/pr-loop/scripts/skills_pr_loop_constants/.claude/CLAUDE.md +0 -1
  111. package/.agents/skills/_shared/pr-loop/scripts/skills_pr_loop_constants/AGENTS.md +0 -1
  112. package/.agents/skills/_shared/pr-loop/scripts/skills_pr_loop_constants/__init__.py +0 -0
  113. package/.agents/skills/_shared/pr-loop/scripts/skills_pr_loop_constants/audit_category_schema_constants.py +0 -37
  114. package/.agents/skills/_shared/pr-loop/scripts/skills_pr_loop_constants/converge_task_list_constants.py +0 -56
  115. package/.agents/skills/_shared/pr-loop/scripts/skills_pr_loop_constants/handoff_constants.py +0 -45
  116. package/.agents/skills/_shared/pr-loop/scripts/skills_pr_loop_constants/pacer_constants.py +0 -47
  117. package/.agents/skills/_shared/pr-loop/scripts/skills_pr_loop_constants/path_resolver_constants.py +0 -157
  118. package/.agents/skills/_shared/pr-loop/scripts/skills_pr_loop_constants/portable_driver_constants.py +0 -177
  119. package/.agents/skills/_shared/pr-loop/scripts/skills_pr_loop_constants/preflight_constants.py +0 -70
  120. package/.agents/skills/_shared/pr-loop/scripts/teardown_worktrees.py +0 -172
  121. package/.agents/skills/_shared/pr-loop/scripts/test__path_resolver.py +0 -106
  122. package/.agents/skills/_shared/pr-loop/scripts/test_audit_category_schema.py +0 -94
  123. package/.agents/skills/_shared/pr-loop/scripts/test_build_audit_prompt.py +0 -499
  124. package/.agents/skills/_shared/pr-loop/scripts/test_build_converge_task_list.py +0 -140
  125. package/.agents/skills/_shared/pr-loop/scripts/test_build_fix_prompt.py +0 -262
  126. package/.agents/skills/_shared/pr-loop/scripts/test_init_loop_state.py +0 -71
  127. package/.agents/skills/_shared/pr-loop/scripts/test_portable_converge_driver.py +0 -1119
  128. package/.agents/skills/_shared/pr-loop/scripts/test_preflight_worktree.py +0 -287
  129. package/.agents/skills/_shared/pr-loop/scripts/test_select_converge_pacer.py +0 -207
  130. package/.agents/skills/_shared/pr-loop/scripts/test_teardown_worktrees.py +0 -59
  131. package/.agents/skills/_shared/pr-loop/scripts/test_write_handoff.py +0 -201
  132. package/.agents/skills/_shared/pr-loop/scripts/write_audit_outcomes.py +0 -182
  133. package/.agents/skills/_shared/pr-loop/scripts/write_fix_outcomes.py +0 -206
  134. package/.agents/skills/_shared/pr-loop/scripts/write_handoff.py +0 -309
  135. package/.agents/skills/_shared/pr-loop/state-schema.md +0 -5
  136. package/.agents/skills/_shared/pr-loop/worker-spawn.md +0 -5
  137. package/.agents/skills/autoconverge/.claude/CLAUDE.md +0 -1
  138. package/.agents/skills/autoconverge/AGENTS.md +0 -1
  139. package/.agents/skills/autoconverge/SKILL.md +0 -431
  140. package/.agents/skills/autoconverge/reference/.claude/CLAUDE.md +0 -1
  141. package/.agents/skills/autoconverge/reference/AGENTS.md +0 -1
  142. package/.agents/skills/autoconverge/reference/closing-report.md +0 -93
  143. package/.agents/skills/autoconverge/reference/convergence-gates.md +0 -31
  144. package/.agents/skills/autoconverge/reference/convergence.md +0 -219
  145. package/.agents/skills/autoconverge/reference/copilot-findings.md +0 -51
  146. package/.agents/skills/autoconverge/reference/gotchas.md +0 -66
  147. package/.agents/skills/autoconverge/reference/headless-safety.md +0 -44
  148. package/.agents/skills/autoconverge/reference/multi-pr.md +0 -128
  149. package/.agents/skills/autoconverge/reference/self-closing-loop.md +0 -84
  150. package/.agents/skills/autoconverge/reference/stop-conditions.md +0 -127
  151. package/.agents/skills/autoconverge/test_portable_pacer_gate.py +0 -54
  152. package/.agents/skills/autoconverge/workflow/.claude/CLAUDE.md +0 -1
  153. package/.agents/skills/autoconverge/workflow/AGENTS.md +0 -1
  154. package/.agents/skills/autoconverge/workflow/aggregate_runs.py +0 -371
  155. package/.agents/skills/autoconverge/workflow/autoconverge_report_constants/.claude/CLAUDE.md +0 -1
  156. package/.agents/skills/autoconverge/workflow/autoconverge_report_constants/AGENTS.md +0 -1
  157. package/.agents/skills/autoconverge/workflow/autoconverge_report_constants/__init__.py +0 -0
  158. package/.agents/skills/autoconverge/workflow/autoconverge_report_constants/render_report_constants.py +0 -250
  159. package/.agents/skills/autoconverge/workflow/converge.clean-audit.test.mjs +0 -665
  160. package/.agents/skills/autoconverge/workflow/converge.codex-gate.test.mjs +0 -472
  161. package/.agents/skills/autoconverge/workflow/converge.contract.test.mjs +0 -64
  162. package/.agents/skills/autoconverge/workflow/converge.copilot-gate.test.mjs +0 -1009
  163. package/.agents/skills/autoconverge/workflow/converge.fix-progress.test.mjs +0 -107
  164. package/.agents/skills/autoconverge/workflow/converge.fix-recovery.test.mjs +0 -33
  165. package/.agents/skills/autoconverge/workflow/converge.merge-conflict.test.mjs +0 -15
  166. package/.agents/skills/autoconverge/workflow/converge.mjs +0 -3132
  167. package/.agents/skills/autoconverge/workflow/converge.p2-advance.test.mjs +0 -202
  168. package/.agents/skills/autoconverge/workflow/converge.path-aware.test.mjs +0 -47
  169. package/.agents/skills/autoconverge/workflow/converge.precatch.test.mjs +0 -152
  170. package/.agents/skills/autoconverge/workflow/converge.run-input.test.mjs +0 -116
  171. package/.agents/skills/autoconverge/workflow/converge_multi.mjs +0 -169
  172. package/.agents/skills/autoconverge/workflow/converge_multi.run-input.test.mjs +0 -173
  173. package/.agents/skills/autoconverge/workflow/convergence_summary.py +0 -110
  174. package/.agents/skills/autoconverge/workflow/fixtures/wf_run/subagents/workflows/wf_881252e6-700/agent-a11d903476b803493.jsonl +0 -2
  175. package/.agents/skills/autoconverge/workflow/fixtures/wf_run/subagents/workflows/wf_881252e6-700/agent-a26213978adeef6fb.jsonl +0 -2
  176. package/.agents/skills/autoconverge/workflow/fixtures/wf_run/subagents/workflows/wf_881252e6-700/agent-a3def0d15ed9d9110.jsonl +0 -2
  177. package/.agents/skills/autoconverge/workflow/fixtures/wf_run/subagents/workflows/wf_881252e6-700/agent-a41f41b1b708ee3b7.jsonl +0 -2
  178. package/.agents/skills/autoconverge/workflow/fixtures/wf_run/subagents/workflows/wf_881252e6-700/agent-a758b880abecc3ff7.jsonl +0 -2
  179. package/.agents/skills/autoconverge/workflow/fixtures/wf_run/subagents/workflows/wf_881252e6-700/agent-a8897b89656b1bd16.jsonl +0 -2
  180. package/.agents/skills/autoconverge/workflow/fixtures/wf_run/subagents/workflows/wf_881252e6-700/agent-ab1c2d3e4f5a6b7c8.jsonl +0 -2
  181. package/.agents/skills/autoconverge/workflow/fixtures/wf_run/subagents/workflows/wf_881252e6-700/agent-abd463d744a1437bc.jsonl +0 -2
  182. package/.agents/skills/autoconverge/workflow/fixtures/wf_run/subagents/workflows/wf_881252e6-700/agent-ad19d027ae8ee1816.jsonl +0 -2
  183. package/.agents/skills/autoconverge/workflow/fixtures/wf_run/workflows/wf_881252e6-700.json +0 -266
  184. package/.agents/skills/autoconverge/workflow/render_report.py +0 -1024
  185. package/.agents/skills/autoconverge/workflow/test_aggregate_runs.py +0 -134
  186. package/.agents/skills/autoconverge/workflow/test_convergence_summary.py +0 -149
  187. package/.agents/skills/autoconverge/workflow/test_render_report.py +0 -812
  188. package/.agents/skills/hitl/SKILL.md +0 -45
  189. package/.agents/skills/pr-cleanup/SKILL.md +0 -140
  190. package/.agents/skills/pr-cleanup/reference/process-inventory.md +0 -17
  191. package/.agents/skills/pr-cleanup/reference/task-seeds.md +0 -22
  192. package/.agents/skills/pr-name-by-capability/SKILL.md +0 -73
  193. package/.agents/skills/pr-name-by-capability/reference/fetch-commands.md +0 -29
  194. package/.agents/skills/pr-name-by-capability/reference/offense-examples.md +0 -32
  195. package/.agents/skills/pr-name-by-capability/reference/report-template.md +0 -29
  196. package/.agents/skills/pr-name-by-capability/reference/rule-checklist.md +0 -38
  197. package/.agents/skills/pr-name-by-capability/reference/task-seeds.md +0 -10
  198. package/.agents/skills/pr-plain-language-cleanup/SKILL.md +0 -93
  199. package/.agents/skills/pr-refinement/SKILL.md +0 -31
  200. package/.agents/skills/pr-shared-extraction/SKILL.md +0 -177
  201. package/.agents/skills/pr-shared-extraction/reference/examples.md +0 -46
  202. package/.agents/skills/pr-shared-extraction/reference/offense-taxonomy.md +0 -100
  203. package/.agents/skills/pr-small-cl/SKILL.md +0 -52
  204. package/.agents/skills/pr-title-description/SKILL.md +0 -96
  205. package/.agents/skills/prototype/SKILL.md +0 -85
  206. package/.agents/skills/prototype/reference/honest-limitations.md +0 -23
  207. package/.agents/skills/prototype/reference/promotion-tasks.md +0 -23
  208. package/.agents/skills/prototype/scripts/build_sandbox_settings.py +0 -249
  209. package/.agents/skills/prototype/scripts/conftest.py +0 -15
  210. package/.agents/skills/prototype/scripts/launch_sandbox.py +0 -205
  211. package/.agents/skills/prototype/scripts/probe_sandbox_safety.py +0 -311
  212. package/.agents/skills/prototype/scripts/prototype_scripts_constants/__init__.py +0 -1
  213. package/.agents/skills/prototype/scripts/prototype_scripts_constants/config/__init__.py +0 -0
  214. package/.agents/skills/prototype/scripts/prototype_scripts_constants/config/build_sandbox_settings_constants.py +0 -41
  215. package/.agents/skills/prototype/scripts/prototype_scripts_constants/config/launch_sandbox_constants.py +0 -23
  216. package/.agents/skills/prototype/scripts/prototype_scripts_constants/config/probe_sandbox_safety_constants.py +0 -45
  217. package/.agents/skills/prototype/scripts/prototype_scripts_constants/config/prototype_common_constants.py +0 -10
  218. package/.agents/skills/prototype/scripts/test_build_sandbox_settings.py +0 -275
  219. package/.agents/skills/prototype/scripts/test_launch_sandbox.py +0 -303
  220. package/.agents/skills/prototype/scripts/test_probe_sandbox_safety.py +0 -312
  221. package/.agents/skills/prototype/workflows/promotion.md +0 -25
  222. package/.agents/skills/prototype/workflows/sandbox.md +0 -35
  223. package/.agents/skills/rebase/.claude/CLAUDE.md +0 -1
  224. package/.agents/skills/rebase/AGENTS.md +0 -1
  225. package/.agents/skills/rebase/SKILL.md +0 -178
  226. package/.agents/skills/review-router/SKILL.md +0 -51
  227. package/.agents/skills/review-router/reference/route-policy.json +0 -7
  228. package/.agents/skills/review-router/reference/task-seeds.md +0 -1
  229. package/.agents/skills/review-router/scripts/conftest.py +0 -4
  230. package/.agents/skills/review-router/scripts/review_router.py +0 -50
  231. package/.agents/skills/review-router/scripts/review_router_cli.py +0 -211
  232. package/.agents/skills/review-router/scripts/review_router_constants/__init__.py +0 -1
  233. package/.agents/skills/review-router/scripts/review_router_constants/config/__init__.py +0 -0
  234. package/.agents/skills/review-router/scripts/review_router_constants/config/constants.py +0 -13
  235. package/.agents/skills/review-router/scripts/test_review_router.py +0 -23
  236. package/.agents/skills/review-router/scripts/test_review_router_cli.py +0 -47
  237. package/.agents/skills/review-tier/SKILL.md +0 -56
  238. package/.agents/skills/review-tier/reference/task-seeds.md +0 -1
  239. package/.agents/skills/review-tier/reference/tier-policy.json +0 -9
  240. package/.agents/skills/review-tier/scripts/conftest.py +0 -4
  241. package/.agents/skills/review-tier/scripts/review_tier.py +0 -359
  242. package/.agents/skills/review-tier/scripts/review_tier_constants/__init__.py +0 -1
  243. package/.agents/skills/review-tier/scripts/review_tier_constants/config/__init__.py +0 -0
  244. package/.agents/skills/review-tier/scripts/review_tier_constants/config/constants.py +0 -29
  245. package/.agents/skills/review-tier/scripts/test_generation.py +0 -159
  246. package/.agents/skills/review-tier/scripts/test_review_tier.py +0 -33
  247. package/.agents/skills/run-claude-dev-env/SKILL.md +0 -84
  248. package/.agents/skills/session-log/.claude/CLAUDE.md +0 -1
  249. package/.agents/skills/session-log/AGENTS.md +0 -1
  250. package/.agents/skills/session-log/SKILL.md +0 -170
  251. package/.agents/skills/session-log/templates/frontmatter.md +0 -40
  252. package/.agents/skills/session-tidy/.claude/CLAUDE.md +0 -1
  253. package/.agents/skills/session-tidy/AGENTS.md +0 -1
  254. package/.agents/skills/session-tidy/SKILL.md +0 -191
  255. package/.agents/skills/skill-builder/references/.claude/CLAUDE.md +0 -1
  256. package/.agents/skills/skill-builder/references/AGENTS.md +0 -1
  257. package/.agents/skills/skill-builder/references/delegation-map.md +0 -130
  258. package/.agents/skills/skill-builder/references/description-field.md +0 -111
  259. package/.agents/skills/skill-builder/references/deterministic-elements.md +0 -218
  260. package/.agents/skills/skill-builder/references/progressive-disclosure.md +0 -122
  261. package/.agents/skills/skill-builder/references/self-audit-checklist.md +0 -126
  262. package/.agents/skills/skill-builder/references/skill-modularity.md +0 -111
  263. package/.agents/skills/skill-builder/references/skill-types.md +0 -232
  264. package/.agents/skills/skill-builder/references/thariq-x-post-skills.json +0 -33
  265. package/.agents/skills/skill-builder/templates/.claude/CLAUDE.md +0 -1
  266. package/.agents/skills/skill-builder/templates/AGENTS.md +0 -1
  267. package/.agents/skills/skill-builder/templates/gap-analysis.md +0 -87
  268. package/.agents/skills/skill-builder/workflows/.claude/CLAUDE.md +0 -1
  269. package/.agents/skills/skill-builder/workflows/AGENTS.md +0 -1
  270. package/.agents/skills/skill-builder/workflows/improve-skill.md +0 -136
  271. package/.agents/skills/skill-builder/workflows/new-skill.md +0 -179
  272. package/.agents/skills/skill-builder/workflows/polish-skill.md +0 -139
  273. package/.agents/skills/source-command-sr-loop/SKILL.md +0 -82
  274. package/.agents/skills/update/.claude/CLAUDE.md +0 -1
  275. package/.agents/skills/update/AGENTS.md +0 -1
  276. package/.agents/skills/update/SKILL.md +0 -190
  277. package/_shared/pr-loop/AGENTS.md +0 -1
  278. package/_shared/pr-loop/CLAUDE.md +0 -1
  279. package/_shared/pr-loop/audit-contract.md +0 -183
  280. package/_shared/pr-loop/audit-reply-template.md +0 -151
  281. package/_shared/pr-loop/code-rules-gate.md +0 -65
  282. package/_shared/pr-loop/fix-protocol.md +0 -60
  283. package/_shared/pr-loop/gh-payloads.md +0 -75
  284. package/_shared/pr-loop/post-audit-thread-contract.md +0 -51
  285. package/_shared/pr-loop/precatch-rubric.md +0 -66
  286. package/_shared/pr-loop/preflight-proposal.md +0 -56
  287. package/_shared/pr-loop/scripts/post_audit_thread.py +0 -1242
  288. package/_shared/pr-loop/scripts/pr_loop_shared_constants/post_audit_thread_constants.py +0 -199
  289. package/_shared/pr-loop/scripts/tests/test_post_audit_thread.py +0 -1115
  290. package/_shared/pr-loop/scripts/tests/test_post_audit_thread_constants.py +0 -129
  291. package/_shared/pr-loop/state-schema.md +0 -45
  292. package/_shared/pr-loop/worker-spawn.md +0 -189
  293. /package/{.agents/skills/_shared/pr-loop/scripts → scripts}/test_durable_post_lint.py +0 -0
@@ -0,0 +1,29 @@
1
+ """Load terminology through the verified installed shared-tree resolver."""
2
+
3
+ from __future__ import annotations
4
+
5
+ import sys
6
+ from pathlib import Path
7
+
8
+ import pytest
9
+ from policy_lint import adapters
10
+
11
+
12
+ def test_pr_loop_loader_uses_the_shared_tree_resolver(
13
+ tmp_path: Path, monkeypatch: pytest.MonkeyPatch,
14
+ ) -> None:
15
+ module_name = "policy_fixture_terminology"
16
+ (tmp_path / f"{module_name}.py").write_text("IS_FIXTURE = True\n", encoding="utf-8")
17
+ all_calls: list[tuple[object, ...]] = []
18
+
19
+ def resolve_directory(*all_arguments: object) -> Path:
20
+ all_calls.append(all_arguments)
21
+ return tmp_path
22
+
23
+ monkeypatch.setattr(adapters, "resolve_shared_scripts_directory", resolve_directory)
24
+ monkeypatch.setattr(sys, "path", list(sys.path))
25
+ loaded = adapters._pr_loop_script_module(module_name)
26
+ assert loaded.IS_FIXTURE is True
27
+ assert Path(loaded.__file__).parent == tmp_path
28
+ assert all_calls[0][2:] == ("pr-loop", f"{module_name}.py", 2)
29
+ monkeypatch.delitem(sys.modules, module_name)
@@ -15,6 +15,7 @@ from policy_lint.model import (
15
15
  Document,
16
16
  DocumentRule,
17
17
  DocumentSet,
18
+ LintReport,
18
19
  LintRequest,
19
20
  SelectionKind,
20
21
  )
@@ -96,6 +97,164 @@ def _terminology_rule() -> ChangeSetRule:
96
97
  return terminology_rule
97
98
 
98
99
 
100
+ def _head_revision(repository_root: Path) -> str:
101
+ completed = subprocess.run(
102
+ ("git", "rev-parse", "HEAD"),
103
+ cwd=repository_root,
104
+ check=True,
105
+ capture_output=True,
106
+ text=True,
107
+ )
108
+ return completed.stdout.strip()
109
+
110
+
111
+ def _git_add(repository_root: Path, *all_paths: str) -> None:
112
+ subprocess.run(
113
+ ("git", "add", *all_paths),
114
+ cwd=repository_root,
115
+ check=True,
116
+ capture_output=True,
117
+ )
118
+
119
+
120
+ def _quota_document_paths(
121
+ repository_root: Path,
122
+ source_name: str = "quota.py",
123
+ documentation_name: str = "README.md",
124
+ ) -> tuple[Path, Path]:
125
+ source_path = repository_root / "src" / source_name
126
+ documentation_path = repository_root / "docs" / documentation_name
127
+ source_path.parent.mkdir(parents=True, exist_ok=True)
128
+ documentation_path.parent.mkdir(parents=True, exist_ok=True)
129
+ return source_path, documentation_path
130
+
131
+
132
+ def _write_text(file_path: Path, text: str) -> None:
133
+ file_path.write_text(text, encoding="utf-8")
134
+
135
+
136
+ def _commit_quota_base(
137
+ repository_root: Path,
138
+ source_text: str,
139
+ documentation_text: str,
140
+ source_name: str = "quota.py",
141
+ documentation_name: str = "README.md",
142
+ ) -> tuple[Path, Path, str]:
143
+ _ensure_git_repository(repository_root)
144
+ source_path, documentation_path = _quota_document_paths(
145
+ repository_root, source_name, documentation_name
146
+ )
147
+ _write_text(source_path, source_text)
148
+ _write_text(documentation_path, documentation_text)
149
+ _commit_repository(repository_root, "base")
150
+ return source_path, documentation_path, _head_revision(repository_root)
151
+
152
+
153
+ def _commit_identifier_then_documentation(
154
+ repository_root: Path,
155
+ source_path: Path,
156
+ documentation_path: Path,
157
+ ) -> None:
158
+ _write_text(source_path, "baseline = 1\npremium_request_interactions = 5\n")
159
+ _commit_repository(repository_root, "identifier")
160
+ _write_text(
161
+ documentation_path,
162
+ "The premium-request-budget field gates the run.\n",
163
+ )
164
+ _commit_repository(repository_root, "documentation")
165
+
166
+
167
+ def _committed_near_miss_from_base(
168
+ repository_root: Path,
169
+ ) -> tuple[Path, Path, str]:
170
+ source_path, documentation_path, comparison_revision = _commit_quota_base(
171
+ repository_root,
172
+ "baseline = 1\n",
173
+ "Baseline quota text.\n",
174
+ )
175
+ _commit_identifier_then_documentation(
176
+ repository_root, source_path, documentation_path
177
+ )
178
+ return source_path, documentation_path, comparison_revision
179
+
180
+
181
+ def _stage_unrelated_index_file(repository_root: Path) -> None:
182
+ _write_text(repository_root / "staged.txt", "unrelated index content\n")
183
+ _git_add(repository_root, "--", "staged.txt")
184
+
185
+
186
+ def _worktree_and_index_near_miss_repository(repository_root: Path) -> str:
187
+ source_path, documentation_path, comparison_revision = (
188
+ _committed_near_miss_from_base(repository_root)
189
+ )
190
+ _write_text(
191
+ source_path,
192
+ "baseline = 1\npremium_request_interactions = 5\nanother_request_total = 2\n",
193
+ )
194
+ _write_text(
195
+ documentation_path,
196
+ "The another-request-budget field gates the run.\n",
197
+ )
198
+ _git_add(repository_root, "-A")
199
+ _write_text(
200
+ documentation_path,
201
+ "The another-request-total field gates the run.\n",
202
+ )
203
+ return comparison_revision
204
+
205
+
206
+ def _existing_identifier_from_base(repository_root: Path) -> str:
207
+ source_path, documentation_path, comparison_revision = _commit_quota_base(
208
+ repository_root,
209
+ "premium_request_interactions = 5\n",
210
+ "Baseline quota text.\n",
211
+ )
212
+ _write_text(
213
+ source_path,
214
+ "premium_request_interactions = 5\npremium_request_interactions = 6\n",
215
+ )
216
+ _write_text(
217
+ documentation_path,
218
+ "The premium-request-budget field gates the run.\n",
219
+ )
220
+ _commit_repository(repository_root, "existing identifier")
221
+ return comparison_revision
222
+
223
+
224
+ def _renamed_and_deleted_near_miss_from_base(repository_root: Path) -> str:
225
+ old_source_path, deleted_documentation_path, comparison_revision = (
226
+ _commit_quota_base(
227
+ repository_root,
228
+ "baseline = 1\n",
229
+ "Obsolete quota text.\n",
230
+ "old_quota.py",
231
+ "obsolete.md",
232
+ )
233
+ )
234
+ new_source_path = repository_root / "src" / "new_quota.py"
235
+ subprocess.run(
236
+ ("git", "mv", "--", str(old_source_path), str(new_source_path)),
237
+ cwd=repository_root,
238
+ check=True,
239
+ capture_output=True,
240
+ )
241
+ _write_text(new_source_path, "baseline = 1\npremium_request_interactions = 5\n")
242
+ deleted_documentation_path.unlink()
243
+ _write_text(
244
+ repository_root / "docs" / "README.md",
245
+ "The premium-request-budget field gates the run.\n",
246
+ )
247
+ _commit_repository(repository_root, "rename and delete")
248
+ return comparison_revision
249
+
250
+
251
+ def _lint_base(repository_root: Path, comparison_revision: str) -> LintReport:
252
+ return lint(
253
+ LintRequest.base(repository_root, comparison_revision),
254
+ all_registry=(_terminology_rule(),),
255
+ )
256
+
257
+
99
258
  def test_hook_format_accepts_claude_settings() -> None:
100
259
  settings_document = Document.from_text(".claude/settings.json", "{}")
101
260
  hooks_document = Document.from_text("hooks/hooks.json", "{}")
@@ -161,7 +320,7 @@ def test_test_pairing_diagnostics_exempts_constants_only_python_modules(
161
320
  (
162
321
  Document.from_text(
163
322
  "hooks_constants/tool_names.py",
164
- "TOOL_NAME: str = \"tool\"\n",
323
+ 'TOOL_NAME: str = "tool"\n',
165
324
  ),
166
325
  ),
167
326
  SelectionKind.STAGED,
@@ -244,9 +403,7 @@ def test_hook_configuration_diagnostics_rejects_registered_action_boundary_path(
244
403
  json.dumps(
245
404
  {
246
405
  "hooks": {
247
- "PreToolUse": [
248
- {"hooks": [{"command": "hooks/blocking/deny.py"}]}
249
- ]
406
+ "PreToolUse": [{"hooks": [{"command": "hooks/blocking/deny.py"}]}]
250
407
  }
251
408
  }
252
409
  ),
@@ -263,7 +420,9 @@ def test_hook_configuration_diagnostics_ignore_description_text(tmp_path: Path)
263
420
  "hooks/hooks.json",
264
421
  json.dumps({"description": "blocking safety controls", "hooks": {}}),
265
422
  )
266
- assert adapters.hook_configuration_diagnostics(configuration_document, tmp_path) == ()
423
+ assert (
424
+ adapters.hook_configuration_diagnostics(configuration_document, tmp_path) == ()
425
+ )
267
426
 
268
427
 
269
428
  def test_hook_configuration_diagnostics_ignore_task_path(tmp_path: Path) -> None:
@@ -271,7 +430,9 @@ def test_hook_configuration_diagnostics_ignore_task_path(tmp_path: Path) -> None
271
430
  "hooks/hooks.json",
272
431
  json.dumps({"hooks": {"PostToolUse": [{"command": "task_runner.py"}]}}),
273
432
  )
274
- assert adapters.hook_configuration_diagnostics(configuration_document, tmp_path) == ()
433
+ assert (
434
+ adapters.hook_configuration_diagnostics(configuration_document, tmp_path) == ()
435
+ )
275
436
 
276
437
 
277
438
  def test_registry_omits_native_ruff_mypy_javascript_adapters() -> None:
@@ -291,7 +452,9 @@ def test_registry_registers_unique_python_validator_rule() -> None:
291
452
  def test_registry_registers_terminology_change_set_rule() -> None:
292
453
  terminology_rule = _terminology_rule()
293
454
  assert terminology_rule.rule_sets == _CHANGED_RULE_SETS
294
- assert terminology_rule.selections == frozenset({SelectionKind.STAGED})
455
+ assert terminology_rule.selections == frozenset(
456
+ {SelectionKind.STAGED, SelectionKind.BASE}
457
+ )
295
458
 
296
459
 
297
460
  def test_registry_runs_test_pairing_for_staged_and_base_changes() -> None:
@@ -313,10 +476,11 @@ def test_terminology_rule_reports_cross_surface_path_and_line(
313
476
  tmp_path,
314
477
  "baseline = 1\n",
315
478
  "premium_request_interactions = 5\n",
316
- "Quota fields use one name.\n"
317
- "The premium-request-budget field gates the run.\n",
479
+ "Quota fields use one name.\nThe premium-request-budget field gates the run.\n",
480
+ )
481
+ lint_report = lint(
482
+ LintRequest.staged(tmp_path), all_registry=(_terminology_rule(),)
318
483
  )
319
- lint_report = lint(LintRequest.staged(tmp_path), all_registry=(_terminology_rule(),))
320
484
 
321
485
  assert len(lint_report.diagnostics) == 1
322
486
  diagnostic = lint_report.diagnostics[0]
@@ -332,15 +496,65 @@ def test_terminology_rule_suppresses_identifier_present_in_prior_tree(
332
496
  _stage_terminology_change(
333
497
  tmp_path,
334
498
  "premium_request_interactions = 5\n",
335
- "premium_request_interactions = 5\n"
336
- "premium_request_interactions = 6\n",
499
+ "premium_request_interactions = 5\npremium_request_interactions = 6\n",
337
500
  "The premium-request-budget field gates the run.\n",
338
501
  )
339
- lint_report = lint(LintRequest.staged(tmp_path), all_registry=(_terminology_rule(),))
502
+ lint_report = lint(
503
+ LintRequest.staged(tmp_path), all_registry=(_terminology_rule(),)
504
+ )
505
+
506
+ assert lint_report.diagnostics == ()
507
+
508
+
509
+ def test_terminology_rule_reports_committed_changes_from_base(
510
+ tmp_path: Path,
511
+ ) -> None:
512
+ _, _, comparison_revision = _committed_near_miss_from_base(tmp_path)
513
+ _stage_unrelated_index_file(tmp_path)
514
+ lint_report = _lint_base(tmp_path, comparison_revision)
515
+ assert lint_report.failed_rules == ()
516
+ assert len(lint_report.diagnostics) == 1
517
+ assert lint_report.diagnostics[0].location is not None
518
+ assert lint_report.diagnostics[0].location.path == PurePosixPath("docs/README.md")
519
+
520
+
521
+ def test_terminology_base_uses_worktree_while_staged_uses_index(
522
+ tmp_path: Path,
523
+ ) -> None:
524
+ comparison_revision = _worktree_and_index_near_miss_repository(tmp_path)
525
+ base_report = _lint_base(tmp_path, comparison_revision)
526
+ staged_report = lint(
527
+ LintRequest.staged(tmp_path),
528
+ all_registry=(_terminology_rule(),),
529
+ )
530
+ assert base_report.failed_rules == ()
531
+ assert staged_report.failed_rules == ()
532
+ assert base_report.diagnostics == ()
533
+ assert len(staged_report.diagnostics) == 1
534
+ assert staged_report.diagnostics[0].location is not None
535
+ assert staged_report.diagnostics[0].location.path == PurePosixPath("docs/README.md")
340
536
 
537
+
538
+ def test_terminology_base_suppresses_identifier_present_in_comparison_base(
539
+ tmp_path: Path,
540
+ ) -> None:
541
+ comparison_revision = _existing_identifier_from_base(tmp_path)
542
+ lint_report = _lint_base(tmp_path, comparison_revision)
543
+ assert lint_report.failed_rules == ()
341
544
  assert lint_report.diagnostics == ()
342
545
 
343
546
 
547
+ def test_terminology_base_handles_renames_and_deletions(
548
+ tmp_path: Path,
549
+ ) -> None:
550
+ comparison_revision = _renamed_and_deleted_near_miss_from_base(tmp_path)
551
+ lint_report = _lint_base(tmp_path, comparison_revision)
552
+ assert lint_report.failed_rules == ()
553
+ assert len(lint_report.diagnostics) == 1
554
+ assert lint_report.diagnostics[0].location is not None
555
+ assert lint_report.diagnostics[0].location.path == PurePosixPath("docs/README.md")
556
+
557
+
344
558
  def test_terminology_rule_skips_file_selection(tmp_path: Path) -> None:
345
559
  document_set = DocumentSet(
346
560
  (Document.from_text("docs/README.md", "text\n"),),
@@ -28,7 +28,7 @@ def _git_environment() -> dict[str, str]:
28
28
  }
29
29
 
30
30
 
31
- def _run_git(repository_root: Path, *all_arguments: str) -> None:
31
+ def _git_stdout(repository_root: Path, *all_arguments: str) -> str:
32
32
  completed = subprocess.run(
33
33
  [constants.GIT_EXECUTABLE, *all_arguments],
34
34
  cwd=repository_root,
@@ -38,6 +38,11 @@ def _run_git(repository_root: Path, *all_arguments: str) -> None:
38
38
  env=_git_environment(),
39
39
  )
40
40
  assert completed.returncode == 0, completed.stderr
41
+ return completed.stdout.strip()
42
+
43
+
44
+ def _run_git(repository_root: Path, *all_arguments: str) -> None:
45
+ _git_stdout(repository_root, *all_arguments)
41
46
 
42
47
 
43
48
  def _initialize_repository(repository_root: Path) -> Path:
@@ -200,7 +205,9 @@ def test_staged_missing_non_delete_blob_should_raise(
200
205
  def test_git_blob_unexpected_failure_should_raise(
201
206
  tmp_path: Path, monkeypatch: pytest.MonkeyPatch
202
207
  ) -> None:
203
- def failed_git(*_all_arguments: object, **_all_keywords: object) -> subprocess.CompletedProcess[bytes]:
208
+ def failed_git(
209
+ *_all_arguments: object, **_all_keywords: object
210
+ ) -> subprocess.CompletedProcess[bytes]:
204
211
  return subprocess.CompletedProcess(
205
212
  args=[constants.GIT_EXECUTABLE],
206
213
  returncode=1,
@@ -254,6 +261,22 @@ def test_base_source_should_compare_merge_base_and_read_worktree_bytes(
254
261
  assert selected_document.origin == ContentOrigin.REVISION_DIFF
255
262
 
256
263
 
264
+ def test_base_selection_records_merge_base_revision_and_staged_does_not(
265
+ tmp_path: Path,
266
+ ) -> None:
267
+ repository_root = _initialize_repository(tmp_path)
268
+ _commit_text(repository_root, "file.py", "base-text\n")
269
+ _run_git(repository_root, "checkout", "--quiet", "-b", "feature")
270
+ _commit_text(repository_root, "file.py", "feature-committed\n")
271
+
272
+ merge_base = _git_stdout(repository_root, "merge-base", "main", "HEAD")
273
+ base_document_set = select_documents(LintRequest.base(repository_root, "main"))
274
+ staged_document_set = select_documents(LintRequest.staged(repository_root))
275
+
276
+ assert base_document_set.base_revision == merge_base
277
+ assert staged_document_set.base_revision is None
278
+
279
+
257
280
  def test_repository_source_should_read_tracked_worktree_files_only(
258
281
  tmp_path: Path,
259
282
  ) -> None:
@@ -0,0 +1,30 @@
1
+ """Preserve Git's active index without accepting repository-directory overrides."""
2
+
3
+ from __future__ import annotations
4
+
5
+ from pathlib import Path
6
+
7
+ import pytest
8
+ from policy_lint import selection_git
9
+
10
+
11
+ def test_active_git_index_survives_environment_sanitization(
12
+ tmp_path: Path, monkeypatch: pytest.MonkeyPatch,
13
+ ) -> None:
14
+ index_path = tmp_path / "index"
15
+ monkeypatch.setenv("GIT_INDEX_FILE", str(index_path))
16
+ monkeypatch.setenv("GIT_DIR", "foreign-repository")
17
+ monkeypatch.setenv("GIT_WORK_TREE", "foreign-worktree")
18
+ monkeypatch.setenv("PRESERVED_SETTING", "fixture")
19
+ active_environment = selection_git._git_subprocess_environment()
20
+ assert active_environment["GIT_INDEX_FILE"] == str(index_path)
21
+ assert "GIT_DIR" not in active_environment
22
+ assert "GIT_WORK_TREE" not in active_environment
23
+ assert active_environment["PRESERVED_SETTING"] == "fixture"
24
+
25
+
26
+ def test_default_index_is_not_replaced_by_an_invented_path(
27
+ monkeypatch: pytest.MonkeyPatch,
28
+ ) -> None:
29
+ monkeypatch.delenv("GIT_INDEX_FILE", raising=False)
30
+ assert "GIT_INDEX_FILE" not in selection_git._git_subprocess_environment()
@@ -96,7 +96,6 @@ def _comment_policy_surfaces(package_root: Path) -> tuple[Path, ...]:
96
96
  package_root / "system-prompts" / "software-engineer.xml",
97
97
  package_root / ".agents" / "agents" / "clean-coder.md",
98
98
  package_root / ".agents" / "agents" / "code-quality-agent.md",
99
- package_root / "_shared" / "pr-loop" / "code-rules-gate.md",
100
99
  package_root / "audit-rubrics" / "category_rubrics" / "category-j-code-rules-compliance.md",
101
100
  package_root / "audit-rubrics" / "prompts" / "category-j-code-rules-compliance.md",
102
101
  package_root / "audit-rubrics" / "category_rubrics" / "category-l-behavior-equivalence.md",
@@ -160,7 +159,7 @@ def _category_l_policy_texts() -> tuple[str, str, str]:
160
159
  )
161
160
 
162
161
 
163
- def _comment_policy_summary_texts() -> tuple[str, str, str, str]:
162
+ def _comment_policy_summary_texts() -> tuple[str, str, str]:
164
163
  clean_coder = _PACKAGE_ROOT / ".agents" / "agents" / "clean-coder.md"
165
164
  category_j = (
166
165
  _PACKAGE_ROOT
@@ -169,24 +168,21 @@ def _comment_policy_summary_texts() -> tuple[str, str, str, str]:
169
168
  / "category-j-code-rules-compliance.md"
170
169
  )
171
170
  code_quality = _PACKAGE_ROOT / ".agents" / "agents" / "code-quality-agent.md"
172
- gate = _PACKAGE_ROOT / "_shared" / "pr-loop" / "code-rules-gate.md"
173
171
  return tuple(
174
172
  each_path.read_text(encoding="utf-8").lower()
175
- for each_path in (clean_coder, category_j, code_quality, gate)
173
+ for each_path in (clean_coder, category_j, code_quality)
176
174
  )
177
175
 
178
176
 
179
177
  def test_comment_policy_uses_changed_comment_names_and_type_directives() -> None:
180
178
  category_l_rubric, category_l_prompt, audit_categories = _category_l_policy_texts()
181
- clean_coder, category_j, code_quality, gate = _comment_policy_summary_texts()
179
+ clean_coder, category_j, code_quality = _comment_policy_summary_texts()
182
180
  assert "| l7 | changed-comment handling" in category_l_rubric
183
181
  assert "**l7. changed-comment handling**" in category_l_prompt
184
182
  assert '"axis_name": "changed-comment handling"' in audit_categories
185
183
  assert "no type-ignore directives" in clean_coder
186
184
  assert "no `# type: ignore` directives" in category_j
187
185
  assert "production and test code" in code_quality
188
- assert "comments tied to touched code are removed" in gate
189
- assert "comments tied to untouched code remain unchanged" in gate
190
186
 
191
187
 
192
188
  def test_comment_policy_removes_directive_justification_guidance() -> None:
@@ -1 +0,0 @@
1
- @../AGENTS.md
@@ -1,5 +0,0 @@
1
- # Audit contract
2
-
3
- **Canonical home:**
4
-
5
- @~/.claude/_shared/pr-loop/audit-contract.md
@@ -1,5 +0,0 @@
1
- # Audit reply template
2
-
3
- **Canonical home:**
4
-
5
- @~/.claude/_shared/pr-loop/audit-reply-template.md
@@ -1,5 +0,0 @@
1
- # Code rules gate
2
-
3
- **Canonical home:**
4
-
5
- @~/.claude/_shared/pr-loop/code-rules-gate.md
@@ -1,5 +0,0 @@
1
- # Fix protocol
2
-
3
- **Canonical home:**
4
-
5
- @~/.claude/_shared/pr-loop/fix-protocol.md
@@ -1,5 +0,0 @@
1
- # Gh payloads
2
-
3
- **Canonical home:**
4
-
5
- @~/.claude/_shared/pr-loop/gh-payloads.md
@@ -1,149 +0,0 @@
1
- # Portable converge driver
2
-
3
- **Rule: deterministic control is script-only.** Phase transitions, wait delays,
4
- clean stamps, ready decisions, task lists, and “what next” never live as prose
5
- for the agent to invent. The agent runs scripts, reads JSON, and only performs
6
- judgment steps the JSON names.
7
-
8
- ## Step 1 — task list (every autoconverge portable run)
9
-
10
- ```
11
- python "$HOME/.claude/skills/_shared/pr-loop/scripts/build_converge_task_list.py" \
12
- [--bugbot-down 0|1] [--copilot-down 0|1] \
13
- [--codex-down 0|1] [--codex-required 0|1]
14
- ```
15
-
16
- Register every `tasks[]` entry on the session task list. **Final task id is
17
- always** `all_runnable_reviews_clean_same_head`. The run is complete only when
18
- that final task is completed: every runnable code review is CLEAN on one
19
- shared HEAD. Do not invent tasks in prose.
20
-
21
- `open-run` embeds the same list (`tasks`, `runnable_review_ids`,
22
- `final_task_id`, `done_when`).
23
-
24
- ## Pacer selection
25
-
26
- ```
27
- python "$HOME/.claude/skills/_shared/pr-loop/scripts/select_converge_pacer.py" \
28
- --skill autoconverge \
29
- --has-workflow <0|1> \
30
- --has-schedule-wakeup <0|1>
31
- ```
32
-
33
- When `pacer` is not `portable`, use the skill’s native Workflow or
34
- ScheduleWakeup path. When `pacer=portable`, use the control script below.
35
-
36
- ## Isolation and worktree
37
-
38
- 1. When the tool list includes `EnterWorktree`, call it (same contract as the
39
- Claude-host skills).
40
- 2. When `EnterWorktree` is absent, isolate with git worktree machinery:
41
- - Prefer an existing worktree already on the PR head ref under
42
- `.claude/worktrees/` (or another dedicated worktree path).
43
- - Otherwise `git fetch origin <headRefName>` and
44
- `git worktree add <path> <headRefName>` (or `gh pr checkout <N>` into a
45
- dedicated directory), then `cd` into that checkout.
46
- 3. Confirm the working directory is the PR’s own repo on the PR head SHA:
47
- `python "$HOME/.claude/skills/_shared/pr-loop/scripts/preflight_worktree.py" --owner <O> --repo <R> --mode strict`.
48
- Non-zero exit → report the `ABORT` line and stop.
49
- 4. Cross-repo routing: every local review and edit runs with cwd set to the **PR worktree** (see autoconverge pre-flight and `preflight_worktree.py --mode strict`).
50
-
51
- `open-run` runs the same strict preflight before seeding state.
52
-
53
- ## Control script
54
-
55
- ```
56
- python "$HOME/.claude/skills/_shared/pr-loop/scripts/portable_converge_driver.py" <command> ...
57
- ```
58
-
59
- Stdout JSON: `status`, `next`, `phase`, `state_file`, optional `commands`,
60
- `wait_seconds`, `blocker`, and on `open-run` the task-list fields. Exit `0` =
61
- ok; `1` = contract failure; `2` = usage error.
62
-
63
- | Command | Deterministic effect |
64
- |---|---|
65
- | `open-run` | Require `portable`; preflight; seed state + task list; when `--codex-down` is off, set `codex_required` from CLI force-on or the weekly usage probe (same rule as `check_convergence`); next=`run_code_review` |
66
- | `after-code-review` | From returncode / dirty_tree / served_command |
67
- | `after-bugteam` | From pushed / converged (bug-audit phase on portable pacer) |
68
- | `after-bugbot` | From classification / inline lag |
69
- | `after-codex` | From classification clean / dirty / down |
70
- | `after-copilot-wait` | From review surfaced / wait cap |
71
- | `after-ready-check` | From check_convergence exit |
72
- | `show-state` | Echo state; rehydrate `commands` / `wait_seconds` for pending next |
73
-
74
- ## Continuous tick loop
75
-
76
- After transport check, PR scope, isolation, permission grant, and the once-per-run
77
- Copilot quota pre-check:
78
-
79
- 1. Seed or restore state via `open-run` or `show-state` (and handoff
80
- `state-copy.json` when resuming).
81
- 2. Run the driver command for the current step; read JSON `next` / `commands` /
82
- `wait_seconds`.
83
- 3. On non-terminal `next`:
84
- - Write state and handoff when the after-* payload says so.
85
- - If `next` is `poll_wait`, sleep `wait_seconds` only, then re-poll and call
86
- the matching after-*.
87
- - If `next` is immediate work, continue in the same turn without sleeping.
88
- 4. On `mark_ready` / `stop_blocked` / named stop: run lifecycle Close, print the
89
- entry skill’s exit block, omit further pacing.
90
- 5. External reviewers remain skippable the same way as Claude-host runs when
91
- opted out or down. Push and head-change reset push-invalidated markers
92
- (`*_clean_at`, `merge_state_status`, `bugbot_down`, `codex_down`).
93
-
94
- ## Agent loop (judgment only)
95
-
96
- 1. Run the driver command for the current step.
97
- 2. If JSON `commands` is non-empty, run that argv (scripted helper).
98
- 3. Map JSON `next` to the single judgment action; report back via the matching
99
- `after-*` command.
100
- 4. Mark session tasks complete only when the scripted stamps say so; complete
101
- the final task only when every runnable review is clean on the same HEAD.
102
-
103
- | `next` | Agent does | Report with |
104
- |---|---|---|
105
- | `run_code_review` | Run `commands` | `after-code-review` |
106
- | `apply_fixes_and_push` | Fix protocol; commit; push | re-review then `after-code-review` |
107
- | `run_bugteam` | Bug-audit lens / worker spawn body | `after-bugteam` |
108
- | `run_bugbot_gate` | Bugbot helper scripts | `after-bugbot` |
109
- | `run_codex_review` | Run Codex review step | `after-codex` |
110
- | `request_copilot_review` | Request Copilot | `after-copilot-wait` |
111
- | `poll_wait` | Sleep `wait_seconds` only | re-poll then after-* |
112
- | `check_ready` | Run `commands` (check_convergence) | `after-ready-check` |
113
- | `mark_ready` | Run `commands` (`gh pr ready`) | teardown |
114
- | `stop_blocked` | Teardown; print blocker | stop |
115
-
116
- ## Autoconverge entry on portable pacer
117
-
118
- When `/autoconverge` selects `pacer=portable`:
119
-
120
- - Complete autoconverge pre-flight (scope, draft ownership, strict worktree,
121
- grant, Copilot quota).
122
- - Drive the continuous tick loop above (scripted phase machine) until ready
123
- or a documented blocker.
124
- - Skip `Workflow({ scriptPath: converge.mjs })` — that path requires the
125
- Workflow tool.
126
- - Teardown uses the lifecycle Close path; the Workflow-only closing HTML
127
- journal report is optional and skipped when no workflow run id exists.
128
- - Resume command on handoff: `/autoconverge <PR URL>`.
129
-
130
- When `/autoconverge` selects `pacer=workflow`, follow the skill’s Workflow
131
- sections unchanged.
132
-
133
- ## Helpers (scripted)
134
-
135
- | Concern | Script |
136
- |---|---|
137
- | Task list | `build_converge_task_list.py` |
138
- | Pacer | `select_converge_pacer.py` |
139
- | Worktree | `preflight_worktree.py` |
140
- | Code review | `$HOME/.claude/scripts/invoke_code_review.py` |
141
- | Workers | `$HOME/.claude/scripts/resolve_worker_spawn.py` |
142
- | Ready | `$HOME/.claude/_shared/pr-loop/scripts/check_convergence.py` |
143
- | Handoff | `write_handoff.py` |
144
-
145
- ## Fail closed
146
-
147
- Never abort solely because Workflow or ScheduleWakeup is missing once
148
- pacer=`portable`. Fail closed on contract failures only: auth, worktree,
149
- unresolvable gates, and wait caps.
@@ -1,5 +0,0 @@
1
- # Post-audit thread contract
2
-
3
- **Canonical home:**
4
-
5
- @~/.claude/_shared/pr-loop/post-audit-thread-contract.md
@@ -1,5 +0,0 @@
1
- # Precatch rubric
2
-
3
- **Canonical home:**
4
-
5
- @~/.claude/_shared/pr-loop/precatch-rubric.md