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.
- package/_shared/advisor/CLAUDE.md +2 -2
- package/_shared/advisor/advisor-protocol.md +20 -20
- package/_shared/advisor/scripts/config/advisor_scripts_constants/model_tier_run_validator_constants.py +15 -12
- package/_shared/advisor/scripts/model_tier_run_validator.py +11 -10
- package/_shared/advisor/scripts/tests/test_model_tier_run_validator.py +25 -19
- package/_shared/advisor/scripts/tests/test_tier_model_ids.py +17 -17
- package/_shared/advisor/scripts/tier_model_ids.py +18 -18
- package/_shared/pr-loop/CLAUDE.md +1 -0
- package/_shared/pr-loop/scripts/CLAUDE.md +2 -1
- package/_shared/pr-loop/scripts/README.md +1 -0
- package/_shared/pr-loop/scripts/code_rules_gate.py +253 -1980
- package/_shared/pr-loop/scripts/code_rules_gate_parts/CLAUDE.md +32 -0
- package/_shared/pr-loop/scripts/code_rules_gate_parts/__init__.py +7 -0
- package/_shared/pr-loop/scripts/code_rules_gate_parts/added_line_maps.py +268 -0
- package/_shared/pr-loop/scripts/code_rules_gate_parts/enforcer_loading.py +172 -0
- package/_shared/pr-loop/scripts/code_rules_gate_parts/gate_arguments.py +70 -0
- package/_shared/pr-loop/scripts/code_rules_gate_parts/gate_running.py +326 -0
- package/_shared/pr-loop/scripts/code_rules_gate_parts/git_blob_readers.py +85 -0
- package/_shared/pr-loop/scripts/code_rules_gate_parts/git_file_sets.py +331 -0
- package/_shared/pr-loop/scripts/code_rules_gate_parts/staged_test_running.py +369 -0
- package/_shared/pr-loop/scripts/code_rules_gate_parts/tests/conftest.py +14 -0
- package/_shared/pr-loop/scripts/code_rules_gate_parts/tests/test_added_line_maps.py +118 -0
- package/_shared/pr-loop/scripts/code_rules_gate_parts/tests/test_enforcer_loading.py +17 -0
- package/_shared/pr-loop/scripts/code_rules_gate_parts/tests/test_gate_arguments.py +29 -0
- package/_shared/pr-loop/scripts/code_rules_gate_parts/tests/test_gate_running.py +99 -0
- package/_shared/pr-loop/scripts/code_rules_gate_parts/tests/test_git_blob_readers.py +69 -0
- package/_shared/pr-loop/scripts/code_rules_gate_parts/tests/test_git_file_sets.py +137 -0
- package/_shared/pr-loop/scripts/code_rules_gate_parts/tests/test_staged_test_running.py +116 -0
- package/_shared/pr-loop/scripts/code_rules_gate_parts/tests/test_violation_scoping.py +75 -0
- package/_shared/pr-loop/scripts/code_rules_gate_parts/tests/test_wrapper_plumb_check.py +49 -0
- package/_shared/pr-loop/scripts/code_rules_gate_parts/violation_scoping.py +328 -0
- package/_shared/pr-loop/scripts/code_rules_gate_parts/wrapper_plumb_check.py +206 -0
- package/_shared/pr-loop/scripts/pr_loop_shared_constants/code_rules_gate_constants.py +24 -17
- package/_shared/pr-loop/scripts/pr_loop_shared_constants/reviews_disabled_constants.py +1 -0
- package/_shared/pr-loop/scripts/reviews_disabled.py +19 -2
- package/_shared/pr-loop/scripts/test_code_rules_gate.py +278 -0
- package/_shared/pr-loop/scripts/tests/test_code_rules_gate_constants.py +6 -39
- package/_shared/pr-loop/scripts/tests/test_reviews_disabled.py +43 -0
- package/_shared/pr-loop/worker-spawn.md +186 -0
- package/agents/code-verifier.md +1 -1
- package/bin/ever-shipped-skills.mjs +3 -0
- package/bin/expand_home_directory_tokens.mjs +1 -1
- package/bin/install.mjs +5 -2
- package/hooks/advisory/refactor_guard.py +3 -4
- package/hooks/blocking/CLAUDE.md +7 -1
- package/hooks/blocking/block_main_commit.py +2 -2
- package/hooks/blocking/claude_md_orphan_file_blocker.py +75 -699
- package/hooks/blocking/claude_md_orphan_file_blocker_parts/CLAUDE.md +28 -0
- package/hooks/blocking/claude_md_orphan_file_blocker_parts/__init__.py +1 -0
- package/hooks/blocking/claude_md_orphan_file_blocker_parts/config/__init__.py +1 -0
- package/hooks/blocking/claude_md_orphan_file_blocker_parts/config/orphan_blocker_constants.py +18 -0
- package/hooks/blocking/claude_md_orphan_file_blocker_parts/decision.py +81 -0
- package/hooks/blocking/claude_md_orphan_file_blocker_parts/references.py +307 -0
- package/hooks/blocking/claude_md_orphan_file_blocker_parts/scan_plan.py +124 -0
- package/hooks/blocking/claude_md_orphan_file_blocker_parts/subtree_scan.py +179 -0
- package/hooks/blocking/claude_md_orphan_file_blocker_parts/tests/conftest.py +10 -0
- package/hooks/blocking/claude_md_orphan_file_blocker_parts/tests/test_decision.py +34 -0
- package/hooks/blocking/claude_md_orphan_file_blocker_parts/tests/test_references.py +42 -0
- package/hooks/blocking/claude_md_orphan_file_blocker_parts/tests/test_scan_plan.py +27 -0
- package/hooks/blocking/claude_md_orphan_file_blocker_parts/tests/test_subtree_scan.py +30 -0
- package/hooks/blocking/code_rules_boolean_mustcheck.py +1 -1
- package/hooks/blocking/code_rules_mock_completeness.py +1 -1
- package/hooks/blocking/code_rules_optional_params.py +2 -2
- package/hooks/blocking/code_rules_shared.py +1 -1
- package/hooks/blocking/code_rules_test_assertions.py +1 -1
- package/hooks/blocking/code_rules_typeddict_stub.py +1 -1
- package/hooks/blocking/gh_pr_author_enforcer.py +1 -1
- package/hooks/blocking/inventory_intent_records/CLAUDE.md +26 -0
- package/hooks/blocking/inventory_intent_records/__init__.py +1 -0
- package/hooks/blocking/inventory_intent_records/config/__init__.py +1 -0
- package/hooks/blocking/inventory_intent_records/config/intent_records_constants.py +20 -0
- package/hooks/blocking/inventory_intent_records/records.py +271 -0
- package/hooks/blocking/inventory_intent_records/tests/conftest.py +10 -0
- package/hooks/blocking/inventory_intent_records/tests/test_records.py +80 -0
- package/hooks/blocking/package_inventory_stale_blocker.py +54 -384
- package/hooks/blocking/package_inventory_stale_blocker_parts/CLAUDE.md +26 -0
- package/hooks/blocking/package_inventory_stale_blocker_parts/__init__.py +1 -0
- package/hooks/blocking/package_inventory_stale_blocker_parts/config/__init__.py +1 -0
- package/hooks/blocking/package_inventory_stale_blocker_parts/config/inventory_blocker_constants.py +16 -0
- package/hooks/blocking/package_inventory_stale_blocker_parts/decision.py +84 -0
- package/hooks/blocking/package_inventory_stale_blocker_parts/inventory_detection.py +307 -0
- package/hooks/blocking/package_inventory_stale_blocker_parts/tests/conftest.py +10 -0
- package/hooks/blocking/package_inventory_stale_blocker_parts/tests/test_decision.py +38 -0
- package/hooks/blocking/package_inventory_stale_blocker_parts/tests/test_inventory_detection.py +61 -0
- package/hooks/blocking/pii_payload_scan.py +138 -42
- package/hooks/blocking/pii_prevention_blocker.py +185 -291
- package/hooks/blocking/pii_prevention_blocker_parts/CLAUDE.md +24 -0
- package/hooks/blocking/pii_prevention_blocker_parts/__init__.py +1 -0
- package/hooks/blocking/pii_prevention_blocker_parts/config/__init__.py +1 -0
- package/hooks/blocking/pii_prevention_blocker_parts/config/repository_resolution_constants.py +28 -0
- package/hooks/blocking/pii_prevention_blocker_parts/repository_exemption.py +214 -0
- package/hooks/blocking/pii_prevention_blocker_parts/repository_resolution.py +208 -0
- package/hooks/blocking/pr_description_command_parser.py +8 -4
- package/hooks/blocking/precommit_code_rules_gate.py +3 -3
- package/hooks/blocking/tdd_enforcer.py +97 -608
- package/hooks/blocking/tdd_enforcer_parts/CLAUDE.md +30 -0
- package/hooks/blocking/tdd_enforcer_parts/__init__.py +1 -0
- package/hooks/blocking/tdd_enforcer_parts/candidate_paths.py +142 -0
- package/hooks/blocking/tdd_enforcer_parts/config/__init__.py +1 -0
- package/hooks/blocking/tdd_enforcer_parts/config/tdd_enforcer_constants.py +32 -0
- package/hooks/blocking/tdd_enforcer_parts/content_analysis.py +268 -0
- package/hooks/blocking/tdd_enforcer_parts/decisions.py +92 -0
- package/hooks/blocking/tdd_enforcer_parts/freshness.py +80 -0
- package/hooks/blocking/tdd_enforcer_parts/git_tracking.py +63 -0
- package/hooks/blocking/tdd_enforcer_parts/path_classification.py +119 -0
- package/hooks/blocking/tdd_enforcer_parts/tests/conftest.py +10 -0
- package/hooks/blocking/tdd_enforcer_parts/tests/test_candidate_paths.py +31 -0
- package/hooks/blocking/tdd_enforcer_parts/tests/test_content_analysis.py +30 -0
- package/hooks/blocking/tdd_enforcer_parts/tests/test_decisions.py +34 -0
- package/hooks/blocking/tdd_enforcer_parts/tests/test_freshness.py +28 -0
- package/hooks/blocking/tdd_enforcer_parts/tests/test_git_tracking.py +48 -0
- package/hooks/blocking/tdd_enforcer_parts/tests/test_path_classification.py +36 -0
- package/hooks/blocking/test_inventory_deadlock_resolution.py +154 -0
- package/hooks/blocking/test_pii_payload_scan.py +168 -0
- package/hooks/blocking/test_tdd_enforcer_restore.py +108 -0
- package/hooks/blocking/tests/conftest.py +10 -0
- package/hooks/blocking/tests/test_pii_prevention_blocker.py +260 -0
- package/hooks/blocking/tests/test_repository_exemption.py +105 -0
- package/hooks/blocking/tests/test_repository_resolution.py +108 -0
- package/hooks/diagnostic/hook_log_extractor.py +12 -10
- package/hooks/git-hooks/post_commit.py +3 -4
- package/hooks/hooks_constants/CLAUDE.md +2 -2
- package/hooks/hooks_constants/banned_identifiers_constants.py +0 -1
- package/hooks/hooks_constants/code_rules_path_utils_constants.py +1 -1
- package/hooks/hooks_constants/local_identity.py +59 -8
- package/hooks/hooks_constants/pii_prevention_constants.py +0 -6
- package/hooks/hooks_constants/test_local_identity.py +105 -3
- package/hooks/pyproject.toml +13 -36
- package/hooks/session/plugin_data_dir_cleanup.py +0 -1
- package/hooks/validation/mypy_validator.py +2 -2
- package/hooks/validators/health_check.py +1 -0
- package/hooks/validators/mypy_integration.py +2 -0
- package/hooks/validators/ruff_integration.py +3 -0
- package/hooks/workflow/auto_formatter.py +5 -4
- package/package.json +1 -1
- package/scripts/CLAUDE.md +4 -0
- package/scripts/dev_env_scripts_constants/CLAUDE.md +6 -4
- package/scripts/dev_env_scripts_constants/code_review_constants.py +71 -0
- package/scripts/dev_env_scripts_constants/grok_worker_constants.py +435 -0
- package/scripts/dev_env_scripts_constants/timing.py +7 -1
- package/scripts/grok_headless_runner.py +294 -0
- package/scripts/grok_worker_preflight.py +410 -0
- package/scripts/invoke_code_review.py +463 -0
- package/scripts/resolve_worker_spawn.py +619 -0
- package/scripts/spawn_grok_batch.py +672 -0
- package/scripts/test_grok_headless_runner.py +626 -0
- package/scripts/test_grok_worker_preflight.py +1054 -0
- package/scripts/test_invoke_code_review.py +672 -0
- package/scripts/test_resolve_worker_spawn.py +1014 -0
- package/scripts/test_spawn_grok_batch.py +1017 -0
- package/skills/CLAUDE.md +5 -3
- package/skills/_shared/pr-loop/scripts/build_audit_prompt.py +72 -13
- package/skills/_shared/pr-loop/scripts/build_fix_prompt.py +121 -14
- package/skills/_shared/pr-loop/scripts/skills_pr_loop_constants/path_resolver_constants.py +78 -0
- package/skills/_shared/pr-loop/scripts/test_build_audit_prompt.py +121 -0
- package/skills/_shared/pr-loop/scripts/test_build_fix_prompt.py +196 -6
- package/skills/autoconverge/CLAUDE.md +3 -3
- package/skills/autoconverge/SKILL.md +9 -3
- package/skills/autoconverge/reference/CLAUDE.md +2 -2
- package/skills/autoconverge/reference/convergence.md +33 -11
- package/skills/autoconverge/reference/stop-conditions.md +16 -5
- package/skills/autoconverge/workflow/CLAUDE.md +2 -1
- package/skills/autoconverge/workflow/converge.clean-audit.test.mjs +7 -2
- package/skills/autoconverge/workflow/converge.codex-gate.test.mjs +300 -0
- package/skills/autoconverge/workflow/converge.contract.test.mjs +5 -5
- package/skills/autoconverge/workflow/converge.copilot-gate.test.mjs +29 -29
- package/skills/autoconverge/workflow/converge.fix-progress.test.mjs +1 -1
- package/skills/autoconverge/workflow/converge.mjs +200 -16
- package/skills/bugteam/CLAUDE.md +2 -2
- package/skills/bugteam/CONSTRAINTS.md +3 -2
- package/skills/bugteam/PROMPTS.md +7 -6
- package/skills/bugteam/SKILL.md +18 -13
- package/skills/bugteam/reference/audit-and-teammates.md +215 -35
- package/skills/bugteam/reference/design-rationale.md +1 -1
- package/skills/bugteam/reference/obstacles/CLAUDE.md +1 -1
- package/skills/bugteam/reference/team-setup.md +8 -2
- package/skills/codex-review/CLAUDE.md +46 -0
- package/skills/codex-review/SKILL.md +181 -0
- package/skills/codex-review/reference/CLAUDE.md +15 -0
- package/skills/codex-review/reference/cli-contract.md +253 -0
- package/skills/codex-review/reference/loop-integration.md +118 -0
- package/skills/codex-review/scripts/codex_down_classifier.py +98 -0
- package/skills/codex-review/scripts/codex_review_scripts_constants/CLAUDE.md +18 -0
- package/skills/codex-review/scripts/codex_review_scripts_constants/__init__.py +1 -0
- package/skills/codex-review/scripts/codex_review_scripts_constants/classifier_constants.py +35 -0
- package/skills/codex-review/scripts/codex_review_scripts_constants/codex_usage_probe_constants.py +86 -0
- package/skills/codex-review/scripts/codex_review_scripts_constants/findings_constants.py +18 -0
- package/skills/codex-review/scripts/codex_review_scripts_constants/run_constants.py +45 -0
- package/skills/codex-review/scripts/codex_usage_probe.py +573 -0
- package/skills/codex-review/scripts/fixtures/auth_failure_synthetic.txt +1 -0
- package/skills/codex-review/scripts/fixtures/config_load_failure_v0.125.0.txt +1 -0
- package/skills/codex-review/scripts/fixtures/freeform_findings_v0.144.3.txt +6 -0
- package/skills/codex-review/scripts/fixtures/model_rejection_v0.125.0.jsonl +5 -0
- package/skills/codex-review/scripts/fixtures/structured_findings.txt +13 -0
- package/skills/codex-review/scripts/fixtures/success_stream_v0.144.3.jsonl +6 -0
- package/skills/codex-review/scripts/fixtures/unknown_failure_synthetic.txt +1 -0
- package/skills/codex-review/scripts/fixtures/usage_limit_synthetic.txt +1 -0
- package/skills/codex-review/scripts/parse_codex_findings.py +207 -0
- package/skills/codex-review/scripts/run_codex_review.py +415 -0
- package/skills/codex-review/scripts/test_codex_down_classifier.py +143 -0
- package/skills/codex-review/scripts/test_codex_usage_probe.py +678 -0
- package/skills/codex-review/scripts/test_parse_codex_findings.py +130 -0
- package/skills/codex-review/scripts/test_run_codex_review.py +812 -0
- package/skills/codex-review/test_skill_scaffold.py +192 -0
- package/skills/grok-spawn/CLAUDE.md +28 -0
- package/skills/grok-spawn/SKILL.md +226 -0
- package/skills/grok-spawn/reference/flag-profiles.md +132 -0
- package/skills/grok-spawn/reference/worker-briefs.md +152 -0
- package/skills/grokify/SKILL.md +9 -1
- package/skills/grokify/capability-claims.test.mjs +28 -0
- package/skills/grokify/evals/README.md +72 -0
- package/skills/grokify/evals/parse-payload.test.mjs +171 -0
- package/skills/grokify/evals/run-capability-evals.mjs +545 -0
- package/skills/orchestrator/SKILL.md +15 -11
- package/skills/orchestrator-refresh/SKILL.md +5 -5
- package/skills/pr-converge/SKILL.md +34 -13
- package/skills/pr-converge/reference/convergence-gates.md +42 -15
- package/skills/pr-converge/reference/fix-protocol.md +1 -1
- package/skills/pr-converge/reference/ground-rules.md +1 -1
- package/skills/pr-converge/reference/per-tick.md +130 -42
- package/skills/pr-converge/reference/state-schema.md +10 -0
- package/skills/pr-converge/scripts/CLAUDE.md +2 -0
- package/skills/pr-converge/scripts/_pr_converge_path_setup.py +5 -1
- package/skills/pr-converge/scripts/check_convergence.py +605 -29
- package/skills/pr-converge/scripts/check_convergence_availability.py +232 -0
- package/skills/pr-converge/scripts/check_convergence_gates.py +279 -235
- package/skills/pr-converge/scripts/check_convergence_thread_gates.py +1 -1
- package/skills/pr-converge/scripts/pr_converge_scripts_constants/convergence_gate_constants.py +36 -2
- package/skills/pr-converge/scripts/test__pr_converge_path_setup.py +4 -0
- package/skills/pr-converge/scripts/test_check_convergence.py +71 -3
- package/skills/pr-converge/scripts/test_check_convergence_availability.py +326 -0
- package/skills/pr-converge/scripts/test_check_convergence_codex.py +507 -0
- package/skills/pr-converge/scripts/test_check_convergence_contract.py +89 -17
- package/skills/pr-converge/scripts/test_check_convergence_fixture.py +179 -0
- package/skills/pr-converge/scripts/test_check_convergence_gates.py +84 -68
- package/skills/pr-converge/scripts/test_check_convergence_thread_gates.py +24 -0
- package/skills/pr-converge/test_step5_host_branch.py +106 -0
- package/skills/pr-loop-cloud-transport/SKILL.md +2 -0
- package/skills/reviewer-gates/SKILL.md +7 -5
- 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** →
|
|
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
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
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
|
-
|
|
135
|
-
|
|
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
|
-
##
|
|
140
|
-
|
|
141
|
-
|
|
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
|
-
|
|
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–
|
|
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–
|
|
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
|
|
114
|
-
|
|
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.
|