claude-dev-env 1.93.0 → 1.94.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (220) hide show
  1. package/_shared/pr-loop/CLAUDE.md +1 -0
  2. package/_shared/pr-loop/audit-contract.md +1 -1
  3. package/_shared/pr-loop/gh-payloads.md +3 -3
  4. package/_shared/pr-loop/post-audit-thread-contract.md +51 -0
  5. package/_shared/pr-loop/scripts/README.md +2 -2
  6. package/_shared/pr-loop/scripts/code_rules_gate.py +127 -13
  7. package/_shared/pr-loop/scripts/fix_hookspath.py +47 -12
  8. package/_shared/pr-loop/scripts/pr_loop_shared_constants/code_rules_gate_constants.py +4 -0
  9. package/_shared/pr-loop/scripts/tests/test_code_rules_gate.py +146 -69
  10. package/_shared/pr-loop/scripts/tests/test_fix_hookspath.py +497 -374
  11. package/_shared/pr-loop/state-schema.md +3 -22
  12. package/bin/CLAUDE.md +1 -1
  13. package/bin/install.mjs +2 -7
  14. package/bin/install.test.mjs +10 -4
  15. package/hooks/blocking/CLAUDE.md +2 -0
  16. package/hooks/blocking/pii_commit_command.py +398 -0
  17. package/hooks/blocking/pii_payload_scan.py +133 -0
  18. package/hooks/blocking/pii_prevention_blocker.py +151 -449
  19. package/hooks/blocking/pii_scanner.py +26 -1
  20. package/hooks/blocking/test_code_rules_enforcer_dead_config_field.py +2 -2
  21. package/hooks/blocking/test_pii_prevention_blocker.py +299 -0
  22. package/hooks/blocking/test_pii_scanner.py +27 -2
  23. package/hooks/blocking/test_verdict_directory_write_blocker.py +42 -7
  24. package/hooks/hooks_constants/CLAUDE.md +2 -2
  25. package/hooks/hooks_constants/code_rules_path_utils_constants.py +0 -2
  26. package/hooks/hooks_constants/local_identity.py +65 -15
  27. package/hooks/hooks_constants/pii_prevention_constants.py +20 -8
  28. package/hooks/hooks_constants/pr_description_enforcer_constants.py +1 -1
  29. package/hooks/hooks_constants/test_local_identity.py +68 -0
  30. package/package.json +1 -1
  31. package/scripts/CLAUDE.md +10 -1
  32. package/scripts/Get-SessionAccount.ps1 +210 -0
  33. package/scripts/tests/CLAUDE.md +15 -1
  34. package/scripts/tests/Get-SessionAccount.Tests.ps1 +350 -0
  35. package/skills/CLAUDE.md +3 -25
  36. package/skills/anthropic-plan/SKILL.md +1 -13
  37. package/skills/autoconverge/CLAUDE.md +5 -2
  38. package/skills/autoconverge/SKILL.md +112 -387
  39. package/skills/autoconverge/reference/CLAUDE.md +4 -1
  40. package/skills/autoconverge/reference/closing-report.md +9 -2
  41. package/skills/autoconverge/reference/convergence.md +26 -22
  42. package/skills/autoconverge/reference/headless-safety.md +44 -0
  43. package/skills/autoconverge/reference/multi-pr.md +88 -0
  44. package/skills/autoconverge/reference/self-closing-loop.md +84 -0
  45. package/skills/autoconverge/reference/stop-conditions.md +21 -13
  46. package/skills/autoconverge/workflow/converge.clean-audit.test.mjs +87 -27
  47. package/skills/autoconverge/workflow/converge.contract.test.mjs +40 -10
  48. package/skills/autoconverge/workflow/converge.copilot-gate.test.mjs +179 -47
  49. package/skills/autoconverge/workflow/converge.fix-progress.test.mjs +1 -1
  50. package/skills/autoconverge/workflow/converge.mjs +284 -94
  51. package/skills/bugteam/CLAUDE.md +1 -1
  52. package/skills/bugteam/CONSTRAINTS.md +3 -3
  53. package/skills/bugteam/PROMPTS.md +8 -19
  54. package/skills/bugteam/SKILL.md +13 -14
  55. package/skills/bugteam/reference/CLAUDE.md +1 -1
  56. package/skills/bugteam/reference/audit-and-teammates.md +2 -2
  57. package/skills/bugteam/reference/copilot-gap-analysis.md +2 -0
  58. package/skills/bugteam/reference/github-pr-reviews.md +56 -38
  59. package/skills/bugteam/reference/team-setup.md +11 -11
  60. package/skills/bugteam/scripts/CLAUDE.md +6 -6
  61. package/skills/bugteam/scripts/README.md +20 -8
  62. package/skills/bugteam/scripts/bugteam_code_rules_gate.py +13 -1463
  63. package/skills/bugteam/scripts/bugteam_fix_hookspath.py +23 -358
  64. package/skills/bugteam/scripts/bugteam_preflight.py +13 -315
  65. package/skills/bugteam/scripts/bugteam_scripts_constants/CLAUDE.md +2 -3
  66. package/skills/bugteam/scripts/test_bugteam_code_rules_gate.py +34 -1053
  67. package/skills/bugteam/scripts/test_bugteam_fix_hookspath.py +30 -347
  68. package/skills/bugteam/scripts/test_bugteam_preflight.py +30 -305
  69. package/skills/copilot-finding-triage/SKILL.md +80 -28
  70. package/skills/copilot-finding-triage/reference/tier-rubric.md +70 -11
  71. package/skills/copilot-finding-triage/templates/notification.md +8 -3
  72. package/skills/everything-search/SKILL.md +1 -2
  73. package/skills/grokify/SKILL.md +58 -0
  74. package/skills/grokify/templates/handoff-template.md +92 -0
  75. package/skills/orchestrator/SKILL.md +12 -8
  76. package/skills/orchestrator-refresh/SKILL.md +3 -3
  77. package/skills/pr-converge/SKILL.md +132 -233
  78. package/skills/pr-converge/reference/convergence-gates.md +102 -66
  79. package/skills/pr-converge/reference/examples.md +37 -25
  80. package/skills/pr-converge/reference/fix-protocol.md +7 -7
  81. package/skills/pr-converge/reference/multi-pr-orchestration.md +10 -4
  82. package/skills/pr-converge/reference/per-tick.md +64 -41
  83. package/skills/pr-converge/reference/state-schema.md +27 -2
  84. package/skills/pr-converge/scripts/CLAUDE.md +8 -0
  85. package/skills/pr-converge/scripts/README.md +4 -3
  86. package/skills/pr-converge/scripts/_pr_converge_path_setup.py +23 -0
  87. package/skills/pr-converge/scripts/check_convergence.py +189 -645
  88. package/skills/pr-converge/scripts/check_convergence_gates.py +235 -0
  89. package/skills/pr-converge/scripts/check_convergence_thread_gates.py +219 -0
  90. package/skills/pr-converge/scripts/conftest.py +8 -0
  91. package/skills/pr-converge/scripts/pr_converge_scripts_constants/CLAUDE.md +1 -0
  92. package/skills/pr-converge/scripts/pr_converge_scripts_constants/convergence_gate_constants.py +36 -0
  93. package/skills/pr-converge/scripts/test__pr_converge_path_setup.py +26 -0
  94. package/skills/pr-converge/scripts/test_check_convergence.py +73 -228
  95. package/skills/pr-converge/scripts/test_check_convergence_contract.py +321 -0
  96. package/skills/pr-converge/scripts/test_check_convergence_gates.py +68 -0
  97. package/skills/pr-converge/scripts/test_check_convergence_thread_gates.py +75 -0
  98. package/skills/privacy-hygiene/SKILL.md +8 -7
  99. package/skills/reviewer-gates/SKILL.md +26 -8
  100. package/skills/session-log/SKILL.md +11 -12
  101. package/skills/session-tidy/SKILL.md +40 -30
  102. package/skills/skill-builder/CLAUDE.md +13 -10
  103. package/skills/skill-builder/SKILL.md +31 -31
  104. package/skills/skill-builder/references/CLAUDE.md +10 -6
  105. package/skills/skill-builder/references/delegation-map.md +13 -4
  106. package/skills/skill-builder/references/description-field.md +113 -0
  107. package/skills/skill-builder/references/self-audit-checklist.md +21 -4
  108. package/skills/skill-builder/references/skill-modularity.md +113 -0
  109. package/skills/skill-builder/references/skill-types.md +4 -0
  110. package/skills/skill-builder/templates/CLAUDE.md +4 -4
  111. package/skills/skill-builder/templates/gap-analysis.md +25 -1
  112. package/skills/skill-builder/workflows/CLAUDE.md +6 -4
  113. package/skills/skill-builder/workflows/improve-skill.md +17 -16
  114. package/skills/skill-builder/workflows/new-skill.md +34 -10
  115. package/skills/skill-builder/workflows/polish-skill.md +59 -43
  116. package/skills/usage-pause/SKILL.md +10 -14
  117. package/skills/bdd-protocol/CLAUDE.md +0 -26
  118. package/skills/bdd-protocol/SKILL.md +0 -30
  119. package/skills/bdd-protocol/references/CLAUDE.md +0 -10
  120. package/skills/bdd-protocol/references/anti-patterns.md +0 -26
  121. package/skills/bdd-protocol/references/example-mapping.md +0 -23
  122. package/skills/bg-agent/CLAUDE.md +0 -17
  123. package/skills/bg-agent/SKILL.md +0 -69
  124. package/skills/bugteam/scripts/bugteam_scripts_constants/bugteam_code_rules_gate_constants.py +0 -55
  125. package/skills/bugteam/scripts/bugteam_scripts_constants/bugteam_fix_hookspath_constants.py +0 -26
  126. package/skills/bugteam/scripts/bugteam_scripts_constants/bugteam_preflight_constants.py +0 -35
  127. package/skills/caveman/CLAUDE.md +0 -15
  128. package/skills/caveman/SKILL.md +0 -38
  129. package/skills/code/CLAUDE.md +0 -17
  130. package/skills/code/SKILL.md +0 -178
  131. package/skills/deep-research/CLAUDE.md +0 -17
  132. package/skills/deep-research/SKILL.md +0 -80
  133. package/skills/findbugs/CLAUDE.md +0 -20
  134. package/skills/findbugs/SKILL.md +0 -241
  135. package/skills/fixbugs/CLAUDE.md +0 -19
  136. package/skills/fixbugs/SKILL.md +0 -142
  137. package/skills/gh-paginate/CLAUDE.md +0 -18
  138. package/skills/gh-paginate/SKILL.md +0 -84
  139. package/skills/gotcha/CLAUDE.md +0 -33
  140. package/skills/gotcha/SKILL.md +0 -73
  141. package/skills/implement/CLAUDE.md +0 -27
  142. package/skills/implement/SKILL.md +0 -66
  143. package/skills/implement/scripts/CLAUDE.md +0 -22
  144. package/skills/implement/scripts/append_note.py +0 -133
  145. package/skills/implement/scripts/implement_scripts_constants/CLAUDE.md +0 -22
  146. package/skills/implement/scripts/implement_scripts_constants/__init__.py +0 -0
  147. package/skills/implement/scripts/implement_scripts_constants/notes_constants.py +0 -12
  148. package/skills/implement/scripts/test_append_note.py +0 -191
  149. package/skills/log-audit/CLAUDE.md +0 -20
  150. package/skills/log-audit/SKILL.md +0 -66
  151. package/skills/log-audit/reference/CLAUDE.md +0 -9
  152. package/skills/log-audit/reference/charter.md +0 -52
  153. package/skills/log-audit/scripts/CLAUDE.md +0 -27
  154. package/skills/log-audit/scripts/cluster_recurrences.py +0 -261
  155. package/skills/log-audit/scripts/collect_log_window.py +0 -199
  156. package/skills/log-audit/scripts/log_audit_constants/CLAUDE.md +0 -12
  157. package/skills/log-audit/scripts/log_audit_constants/__init__.py +0 -0
  158. package/skills/log-audit/scripts/log_audit_constants/cluster_recurrences_constants.py +0 -23
  159. package/skills/log-audit/scripts/log_audit_constants/collect_log_window_constants.py +0 -24
  160. package/skills/log-audit/scripts/log_audit_constants/mine_copilot_findings_constants.py +0 -49
  161. package/skills/log-audit/scripts/mine_copilot_findings.py +0 -302
  162. package/skills/log-audit/scripts/test_cluster_recurrences.py +0 -160
  163. package/skills/log-audit/scripts/test_collect_log_window.py +0 -111
  164. package/skills/log-audit/scripts/test_mine_copilot_findings.py +0 -126
  165. package/skills/logifix/CLAUDE.md +0 -36
  166. package/skills/logifix/SKILL.md +0 -69
  167. package/skills/logifix/scripts/CLAUDE.md +0 -16
  168. package/skills/logifix/scripts/logifix.ps1 +0 -205
  169. package/skills/monitor-open-prs/CLAUDE.md +0 -34
  170. package/skills/monitor-open-prs/SKILL.md +0 -88
  171. package/skills/monitor-open-prs/scripts/CLAUDE.md +0 -17
  172. package/skills/monitor-open-prs/scripts/discover_open_prs.py +0 -69
  173. package/skills/monitor-open-prs/scripts/test_discover_open_prs.py +0 -149
  174. package/skills/monitor-open-prs/test_skill_contract.py +0 -27
  175. package/skills/post-audit-findings/SKILL.md +0 -80
  176. package/skills/pr-consistency-audit/CLAUDE.md +0 -34
  177. package/skills/pr-consistency-audit/SKILL.md +0 -116
  178. package/skills/pr-consistency-audit/reference/CLAUDE.md +0 -16
  179. package/skills/pr-consistency-audit/reference/detection-rules.md +0 -96
  180. package/skills/pr-consistency-audit/reference/illustrations.md +0 -78
  181. package/skills/pr-fix-protocol/SKILL.md +0 -65
  182. package/skills/pr-review-responder/CLAUDE.md +0 -35
  183. package/skills/pr-review-responder/EXAMPLES.md +0 -590
  184. package/skills/pr-review-responder/PRINCIPLES.md +0 -533
  185. package/skills/pr-review-responder/README.md +0 -168
  186. package/skills/pr-review-responder/SKILL.md +0 -203
  187. package/skills/pr-review-responder/TESTING.md +0 -350
  188. package/skills/pr-scope-resolve/SKILL.md +0 -45
  189. package/skills/pre-compact/CLAUDE.md +0 -24
  190. package/skills/pre-compact/SKILL.md +0 -134
  191. package/skills/qbug/CLAUDE.md +0 -40
  192. package/skills/qbug/SKILL.md +0 -387
  193. package/skills/qbug/test_qbug_skill_audit_schema.py +0 -152
  194. package/skills/qbug/test_qbug_skill_post_fix_audit.py +0 -103
  195. package/skills/refine/CLAUDE.md +0 -44
  196. package/skills/refine/SKILL.md +0 -262
  197. package/skills/refine/templates/CLAUDE.md +0 -17
  198. package/skills/refine/templates/implementation-notes-template.html +0 -56
  199. package/skills/refine/templates/plan-template.md +0 -60
  200. package/skills/research-mode/CLAUDE.md +0 -35
  201. package/skills/research-mode/SKILL.md +0 -53
  202. package/skills/structure-prompt/CLAUDE.md +0 -42
  203. package/skills/structure-prompt/SKILL.md +0 -44
  204. package/skills/structure-prompt/reference/CLAUDE.md +0 -28
  205. package/skills/structure-prompt/reference/adversarial-tuning.md +0 -62
  206. package/skills/structure-prompt/reference/block-classification.md +0 -27
  207. package/skills/structure-prompt/reference/canonical-case.md +0 -48
  208. package/skills/structure-prompt/reference/citation-depth.md +0 -70
  209. package/skills/structure-prompt/reference/cleanup.md +0 -33
  210. package/skills/structure-prompt/reference/constraints.md +0 -33
  211. package/skills/structure-prompt/reference/directives.md +0 -37
  212. package/skills/structure-prompt/reference/examples.md +0 -72
  213. package/skills/structure-prompt/reference/instantiation.md +0 -51
  214. package/skills/structure-prompt/reference/output-contract.md +0 -72
  215. package/skills/structure-prompt/reference/per-category.md +0 -23
  216. package/skills/structure-prompt/reference/persona.md +0 -38
  217. package/skills/structure-prompt/reference/research.md +0 -33
  218. package/skills/structure-prompt/reference/structure.md +0 -28
  219. package/skills/verified-build/CLAUDE.md +0 -33
  220. package/skills/verified-build/SKILL.md +0 -33
@@ -1,149 +0,0 @@
1
- """Tests for discover_open_prs.py — merges gh-search output across owners."""
2
-
3
- from __future__ import annotations
4
-
5
- import importlib.util
6
- import json
7
- import pathlib
8
- import sys
9
-
10
- import pytest
11
-
12
-
13
- def _load_discovery_module():
14
- scripts_directory = pathlib.Path(__file__).parent
15
- sys.path.insert(0, str(scripts_directory))
16
- module_path = scripts_directory / "discover_open_prs.py"
17
- module_spec = importlib.util.spec_from_file_location(
18
- "discover_open_prs", module_path
19
- )
20
- loaded_module = importlib.util.module_from_spec(module_spec)
21
- sys.modules["discover_open_prs"] = loaded_module
22
- module_spec.loader.exec_module(loaded_module)
23
- return loaded_module
24
-
25
-
26
- discover_open_prs = _load_discovery_module()
27
-
28
-
29
- def _make_fake_gh(responses_by_owner: dict):
30
- """Return a callable whose behavior mocks subprocess.run for gh search."""
31
-
32
- class FakeCompletedProcess:
33
- def __init__(self, stdout_text: str):
34
- self.stdout = stdout_text
35
- self.returncode = 0
36
-
37
- def fake_run(command_argv, check, capture_output, text):
38
- owner = _extract_owner_argument(command_argv)
39
- stdout_text = json.dumps(responses_by_owner.get(owner, []))
40
- return FakeCompletedProcess(stdout_text)
41
-
42
- return fake_run
43
-
44
-
45
- def _extract_owner_argument(command_argv) -> str:
46
- for each_index, each_token in enumerate(command_argv):
47
- if each_token == "--owner":
48
- return command_argv[each_index + 1]
49
- return ""
50
-
51
-
52
- class TestDiscoverOpenPrsBothOwnersReturnResults:
53
- def test_merges_prs_across_both_owners(self, monkeypatch):
54
- first_owner_prs = [
55
- {
56
- "number": 1,
57
- "repository": {"nameWithOwner": "jl-cmd/alpha"},
58
- "url": "https://github.com/jl-cmd/alpha/pull/1",
59
- "headRefName": "feat-one",
60
- "baseRefName": "main",
61
- }
62
- ]
63
- second_owner_prs = [
64
- {
65
- "number": 2,
66
- "repository": {"nameWithOwner": "JonEcho/beta"},
67
- "url": "https://github.com/JonEcho/beta/pull/2",
68
- "headRefName": "feat-two",
69
- "baseRefName": "main",
70
- }
71
- ]
72
- fake_run = _make_fake_gh(
73
- {"jl-cmd": first_owner_prs, "JonEcho": second_owner_prs}
74
- )
75
- monkeypatch.setattr(discover_open_prs.subprocess, "run", fake_run)
76
-
77
- all_discovered = discover_open_prs.discover_open_prs(
78
- all_owners=["jl-cmd", "JonEcho"]
79
- )
80
-
81
- assert len(all_discovered) == 2
82
- discovered_numbers = sorted(each["number"] for each in all_discovered)
83
- assert discovered_numbers == [1, 2]
84
-
85
-
86
- class TestDiscoverOpenPrsOneOwnerEmpty:
87
- def test_handles_single_owner_returning_empty_list(self, monkeypatch):
88
- first_owner_prs = [
89
- {
90
- "number": 5,
91
- "repository": {"nameWithOwner": "jl-cmd/gamma"},
92
- "url": "https://github.com/jl-cmd/gamma/pull/5",
93
- "headRefName": "feat-five",
94
- "baseRefName": "main",
95
- }
96
- ]
97
- fake_run = _make_fake_gh({"jl-cmd": first_owner_prs, "JonEcho": []})
98
- monkeypatch.setattr(discover_open_prs.subprocess, "run", fake_run)
99
-
100
- all_discovered = discover_open_prs.discover_open_prs(
101
- all_owners=["jl-cmd", "JonEcho"]
102
- )
103
-
104
- assert len(all_discovered) == 1
105
- assert all_discovered[0]["number"] == 5
106
-
107
-
108
- class TestDiscoverOpenPrsBothEmpty:
109
- def test_returns_empty_list_when_no_owner_has_open_prs(self, monkeypatch):
110
- fake_run = _make_fake_gh({"jl-cmd": [], "JonEcho": []})
111
- monkeypatch.setattr(discover_open_prs.subprocess, "run", fake_run)
112
-
113
- all_discovered = discover_open_prs.discover_open_prs(
114
- all_owners=["jl-cmd", "JonEcho"]
115
- )
116
-
117
- assert all_discovered == []
118
-
119
-
120
- class TestDiscoverOpenPrsEntryShape:
121
- def test_each_entry_exposes_number_owner_repo_refs_and_url(self, monkeypatch):
122
- fake_run = _make_fake_gh(
123
- {
124
- "jl-cmd": [
125
- {
126
- "number": 42,
127
- "repository": {"nameWithOwner": "jl-cmd/demo"},
128
- "url": "https://github.com/jl-cmd/demo/pull/42",
129
- "headRefName": "feat-demo",
130
- "baseRefName": "main",
131
- }
132
- ],
133
- "JonEcho": [],
134
- }
135
- )
136
- monkeypatch.setattr(discover_open_prs.subprocess, "run", fake_run)
137
-
138
- all_discovered = discover_open_prs.discover_open_prs(
139
- all_owners=["jl-cmd", "JonEcho"]
140
- )
141
-
142
- assert len(all_discovered) == 1
143
- only_entry = all_discovered[0]
144
- assert only_entry["number"] == 42
145
- assert only_entry["owner"] == "jl-cmd"
146
- assert only_entry["repo"] == "demo"
147
- assert only_entry["head_ref"] == "feat-demo"
148
- assert only_entry["base_ref"] == "main"
149
- assert only_entry["url"].endswith("/pull/42")
@@ -1,27 +0,0 @@
1
- """Markdown assertion tests for monitor-open-prs SKILL.md."""
2
-
3
- from __future__ import annotations
4
-
5
- import pathlib
6
-
7
-
8
- def _read_skill_text() -> str:
9
- skill_path = pathlib.Path(__file__).parent / "SKILL.md"
10
- return skill_path.read_text(encoding="utf-8")
11
-
12
-
13
- def test_skill_has_frontmatter_name():
14
- skill_text = _read_skill_text()
15
- assert skill_text.startswith("---\n")
16
- assert "name: monitor-open-prs" in skill_text
17
-
18
-
19
- def test_skill_references_bugbot_retrigger_flag():
20
- skill_text = _read_skill_text()
21
- assert "--bugbot-retrigger" in skill_text
22
-
23
-
24
- def test_skill_enumerates_both_owner_scopes():
25
- skill_text = _read_skill_text()
26
- assert "jl-cmd" in skill_text
27
- assert "JonEcho" in skill_text
@@ -1,80 +0,0 @@
1
- ---
2
- name: post-audit-findings
3
- description: >-
4
- Publishes an audit pass as a GitHub PR review through post_audit_thread.py:
5
- maps findings to the review-comment JSON shape, splits anchored from
6
- unanchored, and collects the comment and thread ids for the fix loop. Invoked
7
- by audit skills (bugteam, qbug, findbugs) after each pass; not for ad-hoc
8
- comments.
9
- ---
10
-
11
- # Post Audit Findings
12
-
13
- **Core principle:** every audit pass — CLEAN or DIRTY — lands on the PR as exactly one review, so the unresolved-thread gate sees the pass and each finding becomes its own resolvable thread.
14
-
15
- ## How callers invoke this
16
-
17
- - **Skill-capable contexts** (a lead session with the `Skill` tool): `Skill({skill: "post-audit-findings", args: "--skill <caller> --owner <O> --repo <R> --pr-number <N> --commit <head_sha> --state <CLEAN|DIRTY> --findings-json <path>"})`.
18
- - **Fallback** (a subagent or teammate without the `Skill` tool): the caller's spawn prompt says "Read `~/.claude/skills/post-audit-findings/SKILL.md` and apply it with the parameters below."
19
-
20
- `--skill <caller>` is required — the posted review names the audit skill that produced it. Capture `<head_sha>` once, at the start of the posting step, via `git rev-parse HEAD` in the worktree the diff was scoped against.
21
-
22
- ## Findings-JSON mapping
23
-
24
- The findings file's root is a list of objects shaped `{path, line, side, severity, description, fix_summary}`. Map each audit finding:
25
-
26
- - Finding `file` → `path`.
27
- - The `failure_mode` field carries both the failure narrative AND the `Fix:` / `Validation:` text (per [`agents/code-quality-agent.md`](../../agents/code-quality-agent.md), "The `failure_mode` field is the audit-to-fix handoff"). Split it at the literal `Fix:` heading: the prefix becomes `description`; the suffix starting at `Fix:` (including the trailing `Validation:` clause) becomes `fix_summary`. When a finding omits the `Fix:` heading, write the full `failure_mode` text to BOTH fields so the script's `INLINE_COMMENT_BODY_TEMPLATE` still renders coherently.
28
- - Set `side="RIGHT"` for every entry.
29
- - On CLEAN, the file holds an empty array (`[]`).
30
-
31
- ## Anchored vs unanchored partition
32
-
33
- Before serializing, partition findings into **anchored** (the line appears in the diff at `--commit`) and **unanchored** (it does not). Only anchored findings go into the JSON — the GitHub reviews API rejects the ENTIRE POST when any inline comment targets a line outside the diff, so a single unanchored entry breaks the whole review. Surface unanchored findings in the caller's user-facing report instead.
34
-
35
- Zero anchored findings → `--state CLEAN`; one or more → `--state DIRTY`.
36
-
37
- ## Posting
38
-
39
- ```bash
40
- python "$HOME/.claude/_shared/pr-loop/scripts/post_audit_thread.py" \
41
- --skill <caller> \
42
- --owner <owner> \
43
- --repo <repo> \
44
- --pr-number <N> \
45
- --commit <head_sha> \
46
- --state <CLEAN|DIRTY> \
47
- --findings-json <path>
48
- ```
49
-
50
- The script POSTs one review to `/repos/{owner}/{repo}/pulls/{N}/reviews`: `event=APPROVE` on CLEAN (GitHub stores it as `state=APPROVED`; empty `comments[]`; body documents "no findings"), `event=REQUEST_CHANGES` on DIRTY (one inline anchored comment per finding; each becomes its own resolvable thread).
51
-
52
- **Self-PR auto-toggle.** GitHub rejects both `APPROVE` and `REQUEST_CHANGES` with HTTP 422 when the authenticated identity matches the PR author. `post_audit_thread.py` detects this via `gh api user` + `gh api repos/<o>/<r>/pulls/<n>` and auto-resolves an alternate gh account's token for the reviews POST — the active `gh auth` account is not mutated; only the bearer token on the request changes, so no swap-back step exists.
53
-
54
- Configuration:
55
-
56
- - `GH_TOKEN` / `GITHUB_TOKEN` env vars take precedence over the toggle — set one to pin a reviewer identity by token.
57
- - `BUGTEAM_REVIEWER_ACCOUNT` names which authenticated alternate to prefer (for example `BUGTEAM_REVIEWER_ACCOUNT=jl-cmd`). The env var name is shared across every skill that invokes `post_audit_thread.py`. When unset, the script falls back to the first alternate account `gh auth status` reports.
58
- - The named alternate must be logged in (`gh auth login -h github.com -u <login>`) before the audit runs; on self-PR with no usable alternate the script exits 1 with a message pointing at `gh auth login`.
59
-
60
- **Exit codes:** `0` — success; the new review's `html_url` prints to stdout (surface it in the caller's report). `1` — user input error. `2` — retry exhaustion (1s / 4s / 16s backoff across four attempts): a hard blocker. On exit 2 the caller halts the loop (`error: post_audit_thread retry exhausted`) or tells the user the review post failed and the unresolved-thread gate will not see this pass — never a silent retry.
61
-
62
- ## Harvest ids for the fix loop
63
-
64
- After a DIRTY post, fetch the new review's threads once and record, per finding: the finding comment's URL, its numeric comment id (the reply anchor), and its thread node id (`PRRT_…`, the `resolve_thread` handle):
65
-
66
- ```
67
- pull_request_read(method="get_review_comments", ...) → match comments to the new review id
68
- ```
69
-
70
- Hand the id triple to the fix step — `pr-fix-protocol` consumes it for the reply-and-resolve unit. Harvesting at post time saves the fix executor a second fetch and pins the mapping before any thread state changes.
71
-
72
- ## Gotchas
73
-
74
- - **One unanchored comment voids the whole review.** The partition is not an optimization; skipping it makes every DIRTY post a coin flip.
75
- - **CLEAN still posts.** A pass that finds nothing and posts nothing is invisible to the unresolved-thread gate and to anyone auditing the loop's history.
76
- - **Exit 2 is a stop, not a retry.** The script already retried with backoff; a caller looping on top of it hammers the API to no effect.
77
-
78
- ## Folder map
79
-
80
- - `SKILL.md` — this file. The posting script and its body template constants live in `_shared/pr-loop/scripts/` (`post_audit_thread.py`, `pr_loop_shared_constants/post_audit_thread_constants.py`); the review-payload reference is `_shared/pr-loop/gh-payloads.md`.
@@ -1,34 +0,0 @@
1
- # pr-consistency-audit skill
2
-
3
- Audits a PR for cross-file inconsistencies: wrong argument names, missing required args, references to files or scripts that do not exist, stale feature remnants, docstring-vs-code mismatches, placeholder text, cross-file contradictions, parameter naming convention violations, and cross-platform bugs.
4
-
5
- **Trigger:** "audit this PR", "find inconsistencies", "cross-reference docs against scripts", "check for stale references", "PR consistency audit".
6
-
7
- ## Key files
8
-
9
- | File | Purpose |
10
- |---|---|
11
- | `SKILL.md` | Full process: build manifest, find canonical sources, run 10 detection rules, produce summary |
12
- | `reference/detection-rules.md` | All 10 detection rules with procedures |
13
- | `reference/illustrations.md` | Concrete examples of findings with why-they-matter explanations |
14
-
15
- ## Subdirectories
16
-
17
- | Directory | Role |
18
- |---|---|
19
- | `reference/` | Detection rules and worked illustrations |
20
-
21
- ## Process overview
22
-
23
- 1. **Build manifest** — read every changed file; track argparse args, MCP tool calls, shell commands, file path references, named constants, and docstring claims. Write to a temp JSON file.
24
- 2. **Find canonical sources** — note which files define the ground truth for each concept (schemas, payloads, config files, `.py` sources).
25
- 3. **Run all 10 detection rules** — write each finding at once to a temp CSV with `file_path | line_number | rule_id | severity | what_is_wrong | what_it_should_be | evidence_path | evidence_detail`.
26
- 4. **Produce summary** — print totals by rule and severity; list top findings; cite the CSV and manifest paths.
27
-
28
- ## Severity
29
-
30
- | Severity | Meaning |
31
- |---|---|
32
- | P0 | Runtime failure — the command or tool call will error |
33
- | P1 | Confusing or wrong — will mislead but not crash |
34
- | P2 | Cleanup — stale references, docs out of sync |
@@ -1,116 +0,0 @@
1
- ---
2
- name: pr-consistency-audit
3
- description: >-
4
- Audits a PR for cross-file inconsistencies: wrong arguments, missing files or
5
- scripts, stale remnants, docstring mismatches, and cross-platform bugs. Use
6
- when the user says 'audit this PR', 'find inconsistencies', 'cross-reference
7
- docs against scripts', 'check for stale references', or 'PR consistency
8
- audit'.
9
- ---
10
-
11
- # PR Consistency Audit
12
-
13
- Read every changed file in a pull request. Find every inconsistency across files. Leave nothing unchecked. Leave nothing assumed. Zero context needed beyond the diff.
14
-
15
- ## Gotchas
16
-
17
- - The highest-signal rule is canonical-source cross-reference. Do it first. Do it slowly. Copilot found 20 of its 43 findings with this rule alone. Missing it means missing half the bugs.
18
- - Parameter naming conventions are per-tool, not per-project. `issue_read` uses `issue_number` (snake_case). `add_issue_comment` uses `issueNumber` (camelCase). A doc that mixes them is wrong even if snake_case works for `issue_read`.
19
- - When a finding appears in many files with the same wrong pattern, flag every instance individually. Do not say "this is wrong in 20 files" and move on. List every file with its line.
20
- - Template files and obstacle files are often skipped because they feel "generated" or "low priority." They are not. Copilot found 6 issues in template files that human auditors never opened.
21
- - A manifest written to a temp file is not optional. Hold all script signatures, all MCP tool names, all constants, and all concept names in a JSON file. Read from it during detection. Memory fails. Files do not.
22
-
23
- ## When this skill applies
24
-
25
- Trigger when the user provides a PR diff, a list of changed files, or asks to audit cross-file consistency. The agent needs no prior knowledge of the repo, the scripts, or the project conventions.
26
-
27
- ## Process
28
-
29
- ### Step 1: Build the manifest
30
-
31
- Read every file in the diff. Top to bottom. Build `<tmp>/audit-manifest-<timestamp>.json`. Track:
32
-
33
- - Python scripts → argparse arguments (`add_argument("--name", ...)`), which are `required=True`
34
- - MCP tool call patterns in docs → tool name, every parameter used, file and line
35
- - Shell commands (`gh`, `git`, `python`, `bash`) → full command, file, line
36
- - File paths referenced in docs → whether they resolve to real files
37
- - Named concepts in prose → "inline_lag", "COPILOT_WAIT", "bugfind", phase names, state values. File and line each.
38
- - Constants, thresholds, timeouts → value, concept it measures, file, line
39
- - Functions with docstring claims → function name, claim made, file, line
40
-
41
- ### Step 2: Find canonical sources
42
-
43
- Identify the files that define the authoritative form of each concept. Signs a file is canonical:
44
-
45
- - Has structured schemas, payload definitions, API contracts (files like `gh-payloads.md`, `mcp_tool_signatures.json`, `config.py`)
46
- - Name includes "reference", "spec", "schema", "payload", "contract", "canonical"
47
- - Other files cite it as the source of truth
48
- - It defines the implementation that docstrings describe (the `.py` file, not the `.md` that talks about it)
49
-
50
- For each canonical source, note what concept it is canonical for. When a rule needs to decide what is "correct," the canonical source wins.
51
-
52
- ### Step 3: Run detection rules
53
-
54
- Read [`reference/detection-rules.md`](reference/detection-rules.md). Run all ten rules against every file. Write findings immediately to `<tmp>/inconsistency-audit-<timestamp>.csv`:
55
-
56
- ```
57
- file_path | line_number | rule_id | severity | what_is_wrong | what_it_should_be | evidence_path | evidence_detail
58
- ```
59
-
60
- ### Step 4: Produce summary
61
-
62
- Print to stdout:
63
-
64
- ```
65
- ====== DIFF INCONSISTENCY AUDIT ======
66
- Files audited: <N>
67
- Canonical sources: <list>
68
- Total findings: <N>
69
-
70
- By rule:
71
- Rule 1 — canonical_source_cross_reference: X (P0: A, P1: B, P2: C)
72
- ...
73
-
74
- By severity:
75
- P0 (runtime failure): X
76
- P1 (confusing or wrong): Y
77
- P2 (cleanup): Z
78
-
79
- Top findings:
80
- 1. file:line — [P0] — what is wrong — what it should be
81
- 2. ...
82
-
83
- Full report: <tmp>/inconsistency-audit-<timestamp>.csv
84
- Manifest: <tmp>/audit-manifest-<timestamp>.json
85
- ====== END AUDIT ======
86
- ```
87
-
88
- ## Constraints
89
-
90
- - Read every file completely. No skimming.
91
- - Write findings immediately. Do not batch in memory.
92
- - Every finding cites file:line of problem AND file:line of evidence.
93
- - When two files contradict, flag both. Do not guess which is correct.
94
- - If unresolvable, mark "unresolvable — no canonical source found."
95
- - Run every rule. The highest-signal findings come from rules you think will be empty.
96
-
97
- ## Severity
98
-
99
- | Severity | Meaning |
100
- |----------|---------|
101
- | P0 | Runtime failure — the command or tool call will error |
102
- | P1 | Confusing or wrong — will mislead but not crash |
103
- | P2 | Cleanup — stale references, docs out of sync |
104
-
105
- ## File index
106
-
107
- | File | Purpose |
108
- |------|---------|
109
- | `SKILL.md` | Hub — process, constraints, gotchas |
110
- | `reference/detection-rules.md` | All 10 detection rules with procedures |
111
- | `reference/illustrations.md` | Concrete findings with why-they-matter explanations |
112
-
113
- ## Folder map
114
-
115
- - `SKILL.md` — hub.
116
- - `reference/` — detection rules and illustrations.
@@ -1,16 +0,0 @@
1
- # pr-consistency-audit/reference
2
-
3
- Reference material for the `pr-consistency-audit` skill. These files define the detection rules the skill runs and show worked examples of findings.
4
-
5
- ## Key files
6
-
7
- | File | Purpose |
8
- |---|---|
9
- | `detection-rules.md` | All 10 detection rules, each with a procedure for how to run it |
10
- | `illustrations.md` | Concrete examples of findings with explanations of why each matters |
11
-
12
- ## Conventions
13
-
14
- - The skill reads `detection-rules.md` during Step 3 (run detection rules). Every rule must run against every file; none are skippable.
15
- - Rule 1 (canonical-source cross-reference) is the highest-signal rule. The skill runs it first.
16
- - `illustrations.md` is for reviewers and skill authors, not for the skill's runtime process.
@@ -1,96 +0,0 @@
1
- # Detection Rules
2
-
3
- All 10 rules. Run every rule against every file. Do not skip. Do not combine. Rules are independent — a file can trigger multiple rules.
4
-
5
- ## Rule 1: Canonical-source cross-reference
6
-
7
- For every canonical source, scan every other file for usages of the concepts it defines. The canonical source is the ground truth. Flag every mismatch.
8
-
9
- How: Take the canonical MCP payload doc. Extract every tool name and its parameter names. Scan every markdown file for calls to those tools. Compare each call's parameter names against the canonical form.
10
-
11
- How: Take the canonical config file. Extract every constant name and value. Scan every other file. Flag any file that hardcodes the value. Flag any file that uses a different value for the same concept.
12
-
13
- This rule caught 20 of Copilot's 43 findings. It is the highest-signal rule. Run it first.
14
-
15
- ## Rule 2: Parameter naming convention
16
-
17
- Group all MCP tool calls by tool name. Check whether all call sites use the same parameter naming convention.
18
-
19
- How: Extract every parameter name from every tool call. Group by tool. If `add_issue_comment` appears in 10 files and 8 use `issueNumber` while 2 use `issue_number`, flag the 2.
20
-
21
- Conventions are per-tool. `issue_read` uses `issue_number` (snake_case). `add_issue_comment` uses `issueNumber` (camelCase). Snake_case for `add_issue_comment` is wrong.
22
-
23
- Also: check for two different parameter names that mean the same thing. `--number` vs `--pr-number` for a script that expects `--pr-number`.
24
-
25
- ## Rule 3: Code vs docstring behavior
26
-
27
- For every function whose docstring makes a claim about return values or error handling, read the implementation.
28
-
29
- How: Find docstrings that say "returns X when Y" or "raises Z on error." Trace the code path. If the docstring says returns 0 when path missing but the code catches OSError and returns failure, flag it.
30
-
31
- How: Find docstrings that claim a side effect. Check whether the code does it unconditionally. Flag missing precondition checks.
32
-
33
- How: Find error handling claims like "tolerates already-removed worktrees." Read the except blocks. Read the conditionals. Verify every claim.
34
-
35
- ## Rule 4: Nonexistent reference
36
-
37
- Every file path, script name, function name, tool name, or import referenced in a doc must resolve to something real.
38
-
39
- How: Extract every backtick-quoted identifier. Try to resolve it against the diff and the repo. Flag anything that cannot be found. A reference to `fetch_copilot_inline_comments.py` when no such file exists is P0. A reference to `EnterWorktree(path=...)` when no MCP tool by that name exists is P0.
40
-
41
- ## Rule 5: Placeholder detection
42
-
43
- Scan for text that looks like a template never filled in. This is text that cannot be executed as written.
44
-
45
- Patterns to search for:
46
- - Double spaces where a value should be: "Spawn — brief it: check for"
47
- - Angle-bracket placeholders outside the standard `<O>` `<R>` `<N>` `<SHA>` set
48
- - Ellipsis as placeholder: "...", "…"
49
- - "TODO", "FIXME", "HACK", "XXX" in production documentation
50
- - "TKTK", "TK", "placeholder"
51
- - Missing arguments after a flag: `--flag` with no value following
52
- - Sentences that trail off: text ending in ", or", "like", "such as" without completing
53
-
54
- Severity: unexecutable placeholder is P0. Incomplete but still directionally useful is P1.
55
-
56
- ## Rule 6: Cross-file contradiction
57
-
58
- When two files describe the same operation, they must agree.
59
-
60
- How: Group descriptions by topic — "how to post a review," "how to trigger bugbot," "who owns PR posting." For each topic, extract the description from every file. Compare who performs the action, what API is used, what parameters are passed, what the workflow order is. Flag any contradiction.
61
-
62
- Flag both files. Do not assume which is correct unless a canonical source resolves it.
63
-
64
- ## Rule 7: Stale reference
65
-
66
- When a doc describes a feature, branch, phase, or pattern by name, verify the implementation still contains it.
67
-
68
- How: Extract named concepts from decision branches and gotcha sections. Search implementation files for each concept. If a doc describes an "inline_lag" branch but no implementation file contains "inline_lag" or "inline_lag_streak," the doc references a removed feature.
69
-
70
- P1: doc mentions something absent from implementation. P0: doc decision tree includes a branch whose predicate can never be reached because the implementation was removed.
71
-
72
- ## Rule 8: Cross-platform assumption
73
-
74
- Code that handles platform-specific behavior must not break on other platforms.
75
-
76
- When you see Windows-specific patterns (`os.chmod` with `stat.S_IWRITE`, backslash paths, ReadOnly attribute handling), check: Does it run on Linux without crashing? Does `os.chmod(path, stat.S_IWRITE)` produce the right permissions on POSIX? It sets write-only, stripping read and execute from directories.
77
-
78
- Flag anything that would fail on a non-Windows system. Flag the reverse: POSIX-only code that would fail on Windows.
79
-
80
- ## Rule 9: Script invocation correctness
81
-
82
- Every `python scripts/foo.py --*` in docs must match the script's actual argparse interface.
83
-
84
- From your manifest, compare each documented invocation against the script's `add_argument` definitions. Check every flag name matches exactly. Check every `required=True` argument is present. Check no argument appears that the script does not accept.
85
-
86
- Missing required args = P0. Wrong flag names = P0. Missing optional args = P2.
87
-
88
- argparse converts `--pr-number` to `pr_number`. The invocation flag is `--pr-number`, not `--pr_number` or `--number`.
89
-
90
- ## Rule 10: Value consistency
91
-
92
- When the same named concept has a numeric value in multiple files, all files must agree.
93
-
94
- How: Group constants, thresholds, and timeouts by semantic concept. "Bugbot post-trigger wakeup" vs "inline-lag retry delay" are different concepts. Values that represent the same thing must match. Flag any file whose value differs from the majority or from the canonical config.
95
-
96
- Values that legitimately differ by context are not conflicts. Group by full semantic meaning before comparing.
@@ -1,78 +0,0 @@
1
- # Illustrations
2
-
3
- Concrete examples of findings with why-they-matter explanations.
4
-
5
- ## Wrong argument name in script invocation
6
-
7
- ```
8
- file_path: SKILL.md
9
- line_number: 100
10
- rule_id: 9
11
- severity: P0
12
- what_is_wrong: check_bugbot_ci.py --check-active --sha <SHA>
13
- what_it_should_be: check_bugbot_ci.py --owner <O> --repo <R> --check-active --sha <SHA>
14
- evidence_path: scripts/check_bugbot_ci.py
15
- evidence_detail: lines 134-136 define add_argument("--owner", required=True) and add_argument("--repo", required=True). Both required args are missing from the documented invocation.
16
- ```
17
-
18
- Why this matters: If an agent copies the command from the doc, the script fails with "the following arguments are required: --owner, --repo." The agent cannot trigger bugbot.
19
-
20
- ## Parameter naming convention mismatch across tool family
21
-
22
- ```
23
- file_path: SKILL.md
24
- line_number: 162
25
- rule_id: 2
26
- severity: P0
27
- what_is_wrong: add_issue_comment(owner="OWNER", repo="REPO", issue_number=NUMBER, body="bugbot run")
28
- what_it_should_be: add_issue_comment(owner="OWNER", repo="REPO", issueNumber=NUMBER, body="bugbot run")
29
- evidence_path: _shared/pr-loop/gh-payloads.md
30
- evidence_detail: lines 67-72 document add_issue_comment with issueNumber (camelCase). issue_read uses issue_number (snake_case) — the two tools have different conventions.
31
- ```
32
-
33
- Why this matters: The tool call fails at runtime. Twenty files had this same bug because they copied from each other.
34
-
35
- ## Docstring claim contradicts implementation
36
-
37
- ```
38
- file_path: scripts/remove_tree.py
39
- line_number: 15
40
- rule_id: 3
41
- severity: P0
42
- what_is_wrong: Docstring says "returns 0 when the path never existed." Implementation calls shutil.rmtree(target_path) which raises FileNotFoundError, caught as OSError, returning EXIT_CODE_REMOVE_TREE_FAILURE.
43
- what_it_should_be: Check Path(target_path).exists() before rmtree and return 0 when absent, or update the docstring.
44
- evidence_path: scripts/remove_tree.py
45
- evidence_detail: line 15 docstring claim vs lines 22-28 implementation — the except OSError handler returns EXIT_CODE_REMOVE_TREE_FAILURE for FileNotFoundError.
46
- ```
47
-
48
- Why this matters: Teardown scripts calling remove_tree() on an already-cleaned temp directory get a failure return. The orchestrator treats this as a real error.
49
-
50
- ## Stale feature reference in gotcha section
51
-
52
- ```
53
- file_path: SKILL.md
54
- line_number: 34
55
- rule_id: 7
56
- severity: P1
57
- what_is_wrong: Gotcha describes "inline_lag" with its own streak counter and 90s wait. The decision branch for inline_lag is still present in per-tick.md lines 102-106 — the feature was supposed to be removed but both the gotcha and the branch remain.
58
- what_it_should_be: Remove the gotcha and the inline_lag decision branch from per-tick.md.
59
- evidence_path: reference/per-tick.md
60
- evidence_detail: lines 102-106 still contain the fourth BUGBOT decision branch for inline_lag.
61
- ```
62
-
63
- Why this matters: An agent reading the gotcha thinks inline_lag is real and may misclassify a dirty review as transient lag, waiting rather than fixing.
64
-
65
- ## Placeholder text in template file
66
-
67
- ```
68
- file_path: bugteam/obstacles/self-population.md
69
- line_number: 5
70
- rule_id: 5
71
- severity: P1
72
- what_is_wrong: "Spawn — brief it: check for an open PR " contains double spaces where an agent invocation, repo, and PR number should be.
73
- what_it_should_be: Fill in the concrete Agent call or remove the section until populated.
74
- evidence_path: bugteam/obstacles/self-population.md
75
- evidence_detail: Template has placeholder spacing with no variable substitutions defined.
76
- ```
77
-
78
- Why this matters: Obstacle files are reference material for agents. An obstacle with "Spawn — brief it: check for" and no target wastes context and confuses.