claude-dev-env 1.94.0 → 2.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 (280) hide show
  1. package/_shared/advisor/CLAUDE.md +2 -2
  2. package/_shared/advisor/advisor-protocol.md +41 -33
  3. package/_shared/advisor/scripts/config/advisor_scripts_constants/model_tier_run_validator_constants.py +17 -13
  4. package/_shared/advisor/scripts/model_tier_run_validator.py +27 -18
  5. package/_shared/advisor/scripts/tests/test_model_tier_run_validator.py +95 -25
  6. package/_shared/advisor/scripts/tests/test_tier_model_ids.py +17 -17
  7. package/_shared/advisor/scripts/tier_model_ids.py +18 -18
  8. package/_shared/pr-loop/CLAUDE.md +1 -0
  9. package/_shared/pr-loop/scripts/CLAUDE.md +2 -1
  10. package/_shared/pr-loop/scripts/README.md +1 -0
  11. package/_shared/pr-loop/scripts/code_rules_gate.py +253 -1980
  12. package/_shared/pr-loop/scripts/code_rules_gate_parts/CLAUDE.md +32 -0
  13. package/_shared/pr-loop/scripts/code_rules_gate_parts/__init__.py +7 -0
  14. package/_shared/pr-loop/scripts/code_rules_gate_parts/added_line_maps.py +268 -0
  15. package/_shared/pr-loop/scripts/code_rules_gate_parts/enforcer_loading.py +172 -0
  16. package/_shared/pr-loop/scripts/code_rules_gate_parts/gate_arguments.py +70 -0
  17. package/_shared/pr-loop/scripts/code_rules_gate_parts/gate_running.py +326 -0
  18. package/_shared/pr-loop/scripts/code_rules_gate_parts/git_blob_readers.py +85 -0
  19. package/_shared/pr-loop/scripts/code_rules_gate_parts/git_file_sets.py +331 -0
  20. package/_shared/pr-loop/scripts/code_rules_gate_parts/staged_test_running.py +369 -0
  21. package/_shared/pr-loop/scripts/code_rules_gate_parts/tests/conftest.py +14 -0
  22. package/_shared/pr-loop/scripts/code_rules_gate_parts/tests/test_added_line_maps.py +118 -0
  23. package/_shared/pr-loop/scripts/code_rules_gate_parts/tests/test_enforcer_loading.py +17 -0
  24. package/_shared/pr-loop/scripts/code_rules_gate_parts/tests/test_gate_arguments.py +29 -0
  25. package/_shared/pr-loop/scripts/code_rules_gate_parts/tests/test_gate_running.py +99 -0
  26. package/_shared/pr-loop/scripts/code_rules_gate_parts/tests/test_git_blob_readers.py +69 -0
  27. package/_shared/pr-loop/scripts/code_rules_gate_parts/tests/test_git_file_sets.py +137 -0
  28. package/_shared/pr-loop/scripts/code_rules_gate_parts/tests/test_staged_test_running.py +116 -0
  29. package/_shared/pr-loop/scripts/code_rules_gate_parts/tests/test_violation_scoping.py +75 -0
  30. package/_shared/pr-loop/scripts/code_rules_gate_parts/tests/test_wrapper_plumb_check.py +49 -0
  31. package/_shared/pr-loop/scripts/code_rules_gate_parts/violation_scoping.py +328 -0
  32. package/_shared/pr-loop/scripts/code_rules_gate_parts/wrapper_plumb_check.py +206 -0
  33. package/_shared/pr-loop/scripts/pr_loop_shared_constants/code_rules_gate_constants.py +24 -17
  34. package/_shared/pr-loop/scripts/pr_loop_shared_constants/reviews_disabled_constants.py +1 -0
  35. package/_shared/pr-loop/scripts/reviews_disabled.py +19 -2
  36. package/_shared/pr-loop/scripts/test_code_rules_gate.py +278 -0
  37. package/_shared/pr-loop/scripts/tests/test_code_rules_gate_constants.py +6 -39
  38. package/_shared/pr-loop/scripts/tests/test_reviews_disabled.py +43 -0
  39. package/_shared/pr-loop/worker-spawn.md +186 -0
  40. package/agents/code-verifier.md +1 -1
  41. package/bin/CLAUDE.md +10 -1
  42. package/bin/ever-shipped-skills.mjs +73 -0
  43. package/bin/expand_home_directory_tokens.mjs +1 -1
  44. package/bin/install.mjs +140 -7
  45. package/bin/install.prune.test.mjs +457 -0
  46. package/docs/CODE_RULES.md +1 -1
  47. package/hooks/advisory/refactor_guard.py +3 -4
  48. package/hooks/blocking/CLAUDE.md +7 -1
  49. package/hooks/blocking/block_main_commit.py +2 -2
  50. package/hooks/blocking/claude_md_orphan_file_blocker.py +75 -699
  51. package/hooks/blocking/claude_md_orphan_file_blocker_parts/CLAUDE.md +28 -0
  52. package/hooks/blocking/claude_md_orphan_file_blocker_parts/__init__.py +1 -0
  53. package/hooks/blocking/claude_md_orphan_file_blocker_parts/config/__init__.py +1 -0
  54. package/hooks/blocking/claude_md_orphan_file_blocker_parts/config/orphan_blocker_constants.py +18 -0
  55. package/hooks/blocking/claude_md_orphan_file_blocker_parts/decision.py +81 -0
  56. package/hooks/blocking/claude_md_orphan_file_blocker_parts/references.py +307 -0
  57. package/hooks/blocking/claude_md_orphan_file_blocker_parts/scan_plan.py +124 -0
  58. package/hooks/blocking/claude_md_orphan_file_blocker_parts/subtree_scan.py +179 -0
  59. package/hooks/blocking/claude_md_orphan_file_blocker_parts/tests/conftest.py +10 -0
  60. package/hooks/blocking/claude_md_orphan_file_blocker_parts/tests/test_decision.py +34 -0
  61. package/hooks/blocking/claude_md_orphan_file_blocker_parts/tests/test_references.py +42 -0
  62. package/hooks/blocking/claude_md_orphan_file_blocker_parts/tests/test_scan_plan.py +27 -0
  63. package/hooks/blocking/claude_md_orphan_file_blocker_parts/tests/test_subtree_scan.py +30 -0
  64. package/hooks/blocking/code_rules_boolean_mustcheck.py +1 -1
  65. package/hooks/blocking/code_rules_enforcer.py +4 -0
  66. package/hooks/blocking/code_rules_mock_completeness.py +1 -1
  67. package/hooks/blocking/code_rules_optional_params.py +2 -2
  68. package/hooks/blocking/code_rules_shared.py +83 -1
  69. package/hooks/blocking/code_rules_test_assertions.py +1 -1
  70. package/hooks/blocking/code_rules_test_layout.py +9 -3
  71. package/hooks/blocking/code_rules_typeddict_stub.py +1 -1
  72. package/hooks/blocking/gh_pr_author_enforcer.py +1 -1
  73. package/hooks/blocking/inventory_intent_records/CLAUDE.md +26 -0
  74. package/hooks/blocking/inventory_intent_records/__init__.py +1 -0
  75. package/hooks/blocking/inventory_intent_records/config/__init__.py +1 -0
  76. package/hooks/blocking/inventory_intent_records/config/intent_records_constants.py +20 -0
  77. package/hooks/blocking/inventory_intent_records/records.py +271 -0
  78. package/hooks/blocking/inventory_intent_records/tests/conftest.py +10 -0
  79. package/hooks/blocking/inventory_intent_records/tests/test_records.py +80 -0
  80. package/hooks/blocking/package_inventory_stale_blocker.py +54 -384
  81. package/hooks/blocking/package_inventory_stale_blocker_parts/CLAUDE.md +26 -0
  82. package/hooks/blocking/package_inventory_stale_blocker_parts/__init__.py +1 -0
  83. package/hooks/blocking/package_inventory_stale_blocker_parts/config/__init__.py +1 -0
  84. package/hooks/blocking/package_inventory_stale_blocker_parts/config/inventory_blocker_constants.py +16 -0
  85. package/hooks/blocking/package_inventory_stale_blocker_parts/decision.py +84 -0
  86. package/hooks/blocking/package_inventory_stale_blocker_parts/inventory_detection.py +307 -0
  87. package/hooks/blocking/package_inventory_stale_blocker_parts/tests/conftest.py +10 -0
  88. package/hooks/blocking/package_inventory_stale_blocker_parts/tests/test_decision.py +38 -0
  89. package/hooks/blocking/package_inventory_stale_blocker_parts/tests/test_inventory_detection.py +61 -0
  90. package/hooks/blocking/pii_payload_scan.py +138 -42
  91. package/hooks/blocking/pii_prevention_blocker.py +185 -291
  92. package/hooks/blocking/pii_prevention_blocker_parts/CLAUDE.md +24 -0
  93. package/hooks/blocking/pii_prevention_blocker_parts/__init__.py +1 -0
  94. package/hooks/blocking/pii_prevention_blocker_parts/config/__init__.py +1 -0
  95. package/hooks/blocking/pii_prevention_blocker_parts/config/repository_resolution_constants.py +28 -0
  96. package/hooks/blocking/pii_prevention_blocker_parts/repository_exemption.py +214 -0
  97. package/hooks/blocking/pii_prevention_blocker_parts/repository_resolution.py +208 -0
  98. package/hooks/blocking/plain_language_blocker.py +138 -4
  99. package/hooks/blocking/pr_description_command_parser.py +8 -4
  100. package/hooks/blocking/precommit_code_rules_gate.py +3 -3
  101. package/hooks/blocking/sensitive_file_protector.py +114 -48
  102. package/hooks/blocking/tdd_enforcer.py +97 -601
  103. package/hooks/blocking/tdd_enforcer_parts/CLAUDE.md +30 -0
  104. package/hooks/blocking/tdd_enforcer_parts/__init__.py +1 -0
  105. package/hooks/blocking/tdd_enforcer_parts/candidate_paths.py +142 -0
  106. package/hooks/blocking/tdd_enforcer_parts/config/__init__.py +1 -0
  107. package/hooks/blocking/tdd_enforcer_parts/config/tdd_enforcer_constants.py +32 -0
  108. package/hooks/blocking/tdd_enforcer_parts/content_analysis.py +268 -0
  109. package/hooks/blocking/tdd_enforcer_parts/decisions.py +92 -0
  110. package/hooks/blocking/tdd_enforcer_parts/freshness.py +80 -0
  111. package/hooks/blocking/tdd_enforcer_parts/git_tracking.py +63 -0
  112. package/hooks/blocking/tdd_enforcer_parts/path_classification.py +119 -0
  113. package/hooks/blocking/tdd_enforcer_parts/tests/conftest.py +10 -0
  114. package/hooks/blocking/tdd_enforcer_parts/tests/test_candidate_paths.py +31 -0
  115. package/hooks/blocking/tdd_enforcer_parts/tests/test_content_analysis.py +30 -0
  116. package/hooks/blocking/tdd_enforcer_parts/tests/test_decisions.py +34 -0
  117. package/hooks/blocking/tdd_enforcer_parts/tests/test_freshness.py +28 -0
  118. package/hooks/blocking/tdd_enforcer_parts/tests/test_git_tracking.py +48 -0
  119. package/hooks/blocking/tdd_enforcer_parts/tests/test_path_classification.py +36 -0
  120. package/hooks/blocking/test_code_rules_enforcer_scratchpad.py +105 -0
  121. package/hooks/blocking/test_code_rules_shared.py +181 -0
  122. package/hooks/blocking/test_inventory_deadlock_resolution.py +154 -0
  123. package/hooks/blocking/test_pii_payload_scan.py +168 -0
  124. package/hooks/blocking/test_plain_language_blocker_allowlist.py +184 -0
  125. package/hooks/blocking/test_sensitive_file_protector.py +185 -0
  126. package/hooks/blocking/test_tdd_enforcer_restore.py +108 -0
  127. package/hooks/blocking/test_tdd_enforcer_scratchpad.py +105 -0
  128. package/hooks/blocking/tests/conftest.py +10 -0
  129. package/hooks/blocking/tests/test_pii_prevention_blocker.py +260 -0
  130. package/hooks/blocking/tests/test_repository_exemption.py +105 -0
  131. package/hooks/blocking/tests/test_repository_resolution.py +108 -0
  132. package/hooks/diagnostic/hook_log_extractor.py +12 -10
  133. package/hooks/git-hooks/post_commit.py +3 -4
  134. package/hooks/hooks_constants/CLAUDE.md +4 -2
  135. package/hooks/hooks_constants/banned_identifiers_constants.py +0 -1
  136. package/hooks/hooks_constants/code_rules_path_utils_constants.py +1 -1
  137. package/hooks/hooks_constants/harness_scratchpad_constants.py +17 -0
  138. package/hooks/hooks_constants/local_identity.py +59 -8
  139. package/hooks/hooks_constants/pii_prevention_constants.py +0 -6
  140. package/hooks/hooks_constants/plain_language_blocker_constants.py +5 -0
  141. package/hooks/hooks_constants/sensitive_file_protector_constants.py +42 -0
  142. package/hooks/hooks_constants/test_local_identity.py +105 -3
  143. package/hooks/pyproject.toml +52 -4
  144. package/hooks/session/plugin_data_dir_cleanup.py +0 -1
  145. package/hooks/validation/mypy_validator.py +2 -2
  146. package/hooks/validators/CLAUDE.md +1 -1
  147. package/hooks/validators/README.md +2 -0
  148. package/hooks/validators/health_check.py +1 -0
  149. package/hooks/validators/mypy_integration.py +2 -0
  150. package/hooks/validators/python_style_checks.py +114 -136
  151. package/hooks/validators/python_style_helpers.py +95 -0
  152. package/hooks/validators/ruff_integration.py +3 -0
  153. package/hooks/validators/test_python_style_checks.py +0 -164
  154. package/hooks/validators/test_python_style_checks_decorator_gap.py +119 -0
  155. package/hooks/validators/test_python_style_fixes.py +251 -0
  156. package/hooks/validators/test_python_style_helpers.py +125 -0
  157. package/hooks/workflow/auto_formatter.py +5 -4
  158. package/package.json +1 -1
  159. package/rules/CLAUDE.md +1 -0
  160. package/rules/anti-corollary-tests.md +69 -0
  161. package/rules/bdd.md +1 -3
  162. package/rules/code-reviews.md +1 -1
  163. package/rules/gh-paginate.md +1 -1
  164. package/rules/plain-language.md +2 -0
  165. package/scripts/CLAUDE.md +4 -0
  166. package/scripts/dev_env_scripts_constants/CLAUDE.md +6 -4
  167. package/scripts/dev_env_scripts_constants/code_review_constants.py +71 -0
  168. package/scripts/dev_env_scripts_constants/grok_worker_constants.py +435 -0
  169. package/scripts/dev_env_scripts_constants/timing.py +7 -1
  170. package/scripts/grok_headless_runner.py +294 -0
  171. package/scripts/grok_worker_preflight.py +410 -0
  172. package/scripts/invoke_code_review.py +463 -0
  173. package/scripts/resolve_worker_spawn.py +619 -0
  174. package/scripts/spawn_grok_batch.py +672 -0
  175. package/scripts/test_grok_headless_runner.py +626 -0
  176. package/scripts/test_grok_worker_preflight.py +1054 -0
  177. package/scripts/test_invoke_code_review.py +672 -0
  178. package/scripts/test_resolve_worker_spawn.py +1014 -0
  179. package/scripts/test_spawn_grok_batch.py +1017 -0
  180. package/skills/CLAUDE.md +6 -3
  181. package/skills/_shared/pr-loop/scripts/build_audit_prompt.py +72 -13
  182. package/skills/_shared/pr-loop/scripts/build_fix_prompt.py +121 -14
  183. package/skills/_shared/pr-loop/scripts/skills_pr_loop_constants/path_resolver_constants.py +78 -0
  184. package/skills/_shared/pr-loop/scripts/test_build_audit_prompt.py +121 -0
  185. package/skills/_shared/pr-loop/scripts/test_build_fix_prompt.py +196 -6
  186. package/skills/autoconverge/CLAUDE.md +3 -3
  187. package/skills/autoconverge/SKILL.md +9 -3
  188. package/skills/autoconverge/reference/CLAUDE.md +2 -2
  189. package/skills/autoconverge/reference/convergence.md +33 -11
  190. package/skills/autoconverge/reference/stop-conditions.md +16 -5
  191. package/skills/autoconverge/workflow/CLAUDE.md +2 -1
  192. package/skills/autoconverge/workflow/converge.clean-audit.test.mjs +7 -2
  193. package/skills/autoconverge/workflow/converge.codex-gate.test.mjs +300 -0
  194. package/skills/autoconverge/workflow/converge.contract.test.mjs +5 -5
  195. package/skills/autoconverge/workflow/converge.copilot-gate.test.mjs +29 -29
  196. package/skills/autoconverge/workflow/converge.fix-progress.test.mjs +1 -1
  197. package/skills/autoconverge/workflow/converge.mjs +202 -18
  198. package/skills/bugteam/CLAUDE.md +2 -2
  199. package/skills/bugteam/CONSTRAINTS.md +3 -2
  200. package/skills/bugteam/PROMPTS.md +7 -6
  201. package/skills/bugteam/SKILL.md +18 -13
  202. package/skills/bugteam/reference/README.md +2 -3
  203. package/skills/bugteam/reference/audit-and-teammates.md +215 -35
  204. package/skills/bugteam/reference/design-rationale.md +1 -1
  205. package/skills/bugteam/reference/obstacles/CLAUDE.md +1 -1
  206. package/skills/bugteam/reference/team-setup.md +8 -2
  207. package/skills/closeout/SKILL.md +153 -0
  208. package/skills/closeout/reference/handoff-prompt-template.md +72 -0
  209. package/skills/closeout/reference/issue-body-templates.md +108 -0
  210. package/skills/closeout/reference/pii-redaction-checklist.md +36 -0
  211. package/skills/codex-review/CLAUDE.md +46 -0
  212. package/skills/codex-review/SKILL.md +181 -0
  213. package/skills/codex-review/reference/CLAUDE.md +15 -0
  214. package/skills/codex-review/reference/cli-contract.md +253 -0
  215. package/skills/codex-review/reference/loop-integration.md +118 -0
  216. package/skills/codex-review/scripts/codex_down_classifier.py +98 -0
  217. package/skills/codex-review/scripts/codex_review_scripts_constants/CLAUDE.md +18 -0
  218. package/skills/codex-review/scripts/codex_review_scripts_constants/__init__.py +1 -0
  219. package/skills/codex-review/scripts/codex_review_scripts_constants/classifier_constants.py +35 -0
  220. package/skills/codex-review/scripts/codex_review_scripts_constants/codex_usage_probe_constants.py +86 -0
  221. package/skills/codex-review/scripts/codex_review_scripts_constants/findings_constants.py +18 -0
  222. package/skills/codex-review/scripts/codex_review_scripts_constants/run_constants.py +45 -0
  223. package/skills/codex-review/scripts/codex_usage_probe.py +573 -0
  224. package/skills/codex-review/scripts/fixtures/auth_failure_synthetic.txt +1 -0
  225. package/skills/codex-review/scripts/fixtures/config_load_failure_v0.125.0.txt +1 -0
  226. package/skills/codex-review/scripts/fixtures/freeform_findings_v0.144.3.txt +6 -0
  227. package/skills/codex-review/scripts/fixtures/model_rejection_v0.125.0.jsonl +5 -0
  228. package/skills/codex-review/scripts/fixtures/structured_findings.txt +13 -0
  229. package/skills/codex-review/scripts/fixtures/success_stream_v0.144.3.jsonl +6 -0
  230. package/skills/codex-review/scripts/fixtures/unknown_failure_synthetic.txt +1 -0
  231. package/skills/codex-review/scripts/fixtures/usage_limit_synthetic.txt +1 -0
  232. package/skills/codex-review/scripts/parse_codex_findings.py +207 -0
  233. package/skills/codex-review/scripts/run_codex_review.py +415 -0
  234. package/skills/codex-review/scripts/test_codex_down_classifier.py +143 -0
  235. package/skills/codex-review/scripts/test_codex_usage_probe.py +678 -0
  236. package/skills/codex-review/scripts/test_parse_codex_findings.py +130 -0
  237. package/skills/codex-review/scripts/test_run_codex_review.py +812 -0
  238. package/skills/codex-review/test_skill_scaffold.py +192 -0
  239. package/skills/grok-spawn/CLAUDE.md +28 -0
  240. package/skills/grok-spawn/SKILL.md +226 -0
  241. package/skills/grok-spawn/reference/flag-profiles.md +132 -0
  242. package/skills/grok-spawn/reference/worker-briefs.md +152 -0
  243. package/skills/grokify/SKILL.md +9 -1
  244. package/skills/grokify/capability-claims.test.mjs +28 -0
  245. package/skills/grokify/evals/README.md +72 -0
  246. package/skills/grokify/evals/parse-payload.test.mjs +171 -0
  247. package/skills/grokify/evals/run-capability-evals.mjs +545 -0
  248. package/skills/orchestrator/SKILL.md +32 -22
  249. package/skills/orchestrator-refresh/SKILL.md +12 -8
  250. package/skills/pr-converge/CLAUDE.md +1 -1
  251. package/skills/pr-converge/SKILL.md +34 -13
  252. package/skills/pr-converge/reference/convergence-gates.md +42 -15
  253. package/skills/pr-converge/reference/fix-protocol.md +1 -1
  254. package/skills/pr-converge/reference/ground-rules.md +1 -1
  255. package/skills/pr-converge/reference/per-tick.md +130 -42
  256. package/skills/pr-converge/reference/state-schema.md +10 -0
  257. package/skills/pr-converge/scripts/CLAUDE.md +2 -0
  258. package/skills/pr-converge/scripts/_pr_converge_path_setup.py +5 -1
  259. package/skills/pr-converge/scripts/check_convergence.py +605 -29
  260. package/skills/pr-converge/scripts/check_convergence_availability.py +232 -0
  261. package/skills/pr-converge/scripts/check_convergence_gates.py +279 -235
  262. package/skills/pr-converge/scripts/check_convergence_thread_gates.py +1 -1
  263. package/skills/pr-converge/scripts/pr_converge_scripts_constants/convergence_gate_constants.py +36 -2
  264. package/skills/pr-converge/scripts/test__pr_converge_path_setup.py +4 -0
  265. package/skills/pr-converge/scripts/test_check_convergence.py +71 -3
  266. package/skills/pr-converge/scripts/test_check_convergence_availability.py +326 -0
  267. package/skills/pr-converge/scripts/test_check_convergence_codex.py +507 -0
  268. package/skills/pr-converge/scripts/test_check_convergence_contract.py +89 -17
  269. package/skills/pr-converge/scripts/test_check_convergence_fixture.py +179 -0
  270. package/skills/pr-converge/scripts/test_check_convergence_gates.py +84 -68
  271. package/skills/pr-converge/scripts/test_check_convergence_thread_gates.py +24 -0
  272. package/skills/pr-converge/test_step5_host_branch.py +106 -0
  273. package/skills/pr-fix-protocol/SKILL.md +65 -0
  274. package/skills/pr-loop-cloud-transport/SKILL.md +2 -0
  275. package/skills/reviewer-gates/SKILL.md +7 -5
  276. package/skills/skill-builder/references/skill-modularity.md +1 -1
  277. package/skills/team-advisor/SKILL.md +16 -12
  278. package/system-prompts/software-engineer.xml +7 -6
  279. package/hooks/validators/test_verify_paths.py +0 -32
  280. package/hooks/validators/verify_paths.py +0 -57
@@ -99,7 +99,17 @@ Repeat until an exit condition fires.
99
99
  `git merge-base` + `git diff --name-only` live inside the script; see [`../../../_shared/pr-loop/scripts/README.md`](../../../_shared/pr-loop/scripts/README.md) for what lives under this directory, and [`../../../_shared/pr-loop/code-rules-gate.md`](../../../_shared/pr-loop/code-rules-gate.md) for gate-only merge-base / invocation semantics. The lead runs this (not a teammate).
100
100
 
101
101
  2. If exit code **0** → continue to step 2.5 (AUDIT spawn) below.
102
- 3. If exit code **non-zero** → spawn a new **clean-coder** teammate (`mode="bypassPermissions"`) — **standards-fix pass** with instructions: read the script’s stderr, edit the repo until a **re-run** of the **same** gate command exits **0**, then one commit, `git push`, shutdown. Repeat standards-fix spawns until the gate exits **0** or **5** failed gate rounds (each round = one teammate session after a non-zero gate). If still non-zero after 5 rounds → exit reason = `error: code rules gate failed pre-audit`.
102
+ 3. If exit code **non-zero** → run a **standards-fix pass** through the
103
+ worker-spawn dispatcher (role `clean-coder`; see **Standards-fix
104
+ action** below). Instructions: read the gate script’s stderr, edit the
105
+ repo until a **re-run** of the **same** gate command exits **0**. On
106
+ tiers 1 and 3 the headless worker edits and runs tests but never
107
+ commits or pushes — the lead stages with explicit `git add`, mints the
108
+ code-verifier verdict, then commits and pushes. Tier 2 keeps in-agent
109
+ commit and push with `mode="bypassPermissions"`. Repeat standards-fix
110
+ spawns until the gate exits **0** or **5** failed gate rounds (each
111
+ round = one worker session after a non-zero gate). If still non-zero
112
+ after 5 rounds → exit reason = `error: code rules gate failed pre-audit`.
103
113
  4. After gate exit **0**, increment `loop_count`. If `loop_count > 20`, exit reason = `cap reached` (counts **audits**, not standards-only rounds).
104
114
  5. Execute **AUDIT action** (spawn bugfind). Print progress: `Loop <L> audit: ...`
105
115
 
@@ -116,46 +126,216 @@ Repeat until an exit condition fires.
116
126
 
117
127
  ## AUDIT action
118
128
 
119
- Spawn one audit agent that walks all A–P categories:
120
-
121
- ```
122
- Agent(
123
- subagent_type="code-quality-agent",
124
- name="bugfind-pr<N>-loop<L>",
125
- model="opus",
126
- run_in_background=true,
127
- description="Audit {owner}/{repo}#{N} loop {L}",
128
- prompt="<output of build_audit_prompt.py; see ../../_shared/pr-loop/scripts/build_audit_prompt.py>"
129
- )
130
- ```
129
+ Walk all A–Q categories through the worker-spawn dispatcher
130
+ ([`worker-spawn.md`](../../../_shared/pr-loop/worker-spawn.md)). Every loop
131
+ is a fresh process or a fresh agent context.
132
+
133
+ 1. **Build the headless audit prompt** and write it to a prompt file under the
134
+ per-PR workspace:
135
+
136
+ ```bash
137
+ python "${CLAUDE_SKILL_DIR}/../_shared/pr-loop/scripts/build_audit_prompt.py" \
138
+ --owner <O> --repo <R> --pr-number <N> --loop <L> \
139
+ --head-ref <head> --base-ref <base> \
140
+ --worktree-path <worktree_path> --run-temp-dir <run_temp_dir> \
141
+ --flavor headless \
142
+ > "${run_temp_dir}/pr-<N>/loop-<L>.audit-prompt.xml"
143
+ ```
144
+
145
+ Optional: `--pr-body-file <path>` when the PR body is available on disk.
146
+
147
+ 2. **Dispatch** via
148
+ [`resolve_worker_spawn.py`](../../../scripts/resolve_worker_spawn.py). Role
149
+ `bugteam` maps to primary agent `code-quality-agent`:
150
+
151
+ ```bash
152
+ python "${CLAUDE_SKILL_DIR}/../../scripts/resolve_worker_spawn.py" \
153
+ --role bugteam \
154
+ --prompt-file "${run_temp_dir}/pr-<N>/loop-<L>.audit-prompt.xml" \
155
+ --cwd <worktree_path> \
156
+ --run-temp-dir <run_temp_dir>
157
+ ```
158
+
159
+ The lead **blocks on the process** and reads the stdout JSON result.
160
+
161
+ 3. **Follow the result:**
162
+
163
+ - **Tier 1 or 3 served** (`tier_used` is `1` or `3`, exit `0`): the
164
+ dispatcher ran the worker to completion. Read the outcome XML at
165
+ `<worktree_path>/.bugteam-pr<N>-loop<L>.outcomes.xml`. The **lead**
166
+ posts the audit review with
167
+ [`post_audit_thread.py`](../../../_shared/pr-loop/scripts/post_audit_thread.py)
168
+ (see [SKILL.md § Audit posting](../SKILL.md#audit-posting)).
169
+ - **`claude_agent_required`** (exit `2`, attempts include tier `2` with
170
+ that reason): rebuild the prompt with default `--flavor agent` (omit
171
+ `--flavor` or pass `agent`) and spawn the Agent-tool worker, including
172
+ in-worker posting:
173
+
174
+ ```
175
+ Agent(
176
+ subagent_type="code-quality-agent",
177
+ name="bugfind-pr<N>-loop<L>",
178
+ model="opus",
179
+ run_in_background=true,
180
+ description="Audit {owner}/{repo}#{N} loop {L}",
181
+ prompt="<output of build_audit_prompt.py --flavor agent>"
182
+ )
183
+ ```
131
184
 
132
185
  The audit prompt XML is emitted by
133
186
  [`build_audit_prompt.py`](../../_shared/pr-loop/scripts/build_audit_prompt.py).
134
- Run it with `--owner --repo --pr-number --loop --head-ref --base-ref --worktree-path --run-temp-dir`
135
- to generate the complete `<spawn_prompt>` XML on stdout.
187
+ `--flavor headless` targets the dispatcher path (gh reads, outcome file, no
188
+ MCP/TaskCreate/Artifact). Default `--flavor agent` targets the Agent-tool
189
+ path (MCP posting).
136
190
 
137
191
  `last_action = "audited"`. Append audit metadata to `audit_log`.
138
192
 
139
- ## FIX action (fresh teammate)
140
-
141
- Spawn:
193
+ ## Standards-fix action
194
+
195
+ Route through the worker-spawn dispatcher
196
+ ([`worker-spawn.md`](../../../_shared/pr-loop/worker-spawn.md)). Role
197
+ `clean-coder` maps to primary agent `clean-coder`. Every round is a fresh
198
+ process or a fresh agent context. The **5-round cap** stays (each round = one
199
+ worker session after a non-zero gate).
200
+
201
+ 1. **Write a standards-fix prompt** under the per-PR workspace that includes
202
+ the gate stderr, the exact gate re-run command, and the worktree path. On
203
+ headless tiers the permission flag maps to each CLI's own flag
204
+ (`--permission-mode bypassPermissions`).
205
+
206
+ 2. **Dispatch:**
207
+
208
+ ```bash
209
+ python "${CLAUDE_SKILL_DIR}/../../scripts/resolve_worker_spawn.py" \
210
+ --role clean-coder \
211
+ --prompt-file "${run_temp_dir}/pr-<N>/loop-<L>.standards-fix-prompt.txt" \
212
+ --cwd <worktree_path> \
213
+ --run-temp-dir <run_temp_dir>
214
+ ```
215
+
216
+ 3. **Follow the result:**
217
+
218
+ - **Tier 1 or 3 served** (`tier_used` is `1` or `3`, exit `0`): the
219
+ headless worker edits and runs tests but never commits or pushes. The
220
+ lead session stages the worker's files itself with an explicit `git add`
221
+ (the session edit tracker does not see files the lead did not edit),
222
+ mints the code-verifier verdict in its own context, then commits and
223
+ pushes — so the commit gate and the staged-commit scans fire on the real
224
+ diff. Re-run the gate command; if still non-zero, start the next round.
225
+ - **`claude_agent_required`** (exit `2`, attempts include tier `2` with
226
+ that reason): spawn the Agent-tool worker with in-agent commit and push:
227
+
228
+ ```
229
+ Agent(
230
+ subagent_type="clean-coder",
231
+ name="standards-fix-pr<N>-loop<L>-round<R>",
232
+ model="opus",
233
+ mode="bypassPermissions",
234
+ run_in_background=true,
235
+ description="Standards-fix {owner}/{repo}#{N} loop {L} round {R}",
236
+ prompt="<gate stderr + re-run command + commit/push/shutdown>"
237
+ )
238
+ ```
239
+
240
+ The missing-subagent refusal in [`../SKILL.md`](../SKILL.md) applies to tier 2
241
+ only; headless tiers rely on the preflight's agent-definition-file check.
142
242
 
143
- ```
144
- Agent(
145
- subagent_type="clean-coder",
146
- name="bugfix-pr<N>-loop<L>",
147
- mode="bypassPermissions",
148
- run_in_background=true,
149
- description="Bugfix PR <N> loop <L>",
150
- prompt="<output of build_fix_prompt.py; see ../../_shared/pr-loop/scripts/build_fix_prompt.py>"
151
- )
152
- ```
153
-
154
- The teammate sees only the latest audit’s findings — each `Agent` call starts with a fresh context window; prior-loop findings, fix history, and chat stay in the lead.
155
-
156
- Pass finding comment URL, comment id, and thread node id for each finding (from `loop_comment_index`) in the XML prompt so the teammate owns both the reply and the thread resolution. After commit, the teammate posts one reply per finding using the unified template at [`../../../_shared/pr-loop/audit-reply-template.md`](../../../_shared/pr-loop/audit-reply-template.md) — the full header / horizontal rule / `<action_heading> ✅` / explanation / anchored-bullet / closing-paragraph skeleton, with `<status_line>` set per the path (`Fixed in <short_sha>` for `status=fixed`, `Could not address this loop` for `status=could_not_address`, `Hook blocked the fix commit` for `status=hook_blocked`). Per-thread reply and `resolve_thread` are atomic; the mechanics follow the shared 13-step sequence in [`../../../_shared/pr-loop/fix-protocol.md`](../../../_shared/pr-loop/fix-protocol.md) (step 12 carries the exact reply-and-resolve sequence). Same identity model as bugfind: teammate posts; lead waits.
243
+ ## FIX action (fresh teammate)
157
244
 
158
- After replies, the teammate writes outcome XML (schema in [`../PROMPTS.md`](../PROMPTS.md)).
245
+ Route through the worker-spawn dispatcher
246
+ ([`worker-spawn.md`](../../../_shared/pr-loop/worker-spawn.md)). Role
247
+ `clean-coder` maps to primary agent `clean-coder`. Every loop is a fresh
248
+ process or a fresh agent context. The teammate sees only the latest audit’s
249
+ findings — prior-loop findings, fix history, and chat stay in the lead.
250
+
251
+ Pass finding comment URL, comment id, and thread node id for each finding
252
+ (from `loop_comment_index`) in the XML prompt.
253
+
254
+ 1. **Build the headless fix prompt** and write it to a prompt file under the
255
+ per-PR workspace:
256
+
257
+ ```bash
258
+ python "${CLAUDE_SKILL_DIR}/../_shared/pr-loop/scripts/build_fix_prompt.py" \
259
+ --owner <O> --repo <R> --pr-number <N> --loop <L> \
260
+ --head-ref <head> --base-ref <base> \
261
+ --worktree-path <worktree_path> \
262
+ --findings-json <findings_json_path> \
263
+ --flavor headless \
264
+ > "${run_temp_dir}/pr-<N>/loop-<L>.fix-prompt.xml"
265
+ ```
266
+
267
+ 2. **Dispatch** via
268
+ [`resolve_worker_spawn.py`](../../../scripts/resolve_worker_spawn.py):
269
+
270
+ ```bash
271
+ python "${CLAUDE_SKILL_DIR}/../../scripts/resolve_worker_spawn.py" \
272
+ --role clean-coder \
273
+ --prompt-file "${run_temp_dir}/pr-<N>/loop-<L>.fix-prompt.xml" \
274
+ --cwd <worktree_path> \
275
+ --run-temp-dir <run_temp_dir>
276
+ ```
277
+
278
+ The lead **blocks on the process** and reads the stdout JSON result.
279
+
280
+ 3. **Follow the result:**
281
+
282
+ - **Tier 1 or 3 served** (`tier_used` is `1` or `3`, exit `0`): On tiers 1
283
+ and 3 the headless worker edits and runs tests but never commits or
284
+ pushes. The lead session stages the worker's files itself with an
285
+ explicit `git add` (the session edit tracker does not see files the lead
286
+ did not edit), mints the code-verifier verdict in its own context, then
287
+ commits and pushes — so the commit gate and the staged-commit scans fire
288
+ on the real diff. Read the outcome XML at
289
+ `<worktree_path>/.bugteam-pr<N>-loop<L>.fix-outcomes.xml`. The **lead**
290
+ posts one reply per finding using the unified template at
291
+ [`../../../_shared/pr-loop/audit-reply-template.md`](../../../_shared/pr-loop/audit-reply-template.md)
292
+ — the full header / horizontal rule / `<action_heading> ✅` /
293
+ explanation / anchored-bullet / closing-paragraph skeleton, with
294
+ `<status_line>` set per the path (`Fixed in <short_sha>` for
295
+ `status=fixed`, `Could not address this loop` for
296
+ `status=could_not_address`, `Hook blocked the fix commit` for
297
+ `status=hook_blocked`). Per-thread reply and `resolve_thread` are
298
+ atomic; the mechanics follow the shared 13-step sequence in
299
+ [`../../../_shared/pr-loop/fix-protocol.md`](../../../_shared/pr-loop/fix-protocol.md)
300
+ (step 12 carries the exact reply-and-resolve sequence).
301
+ - **`claude_agent_required`** (exit `2`, attempts include tier `2` with
302
+ that reason): Tier 2 keeps the current behavior end to end, including
303
+ in-agent commit and push and `mode="bypassPermissions"`. Rebuild the
304
+ prompt with default `--flavor agent` (omit `--flavor` or pass `agent`)
305
+ and spawn the Agent-tool worker, pinning model opus:
306
+
307
+ ```
308
+ Agent(
309
+ subagent_type="clean-coder",
310
+ name="bugfix-pr<N>-loop<L>",
311
+ model="opus",
312
+ mode="bypassPermissions",
313
+ run_in_background=true,
314
+ description="Bugfix PR <N> loop <L>",
315
+ prompt="<output of build_fix_prompt.py --flavor agent>"
316
+ )
317
+ ```
318
+
319
+ After commit, the teammate posts one reply per finding using the same
320
+ unified template and writes outcome XML (schema in
321
+ [`../PROMPTS.md`](../PROMPTS.md)).
322
+
323
+ The fix prompt XML is emitted by
324
+ [`build_fix_prompt.py`](../../_shared/pr-loop/scripts/build_fix_prompt.py).
325
+ `--flavor headless` targets the dispatcher path (gh reads, outcome file, no
326
+ commit/push/MCP/TaskCreate/Artifact). Default `--flavor agent` targets the
327
+ Agent-tool path (in-agent commit, push, and MCP replies). On headless tiers
328
+ the permission flag maps to each CLI's own flag
329
+ (`--permission-mode bypassPermissions`).
330
+
331
+ ### Tier-1 flag profiles
332
+
333
+ When tier-1 (headless grok) runs for audit or fix work and the **grok-spawn**
334
+ skill is installed on the host, take CLI flag profiles from that skill's
335
+ flag-profiles reference. Do not restate those flags here. When the skill is
336
+ absent, use the host's grok headless defaults from the worker-spawn protocol
337
+ and the headless runner. This page keeps the Agent-tool spawn shape for
338
+ Claude-host teammates.
159
339
 
160
340
  ### Shutdown (bugfix)
161
341
 
@@ -163,9 +343,9 @@ Same self-termination model as bugfind. Missing notification → hard blocker.
163
343
 
164
344
  `approve: false` → `error: bugfix teammate refused shutdown` → Step 4 (`pr-loop-lifecycle` Close).
165
345
 
166
- Substitute placeholders from `last_findings` into the fix prompt per [`../PROMPTS.md`](../PROMPTS.md). The spawn XML includes TaskCreate/self_audit_checklist for task tracking — the FIX subagent MUST create tasks before starting.
346
+ Substitute placeholders from `last_findings` into the fix prompt per [`../PROMPTS.md`](../PROMPTS.md). The agent-flavor spawn XML includes TaskCreate/self_audit_checklist for task tracking — the tier-2 FIX subagent MUST create tasks before starting. Headless flavors omit TaskCreate.
167
347
 
168
- **Verify push:** `git rev-parse HEAD` after fix must differ from before; new HEAD must exist on `origin/<branch>` (`git fetch origin <branch> && git rev-parse origin/<branch>` matches `HEAD`). If HEAD did not change → `stuck — bugfix teammate could not address findings`.
348
+ **Verify push:** `git rev-parse HEAD` after fix must differ from before; new HEAD must exist on `origin/<branch>` (`git fetch origin <branch> && git rev-parse origin/<branch>` matches `HEAD`). If HEAD did not change → `stuck — bugfix teammate could not address findings`. On tiers 1 and 3 this check runs after the **lead** commit and push.
169
349
 
170
350
  **Scope verification.** Run `git diff HEAD~1 --name-only` and compare against the set of files referenced in `bugs_to_fix`. When the commit touches files NOT in the `bugs_to_fix` list, judge whether the extras are a coherent part of the fix: a shared helper the auditor did not think to name, a test file that exercises the fix, a config update the fix requires. If the extras are coherent with the fix, note them in the outcome XML's `<scope_notes>` and keep the outcome as `fixed`. If the extras look unrelated, suspicious, or out of scope, downgrade to `unverified_fixed` with reason `commit touched unexpected files: <list>`. The auditor's file list is a default, not a contract — the fix's coherence is the contract.
171
351
 
@@ -2,7 +2,7 @@
2
2
 
3
3
  ## Core principle (expanded)
4
4
 
5
- One audit agent (`code-quality-agent`, opus) walks all A–P categories per loop. One fix agent (`clean-coder`, opus) addresses the audit's findings.
5
+ One audit agent (`code-quality-agent`, opus) walks all A–Q categories per loop. One fix agent (`clean-coder`, opus) addresses the audit's findings.
6
6
 
7
7
  Fresh-spawn clean-room isolation: each `Agent` call creates a new subagent with its own context window and no access to prior conversation. After the subagent writes its outcome XML and self-terminates, the lead reads the file. Results never accumulate in the lead’s context beyond the XML artifact. Verbatim Anthropic quotes and URLs: [`../sources.md`](../sources.md).
8
8
 
@@ -8,7 +8,7 @@ Per-step obstacle guides for the `bugteam` skill. Each file addresses a specific
8
8
  |---|---|
9
9
  | `audit-assign-ids.md` | Assigning stable finding IDs in the audit output. |
10
10
  | `audit-capture-excerpts.md` | Capturing code excerpts for each finding. |
11
- | `audit-walk-categories.md` | Walking all A–P categories without skipping. |
11
+ | `audit-walk-categories.md` | Walking all A–Q categories without skipping. |
12
12
  | `audit-write-xml.md` | Writing the outcome XML from an audit pass. |
13
13
  | `fix-append-summary.md` | Appending the fix summary to the outcome XML. |
14
14
  | `fix-apply-fixes.md` | Applying code fixes from the finding list. |
@@ -110,8 +110,14 @@ truth.
110
110
  `<run_temp_dir>` and pass that literal path to every shell command that follows.
111
111
 
112
112
  - **Subagent roles (spawned per loop, not at invocation start):**
113
- - `bugfind` — `code-quality-agent`, model opus (Opus 4.7 at default xhigh effort)
114
- - `bugfix` `clean-coder`, no model pin (the lead picks the model per task)
113
+ - `bugfind` — `code-quality-agent`, model opus; routes through
114
+ `resolve_worker_spawn.py` with role `bugteam` (primary agent
115
+ `code-quality-agent`)
116
+ - `bugfix` — `clean-coder`, model opus; routes through
117
+ `resolve_worker_spawn.py` with role `clean-coder` (primary agent
118
+ `clean-coder`). Tier 2 Agent spawn pins `model="opus"`.
119
+ - `standards-fix` — `clean-coder` via the same dispatcher role; 5-round
120
+ cap; tier 2 pins `model="opus"` and `mode="bypassPermissions"`
115
121
 
116
122
  ### Loop state block
117
123
 
@@ -0,0 +1,153 @@
1
+ ---
2
+ name: closeout
3
+ description: >-
4
+ Harvests session obstacles into GitHub issues backed by quoted evidence at
5
+ session end, validates each draft with the user, dedupes against open and
6
+ closed issues, routes each to its repo, files children then a parent
7
+ checklist, and prints a computed cloud handoff prompt. Triggers: /closeout,
8
+ close out this session, close out the session, file the session obstacles,
9
+ session closeout, harvest session obstacles, end-of-session issue filing.
10
+ Near-miss: not session-log, which journals the session to the vault; closeout
11
+ files GitHub issues and prints a handoff prompt, and writes no session
12
+ journal.
13
+ ---
14
+
15
+ # Closeout
16
+
17
+ **Core principle:** At the end of a working session, turn the obstacles the session hit into user-approved GitHub issues — each backed by a quoted line — plus a computed cloud handoff prompt, never guessing, never filing without approval, never touching the host repo's live pipeline.
18
+
19
+ ## Gotchas
20
+
21
+ Highest-signal content. Append a bullet each time a run fails in a new way.
22
+
23
+ - An obstacle stated from memory drifts. File only what the session can quote word for word — the actual error text, the exact command, the exact log line. A candidate that cannot be quoted goes under "Unverified candidates" for the user to judge, never into a filed issue as fact.
24
+ - Skipping the confirmation gate files noise to a shared server that other people read. Every parent and child draft passes the AskUserQuestion gate before any write.
25
+ - A body that leans on chat context reads as a puzzle to anyone who opens the issue cold. Write each body so a reader with zero session context acts on it: name the failure, the count, and the quoted line.
26
+ - A `--body` string mangles backticks on GitHub — they land as literal `\``. Every `gh` create and comment uses `--body-file <path>`.
27
+ - A dedupe search that skips closed issues re-files a twin the team already resolved. The search covers `--state all`.
28
+ - A volatile path in an issue body breaks the moment the job scratch is cleaned. Keep temp dirs, worktrees, and `$CLAUDE_JOB_DIR` out of every body.
29
+
30
+ ## When this skill applies
31
+
32
+ Run this skill **at the end** of a working session, from inside that same session, when the session hit obstacles worth filing — hook blocks, gates that fired wrongly, tools that failed, forced workarounds, dead ends.
33
+
34
+ Triggers: `/closeout`, "close out this session", "file the session obstacles", "session closeout", "harvest session obstacles", "end-of-session issue filing".
35
+
36
+ **Refusal cases — first match wins:**
37
+
38
+ - **Mid-session, work still open.** Respond: `Closeout runs at session end. Keep working, and run /closeout once the session's work is done.`
39
+ - **Asked to journal the session.** Respond: `Closeout files GitHub issues; it does not write a session journal. For a session report to the vault, use /session-log.`
40
+ - **No obstacles this session.** Respond: `No obstacles to file — the session hit no hook blocks, tool failures, or dead ends worth an issue. Nothing to close out.`
41
+
42
+ ## The process
43
+
44
+ ```
45
+ - [ ] Phase 1 — Harvest obstacles from the three sources; quote verbatim evidence
46
+ - [ ] Phase 1 — Run the PII pass over every candidate
47
+ - [ ] Phase 2 — Draft the parent + children set
48
+ - [ ] Phase 2 — Confirmation gate: AskUserQuestion, file only on approval
49
+ - [ ] Phase 3 — Dedupe each candidate against open and closed issues
50
+ - [ ] Phase 4 — Route each issue to its repo
51
+ - [ ] Phase 5 — File children, then the parent checklist
52
+ - [ ] Phase 6 — Print the computed cloud handoff prompt in chat
53
+ ```
54
+
55
+ ### Track the phases on the task list
56
+
57
+ At invocation, copy the six phases onto the session task list — one task each via TaskCreate: harvest, draft + user validation, dedupe, repo routing, filing, handoff prompt. Mark a task `in_progress` with TaskUpdate when its phase starts and `completed` when the phase finishes.
58
+
59
+ Hold one line on the filing task: never mark it `completed` while any planned issue is still uncreated. A filing phase that lands fewer issues than the approved set keeps the filing task open, with the missing issues named on it.
60
+
61
+ ### Phase 1 — Harvest obstacles
62
+
63
+ Read three sources, in order:
64
+
65
+ 1. **This session's conversation** — the chat log visible in context.
66
+ 2. **The session task list** — TaskCreate/TaskUpdate records read through TaskList and TaskGet.
67
+ 3. **Tool results still in the context window** — hook denials, command output, log tails.
68
+
69
+ An obstacle is a hook block, a gate that fired wrongly, a tool that failed, a forced workaround, or a dead end.
70
+
71
+ **Non-negotiable evidence rule:** every filed issue quotes verbatim evidence captured this session — the actual error text, the exact command, the exact log line. An obstacle you cannot quote is dropped, or listed under a "Unverified candidates" section of the drafts for the user to decide. It is never filed as fact.
72
+
73
+ **PII pass (runs on every run):** strip personal data from every issue body and from the handoff prompt — emails, real names, home paths, private hosts and IPs, account ids, tokens. The pass runs whether the target repo is public or private; repository visibility changes only how aggressive the redaction is (public repos get the strictest pass), never whether the pass runs. Checklist and swaps: [reference/pii-redaction-checklist.md](reference/pii-redaction-checklist.md).
74
+
75
+ ### Phase 2 — Draft and validate with the user
76
+
77
+ Build the parent → children issue set as drafts. Body shapes and worked examples: [reference/issue-body-templates.md](reference/issue-body-templates.md).
78
+
79
+ Then the **mandatory confirmation gate**. Present through AskUserQuestion:
80
+
81
+ - Each drafted parent and child — title, target repo, one line of scope each.
82
+ - Any PII concern the pass found.
83
+ - Any closed twin a dedupe search surfaced (see Phase 3), as a reopen/comment/file-new choice.
84
+
85
+ Filing to GitHub is an irreversible write to a shared server that other people read. File only on explicit user approval. The user validates every finding before anything is posted.
86
+
87
+ ### Phase 3 — Dedupe
88
+
89
+ Before filing each candidate, search open and closed issues on the target repo:
90
+
91
+ ```
92
+ gh issue list --search "<terms>" --state all
93
+ ```
94
+
95
+ - **Open twin exists** → comment on it, rather than filing a new issue.
96
+ - **Closed twin exists** → do not silently file or comment. Surface it in the Phase 2 gate as "previously closed twin — reopen, comment, or file new" for the user to decide.
97
+
98
+ `gh issue list` needs no pagination flags. If you show a `gh api` read of a paginated list endpoint anywhere, show `--paginate --slurp` piped to external `jq` — `gh`'s built-in `--jq` runs per page and gives wrong cross-page results.
99
+
100
+ ### Phase 4 — Repo routing
101
+
102
+ Route each issue by a deterministic rule:
103
+
104
+ - The evidence names a file under the dev-env tree — `packages/claude-dev-env/hooks/`, `rules/`, `skills/`, `commands/`, `agents/`, `bin/`, or `docs/` — or an installed copy of those under `~/.claude/` (hooks, rules, skills, commands, agents) → file against **claude-dev-env**.
105
+ - Otherwise → the **working repo**, read live:
106
+
107
+ ```
108
+ gh repo view --json nameWithOwner
109
+ ```
110
+
111
+ - **Cross-repo case** — a hook shipped by repo B blocked work in repo A → file against **B** and reference A in the body.
112
+
113
+ ### Phase 5 — File
114
+
115
+ File **children first**, then the parent. The parent body is a checklist of `- [ ] owner/repo#N` lines, one per child created.
116
+
117
+ - Every `gh issue create` and `gh issue comment` uses `--body-file <path>`, never `--body`.
118
+ - No volatile paths in any body: no temp dirs, no worktrees, no `$CLAUDE_JOB_DIR`, no `.claude-editor/jobs` or `.claude/worktrees` paths.
119
+ - Bodies are self-contained and specific: the failure mode, the count, and the quoted line — not "improve error handling".
120
+
121
+ ### Phase 6 — Computed handoff prompt
122
+
123
+ Print **in chat** (not a file) a prompt the user pastes into a cloud session that opens PRs for the filed issues and drives them to convergence. Template and worked example: [reference/handoff-prompt-template.md](reference/handoff-prompt-template.md).
124
+
125
+ The prompt is computed, not a bare list. It carries:
126
+
127
+ 1. **Safety boundaries** — what must never be run, merged, deployed, or synced. The working repo's pipeline is live in production.
128
+ 2. **Base branch and verification commands** — read the base branch and the per-package verification commands from the target repo's CLAUDE.md and docs at runtime.
129
+ 3. **Dependency order** — which issue must land before which, and which issues touch the same files and so must stack on one branch rather than run in parallel.
130
+
131
+ If any issue cannot be done from a cloud session — it needs a local environment, physical devices, or a private network — the prompt says so per issue and scopes the cloud work to what a cloud session can reach.
132
+
133
+ ## Skill boundaries
134
+
135
+ This skill runs inside a repo whose pipeline is live in production. Hold these lines:
136
+
137
+ - It never runs that pipeline, never merges, never deploys, never syncs.
138
+ - It never runs the host repo's automations.
139
+ - It creates issues and comments and prints text. Nothing else.
140
+
141
+ ## File index
142
+
143
+ | File | Purpose |
144
+ |------|---------|
145
+ | `SKILL.md` | This hub — core principle, gotchas, refusal cases, six-phase process, boundaries |
146
+ | `reference/issue-body-templates.md` | Parent and child issue body shapes with worked examples |
147
+ | `reference/pii-redaction-checklist.md` | The PII pass: categories, swaps, public-versus-private aggression |
148
+ | `reference/handoff-prompt-template.md` | The computed cloud handoff prompt shape with a worked example |
149
+
150
+ ## Folder map
151
+
152
+ - `SKILL.md` — hub: principle, gotchas, refusal, six-phase process, boundaries.
153
+ - `reference/` — issue body templates, PII redaction checklist, handoff prompt template.
@@ -0,0 +1,72 @@
1
+ # Handoff prompt template
2
+
3
+ The closing session prints this prompt in chat. The user pastes it into a cloud session that opens PRs for the filed issues and drives them to convergence. The prompt is computed from the filed set — the safety lines, base branch, verification commands, and dependency order are read at runtime, not guessed.
4
+
5
+ ## Contents
6
+
7
+ - [Shape](#shape)
8
+ - [How to compute each block](#how-to-compute-each-block)
9
+ - [Worked example](#worked-example)
10
+
11
+ ## Shape
12
+
13
+ ```markdown
14
+ # Cloud handoff — <parent issue owner/repo#N>
15
+
16
+ ## Task
17
+ Open a PR per filed issue below and drive each to convergence.
18
+
19
+ ## Safety — never do these
20
+ - Never run, merge, deploy, or sync the <working repo> pipeline. It is live in production.
21
+ - Never run the host repo's automations.
22
+ - <any repo-specific never line read from the target CLAUDE.md>
23
+
24
+ ## Base branch and verification
25
+ - Base branch: <base>
26
+ - Per-package verification commands:
27
+ - <package A>: <command>
28
+ - <package B>: <command>
29
+
30
+ ## Issues, in dependency order
31
+ 1. owner/repo#<N> — <title>. <cloud-doable? yes / no + why>.
32
+ 2. owner/repo#<N> — <title>. Depends on #<N> landing first.
33
+ 3. owner/repo#<N> — <title>. Touches the same files as #<N>; stack on one branch, do not run in parallel.
34
+
35
+ ## Cannot be done from a cloud session
36
+ - owner/repo#<N> — needs <local environment / physical device / private network>. Scope the cloud work to <what a cloud session can reach>.
37
+ ```
38
+
39
+ ## How to compute each block
40
+
41
+ - **Safety lines** — read the working repo's CLAUDE.md and docs for the pipeline, deploy, and sync commands the cloud session must never run. Name each one.
42
+ - **Base branch** — read it live from the target repo (its default branch), not from memory.
43
+ - **Verification commands** — read the per-package test and check commands from the target repo's CLAUDE.md or docs. List one line per package a filed issue touches.
44
+ - **Dependency order** — for each pair of issues, decide: does one need the other's change to land first? Do they touch the same files? Same-file issues stack on one branch; independent issues run in parallel.
45
+ - **Cloud reachability** — for each issue, decide whether a cloud session can do the work. An issue needing a local environment, physical devices, or a private network is marked, and the cloud work is scoped to the reachable part.
46
+
47
+ ## Worked example
48
+
49
+ ```markdown
50
+ # Cloud handoff — jl-cmd/claude-dev-env#100
51
+
52
+ ## Task
53
+ Open a PR per filed issue below and drive each to convergence.
54
+
55
+ ## Safety — never do these
56
+ - Never run, merge, deploy, or sync the claude-dev-env publish pipeline. It is live in production (publishes to npm).
57
+ - Never run the host repo's automations.
58
+ - Never hand-edit .cursor/BUGBOT.md; it is generated from AGENTS.md.
59
+
60
+ ## Base branch and verification
61
+ - Base branch: main
62
+ - Per-package verification commands:
63
+ - claude-dev-env (JS): cd packages/claude-dev-env && npm test
64
+ - claude-dev-env (Python): python -m pytest packages/claude-dev-env
65
+
66
+ ## Issues, in dependency order
67
+ 1. jl-cmd/claude-dev-env#101 — inline-collection gate fires in exempt test files. Cloud-doable: yes.
68
+ 2. jl-cmd/claude-dev-env#102 — boolean-naming gate flags a fixture variable. Touches the same file as #101 (code_rules_enforcer.py); stack on one branch with #101, do not run in parallel.
69
+
70
+ ## Cannot be done from a cloud session
71
+ - None. Both issues are pure hook-logic changes with local pytest coverage a cloud session can run.
72
+ ```
@@ -0,0 +1,108 @@
1
+ # Issue body templates
2
+
3
+ Body shapes for the parent tracking issue and its child issues, plus a worked example. Every body is self-contained: a reader with zero session context understands it. Every body carries a quoted line of evidence captured this session. Write each body to a temp file and pass it with `gh issue create --body-file <path>`.
4
+
5
+ ## Contents
6
+
7
+ - [Child issue body](#child-issue-body)
8
+ - [Parent tracking issue body](#parent-tracking-issue-body)
9
+ - [Worked example — child](#worked-example--child)
10
+ - [Worked example — parent](#worked-example--parent)
11
+ - [Body rules](#body-rules)
12
+
13
+ ## Child issue body
14
+
15
+ One obstacle per child. Fill every section:
16
+
17
+ ```markdown
18
+ ## What happened
19
+
20
+ <One sentence: the failure mode, in plain terms.>
21
+
22
+ ## Evidence
23
+
24
+ <The verbatim line captured this session — error text, command, or log line — in a fenced block.>
25
+
26
+ ```
27
+ <exact quoted text>
28
+ ```
29
+
30
+ ## Where
31
+
32
+ <The file, hook, gate, or tool the evidence names. Path relative to the repo root.>
33
+
34
+ ## Impact
35
+
36
+ <What the obstacle cost: work blocked, count of times hit, workaround forced.>
37
+
38
+ ## Proposed fix
39
+
40
+ <The specific change. Name the failure mode and the condition, not "improve error handling".>
41
+ ```
42
+
43
+ ## Parent tracking issue body
44
+
45
+ The parent gathers the children. Its body is a checklist, one line per child created:
46
+
47
+ ```markdown
48
+ ## Session closeout — <short session label>
49
+
50
+ Obstacles this session, filed as child issues:
51
+
52
+ - [ ] owner/repo#<N> — <child title>
53
+ - [ ] owner/repo#<N> — <child title>
54
+ - [ ] owner/repo#<N> — <child title>
55
+
56
+ ## Handoff
57
+
58
+ A cloud handoff prompt for these issues was printed in the closing session. It carries the safety boundaries, base branch, per-package verification commands, and the dependency order among the children.
59
+ ```
60
+
61
+ ## Worked example — child
62
+
63
+ ```markdown
64
+ ## What happened
65
+
66
+ The code_rules_enforcer hook blocked a valid list literal in a test file, where test files are exempt from the magic-value gate.
67
+
68
+ ## Evidence
69
+
70
+ ```
71
+ BLOCKED: [MAGIC_VALUE] Inline list literal [200, 404, 500] in a function body -- extract to a named constant in config/.
72
+ ```
73
+
74
+ ## Where
75
+
76
+ packages/claude-dev-env/hooks/blocking/code_rules_enforcer.py — the inline-collection check.
77
+
78
+ ## Impact
79
+
80
+ Hit 3 times in one session on three test files. Forced a workaround: moving each literal to a module constant the test did not need.
81
+
82
+ ## Proposed fix
83
+
84
+ Extend the test-file exemption that already covers the magic-value gate to also cover the inline-collection check, so list and set literals in test bodies pass.
85
+ ```
86
+
87
+ ## Worked example — parent
88
+
89
+ ```markdown
90
+ ## Session closeout — hook exemptions for test files
91
+
92
+ Obstacles this session, filed as child issues:
93
+
94
+ - [ ] jl-cmd/claude-dev-env#101 — inline-collection gate fires in exempt test files
95
+ - [ ] jl-cmd/claude-dev-env#102 — boolean-naming gate flags a fixture variable
96
+
97
+ ## Handoff
98
+
99
+ A cloud handoff prompt for these issues was printed in the closing session. It carries the safety boundaries, base branch, per-package verification commands, and the dependency order among the children.
100
+ ```
101
+
102
+ ## Body rules
103
+
104
+ - **Quoted evidence is required.** No child ships without a fenced block holding a line captured this session.
105
+ - **No volatile paths.** No temp dirs, worktrees, `$CLAUDE_JOB_DIR`, `.claude-editor/jobs`, or `.claude/worktrees` paths in any body. Paste text inline; for a binary artifact, upload it to a durable release and link that URL.
106
+ - **No chat references.** Drop "as discussed" and "the choice we picked". State each fact on its own.
107
+ - **Specific over vague.** "The gate fires on `[200, 404, 500]` in a test body" beats "the gate is too strict".
108
+ - **PII stripped.** Run the PII pass (see the PII redaction checklist) over every body before it reaches the confirmation gate.