claude-dev-env 1.95.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 (240) hide show
  1. package/_shared/advisor/CLAUDE.md +2 -2
  2. package/_shared/advisor/advisor-protocol.md +20 -20
  3. package/_shared/advisor/scripts/config/advisor_scripts_constants/model_tier_run_validator_constants.py +15 -12
  4. package/_shared/advisor/scripts/model_tier_run_validator.py +11 -10
  5. package/_shared/advisor/scripts/tests/test_model_tier_run_validator.py +25 -19
  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/ever-shipped-skills.mjs +3 -0
  42. package/bin/expand_home_directory_tokens.mjs +1 -1
  43. package/bin/install.mjs +5 -2
  44. package/hooks/advisory/refactor_guard.py +3 -4
  45. package/hooks/blocking/CLAUDE.md +7 -1
  46. package/hooks/blocking/block_main_commit.py +2 -2
  47. package/hooks/blocking/claude_md_orphan_file_blocker.py +75 -699
  48. package/hooks/blocking/claude_md_orphan_file_blocker_parts/CLAUDE.md +28 -0
  49. package/hooks/blocking/claude_md_orphan_file_blocker_parts/__init__.py +1 -0
  50. package/hooks/blocking/claude_md_orphan_file_blocker_parts/config/__init__.py +1 -0
  51. package/hooks/blocking/claude_md_orphan_file_blocker_parts/config/orphan_blocker_constants.py +18 -0
  52. package/hooks/blocking/claude_md_orphan_file_blocker_parts/decision.py +81 -0
  53. package/hooks/blocking/claude_md_orphan_file_blocker_parts/references.py +307 -0
  54. package/hooks/blocking/claude_md_orphan_file_blocker_parts/scan_plan.py +124 -0
  55. package/hooks/blocking/claude_md_orphan_file_blocker_parts/subtree_scan.py +179 -0
  56. package/hooks/blocking/claude_md_orphan_file_blocker_parts/tests/conftest.py +10 -0
  57. package/hooks/blocking/claude_md_orphan_file_blocker_parts/tests/test_decision.py +34 -0
  58. package/hooks/blocking/claude_md_orphan_file_blocker_parts/tests/test_references.py +42 -0
  59. package/hooks/blocking/claude_md_orphan_file_blocker_parts/tests/test_scan_plan.py +27 -0
  60. package/hooks/blocking/claude_md_orphan_file_blocker_parts/tests/test_subtree_scan.py +30 -0
  61. package/hooks/blocking/code_rules_boolean_mustcheck.py +1 -1
  62. package/hooks/blocking/code_rules_mock_completeness.py +1 -1
  63. package/hooks/blocking/code_rules_optional_params.py +2 -2
  64. package/hooks/blocking/code_rules_shared.py +1 -1
  65. package/hooks/blocking/code_rules_test_assertions.py +1 -1
  66. package/hooks/blocking/code_rules_typeddict_stub.py +1 -1
  67. package/hooks/blocking/gh_pr_author_enforcer.py +1 -1
  68. package/hooks/blocking/inventory_intent_records/CLAUDE.md +26 -0
  69. package/hooks/blocking/inventory_intent_records/__init__.py +1 -0
  70. package/hooks/blocking/inventory_intent_records/config/__init__.py +1 -0
  71. package/hooks/blocking/inventory_intent_records/config/intent_records_constants.py +20 -0
  72. package/hooks/blocking/inventory_intent_records/records.py +271 -0
  73. package/hooks/blocking/inventory_intent_records/tests/conftest.py +10 -0
  74. package/hooks/blocking/inventory_intent_records/tests/test_records.py +80 -0
  75. package/hooks/blocking/package_inventory_stale_blocker.py +54 -384
  76. package/hooks/blocking/package_inventory_stale_blocker_parts/CLAUDE.md +26 -0
  77. package/hooks/blocking/package_inventory_stale_blocker_parts/__init__.py +1 -0
  78. package/hooks/blocking/package_inventory_stale_blocker_parts/config/__init__.py +1 -0
  79. package/hooks/blocking/package_inventory_stale_blocker_parts/config/inventory_blocker_constants.py +16 -0
  80. package/hooks/blocking/package_inventory_stale_blocker_parts/decision.py +84 -0
  81. package/hooks/blocking/package_inventory_stale_blocker_parts/inventory_detection.py +307 -0
  82. package/hooks/blocking/package_inventory_stale_blocker_parts/tests/conftest.py +10 -0
  83. package/hooks/blocking/package_inventory_stale_blocker_parts/tests/test_decision.py +38 -0
  84. package/hooks/blocking/package_inventory_stale_blocker_parts/tests/test_inventory_detection.py +61 -0
  85. package/hooks/blocking/pii_payload_scan.py +138 -42
  86. package/hooks/blocking/pii_prevention_blocker.py +185 -291
  87. package/hooks/blocking/pii_prevention_blocker_parts/CLAUDE.md +24 -0
  88. package/hooks/blocking/pii_prevention_blocker_parts/__init__.py +1 -0
  89. package/hooks/blocking/pii_prevention_blocker_parts/config/__init__.py +1 -0
  90. package/hooks/blocking/pii_prevention_blocker_parts/config/repository_resolution_constants.py +28 -0
  91. package/hooks/blocking/pii_prevention_blocker_parts/repository_exemption.py +214 -0
  92. package/hooks/blocking/pii_prevention_blocker_parts/repository_resolution.py +208 -0
  93. package/hooks/blocking/pr_description_command_parser.py +8 -4
  94. package/hooks/blocking/precommit_code_rules_gate.py +3 -3
  95. package/hooks/blocking/tdd_enforcer.py +97 -608
  96. package/hooks/blocking/tdd_enforcer_parts/CLAUDE.md +30 -0
  97. package/hooks/blocking/tdd_enforcer_parts/__init__.py +1 -0
  98. package/hooks/blocking/tdd_enforcer_parts/candidate_paths.py +142 -0
  99. package/hooks/blocking/tdd_enforcer_parts/config/__init__.py +1 -0
  100. package/hooks/blocking/tdd_enforcer_parts/config/tdd_enforcer_constants.py +32 -0
  101. package/hooks/blocking/tdd_enforcer_parts/content_analysis.py +268 -0
  102. package/hooks/blocking/tdd_enforcer_parts/decisions.py +92 -0
  103. package/hooks/blocking/tdd_enforcer_parts/freshness.py +80 -0
  104. package/hooks/blocking/tdd_enforcer_parts/git_tracking.py +63 -0
  105. package/hooks/blocking/tdd_enforcer_parts/path_classification.py +119 -0
  106. package/hooks/blocking/tdd_enforcer_parts/tests/conftest.py +10 -0
  107. package/hooks/blocking/tdd_enforcer_parts/tests/test_candidate_paths.py +31 -0
  108. package/hooks/blocking/tdd_enforcer_parts/tests/test_content_analysis.py +30 -0
  109. package/hooks/blocking/tdd_enforcer_parts/tests/test_decisions.py +34 -0
  110. package/hooks/blocking/tdd_enforcer_parts/tests/test_freshness.py +28 -0
  111. package/hooks/blocking/tdd_enforcer_parts/tests/test_git_tracking.py +48 -0
  112. package/hooks/blocking/tdd_enforcer_parts/tests/test_path_classification.py +36 -0
  113. package/hooks/blocking/test_inventory_deadlock_resolution.py +154 -0
  114. package/hooks/blocking/test_pii_payload_scan.py +168 -0
  115. package/hooks/blocking/test_tdd_enforcer_restore.py +108 -0
  116. package/hooks/blocking/tests/conftest.py +10 -0
  117. package/hooks/blocking/tests/test_pii_prevention_blocker.py +260 -0
  118. package/hooks/blocking/tests/test_repository_exemption.py +105 -0
  119. package/hooks/blocking/tests/test_repository_resolution.py +108 -0
  120. package/hooks/diagnostic/hook_log_extractor.py +12 -10
  121. package/hooks/git-hooks/post_commit.py +3 -4
  122. package/hooks/hooks_constants/CLAUDE.md +2 -2
  123. package/hooks/hooks_constants/banned_identifiers_constants.py +0 -1
  124. package/hooks/hooks_constants/code_rules_path_utils_constants.py +1 -1
  125. package/hooks/hooks_constants/local_identity.py +59 -8
  126. package/hooks/hooks_constants/pii_prevention_constants.py +0 -6
  127. package/hooks/hooks_constants/test_local_identity.py +105 -3
  128. package/hooks/pyproject.toml +13 -36
  129. package/hooks/session/plugin_data_dir_cleanup.py +0 -1
  130. package/hooks/validation/mypy_validator.py +2 -2
  131. package/hooks/validators/health_check.py +1 -0
  132. package/hooks/validators/mypy_integration.py +2 -0
  133. package/hooks/validators/ruff_integration.py +3 -0
  134. package/hooks/workflow/auto_formatter.py +5 -4
  135. package/package.json +1 -1
  136. package/scripts/CLAUDE.md +4 -0
  137. package/scripts/dev_env_scripts_constants/CLAUDE.md +6 -4
  138. package/scripts/dev_env_scripts_constants/code_review_constants.py +71 -0
  139. package/scripts/dev_env_scripts_constants/grok_worker_constants.py +435 -0
  140. package/scripts/dev_env_scripts_constants/timing.py +7 -1
  141. package/scripts/grok_headless_runner.py +294 -0
  142. package/scripts/grok_worker_preflight.py +410 -0
  143. package/scripts/invoke_code_review.py +463 -0
  144. package/scripts/resolve_worker_spawn.py +619 -0
  145. package/scripts/spawn_grok_batch.py +672 -0
  146. package/scripts/test_grok_headless_runner.py +626 -0
  147. package/scripts/test_grok_worker_preflight.py +1054 -0
  148. package/scripts/test_invoke_code_review.py +672 -0
  149. package/scripts/test_resolve_worker_spawn.py +1014 -0
  150. package/scripts/test_spawn_grok_batch.py +1017 -0
  151. package/skills/CLAUDE.md +5 -3
  152. package/skills/_shared/pr-loop/scripts/build_audit_prompt.py +72 -13
  153. package/skills/_shared/pr-loop/scripts/build_fix_prompt.py +121 -14
  154. package/skills/_shared/pr-loop/scripts/skills_pr_loop_constants/path_resolver_constants.py +78 -0
  155. package/skills/_shared/pr-loop/scripts/test_build_audit_prompt.py +121 -0
  156. package/skills/_shared/pr-loop/scripts/test_build_fix_prompt.py +196 -6
  157. package/skills/autoconverge/CLAUDE.md +3 -3
  158. package/skills/autoconverge/SKILL.md +9 -3
  159. package/skills/autoconverge/reference/CLAUDE.md +2 -2
  160. package/skills/autoconverge/reference/convergence.md +33 -11
  161. package/skills/autoconverge/reference/stop-conditions.md +16 -5
  162. package/skills/autoconverge/workflow/CLAUDE.md +2 -1
  163. package/skills/autoconverge/workflow/converge.clean-audit.test.mjs +7 -2
  164. package/skills/autoconverge/workflow/converge.codex-gate.test.mjs +300 -0
  165. package/skills/autoconverge/workflow/converge.contract.test.mjs +5 -5
  166. package/skills/autoconverge/workflow/converge.copilot-gate.test.mjs +29 -29
  167. package/skills/autoconverge/workflow/converge.fix-progress.test.mjs +1 -1
  168. package/skills/autoconverge/workflow/converge.mjs +200 -16
  169. package/skills/bugteam/CLAUDE.md +2 -2
  170. package/skills/bugteam/CONSTRAINTS.md +3 -2
  171. package/skills/bugteam/PROMPTS.md +7 -6
  172. package/skills/bugteam/SKILL.md +18 -13
  173. package/skills/bugteam/reference/audit-and-teammates.md +215 -35
  174. package/skills/bugteam/reference/design-rationale.md +1 -1
  175. package/skills/bugteam/reference/obstacles/CLAUDE.md +1 -1
  176. package/skills/bugteam/reference/team-setup.md +8 -2
  177. package/skills/codex-review/CLAUDE.md +46 -0
  178. package/skills/codex-review/SKILL.md +181 -0
  179. package/skills/codex-review/reference/CLAUDE.md +15 -0
  180. package/skills/codex-review/reference/cli-contract.md +253 -0
  181. package/skills/codex-review/reference/loop-integration.md +118 -0
  182. package/skills/codex-review/scripts/codex_down_classifier.py +98 -0
  183. package/skills/codex-review/scripts/codex_review_scripts_constants/CLAUDE.md +18 -0
  184. package/skills/codex-review/scripts/codex_review_scripts_constants/__init__.py +1 -0
  185. package/skills/codex-review/scripts/codex_review_scripts_constants/classifier_constants.py +35 -0
  186. package/skills/codex-review/scripts/codex_review_scripts_constants/codex_usage_probe_constants.py +86 -0
  187. package/skills/codex-review/scripts/codex_review_scripts_constants/findings_constants.py +18 -0
  188. package/skills/codex-review/scripts/codex_review_scripts_constants/run_constants.py +45 -0
  189. package/skills/codex-review/scripts/codex_usage_probe.py +573 -0
  190. package/skills/codex-review/scripts/fixtures/auth_failure_synthetic.txt +1 -0
  191. package/skills/codex-review/scripts/fixtures/config_load_failure_v0.125.0.txt +1 -0
  192. package/skills/codex-review/scripts/fixtures/freeform_findings_v0.144.3.txt +6 -0
  193. package/skills/codex-review/scripts/fixtures/model_rejection_v0.125.0.jsonl +5 -0
  194. package/skills/codex-review/scripts/fixtures/structured_findings.txt +13 -0
  195. package/skills/codex-review/scripts/fixtures/success_stream_v0.144.3.jsonl +6 -0
  196. package/skills/codex-review/scripts/fixtures/unknown_failure_synthetic.txt +1 -0
  197. package/skills/codex-review/scripts/fixtures/usage_limit_synthetic.txt +1 -0
  198. package/skills/codex-review/scripts/parse_codex_findings.py +207 -0
  199. package/skills/codex-review/scripts/run_codex_review.py +415 -0
  200. package/skills/codex-review/scripts/test_codex_down_classifier.py +143 -0
  201. package/skills/codex-review/scripts/test_codex_usage_probe.py +678 -0
  202. package/skills/codex-review/scripts/test_parse_codex_findings.py +130 -0
  203. package/skills/codex-review/scripts/test_run_codex_review.py +812 -0
  204. package/skills/codex-review/test_skill_scaffold.py +192 -0
  205. package/skills/grok-spawn/CLAUDE.md +28 -0
  206. package/skills/grok-spawn/SKILL.md +226 -0
  207. package/skills/grok-spawn/reference/flag-profiles.md +132 -0
  208. package/skills/grok-spawn/reference/worker-briefs.md +152 -0
  209. package/skills/grokify/SKILL.md +9 -1
  210. package/skills/grokify/capability-claims.test.mjs +28 -0
  211. package/skills/grokify/evals/README.md +72 -0
  212. package/skills/grokify/evals/parse-payload.test.mjs +171 -0
  213. package/skills/grokify/evals/run-capability-evals.mjs +545 -0
  214. package/skills/orchestrator/SKILL.md +15 -11
  215. package/skills/orchestrator-refresh/SKILL.md +5 -5
  216. package/skills/pr-converge/SKILL.md +34 -13
  217. package/skills/pr-converge/reference/convergence-gates.md +42 -15
  218. package/skills/pr-converge/reference/fix-protocol.md +1 -1
  219. package/skills/pr-converge/reference/ground-rules.md +1 -1
  220. package/skills/pr-converge/reference/per-tick.md +130 -42
  221. package/skills/pr-converge/reference/state-schema.md +10 -0
  222. package/skills/pr-converge/scripts/CLAUDE.md +2 -0
  223. package/skills/pr-converge/scripts/_pr_converge_path_setup.py +5 -1
  224. package/skills/pr-converge/scripts/check_convergence.py +605 -29
  225. package/skills/pr-converge/scripts/check_convergence_availability.py +232 -0
  226. package/skills/pr-converge/scripts/check_convergence_gates.py +279 -235
  227. package/skills/pr-converge/scripts/check_convergence_thread_gates.py +1 -1
  228. package/skills/pr-converge/scripts/pr_converge_scripts_constants/convergence_gate_constants.py +36 -2
  229. package/skills/pr-converge/scripts/test__pr_converge_path_setup.py +4 -0
  230. package/skills/pr-converge/scripts/test_check_convergence.py +71 -3
  231. package/skills/pr-converge/scripts/test_check_convergence_availability.py +326 -0
  232. package/skills/pr-converge/scripts/test_check_convergence_codex.py +507 -0
  233. package/skills/pr-converge/scripts/test_check_convergence_contract.py +89 -17
  234. package/skills/pr-converge/scripts/test_check_convergence_fixture.py +179 -0
  235. package/skills/pr-converge/scripts/test_check_convergence_gates.py +84 -68
  236. package/skills/pr-converge/scripts/test_check_convergence_thread_gates.py +24 -0
  237. package/skills/pr-converge/test_step5_host_branch.py +106 -0
  238. package/skills/pr-loop-cloud-transport/SKILL.md +2 -0
  239. package/skills/reviewer-gates/SKILL.md +7 -5
  240. package/skills/team-advisor/SKILL.md +7 -7
@@ -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,46 @@
1
+ # codex-review
2
+
3
+ Runs OpenAI Codex as a local PR or uncommitted-diff reviewer: opt-out gate, version/shape probe, target pick, classifying review (`codex exec … review --json`), outcome classification, and handoff of findings into `pr-fix-protocol`. Triggered by `/codex-review`, `codex review`, `run codex review`, `babysit codex review`, or `codex as a PR reviewer`.
4
+
5
+ ## Purpose
6
+
7
+ One Codex review pass per invocation. The skill owns sequence and skill-level classification (`down` / `clean` / `findings`). The headless wrapper is capture-only (`completed` / `codex_down` plus raw fields). Shared peers own opt-out parsing (`reviews_disabled.py` / `reviewer-gates`) and the fix sequence (`pr-fix-protocol`). Observed raw CLI surface, wrapper capture contract, probe signals, failure fixtures, auth modes, cloud runbook, and classification map live under `reference/cli-contract.md`; PR-loop wiring lives under `reference/loop-integration.md`.
8
+
9
+ ## Key files
10
+
11
+ | File | Purpose |
12
+ |---|---|
13
+ | `SKILL.md` | Flow skeleton: opt-out → probe → target → wrapper → classify → fix handoff; refusals; sub-skills table; ground rules. |
14
+ | `reference/cli-contract.md` | Wrapper entrypoint and argv; version/shape probe; success JSONL and findings parse; failure classes tied to fixtures; auth modes; cloud runbook. |
15
+ | `reference/loop-integration.md` | Gate placement in pr-converge and autoconverge; threshold rule; opt-out token; state fields; re-entry after fixes. |
16
+ | `scripts/run_codex_review.py` | Headless capture wrapper: probes, single-target argv, JSONL capture, `completed` / `codex_down`. |
17
+ | `scripts/test_run_codex_review.py` | Behavioral tests for `run_codex_review`. |
18
+ | `scripts/codex_down_classifier.py` | Maps a Codex run's exit code and stream text to a failure detail class and the gate outcome class (`completed` / `codex_down`). |
19
+ | `scripts/parse_codex_findings.py` | Parses reviewer text into findings: fenced JSON first, then the freeform bullet shape, then a single floor finding. |
20
+ | `scripts/codex_usage_probe.py` | Weekly usage probe CLI: app-server rate-limits read, null-on-unknown JSON report. |
21
+ | `scripts/test_codex_usage_probe.py` | Unit tests for the weekly usage probe and gate helper. |
22
+ | `scripts/codex_review_scripts_constants/run_constants.py` | Named constants package for skill scripts: binary name, flags, prompt, probe pattern, timeout, exit sentinels, JSONL keys, capture outcome labels. |
23
+ | `scripts/codex_review_scripts_constants/codex_usage_probe_constants.py` | Named constants for the weekly usage probe. |
24
+
25
+ ## Subdirectories
26
+
27
+ | Directory | Role |
28
+ |---|---|
29
+ | `reference/` | Progressive-disclosure pages for cli-contract and loop-integration. |
30
+ | `scripts/` | Capture wrapper, classifier, findings parser, weekly usage probe, tests, fixtures, and constants package. |
31
+
32
+ ## Environment opt-out
33
+
34
+ Step 0 runs `reviews_disabled.py --reviewer codex` before any probe or review invoke.
35
+
36
+ | Gate exit | Meaning for this skill |
37
+ |---|---|
38
+ | 0 | Opt-out active — refuse with the opt-out line in `SKILL.md` and stop |
39
+ | 1 | Continue the flow |
40
+ | Any other | Blocker — stop; do not invent an opt-out refusal |
41
+
42
+ Set `CLAUDE_REVIEWS_DISABLED=codex` to disable. This package does not re-parse `CLAUDE_REVIEWS_DISABLED`; the shared gate owns the token parse.
43
+
44
+ ## Scripts surface
45
+
46
+ `scripts/` holds the capture wrapper (`run_codex_review.py`), the down classifier (`codex_down_classifier.py`), the findings parser (`parse_codex_findings.py`), the weekly usage probe (`codex_usage_probe.py`), their tests, fixtures, and named constants. The wrapper returns capture fields only (`completed` / `codex_down`); agents map those fields to skill classes via the skill-class map and parse findings through `parse_codex_findings`. Classify only from a `codex exec … review --json` JSONL stream; do not invent a non-JSONL parse.
@@ -0,0 +1,181 @@
1
+ ---
2
+ name: codex-review
3
+ description: >-
4
+ Runs OpenAI Codex as a local PR or uncommitted-diff reviewer and routes
5
+ findings into the shared fix protocol. Triggers: '/codex-review', 'codex
6
+ review', 'run codex review', 'babysit codex review', 'codex as a PR reviewer'.
7
+ ---
8
+
9
+ # Codex Review
10
+
11
+ Runs one Codex review pass against a chosen target, classifies the outcome, and hands findings to the shared fix protocol. Does not reimplement opt-out parsing or the fix sequence.
12
+
13
+ ## When this skill applies
14
+
15
+ - The user wants Codex (the OpenAI Codex CLI) as a reviewer on the current PR branch, or on uncommitted work when no PR loop is active.
16
+ - The user asks to babysit or re-run Codex review after fixes.
17
+
18
+ ## Refusals
19
+
20
+ Respond with the quoted line exactly and stop:
21
+
22
+ - Opt-out gate exit 0: `/codex-review is disabled via CLAUDE_REVIEWS_DISABLED.`
23
+ - Version or shape probe reports Codex unavailable: `/codex-review cannot run: Codex CLI is missing or the shape probe failed.`
24
+ - Skill class is `down` (wrapper `outcome_class` is `codex_down`): `/codex-review cannot complete: Codex reviewer is down.`
25
+
26
+ Gate exits other than 0 or 1 are blockers: stop without a probe or review invoke. Do not invent an opt-out refusal for a non-opt-out failure.
27
+
28
+ ## Sub-skills
29
+
30
+ | Skill | When | Produces |
31
+ |---|---|---|
32
+ | `reviewer-gates` | Step 0 — opt-out semantics for external reviewers | Gate contract for `reviews_disabled.py`; refusal line shape |
33
+ | `pr-fix-protocol` | Step 5 — classification is `findings` | Fix sequence, reply-and-resolve unit, unresolved-thread sweep |
34
+
35
+ If `pr-fix-protocol` is not installed when findings exist, stop with: `/codex-review needs the pr-fix-protocol skill to apply findings.`
36
+
37
+ ## Process checklist
38
+
39
+ ```
40
+ - [ ] Step 0 — Opt-out gate
41
+ - [ ] Step 1 — Version and shape probe
42
+ - [ ] Step 2 — Target pick
43
+ - [ ] Step 3 — Run classifying review
44
+ - [ ] Step 4 — Classify outcome
45
+ - [ ] Step 5 — Route findings (or stop on clean / down)
46
+ ```
47
+
48
+ ### Step 0: Opt-out gate
49
+
50
+ Before any other work, run:
51
+
52
+ ```bash
53
+ python "$HOME/.claude/_shared/pr-loop/scripts/reviews_disabled.py" --reviewer codex
54
+ ```
55
+
56
+ - **Exit 0** — Codex reviews are disabled: refuse with the opt-out line above. Do not probe, review, or fix.
57
+ - **Exit 1** — continue.
58
+ - **Any other exit** — treat as a blocker and stop; do not skip the gate or continue as if it exited 1. Do not report the opt-out refusal line for a non-opt-out failure.
59
+
60
+ Gate semantics live in `reviewer-gates` ([../reviewer-gates/SKILL.md](../reviewer-gates/SKILL.md)). The shared script owns the token parse; this skill does not re-parse `CLAUDE_REVIEWS_DISABLED`.
61
+
62
+ ### Step 1: Version and shape probe
63
+
64
+ Probe the local Codex CLI so the run fails closed when the binary is missing or the installed shape does not match the contract.
65
+
66
+ - **Contract owner:** [reference/cli-contract.md](reference/cli-contract.md) — probe command (`codex exec review --help`), minimum shape signals, and fail-as-`codex_down` rule.
67
+ - **Probe outcome:** continue only when the probe reports a supported shape. On failure, refuse with the probe refusal line above (skill class `down`).
68
+
69
+ ### Step 2: Target pick
70
+
71
+ Choose what Codex reviews:
72
+
73
+ | Context | Target |
74
+ |---|---|
75
+ | PR-loop caller (or an open PR on the current branch) | Diff against the PR base branch (`--base`) |
76
+ | Standalone run with no PR | Uncommitted work via `--uncommitted` (staged + unstaged + untracked) |
77
+
78
+ Do not invent a synthetic commit range when a base branch is available. Loop-caller wiring for base-branch resolution lives in [reference/loop-integration.md](reference/loop-integration.md).
79
+
80
+ ### Step 3: Run classifying review
81
+
82
+ Call `scripts/run_codex_review.py` (`run_codex_review`) against the chosen target on the classifying path.
83
+
84
+ - **Classifying command:** `codex exec [options] review --json …` — this is the only path that emits the success JSONL stream Step 4 reads. Full surface: [reference/cli-contract.md](reference/cli-contract.md).
85
+ - **Non-classifying form:** plain `codex review` (no `exec`, no `--json`) is not a classification input on the observed CLI; do not feed its stdout into Step 4.
86
+ - **Contract owner:** [reference/cli-contract.md](reference/cli-contract.md) — wrapper entrypoint, required arguments (target, repo root, run-state directory), capture fields, and exit codes.
87
+ - **Wrapper boundary (capture only):** returns `completed` or `codex_down`, plus `exit_code`, `binary_version`, `jsonl_path`, and `agent_message`. It does not emit skill classes `down` / `clean` / `findings` and does not parse findings.
88
+ - **This skill's job:** pass the Step 2 target, ensure `run_state_directory` exists, and hand the capture outcome to Step 4. Do not parse raw Codex stdout inline outside the documented parser path. Fail closed on probe miss, non-usable stream, or `codex_down`.
89
+
90
+ ### Step 4: Classify outcome
91
+
92
+ Map the wrapper capture (and its JSONL observation) to exactly one skill-level class:
93
+
94
+ | Skill class | From wrapper | Meaning | Next action |
95
+ |---|---|---|---|
96
+ | `down` | `outcome_class == codex_down` | Codex did not produce a usable review (tool failure, auth, crash, shape miss) | Refuse with the down line; stop |
97
+ | `clean` | `outcome_class == completed` and findings parse empty | Review completed with no findings against the target | Report one-line clean summary; stop |
98
+ | `findings` | `outcome_class == completed` and findings parse non-empty | Review completed with one or more addressable findings | Continue to Step 5 |
99
+
100
+ `outcome_class` is the capture success signal. A process `exit_code` of 0 does not mean success when the wrapper already set `codex_down` (for example a shape probe that exits 0 but lacks required flags).
101
+
102
+ #### Skill class ↔ CLI observation map
103
+
104
+ | Skill class | Maps from (cli-contract) | Signal |
105
+ |---|---|---|
106
+ | `down` | `codex_down` rows; unrecognized probe shape | Non-usable review (exit 1/2 failures, config/auth/model errors, probe miss) |
107
+ | `clean` | Wrapper `completed` and `parse_codex_findings(agent_message)` empty (blank text or structured `[]`) | Usable review, zero addressable findings |
108
+ | `findings` | Wrapper `completed` and `parse_codex_findings(agent_message)` non-empty (fenced JSON objects, freeform `- [P#]` bullets, or floor text) | Usable review with addressable findings |
109
+
110
+ Raw CLI failure vocabulary is `codex_down` only ([reference/cli-contract.md](reference/cli-contract.md)). Skill steps and loop re-entry use `down` / `clean` / `findings`. Classification rules, findings parse, and payload fields live in [reference/cli-contract.md](reference/cli-contract.md).
111
+
112
+ ### Step 5: Route findings into the shared fix protocol
113
+
114
+ When the class is `findings`:
115
+
116
+ 1. Read `$HOME/.claude/skills/pr-fix-protocol/SKILL.md` (or invoke `pr-fix-protocol` by name when the `Skill` tool is available).
117
+ 2. Pass the findings payload, PR scope when present, and worktree path.
118
+ 3. Apply the protocol end to end — failing test first when behavior is at stake, one fix commit, push when the caller requires it, reply and resolve per thread when the review is on a PR.
119
+
120
+ This skill does not restate the fix sequence. Orchestrator callers that re-enter after a push follow [reference/loop-integration.md](reference/loop-integration.md).
121
+
122
+ ## Ground rules
123
+
124
+ - **One capability:** run Codex review and classify; fixes go through `pr-fix-protocol`.
125
+ - **Compose, do not rebuild:** opt-out via `reviews_disabled.py`; fixes via `pr-fix-protocol`.
126
+ - **Fail closed** on opt-out, non-0/1 gate exit, probe failure, and `down`.
127
+ - **Preserve draft state** of any open PR; this skill does not flip ready.
128
+ - **Honor hooks** on any commit the fix protocol creates.
129
+
130
+ ## Examples
131
+
132
+ <example>
133
+ User: `/codex-review`
134
+ Claude: [runs opt-out gate; on exit 1 probes Codex shape, picks base-branch or `--uncommitted` target, runs `codex exec … review --json`, classifies from JSONL, reports clean or routes findings; on non-0/1 gate exit stops as a blocker]
135
+ </example>
136
+
137
+ <example>
138
+ `CLAUDE_REVIEWS_DISABLED=codex`
139
+ Claude: `/codex-review is disabled via CLAUDE_REVIEWS_DISABLED.`
140
+ </example>
141
+
142
+ <example>
143
+ User: "babysit codex review on this PR"
144
+ Claude: [same flow; after findings, applies pr-fix-protocol, then re-runs the classifying review once for confirmation when the caller stays on this skill]
145
+ </example>
146
+
147
+ ## Gotchas
148
+
149
+ - **Opt-out uses `CLAUDE_REVIEWS_DISABLED=codex`.** `reviews_disabled.py --reviewer codex` exit 0 disables the review; exit 1 continues the probe and wrapper. Standalone `/codex-review` stops with the opt-out refusal line and never runs the wrapper (no `codex_down` capture). Orchestrator gates map the same exit 0 to `codex_down` / `codexDown` bypass on the machine checklist. Export `CLAUDE_REVIEWS_DISABLED=codex` (alone or comma-joined with other reviewers). A gate parse failure for an unknown token is a blocker — stop rather than skipping the gate. The shared gate must list `codex` among known reviewers for Step 0 to accept the flag.
150
+ - **Only `codex exec … review --json` JSONL is classifiable.** Plain `codex review` stdout is non-classifying. Only a Step 4 `findings` class enters Step 5.
151
+ - **Wrapper capture is not skill classification.** Step 5 consumes the skill-class payload from Step 4 (`down` / `clean` / `findings`), built from the wrapper's capture fields and the findings parse.
152
+ - **Uncommitted targets have no review threads.** Fix protocol reply-and-resolve applies only when a PR carries threads; local-only runs stop after the fix commit path the protocol allows without a PR.
153
+
154
+ ## File index
155
+
156
+ | File | Purpose |
157
+ |---|---|
158
+ | `SKILL.md` | Hub: opt-out, probe, target, classifying review, classify, fix handoff |
159
+ | `CLAUDE.md` | Package map for agents opening this skill |
160
+ | `reference/cli-contract.md` | CLI probe, wrapper capture, auth, cloud runbook, fixture-backed failure classes |
161
+ | `reference/loop-integration.md` | Gate placement, threshold, opt-out, state fields, re-entry |
162
+ | `scripts/run_codex_review.py` | Headless capture wrapper (`run_codex_review`) |
163
+ | `scripts/test_run_codex_review.py` | Behavioral tests for the capture wrapper |
164
+ | `scripts/codex_down_classifier.py` | Maps exit code and stream text to detail class and `completed` / `codex_down` |
165
+ | `scripts/parse_codex_findings.py` | Parses agent text: fenced JSON, freeform bullets, then floor |
166
+ | `scripts/codex_review_scripts_constants/run_constants.py` | Importable named constants for the capture wrapper |
167
+ | `scripts/codex_usage_probe.py` | Weekly usage probe CLI (`percent_left`, `window_reset`, `source`) |
168
+ | `scripts/test_codex_usage_probe.py` | Probe unit tests (app-server fixtures and gate helper) |
169
+ | `scripts/codex_review_scripts_constants/codex_usage_probe_constants.py` | Named constants for the weekly usage probe |
170
+
171
+ ## Folder map
172
+
173
+ - `SKILL.md` — orchestration steps and refusals.
174
+ - `CLAUDE.md` — purpose, trigger, key files.
175
+ - `reference/` — stable homes for cli-contract and loop-integration detail.
176
+ - `scripts/` — capture wrapper, classifier, findings parser, weekly usage probe, tests, fixtures, and constants package.
177
+ - `scripts/run_codex_review.py` — headless capture wrapper entrypoint.
178
+ - `scripts/codex_down_classifier.py` — detail-class and gate-outcome classifier.
179
+ - `scripts/parse_codex_findings.py` — findings parser entrypoint.
180
+ - `scripts/codex_usage_probe.py` — weekly usage probe entrypoint.
181
+ - `scripts/codex_review_scripts_constants/` — importable constants package for skill scripts.
@@ -0,0 +1,15 @@
1
+ # codex-review/reference
2
+
3
+ Reference pages for the `codex-review` skill. `SKILL.md` cites these files for CLI contract and PR-loop integration detail.
4
+
5
+ ## Key files
6
+
7
+ | File | Purpose |
8
+ |---|---|
9
+ | `cli-contract.md` | Observed Codex CLI review surface: classifying `codex exec … review --json` path, wrapper capture (`completed` / `codex_down`), probe signals, success JSONL and findings parse, fixture-backed failure classes, skill-class map (`down` / `clean` / `findings`), auth modes, and cloud runbook. |
10
+ | `loop-integration.md` | Gate placement in pr-converge and autoconverge; threshold rule; opt-out token; state fields; target selection; skill-class vocabulary; findings handoff; re-entry after a fix push. |
11
+
12
+ ## Conventions
13
+
14
+ - Each page is the stable home for one child workstream. Cross-references from `SKILL.md` use these paths.
15
+ - Keep one level deep: `SKILL.md` links here; orchestrator-owned detail links out to pr-converge / autoconverge pages rather than restating them.