claude-dev-env 1.95.0 → 2.0.1

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 (241) 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/test_verifier_verdict_minter.py +55 -158
  117. package/hooks/blocking/tests/conftest.py +10 -0
  118. package/hooks/blocking/tests/test_pii_prevention_blocker.py +260 -0
  119. package/hooks/blocking/tests/test_repository_exemption.py +105 -0
  120. package/hooks/blocking/tests/test_repository_resolution.py +108 -0
  121. package/hooks/diagnostic/hook_log_extractor.py +12 -10
  122. package/hooks/git-hooks/post_commit.py +3 -4
  123. package/hooks/hooks_constants/CLAUDE.md +2 -2
  124. package/hooks/hooks_constants/banned_identifiers_constants.py +0 -1
  125. package/hooks/hooks_constants/code_rules_path_utils_constants.py +1 -1
  126. package/hooks/hooks_constants/local_identity.py +59 -8
  127. package/hooks/hooks_constants/pii_prevention_constants.py +0 -6
  128. package/hooks/hooks_constants/test_local_identity.py +105 -3
  129. package/hooks/pyproject.toml +13 -36
  130. package/hooks/session/plugin_data_dir_cleanup.py +0 -1
  131. package/hooks/validation/mypy_validator.py +2 -2
  132. package/hooks/validators/health_check.py +1 -0
  133. package/hooks/validators/mypy_integration.py +2 -0
  134. package/hooks/validators/ruff_integration.py +3 -0
  135. package/hooks/workflow/auto_formatter.py +5 -4
  136. package/package.json +1 -1
  137. package/scripts/CLAUDE.md +4 -0
  138. package/scripts/dev_env_scripts_constants/CLAUDE.md +6 -4
  139. package/scripts/dev_env_scripts_constants/code_review_constants.py +71 -0
  140. package/scripts/dev_env_scripts_constants/grok_worker_constants.py +435 -0
  141. package/scripts/dev_env_scripts_constants/timing.py +7 -1
  142. package/scripts/grok_headless_runner.py +294 -0
  143. package/scripts/grok_worker_preflight.py +410 -0
  144. package/scripts/invoke_code_review.py +463 -0
  145. package/scripts/resolve_worker_spawn.py +619 -0
  146. package/scripts/spawn_grok_batch.py +672 -0
  147. package/scripts/test_grok_headless_runner.py +626 -0
  148. package/scripts/test_grok_worker_preflight.py +1054 -0
  149. package/scripts/test_invoke_code_review.py +672 -0
  150. package/scripts/test_resolve_worker_spawn.py +1014 -0
  151. package/scripts/test_spawn_grok_batch.py +1017 -0
  152. package/skills/CLAUDE.md +5 -3
  153. package/skills/_shared/pr-loop/scripts/build_audit_prompt.py +72 -13
  154. package/skills/_shared/pr-loop/scripts/build_fix_prompt.py +121 -14
  155. package/skills/_shared/pr-loop/scripts/skills_pr_loop_constants/path_resolver_constants.py +78 -0
  156. package/skills/_shared/pr-loop/scripts/test_build_audit_prompt.py +121 -0
  157. package/skills/_shared/pr-loop/scripts/test_build_fix_prompt.py +196 -6
  158. package/skills/autoconverge/CLAUDE.md +3 -3
  159. package/skills/autoconverge/SKILL.md +9 -3
  160. package/skills/autoconverge/reference/CLAUDE.md +2 -2
  161. package/skills/autoconverge/reference/convergence.md +33 -11
  162. package/skills/autoconverge/reference/stop-conditions.md +16 -5
  163. package/skills/autoconverge/workflow/CLAUDE.md +2 -1
  164. package/skills/autoconverge/workflow/converge.clean-audit.test.mjs +7 -2
  165. package/skills/autoconverge/workflow/converge.codex-gate.test.mjs +300 -0
  166. package/skills/autoconverge/workflow/converge.contract.test.mjs +5 -5
  167. package/skills/autoconverge/workflow/converge.copilot-gate.test.mjs +29 -29
  168. package/skills/autoconverge/workflow/converge.fix-progress.test.mjs +1 -1
  169. package/skills/autoconverge/workflow/converge.mjs +200 -16
  170. package/skills/bugteam/CLAUDE.md +2 -2
  171. package/skills/bugteam/CONSTRAINTS.md +3 -2
  172. package/skills/bugteam/PROMPTS.md +7 -6
  173. package/skills/bugteam/SKILL.md +18 -13
  174. package/skills/bugteam/reference/audit-and-teammates.md +215 -35
  175. package/skills/bugteam/reference/design-rationale.md +1 -1
  176. package/skills/bugteam/reference/obstacles/CLAUDE.md +1 -1
  177. package/skills/bugteam/reference/team-setup.md +8 -2
  178. package/skills/codex-review/CLAUDE.md +46 -0
  179. package/skills/codex-review/SKILL.md +181 -0
  180. package/skills/codex-review/reference/CLAUDE.md +15 -0
  181. package/skills/codex-review/reference/cli-contract.md +253 -0
  182. package/skills/codex-review/reference/loop-integration.md +118 -0
  183. package/skills/codex-review/scripts/codex_down_classifier.py +98 -0
  184. package/skills/codex-review/scripts/codex_review_scripts_constants/CLAUDE.md +18 -0
  185. package/skills/codex-review/scripts/codex_review_scripts_constants/__init__.py +1 -0
  186. package/skills/codex-review/scripts/codex_review_scripts_constants/classifier_constants.py +35 -0
  187. package/skills/codex-review/scripts/codex_review_scripts_constants/codex_usage_probe_constants.py +86 -0
  188. package/skills/codex-review/scripts/codex_review_scripts_constants/findings_constants.py +18 -0
  189. package/skills/codex-review/scripts/codex_review_scripts_constants/run_constants.py +45 -0
  190. package/skills/codex-review/scripts/codex_usage_probe.py +573 -0
  191. package/skills/codex-review/scripts/fixtures/auth_failure_synthetic.txt +1 -0
  192. package/skills/codex-review/scripts/fixtures/config_load_failure_v0.125.0.txt +1 -0
  193. package/skills/codex-review/scripts/fixtures/freeform_findings_v0.144.3.txt +6 -0
  194. package/skills/codex-review/scripts/fixtures/model_rejection_v0.125.0.jsonl +5 -0
  195. package/skills/codex-review/scripts/fixtures/structured_findings.txt +13 -0
  196. package/skills/codex-review/scripts/fixtures/success_stream_v0.144.3.jsonl +6 -0
  197. package/skills/codex-review/scripts/fixtures/unknown_failure_synthetic.txt +1 -0
  198. package/skills/codex-review/scripts/fixtures/usage_limit_synthetic.txt +1 -0
  199. package/skills/codex-review/scripts/parse_codex_findings.py +207 -0
  200. package/skills/codex-review/scripts/run_codex_review.py +415 -0
  201. package/skills/codex-review/scripts/test_codex_down_classifier.py +143 -0
  202. package/skills/codex-review/scripts/test_codex_usage_probe.py +678 -0
  203. package/skills/codex-review/scripts/test_parse_codex_findings.py +130 -0
  204. package/skills/codex-review/scripts/test_run_codex_review.py +812 -0
  205. package/skills/codex-review/test_skill_scaffold.py +192 -0
  206. package/skills/grok-spawn/CLAUDE.md +28 -0
  207. package/skills/grok-spawn/SKILL.md +226 -0
  208. package/skills/grok-spawn/reference/flag-profiles.md +132 -0
  209. package/skills/grok-spawn/reference/worker-briefs.md +152 -0
  210. package/skills/grokify/SKILL.md +9 -1
  211. package/skills/grokify/capability-claims.test.mjs +28 -0
  212. package/skills/grokify/evals/README.md +72 -0
  213. package/skills/grokify/evals/parse-payload.test.mjs +171 -0
  214. package/skills/grokify/evals/run-capability-evals.mjs +545 -0
  215. package/skills/orchestrator/SKILL.md +42 -29
  216. package/skills/orchestrator-refresh/SKILL.md +17 -9
  217. package/skills/pr-converge/SKILL.md +34 -13
  218. package/skills/pr-converge/reference/convergence-gates.md +42 -15
  219. package/skills/pr-converge/reference/fix-protocol.md +1 -1
  220. package/skills/pr-converge/reference/ground-rules.md +1 -1
  221. package/skills/pr-converge/reference/per-tick.md +130 -42
  222. package/skills/pr-converge/reference/state-schema.md +10 -0
  223. package/skills/pr-converge/scripts/CLAUDE.md +2 -0
  224. package/skills/pr-converge/scripts/_pr_converge_path_setup.py +5 -1
  225. package/skills/pr-converge/scripts/check_convergence.py +605 -29
  226. package/skills/pr-converge/scripts/check_convergence_availability.py +232 -0
  227. package/skills/pr-converge/scripts/check_convergence_gates.py +279 -235
  228. package/skills/pr-converge/scripts/check_convergence_thread_gates.py +1 -1
  229. package/skills/pr-converge/scripts/pr_converge_scripts_constants/convergence_gate_constants.py +36 -2
  230. package/skills/pr-converge/scripts/test__pr_converge_path_setup.py +4 -0
  231. package/skills/pr-converge/scripts/test_check_convergence.py +71 -3
  232. package/skills/pr-converge/scripts/test_check_convergence_availability.py +326 -0
  233. package/skills/pr-converge/scripts/test_check_convergence_codex.py +507 -0
  234. package/skills/pr-converge/scripts/test_check_convergence_contract.py +89 -17
  235. package/skills/pr-converge/scripts/test_check_convergence_fixture.py +179 -0
  236. package/skills/pr-converge/scripts/test_check_convergence_gates.py +84 -68
  237. package/skills/pr-converge/scripts/test_check_convergence_thread_gates.py +24 -0
  238. package/skills/pr-converge/test_step5_host_branch.py +106 -0
  239. package/skills/pr-loop-cloud-transport/SKILL.md +2 -0
  240. package/skills/reviewer-gates/SKILL.md +7 -5
  241. package/skills/team-advisor/SKILL.md +7 -7
@@ -0,0 +1,192 @@
1
+ """Scaffold contract tests for the codex-review skill package."""
2
+
3
+ from __future__ import annotations
4
+
5
+ import importlib
6
+ import tomllib
7
+ from pathlib import Path
8
+
9
+
10
+ SKILL_DIRECTORY = Path(__file__).resolve().parent
11
+ SKILL_PATH = SKILL_DIRECTORY / "SKILL.md"
12
+ PACKAGE_MAP_PATH = SKILL_DIRECTORY / "CLAUDE.md"
13
+ REFERENCE_DIRECTORY = SKILL_DIRECTORY / "reference"
14
+ PACKAGE_ROOT = SKILL_DIRECTORY.parents[1]
15
+ PYPROJECT_PATH = PACKAGE_ROOT / "pyproject.toml"
16
+ EVER_SHIPPED_SKILLS_PATH = PACKAGE_ROOT / "bin" / "ever-shipped-skills.mjs"
17
+ CONSTANTS_PACKAGE_NAME = "codex_review_scripts_constants"
18
+ CONSTANTS_PACKAGE_DIR = "skills/codex-review/scripts/codex_review_scripts_constants"
19
+ SKILL_NAME = "codex-review"
20
+ MAXIMUM_SKILL_BODY_LINE_COUNT = 500
21
+
22
+
23
+ def _read_skill_text() -> str:
24
+ return SKILL_PATH.read_text(encoding="utf-8")
25
+
26
+
27
+ def test_constants_package_imports() -> None:
28
+ constants_package = importlib.import_module(CONSTANTS_PACKAGE_NAME)
29
+
30
+ assert constants_package.__name__ == CONSTANTS_PACKAGE_NAME
31
+
32
+
33
+ def test_pyproject_registers_constants_package() -> None:
34
+ parsed_pyproject = tomllib.loads(PYPROJECT_PATH.read_text(encoding="utf-8"))
35
+ setuptools_table = parsed_pyproject["tool"]["setuptools"]
36
+ all_packages = setuptools_table["packages"]
37
+ package_directory_by_name = setuptools_table["package-dir"]
38
+
39
+ assert CONSTANTS_PACKAGE_NAME in all_packages
40
+ assert package_directory_by_name[CONSTANTS_PACKAGE_NAME] == CONSTANTS_PACKAGE_DIR
41
+
42
+
43
+ def test_ever_shipped_skills_lists_codex_review() -> None:
44
+ ever_shipped_text = EVER_SHIPPED_SKILLS_PATH.read_text(encoding="utf-8")
45
+
46
+ assert f"'{SKILL_NAME}'" in ever_shipped_text
47
+
48
+
49
+ def test_skill_md_exists_with_trigger_description() -> None:
50
+ skill_text = _read_skill_text()
51
+
52
+ assert "name: codex-review" in skill_text
53
+ assert "/codex-review" in skill_text
54
+ assert "codex review" in skill_text
55
+ assert "run codex review" in skill_text
56
+ assert "babysit codex review" in skill_text
57
+ assert "codex as a PR reviewer" in skill_text
58
+
59
+
60
+ def test_skill_composes_opt_out_and_fix_protocol_by_name() -> None:
61
+ skill_text = _read_skill_text()
62
+
63
+ assert "reviews_disabled.py" in skill_text
64
+ assert "--reviewer codex" in skill_text
65
+ assert "pr-fix-protocol" in skill_text
66
+ assert "reviewer-gates" in skill_text
67
+
68
+
69
+ def test_skill_documents_gate_exit_contract() -> None:
70
+ skill_text = _read_skill_text()
71
+
72
+ assert "--reviewer codex" in skill_text
73
+ assert "Exit 0" in skill_text
74
+ assert "Exit 1" in skill_text
75
+ assert "Any other exit" in skill_text
76
+ assert "blocker" in skill_text
77
+ assert "CLAUDE_REVIEWS_DISABLED=codex" in skill_text
78
+ assert "not among them" not in skill_text
79
+ assert "codex is not among" not in skill_text
80
+
81
+
82
+ def test_skill_documents_flow_skeleton() -> None:
83
+ skill_text = _read_skill_text()
84
+ skill_text_lower = skill_text.lower()
85
+
86
+ assert "shape probe" in skill_text_lower
87
+ assert "classif" in skill_text_lower
88
+ assert "`down`" in skill_text
89
+ assert "`clean`" in skill_text
90
+ assert "`findings`" in skill_text
91
+ assert "`codex_down`" in skill_text
92
+ assert "base branch" in skill_text_lower
93
+ assert "uncommitted" in skill_text_lower
94
+ assert "untracked" in skill_text_lower
95
+
96
+
97
+ def test_skill_classifying_path_is_exec_with_json() -> None:
98
+ skill_text = _read_skill_text()
99
+ cli_contract_text = (REFERENCE_DIRECTORY / "cli-contract.md").read_text(
100
+ encoding="utf-8"
101
+ )
102
+
103
+ assert "codex exec" in skill_text
104
+ assert "--json" in skill_text
105
+ assert (
106
+ "codex exec … review --json" in skill_text
107
+ or "codex exec [options] review --json" in skill_text
108
+ )
109
+ assert "non-classifying" in skill_text.lower() or "Non-classifying" in skill_text
110
+ assert "codex exec" in cli_contract_text
111
+ assert "--json" in cli_contract_text
112
+ assert "non-classifying" in cli_contract_text.lower()
113
+
114
+
115
+ def test_cli_contract_probe_lists_minimum_shape_signals() -> None:
116
+ cli_contract_text = (REFERENCE_DIRECTORY / "cli-contract.md").read_text(
117
+ encoding="utf-8"
118
+ )
119
+
120
+ assert "codex exec review --help" in cli_contract_text
121
+ assert "Minimum shape signals" in cli_contract_text
122
+ assert "Fail-closed rule" in cli_contract_text
123
+ assert "--uncommitted" in cli_contract_text
124
+ assert "--base" in cli_contract_text
125
+ assert "--commit" in cli_contract_text
126
+ assert "--json" in cli_contract_text
127
+ assert "`review`" in cli_contract_text
128
+
129
+
130
+ def test_scripts_surface_names_capture_wrapper_and_constants() -> None:
131
+ skill_text = _read_skill_text()
132
+ package_map_text = PACKAGE_MAP_PATH.read_text(encoding="utf-8")
133
+ constants_map_text = (
134
+ SKILL_DIRECTORY / "scripts" / "codex_review_scripts_constants" / "CLAUDE.md"
135
+ ).read_text(encoding="utf-8")
136
+ wrapper_path = SKILL_DIRECTORY / "scripts" / "run_codex_review.py"
137
+
138
+ assert wrapper_path.is_file()
139
+ assert "run_codex_review.py" in skill_text
140
+ assert "run_codex_review.py" in package_map_text
141
+ assert "capture only" in skill_text.lower() or "capture-only" in skill_text.lower()
142
+ assert "completed" in skill_text
143
+ assert "codex_down" in skill_text
144
+ assert "non-classifying" in skill_text.lower()
145
+ assert "run_constants.py" in constants_map_text
146
+ assert "run_codex_review.py" in constants_map_text
147
+
148
+
149
+ def test_uncommitted_includes_untracked() -> None:
150
+ skill_text = _read_skill_text()
151
+ cli_contract_text = (REFERENCE_DIRECTORY / "cli-contract.md").read_text(
152
+ encoding="utf-8"
153
+ )
154
+ loop_integration_text = (REFERENCE_DIRECTORY / "loop-integration.md").read_text(
155
+ encoding="utf-8"
156
+ )
157
+
158
+ assert "untracked" in skill_text.lower()
159
+ assert "staged + unstaged + untracked" in cli_contract_text.lower()
160
+ assert "untracked" in loop_integration_text.lower()
161
+ assert "--uncommitted" in skill_text
162
+ assert "--uncommitted" in loop_integration_text
163
+
164
+
165
+ def test_skill_body_stays_under_line_cap() -> None:
166
+ skill_line_count = len(_read_skill_text().splitlines())
167
+
168
+ assert skill_line_count < MAXIMUM_SKILL_BODY_LINE_COUNT
169
+
170
+
171
+ def test_package_map_claude_md_exists() -> None:
172
+ package_map_text = PACKAGE_MAP_PATH.read_text(encoding="utf-8")
173
+
174
+ assert "codex-review" in package_map_text
175
+ assert "SKILL.md" in package_map_text
176
+ assert "reference/" in package_map_text
177
+ assert "cli-contract.md" in package_map_text
178
+ assert "codex_down" in package_map_text
179
+ assert "review --json" in package_map_text
180
+
181
+
182
+ def test_reference_shell_pages_exist() -> None:
183
+ assert (REFERENCE_DIRECTORY / "cli-contract.md").is_file()
184
+ assert (REFERENCE_DIRECTORY / "loop-integration.md").is_file()
185
+ assert (REFERENCE_DIRECTORY / "CLAUDE.md").is_file()
186
+
187
+
188
+ def test_constants_package_directory_exists() -> None:
189
+ constants_directory = SKILL_DIRECTORY / "scripts" / "codex_review_scripts_constants"
190
+
191
+ assert (constants_directory / "__init__.py").is_file()
192
+ assert (constants_directory / "CLAUDE.md").is_file()
@@ -0,0 +1,28 @@
1
+ # grok-spawn
2
+
3
+ **Trigger:** `/grok-spawn`, "spawn grok workers", "grok worker fleet", "run this with grok workers", "headless grok batch".
4
+
5
+ Orchestrator playbook for fleets of headless grok CLI workers. Composes
6
+ `grok_worker_preflight.py` and `spawn_grok_batch.py` by name. Holds no spawn
7
+ logic of its own. The calling session verifies results and owns every commit,
8
+ push, and GitHub post.
9
+
10
+ ## Subdirectories
11
+
12
+ | Directory | Role |
13
+ |---|---|
14
+ | `reference/` | Prompt-part templates and tool-profile flag docs the hub cites on demand. |
15
+
16
+ ## Key files
17
+
18
+ | File | Role |
19
+ |---|---|
20
+ | `SKILL.md` | Entry protocol: when to use, gotchas, preflight → batch spec → launch → collect → verify. |
21
+ | `reference/worker-briefs.md` | Readonly investigation brief, build brief (edits and tests only), report contract. |
22
+ | `reference/flag-profiles.md` | Readonly vs build flag sets, shared flags, leader-socket and stagger rules, `--agent` note. |
23
+
24
+ ## Entry point
25
+
26
+ No skill-local scripts. Runtime lives in `$HOME/.claude/scripts/`
27
+ (`grok_worker_preflight.py`, `spawn_grok_batch.py`, `grok_headless_runner.py`)
28
+ after install. Constants live in `scripts/dev_env_scripts_constants/`.
@@ -0,0 +1,226 @@
1
+ ---
2
+ name: grok-spawn
3
+ description: >-
4
+ Spawn headless grok worker fleets via preflight and spawn_grok_batch.
5
+ Triggers: /grok-spawn, spawn grok workers, grok worker fleet, run this with
6
+ grok workers, headless grok batch.
7
+ ---
8
+
9
+ # Grok Spawn
10
+
11
+ Orchestrator playbook for fleets of headless grok CLI workers. This skill names
12
+ the scripts and the brief templates; it holds no spawn logic of its own.
13
+
14
+ ## Gotchas
15
+
16
+ - Workers never commit, push, or call `gh`. The calling session stages, verifies,
17
+ commits, pushes, and posts to GitHub.
18
+ - Grok has no `SendMessage` and no Claude Agent tool. Work that needs live
19
+ teammate chat or Claude-only tools stays in this session or a Claude agent.
20
+ - Each worker gets its own `--leader-socket`. Sharing one socket across processes
21
+ races and fails.
22
+ - Preflight is a soft gate: a fallthrough reason means skip the fleet and use
23
+ the next tier, not a hard crash of the whole run.
24
+ - Prompt parts are plain files. Conversation-relative phrases ("as above") mean
25
+ nothing to a headless worker — every brief stands alone.
26
+ - `spawn_grok_batch.py` re-runs preflight before launch. An early preflight call
27
+ still helps you abort before writing the batch spec.
28
+
29
+ ## When this skill applies
30
+
31
+ Use when the user asks for a **grok worker fleet**, a **headless grok batch**, or
32
+ types `/grok-spawn`.
33
+
34
+ Good fits:
35
+
36
+ - Fan-out read-only research across several paths or files
37
+ - Parallel bite-sized build work where each worker owns a closed scope
38
+
39
+ **Do not use** when the work needs:
40
+
41
+ - Live `SendMessage` coordination between agents
42
+ - Claude-only tools (Agent tool, warm session-advisor, Claude MCP surfaces the
43
+ grok CLI does not load the same way)
44
+
45
+ For a single interactive Grok Build handoff paste, use `/grokify` instead.
46
+
47
+ **Refusal:** no concrete worker tasks — reply `What should the grok workers do?
48
+ List each role in one line.` and stop.
49
+
50
+ ## Process
51
+
52
+ Copy this checklist and check items off as you go.
53
+
54
+ ```
55
+ [ ] 1. Preflight (#96 soft gate)
56
+ [ ] 2. Write prompt-part files (briefs + report contract)
57
+ [ ] 3. Write the batch JSON spec
58
+ [ ] 4. Run spawn_grok_batch.py
59
+ [ ] 5. Read the batch summary and per-worker reports
60
+ [ ] 6. Verify, then own every git and gh step yourself
61
+ ```
62
+
63
+ ### 1. Preflight
64
+
65
+ Scripts ship under `$HOME/.claude/scripts/` after install (or the package
66
+ `scripts/` tree in this repo).
67
+
68
+ ```bash
69
+ python "$HOME/.claude/scripts/grok_worker_preflight.py" \
70
+ --role bugteam \
71
+ --run-temp-dir "<run-state-dir>"
72
+ ```
73
+
74
+ Optional live ping (cached under the run state dir):
75
+
76
+ ```bash
77
+ python "$HOME/.claude/scripts/grok_worker_preflight.py" \
78
+ --role bugteam \
79
+ --ping \
80
+ --run-temp-dir "<run-state-dir>"
81
+ ```
82
+
83
+ Stdout is one line:
84
+
85
+ - `grok_preflight: ok` — continue
86
+ - `grok_preflight: fallthrough reason=<reason>` — report the reason, skip the
87
+ fleet, fall to the next tier
88
+
89
+ Pick a fresh run state directory for the fleet (sockets, prompts, reports, ping
90
+ cache). Reuse that same path for preflight and the batch launcher.
91
+
92
+ ### 2. Write prompt-part files
93
+
94
+ For each worker, write one or more part files on disk. Assemble from:
95
+
96
+ | Part | Source |
97
+ |---|---|
98
+ | Role brief | [`reference/worker-briefs.md`](reference/worker-briefs.md) — readonly or build template |
99
+ | Report contract | Same file — every worker ends with the report sections |
100
+ | Task body | Task-specific scope, paths, acceptance lines (you author this) |
101
+
102
+ Order matters: the batch launcher joins part bodies in list order after the
103
+ tool-profile header. Put the brief first, task body next, report contract last.
104
+
105
+ Flag sets and profile meaning:
106
+ [`reference/flag-profiles.md`](reference/flag-profiles.md).
107
+
108
+ ### 3. Write the batch JSON spec
109
+
110
+ Shape:
111
+
112
+ ```json
113
+ {
114
+ "role": "bugteam",
115
+ "should_ping": false,
116
+ "workers": [
117
+ {
118
+ "role_name": "investigate-hooks",
119
+ "prompt_parts": [
120
+ "/abs/path/to/readonly-brief.md",
121
+ "/abs/path/to/task-body.md",
122
+ "/abs/path/to/report-contract.md"
123
+ ],
124
+ "cwd": "/abs/path/to/worktree",
125
+ "tool_profile": "readonly",
126
+ "timeout_seconds": 600,
127
+ "is_repo_only": true,
128
+ "max_turns": 8,
129
+ "agent_name": null
130
+ }
131
+ ]
132
+ }
133
+ ```
134
+
135
+ | Field | Meaning |
136
+ |---|---|
137
+ | `role` | Preflight role whose agent files must be installed (default `bugteam`) |
138
+ | `should_ping` | When true, preflight runs the opt-in live ping |
139
+ | `workers` | Non-empty list of worker objects |
140
+ | `role_name` | Label on the summary report for this worker |
141
+ | `prompt_parts` | Ordered absolute paths to part files |
142
+ | `cwd` | Working directory for that worker |
143
+ | `tool_profile` | `readonly` or `build` |
144
+ | `timeout_seconds` | Per-worker timeout (default 600) |
145
+ | `is_repo_only` | Readonly only: when true, also pass `--disable-web-search` |
146
+ | `max_turns` | Turn cap (default 8) |
147
+ | `agent_name` | Optional `--agent` name, or `null` |
148
+
149
+ Put the spec file under the run state directory (or any path you pass to
150
+ `--spec`).
151
+
152
+ ### 4. Launch the batch
153
+
154
+ ```bash
155
+ python "$HOME/.claude/scripts/spawn_grok_batch.py" \
156
+ --spec "<batch-spec.json>" \
157
+ --run-temp-dir "<run-state-dir>"
158
+ ```
159
+
160
+ The launcher:
161
+
162
+ 1. Runs preflight once for the whole batch
163
+ 2. Staggers worker starts (15s between index 0, 1, 2, …)
164
+ 3. Mints per-worker prompt, report, leader-socket, and debug paths
165
+ 4. Prints one JSON summary on stdout
166
+
167
+ Exit code `0` only when preflight is usable and every worker is ok.
168
+
169
+ ### 5. Collect reports
170
+
171
+ Read the stdout JSON:
172
+
173
+ | Key | Meaning |
174
+ |---|---|
175
+ | `is_preflight_usable` | Soft gate result |
176
+ | `preflight_reason` | Fallthrough reason, or null |
177
+ | `workers` | Per-worker reports |
178
+
179
+ Each worker entry carries `role_name`, `tool_profile`, `returncode`,
180
+ `classification`, `is_ok`, `report_text`, `output_file`, `leader_socket`,
181
+ `prompt_file`, `debug_file`.
182
+
183
+ Open each `output_file` (or use `report_text`) and check the report contract
184
+ sections. Failed workers (`is_ok` false) keep their classification
185
+ (`usage_limit`, `auth_failure`, `timeout`, `error`) for routing; read their
186
+ `debug_file` for the grok-side log of the run.
187
+
188
+ A negative `returncode` means no grok process produced it: `-1` timeout, `-2`
189
+ launch failure, `-3` the launcher itself raised before the process started (a
190
+ missing prompt-part file, for example).
191
+
192
+ ### 6. Verify and own git / gh
193
+
194
+ The calling session:
195
+
196
+ 1. Diffs the worktrees the build workers touched
197
+ 2. Re-runs the named tests
198
+ 3. Maps each acceptance line to evidence
199
+ 4. Stages, commits, pushes, and posts GitHub updates as needed
200
+
201
+ Build workers stop at stage-ready edits and a written report. They do not run
202
+ `git commit`, `git push`, or `gh`.
203
+
204
+ ## Composition
205
+
206
+ | Script | Role |
207
+ |---|---|
208
+ | `grok_worker_preflight.py` | Soft gate (#96): binary, auth, install, optional ping |
209
+ | `spawn_grok_batch.py` | Batch launch, stagger, report collect |
210
+ | `grok_headless_runner.py` | One-worker runner (called by the batch launcher) |
211
+
212
+ Sibling skill: `/grokify` for a single paste-ready interactive Grok Build handoff.
213
+
214
+ ## File index
215
+
216
+ | File | Purpose |
217
+ |---|---|
218
+ | `SKILL.md` | Trigger, gotchas, process, batch shape, composition |
219
+ | `CLAUDE.md` | Package map for this skill folder |
220
+ | `reference/worker-briefs.md` | Readonly brief, build brief, report contract templates |
221
+ | `reference/flag-profiles.md` | Readonly vs build flags, shared flags, socket and stagger rules |
222
+
223
+ ## Folder map
224
+
225
+ - `SKILL.md` — hub and process.
226
+ - `reference/` — brief templates and flag profiles.
@@ -0,0 +1,132 @@
1
+ # Flag profiles
2
+
3
+ Exact flag sets used by `spawn_grok_batch.py` and `grok_headless_runner.py`.
4
+ Constants live in `scripts/dev_env_scripts_constants/grok_worker_constants.py`
5
+ and `scripts/dev_env_scripts_constants/timing.py`.
6
+
7
+ You choose a profile per worker via `tool_profile` on the batch spec. The
8
+ launcher builds the argv; do not hand-roll a parallel flag set unless you are
9
+ debugging outside the batch launcher.
10
+
11
+ ---
12
+
13
+ ## Shared base flags (every worker)
14
+
15
+ The headless runner always passes:
16
+
17
+ | Flag | Value / source |
18
+ |---|---|
19
+ | `--prompt-file` | Assembled per-worker prompt path under the run state dir |
20
+ | `--cwd` | Worker `cwd` from the batch spec |
21
+ | `--output-format` | `json` |
22
+ | `--always-approve` | present (auto-approve tool runs) |
23
+ | `--max-turns` | Worker `max_turns` (default `8`) |
24
+ | `--leader-socket` | Unique per-worker socket path under the run state dir |
25
+ | `--debug-file` | Unique per-worker debug log (batch launcher adds this) |
26
+
27
+ Optional:
28
+
29
+ | Flag | When |
30
+ |---|---|
31
+ | `--agent <name>` | Worker `agent_name` is a non-null string |
32
+ | `--model <id>` | Only when `GROK_MODEL_PIN` in constants is non-empty |
33
+
34
+ The runner does not pass `--permission-mode` or `--reasoning-effort`. If you
35
+ invoke `grok` by hand outside the launcher, those CLI flags stay available on
36
+ the binary; the batch path does not set them.
37
+
38
+ ---
39
+
40
+ ## Profile: `readonly`
41
+
42
+ Batch field: `"tool_profile": "readonly"`.
43
+
44
+ Extra flags the batch launcher appends:
45
+
46
+ ```
47
+ --disallowed-tools Write,Edit,Bash
48
+ ```
49
+
50
+ When `"is_repo_only": true`, also:
51
+
52
+ ```
53
+ --disable-web-search
54
+ ```
55
+
56
+ Prompt header prepended by the launcher:
57
+
58
+ ```
59
+ Tool profile: readonly. Do not write, edit, or run shell commands.
60
+ ```
61
+
62
+ Use for investigation, file:line mapping, and plan input. Pair with the
63
+ read-only brief in `worker-briefs.md`.
64
+
65
+ ---
66
+
67
+ ## Profile: `build`
68
+
69
+ Batch field: `"tool_profile": "build"`.
70
+
71
+ Extra tool-restriction flags: none (full tool surface).
72
+
73
+ Prompt header prepended by the launcher:
74
+
75
+ ```
76
+ Tool profile: build. Never commit, push, or call gh.
77
+ ```
78
+
79
+ Use for edits and tests inside a closed file allow list. Pair with the build
80
+ brief in `worker-briefs.md`. The lead session owns git and `gh`.
81
+
82
+ ---
83
+
84
+ ## Leader socket rule
85
+
86
+ Every process — preflight probes, live ping, and each worker — gets its own
87
+ `--leader-socket` path under the run state directory.
88
+
89
+ - Batch workers: `grok-leader-<uuid>.sock` (minted per launch)
90
+ - Preflight auth probe: `grok-preflight-auth.sock`
91
+ - Preflight ping: `grok-preflight-ping.sock`
92
+
93
+ Never point two live processes at the same socket path.
94
+
95
+ ---
96
+
97
+ ## Stagger
98
+
99
+ `WORKER_STAGGER_SECONDS` is `15`. Worker index `i` sleeps `i * 15` seconds
100
+ before start (index 0 starts at once, index 1 after 15s, index 2 after 30s).
101
+ The batch launcher applies this; you do not sleep in the skill.
102
+
103
+ ---
104
+
105
+ ## `--agent` and user-level Claude config
106
+
107
+ When `agent_name` is set, the runner passes `--agent <name>`. Grok loads the
108
+ named agent charter from the **user-level** Claude config home (`~/.claude/`):
109
+
110
+ - `agents/` — agent definition files (for example `code-quality-agent.md`,
111
+ `clean-coder.md`)
112
+ - `skills/`, `rules/`, `hooks/` — the rest of the installed Claude config the
113
+ grok CLI reads for that run
114
+
115
+ Preflight role `bugteam` checks that `code-quality-agent.md` and
116
+ `clean-coder.md` exist under `~/.claude/agents/` and that the
117
+ `claude-dev-env` install manifest is present. Install or reinstall
118
+ `claude-dev-env` before a fleet that relies on those agents.
119
+
120
+ Pass `agent_name: null` (or omit the field) when the worker should run without
121
+ a named agent charter.
122
+
123
+ ---
124
+
125
+ ## Profile choice cheat sheet
126
+
127
+ | Work | `tool_profile` | `is_repo_only` | `agent_name` |
128
+ |---|---|---|---|
129
+ | Map call sites in-repo only | `readonly` | `true` | `null` or an audit agent |
130
+ | Research that may need the web | `readonly` | `false` | `null` |
131
+ | Closed edit + tests | `build` | ignored | often `clean-coder` |
132
+ | Audit-style read under a charter | `readonly` | as needed | `code-quality-agent` |