claude-dev-env 1.38.1 → 1.40.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/CLAUDE.md +10 -36
- package/_shared/pr-loop/audit-reply-template.md +147 -0
- package/_shared/pr-loop/fix-protocol.md +25 -4
- package/_shared/pr-loop/gh-payloads.md +37 -50
- package/_shared/pr-loop/scripts/code_rules_gate.py +0 -60
- package/_shared/pr-loop/scripts/config/post_audit_thread_constants.py +199 -0
- package/_shared/pr-loop/scripts/config/reviews_disabled_constants.py +8 -0
- package/_shared/pr-loop/scripts/post_audit_thread.py +1242 -0
- package/_shared/pr-loop/scripts/preflight.py +129 -2
- package/_shared/pr-loop/scripts/reviews_disabled.py +59 -0
- package/_shared/pr-loop/scripts/tests/test_code_rules_gate.py +0 -19
- package/_shared/pr-loop/scripts/tests/test_post_audit_thread.py +1116 -0
- package/_shared/pr-loop/scripts/tests/test_post_audit_thread_constants.py +127 -0
- package/_shared/pr-loop/scripts/tests/test_preflight.py +41 -0
- package/_shared/pr-loop/scripts/tests/test_reviews_disabled.py +36 -0
- package/_shared/pr-loop/state-schema.md +1 -1
- package/agents/clean-coder.md +2 -2
- package/agents/pr-description-writer.md +150 -52
- package/bin/install.mjs +6 -7
- package/bin/install.test.mjs +8 -0
- package/commands/doc-gist.md +16 -0
- package/commands/plan.md +0 -2
- package/commands/review-plan.md +1 -1
- package/docs/CODE_RULES.md +122 -2
- package/docs/PR_DESCRIPTION_GUIDE.md +127 -64
- package/hooks/blocking/bot_mention_comment_blocker.py +75 -0
- package/hooks/blocking/code_rules_enforcer.py +1143 -129
- package/hooks/blocking/convergence_gate_blocker.py +130 -0
- package/hooks/blocking/destructive_command_blocker.py +74 -0
- package/hooks/blocking/gh_body_arg_blocker.py +30 -0
- package/hooks/blocking/md_to_html_blocker.py +119 -0
- package/hooks/blocking/pr_description_enforcer.py +57 -22
- package/hooks/blocking/test_bot_mention_comment_blocker.py +131 -0
- package/hooks/blocking/test_code_rules_enforcer.py +21 -0
- package/hooks/blocking/test_code_rules_enforcer_any_exempt_files.py +70 -0
- package/hooks/blocking/test_code_rules_enforcer_any_imports_and_cast.py +92 -0
- package/hooks/blocking/test_code_rules_enforcer_banned_import_alias.py +143 -0
- package/hooks/blocking/test_code_rules_enforcer_banned_prefixes.py +152 -0
- package/hooks/blocking/test_code_rules_enforcer_bare_except.py +120 -0
- package/hooks/blocking/test_code_rules_enforcer_boundary_types.py +175 -0
- package/hooks/blocking/test_code_rules_enforcer_cap_meta.py +0 -1
- package/hooks/blocking/test_code_rules_enforcer_collection_prefix.py +50 -0
- package/hooks/blocking/test_code_rules_enforcer_docstring_format.py +255 -0
- package/hooks/blocking/test_code_rules_enforcer_inline_tuple_string_magic.py +130 -0
- package/hooks/blocking/test_code_rules_enforcer_stub_implementations.py +141 -0
- package/hooks/blocking/test_code_rules_enforcer_test_branching.py +143 -0
- package/hooks/blocking/test_code_rules_enforcer_thin_wrapper_files.py +169 -0
- package/hooks/blocking/test_code_rules_enforcer_todo_markers.py +99 -0
- package/hooks/blocking/test_code_rules_enforcer_typed_dict_pairs.py +141 -0
- package/hooks/blocking/test_convergence_gate_blocker.py +63 -0
- package/hooks/blocking/test_destructive_command_blocker.py +146 -0
- package/hooks/blocking/test_destructive_command_blocker_no_verify.py +102 -0
- package/hooks/blocking/test_gh_body_arg_blocker.py +45 -0
- package/hooks/blocking/test_md_to_html_blocker.py +317 -0
- package/hooks/blocking/test_pr_description_enforcer.py +69 -8
- package/hooks/config/any_type_config.py +7 -0
- package/hooks/config/banned_identifiers_constants.py +11 -0
- package/hooks/config/blocking_check_limits.py +38 -0
- package/hooks/config/bot_mention_comment_blocker_constants.py +20 -0
- package/hooks/config/code_rules_enforcer_constants.py +53 -0
- package/hooks/config/convergence_branch_constants.py +9 -0
- package/hooks/config/doc_gist_auto_publish_constants.py +18 -0
- package/hooks/config/html_companion_constants.py +20 -0
- package/hooks/config/inline_tuple_string_magic_constants.py +22 -0
- package/hooks/config/pr_description_enforcer_constants.py +14 -0
- package/hooks/config/test_banned_identifiers_constants.py +17 -0
- package/hooks/hooks.json +28 -20
- package/hooks/pyproject.toml +69 -0
- package/hooks/validators/mypy_integration.py +47 -1
- package/hooks/validators/run_all_validators.py +3 -3
- package/hooks/validators/test_mypy_integration.py +50 -1
- package/hooks/workflow/doc_gist_auto_publish.py +144 -0
- package/hooks/workflow/md_to_html_companion.py +365 -0
- package/hooks/workflow/test_doc_gist_auto_publish.py +117 -0
- package/hooks/workflow/test_md_to_html_companion.py +452 -0
- package/package.json +1 -1
- package/rules/gh-body-file.md +2 -0
- package/scripts/Install-SweepEmptyDirs.ps1 +111 -0
- package/scripts/check.ps1 +106 -0
- package/scripts/config/timing.py +11 -0
- package/scripts/sweep_empty_dirs.py +138 -0
- package/scripts/sync_to_cursor/rules.py +1 -1
- package/scripts/test_sweep_empty_dirs.py +183 -0
- package/skills/_shared/pr-loop/prompts/pr-consistency-audit.xml +323 -0
- package/skills/_shared/pr-loop/scripts/_cli_utils.py +22 -0
- package/skills/_shared/pr-loop/scripts/_path_resolver.py +165 -0
- package/skills/_shared/pr-loop/scripts/_xml_utils.py +20 -0
- package/skills/_shared/pr-loop/scripts/build_audit_prompt.py +182 -0
- package/skills/_shared/pr-loop/scripts/build_fix_prompt.py +185 -0
- package/skills/_shared/pr-loop/scripts/config/__init__.py +0 -0
- package/skills/_shared/pr-loop/scripts/config/path_resolver_constants.py +78 -0
- package/skills/_shared/pr-loop/scripts/init_loop_state.py +135 -0
- package/skills/_shared/pr-loop/scripts/teardown_worktrees.py +175 -0
- package/skills/_shared/pr-loop/scripts/write_audit_outcomes.py +182 -0
- package/skills/_shared/pr-loop/scripts/write_fix_outcomes.py +206 -0
- package/skills/bugteam/CONSTRAINTS.md +21 -22
- package/skills/bugteam/EXAMPLES.md +3 -3
- package/skills/bugteam/PROMPTS.md +227 -67
- package/skills/bugteam/SKILL.md +132 -455
- package/skills/bugteam/reference/README.md +1 -1
- package/skills/bugteam/reference/audit-and-teammates.md +112 -39
- package/skills/bugteam/reference/audit-contract.md +4 -22
- package/skills/bugteam/reference/copilot-gap-analysis.md +8 -5
- package/skills/bugteam/reference/design-rationale.md +2 -2
- package/skills/bugteam/reference/github-pr-reviews.md +50 -57
- package/skills/bugteam/reference/obstacles/audit-assign-ids.md +13 -0
- package/skills/bugteam/reference/obstacles/audit-capture-excerpts.md +13 -0
- package/skills/bugteam/reference/obstacles/audit-walk-categories.md +13 -0
- package/skills/bugteam/reference/obstacles/audit-write-xml.md +13 -0
- package/skills/bugteam/reference/obstacles/fix-append-summary.md +13 -0
- package/skills/bugteam/reference/obstacles/fix-apply-fixes.md +13 -0
- package/skills/bugteam/reference/obstacles/fix-git-add-commit.md +13 -0
- package/skills/bugteam/reference/obstacles/fix-git-push.md +13 -0
- package/skills/bugteam/reference/obstacles/fix-post-reply.md +13 -0
- package/skills/bugteam/reference/obstacles/fix-publish-summary.md +13 -0
- package/skills/bugteam/reference/obstacles/fix-py-compile.md +13 -0
- package/skills/bugteam/reference/obstacles/fix-read-files.md +13 -0
- package/skills/bugteam/reference/obstacles/fix-resolve-thread.md +13 -0
- package/skills/bugteam/reference/obstacles/fix-test-suite.md +13 -0
- package/skills/bugteam/reference/obstacles/fix-violation-count.md +13 -0
- package/skills/bugteam/reference/obstacles/fix-write-xml.md +13 -0
- package/skills/bugteam/reference/team-setup.md +111 -9
- package/skills/bugteam/reference/teardown-publish-permissions.md +39 -8
- package/skills/bugteam/scripts/README.md +60 -0
- package/skills/bugteam/scripts/_claude_permissions_common.py +358 -0
- package/skills/bugteam/scripts/bugteam_code_rules_gate.py +976 -0
- package/skills/bugteam/scripts/bugteam_fix_hookspath.py +375 -0
- package/skills/bugteam/scripts/bugteam_preflight.py +328 -0
- package/skills/bugteam/scripts/config/bugteam_code_rules_gate_constants.py +25 -0
- package/skills/bugteam/scripts/config/bugteam_fix_hookspath_constants.py +26 -0
- package/skills/bugteam/scripts/config/bugteam_preflight_constants.py +35 -0
- package/skills/bugteam/scripts/config/claude_permissions_common_constants.py +20 -0
- package/skills/bugteam/scripts/config/probe_code_rules_enforcer_check_constants.py +12 -0
- package/skills/bugteam/scripts/config/windows_safe_rmtree_constants.py +7 -0
- package/skills/bugteam/scripts/grant_project_claude_permissions.py +175 -0
- package/skills/bugteam/scripts/probe_code_rules_enforcer_check.py +107 -0
- package/skills/bugteam/scripts/revoke_project_claude_permissions.py +220 -0
- package/skills/bugteam/scripts/test__claude_permissions_common.py +112 -0
- package/skills/bugteam/scripts/test_bugteam_code_rules_gate.py +400 -0
- package/skills/bugteam/scripts/test_bugteam_fix_hookspath.py +384 -0
- package/skills/bugteam/scripts/test_bugteam_preflight.py +309 -0
- package/skills/bugteam/scripts/test_claude_permissions_common.py +195 -0
- package/skills/bugteam/scripts/test_grant_project_claude_permissions.py +55 -0
- package/skills/bugteam/scripts/test_probe_code_rules_enforcer_check.py +76 -0
- package/skills/bugteam/scripts/test_revoke_project_claude_permissions.py +55 -0
- package/skills/bugteam/scripts/test_windows_safe_rmtree.py +108 -0
- package/skills/bugteam/scripts/windows_safe_rmtree.py +100 -0
- package/skills/bugteam/test_skill_additions.py +1 -11
- package/skills/code/SKILL.md +176 -0
- package/skills/copilot-review/SKILL.md +16 -0
- package/skills/doc-gist/SKILL.md +99 -0
- package/skills/doc-gist/references/examples/01-exploration-code-approaches.html +453 -0
- package/skills/doc-gist/references/examples/02-exploration-visual-designs.html +515 -0
- package/skills/doc-gist/references/examples/03-code-review-pr.html +638 -0
- package/skills/doc-gist/references/examples/04-code-understanding.html +491 -0
- package/skills/doc-gist/references/examples/05-design-system.html +629 -0
- package/skills/doc-gist/references/examples/06-component-variants.html +605 -0
- package/skills/doc-gist/references/examples/07-prototype-animation.html +455 -0
- package/skills/doc-gist/references/examples/08-prototype-interaction.html +396 -0
- package/skills/doc-gist/references/examples/09-slide-deck.html +592 -0
- package/skills/doc-gist/references/examples/10-svg-illustrations.html +492 -0
- package/skills/doc-gist/references/examples/11-status-report.html +528 -0
- package/skills/doc-gist/references/examples/12-incident-report.html +596 -0
- package/skills/doc-gist/references/examples/13-flowchart-diagram.html +395 -0
- package/skills/doc-gist/references/examples/14-research-feature-explainer.html +381 -0
- package/skills/doc-gist/references/examples/15-research-concept-explainer.html +368 -0
- package/skills/doc-gist/references/examples/16-implementation-plan.html +702 -0
- package/skills/doc-gist/references/examples/17-pr-writeup.html +595 -0
- package/skills/doc-gist/references/examples/18-editor-triage-board.html +573 -0
- package/skills/doc-gist/references/examples/19-editor-feature-flags.html +663 -0
- package/skills/doc-gist/references/examples/20-editor-prompt-tuner.html +722 -0
- package/skills/doc-gist/references/examples/README.md +5 -0
- package/skills/doc-gist/scripts/config/__init__.py +0 -0
- package/skills/doc-gist/scripts/config/gist_upload_constants.py +16 -0
- package/skills/doc-gist/scripts/gist_upload.py +177 -0
- package/skills/doc-gist/scripts/test_gist_upload.py +51 -0
- package/skills/findbugs/SKILL.md +96 -2
- package/skills/monitor-open-prs/SKILL.md +14 -32
- package/skills/monitor-open-prs/test_skill_contract.py +0 -11
- package/skills/pr-consistency-audit/SKILL.md +112 -0
- package/skills/pr-consistency-audit/reference/detection-rules.md +96 -0
- package/skills/pr-consistency-audit/reference/illustrations.md +78 -0
- package/skills/pr-converge/SKILL.md +229 -23
- package/skills/pr-converge/config/__init__.py +0 -0
- package/skills/pr-converge/config/constants.py +63 -0
- package/skills/pr-converge/reference/convergence-gates.md +138 -44
- package/skills/pr-converge/reference/examples.md +43 -11
- package/skills/pr-converge/reference/fix-protocol.md +6 -5
- package/skills/pr-converge/reference/ground-rules.md +5 -3
- package/skills/pr-converge/reference/multi-pr-orchestration.md +44 -19
- package/skills/pr-converge/reference/obstacles/fix-post-replies.md +13 -0
- package/skills/pr-converge/reference/obstacles/fix-publish-summary.md +13 -0
- package/skills/pr-converge/reference/obstacles/fix-push.md +13 -0
- package/skills/pr-converge/reference/obstacles/fix-read-filelines.md +13 -0
- package/skills/pr-converge/reference/obstacles/fix-reset-state.md +13 -0
- package/skills/pr-converge/reference/obstacles/fix-resolve-threads.md +13 -0
- package/skills/pr-converge/reference/obstacles/fix-spawn-clean-coder.md +13 -0
- package/skills/pr-converge/reference/obstacles/fix-stage-commit.md +13 -0
- package/skills/pr-converge/reference/obstacles/fix-trigger-bugbot.md +13 -0
- package/skills/pr-converge/reference/obstacles/fix-write-test.md +13 -0
- package/skills/pr-converge/reference/per-tick.md +107 -31
- package/skills/pr-converge/reference/state-schema.md +22 -1
- package/skills/pr-converge/reference/stop-conditions.md +9 -7
- package/skills/pr-converge/scripts/README.md +34 -46
- package/skills/pr-converge/scripts/check_bugbot_ci.py +279 -0
- package/skills/pr-converge/scripts/check_convergence.py +497 -0
- package/skills/pr-converge/scripts/check_pending_reviews.py +154 -0
- package/skills/pr-converge/scripts/config/pr_converge_constants.py +118 -0
- package/skills/pr-converge/scripts/fetch_copilot_reviews.py +134 -0
- package/skills/pr-converge/scripts/post_fix_reply.py +168 -0
- package/skills/pr-converge/scripts/test_check_bugbot_ci.py +312 -0
- package/skills/pr-converge/workflows/schedule-wakeup-loop.md +5 -12
- package/skills/qbug/SKILL.md +157 -27
- package/skills/session-log/SKILL.md +216 -114
- package/skills/session-tidy/SKILL.md +1 -1
- package/skills/skill-builder/SKILL.md +138 -56
- package/skills/skill-builder/references/delegation-map.md +72 -113
- package/skills/skill-builder/references/progressive-disclosure.md +122 -0
- package/skills/skill-builder/references/self-audit-checklist.md +92 -0
- package/skills/skill-builder/references/skill-types.md +228 -0
- package/skills/skill-builder/references/thariq-x-post-skills.json +33 -0
- package/skills/skill-builder/templates/gap-analysis.md +15 -8
- package/skills/skill-builder/workflows/improve-skill.md +86 -57
- package/skills/skill-builder/workflows/new-skill.md +80 -168
- package/skills/skill-builder/workflows/polish-skill.md +78 -54
- package/skills/structure-prompt/SKILL.md +50 -0
- package/skills/structure-prompt/reference/adversarial-tuning.md +62 -0
- package/skills/structure-prompt/reference/block-classification.md +27 -0
- package/skills/structure-prompt/reference/canonical-case.md +48 -0
- package/skills/structure-prompt/reference/citation-depth.md +70 -0
- package/skills/structure-prompt/reference/cleanup.md +33 -0
- package/skills/structure-prompt/reference/constraints.md +33 -0
- package/skills/structure-prompt/reference/directives.md +37 -0
- package/skills/structure-prompt/reference/examples.md +72 -0
- package/skills/structure-prompt/reference/instantiation.md +51 -0
- package/skills/structure-prompt/reference/output-contract.md +72 -0
- package/skills/structure-prompt/reference/per-category.md +23 -0
- package/skills/structure-prompt/reference/persona.md +38 -0
- package/skills/structure-prompt/reference/research.md +33 -0
- package/skills/structure-prompt/reference/structure.md +28 -0
- package/agents/code-standards-agent.md +0 -93
- package/agents/groq-coder.md +0 -113
- package/agents/plan-executor.md +0 -226
- package/agents/project-docs-analyzer.md +0 -53
- package/agents/project-structure-organizer-agent.md +0 -72
- package/agents/skill-to-agent-converter.md +0 -370
- package/agents/skill-writer-agent.md +0 -470
- package/agents/user-docs-writer.md +0 -67
- package/agents/workflow-visual-documenter.md +0 -82
- package/commands/readability-review.md +0 -20
- package/hooks/mypy.ini +0 -2
- package/hooks/notification/attention_needed_notify.py +0 -71
- package/hooks/notification/claude_notification_handler.py +0 -67
- package/hooks/notification/notification_utils.py +0 -267
- package/hooks/notification/subagent_complete_notify.py +0 -381
- package/hooks/notification/test_attention_needed_notify.py +0 -47
- package/hooks/notification/test_claude_notification_handler.py +0 -54
- package/hooks/notification/test_notification_utils.py +0 -91
- package/hooks/notification/test_subagent_complete_notify.py +0 -79
- package/scripts/config/groq_bugteam_config.py +0 -230
- package/scripts/config/test_groq_bugteam_config.py +0 -83
- package/scripts/config/test_spec_implementer_prompt.py +0 -32
- package/scripts/groq_bugteam.README.md +0 -131
- package/scripts/groq_bugteam.py +0 -647
- package/scripts/groq_bugteam_dotenv.py +0 -40
- package/scripts/groq_bugteam_spec.py +0 -226
- package/scripts/test_groq_bugteam.py +0 -529
- package/scripts/test_groq_bugteam_apply_fix_from_spec.py +0 -426
- package/scripts/test_groq_bugteam_dotenv.py +0 -66
- package/scripts/test_groq_bugteam_spec.py +0 -338
- package/skills/bugteam/SKILL_EVALS.md +0 -309
- package/skills/dream/SKILL.md +0 -118
- package/skills/ingest/SKILL.md +0 -40
- package/skills/npm-creator/SKILL.md +0 -187
- package/skills/readability-review/SKILL.md +0 -127
- package/skills/resume-review/SKILL.md +0 -261
- package/skills/rule-audit/SKILL.md +0 -307
- package/skills/rule-creator/SKILL.md +0 -150
- package/skills/searching-obsidian-vault/SKILL.md +0 -131
- package/skills/skill-writer/REFERENCE.md +0 -284
- package/skills/skill-writer/SKILL.md +0 -222
- package/skills/tdd-team/SKILL.md +0 -128
|
@@ -1,28 +1,27 @@
|
|
|
1
|
-
# Bugteam
|
|
2
|
-
|
|
3
|
-
##
|
|
4
|
-
|
|
5
|
-
- **
|
|
6
|
-
- **
|
|
7
|
-
-
|
|
8
|
-
- **
|
|
9
|
-
- **
|
|
10
|
-
- **
|
|
1
|
+
# Bugteam — invariants and design rationale
|
|
2
|
+
|
|
3
|
+
## Constraints
|
|
4
|
+
|
|
5
|
+
- **Full A–K audit every loop, no exceptions.** PR size, "focused audit," "team overhead," "CODE_RULES already passed" — not valid reasons. Empty `<findings/>` for any category is a valid result. The audit agent walks all A–K rubrics each loop.
|
|
6
|
+
- **One run per invocation, multi-PR supported.** All PRs in a single /bugteam invocation share one `run_temp_dir`. Per-PR identity lives in the subagent name prefix (`bugfind-pr<N>-loop<L>` / `bugfix-pr<N>-loop<L>`) and the `<run_temp_dir>/pr-<N>/` subfolder containing that PR's git worktree, diff patches, and outcome XML files.
|
|
7
|
+
- **Grant before any spawn, revoke before any return.** Step 0 grants project `.claude/**` permissions; Step 5 revokes. Both are mandatory. Revoke runs on every exit path including error, cap-reached, and stuck.
|
|
8
|
+
- **Fresh subagent per loop.** Both bugfind and bugfix are spawned new each loop. Reusing a subagent across loops accumulates context inside that subagent's window — defeats clean-room.
|
|
9
|
+
- **One up-front confirmation = whole cycle.** The `/bugteam` invocation authorizes the entire cycle; every subsequent decision runs on that single authorization.
|
|
10
|
+
- **20-loop hard cap.** Counted as **AUDIT** completions (increment in Step 3). Standards-fix passes before an audit do not advance `loop_count`. Worst case includes extra clean-coder spawns for the code-rules gate.
|
|
11
|
+
- **Code rules gate before every AUDIT.** Run `${CLAUDE_SKILL_DIR}/scripts/bugteam_code_rules_gate.py` until exit **0** before spawning **bugfind**. Same `validate_content` logic as `hooks/blocking/code_rules_enforcer.py`.
|
|
12
|
+
- **Clean-room audits, every loop.** Each bugfind subagent's spawn prompt contains only the PR scope, audit rubric, and the current loop number. Prior loop history stays in the lead.
|
|
13
|
+
- **Targeted fixes.** Each fix subagent sees ONLY the most recent audit's findings. Prior loops are invisible to the fix subagent.
|
|
14
|
+
- **Fix subagent receives the latest audit as its input contract.** Each loop's fix run operates on the current audit's output and only that.
|
|
15
|
+
- **Lead owns the final PR description rewrite only** (Step 4.5), via the `pr-description-writer` agent.
|
|
11
16
|
|
|
12
17
|
## Why this design
|
|
13
18
|
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
Bugteam's purpose is to make real PRs better before they ship, not to just point out problems. A review that says "fix this bug" without giving the author<subagent> a chance to fix it in the same session would be a weaker intervention — the PR author still has to go back, figure out the fix, apply it, re-push, and re-trigger review. By bundling fix attempts into the same loop, bugteam reduces round-trips from N audits + N manual fix cycles to N audits + N automated fix attempts, with no human context-switching.
|
|
17
|
-
|
|
18
|
-
### Why 10 loops — why not unlimited
|
|
19
|
-
|
|
20
|
-
A PR that needs more than 10 audit-fix rounds has deeper problems than bugteam can address. The 10-loop cap is a forcing function: after 10 rounds, escalate to `/findbugs` or human review rather than grinding on diminishing returns.
|
|
21
|
-
|
|
22
|
-
### Why outcome XML — why not JSON
|
|
19
|
+
The three sibling skills compose, but `/bugteam` solves a problem they cannot solve in sequence:
|
|
23
20
|
|
|
24
|
-
|
|
21
|
+
- `/findbugs` audits once and stops.
|
|
22
|
+
- `/fixbugs` fixes the findings of one audit and stops.
|
|
23
|
+
- A human-driven `/findbugs` → `/fixbugs` → `/findbugs` → `/fixbugs` cycle works but requires the user to drive it.
|
|
25
24
|
|
|
26
|
-
|
|
25
|
+
`/bugteam` automates that cycle. The clean-room property is preserved by spawning a fresh audit agent each loop with no inherited context — every audit is independent of the prior loop's verdict. The 20-loop cap is the safety: pathological cases (audit agent oscillating, fix agent regressing) cannot run away.
|
|
27
26
|
|
|
28
|
-
|
|
27
|
+
The single up-front confirmation is the explicit trade — `/bugteam` is more autonomous than `/findbugs`+`/fixbugs` chained manually. The user accepts that autonomy by typing the command. Stop conditions and the loop log give the user full visibility on exit.
|
|
@@ -19,12 +19,12 @@ Claude: [resolves PR #42, runs loop]
|
|
|
19
19
|
|
|
20
20
|
<example>
|
|
21
21
|
User: `/bugteam`
|
|
22
|
-
Claude: [runs
|
|
22
|
+
Claude: [runs 20 loops without convergence]
|
|
23
23
|
|
|
24
|
-
`Loop
|
|
24
|
+
`Loop 20 audit: 0P0 / 1P1 / 2P2`
|
|
25
25
|
|
|
26
26
|
`/bugteam exit: cap reached`
|
|
27
|
-
`Loops:
|
|
27
|
+
`Loops: 20`
|
|
28
28
|
`Remaining: 0P0 / 1P1 / 2P2 — run /findbugs for human triage`
|
|
29
29
|
</example>
|
|
30
30
|
|
|
@@ -38,11 +38,11 @@ cd into `<worktree_path>` before any git or file operation.
|
|
|
38
38
|
verified-clean -- re-audit with a concrete trace.
|
|
39
39
|
|
|
40
40
|
Categories A–K (one-line summary; full rubric and sub-bucket decomposition
|
|
41
|
-
for each is in
|
|
41
|
+
for each is in `$HOME/.claude/audit-rubrics/category_rubrics/`;
|
|
42
42
|
ready-to-send Variant C prompts — each with a PR/repo-independent
|
|
43
43
|
generalized skeleton above a `---` separator and a worked example against
|
|
44
44
|
an authentic PR below — are in
|
|
45
|
-
|
|
45
|
+
`$HOME/.claude/audit-rubrics/prompts/`):
|
|
46
46
|
|
|
47
47
|
A. API contract verification (signatures, return types, async/await correctness)
|
|
48
48
|
B. Selector / query / engine compatibility
|
|
@@ -69,11 +69,24 @@ cd into `<worktree_path>` before any git or file operation.
|
|
|
69
69
|
</constraints>
|
|
70
70
|
|
|
71
71
|
<comment_posting>
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
72
|
+
Load all A–K rubrics from
|
|
73
|
+
`$HOME/.claude/audit-rubrics/{category_rubrics,prompts}/`. The prompt file
|
|
74
|
+
is a template for output shape, not a straitjacket — reorganize when the
|
|
75
|
+
diff demands it. The diff supplies the findings; the rubric supplies the
|
|
76
|
+
sub-bucket decomposition and decision criteria. Both must be loaded.
|
|
75
77
|
|
|
76
|
-
|
|
78
|
+
Before starting, create one task per checklist item via TaskCreate. Use
|
|
79
|
+
TaskUpdate to mark each in_progress as you begin it and completed when
|
|
80
|
+
done.
|
|
81
|
+
|
|
82
|
+
<self_audit_checklist>
|
|
83
|
+
[ ] Walk all 11 categories (A–K), each with Shape A or Shape B
|
|
84
|
+
[ ] Assign finding IDs (loop<L>-<K>)
|
|
85
|
+
[ ] Capture excerpts, validate anchors, format finding bodies
|
|
86
|
+
[ ] Build findings JSON, invoke post_audit_thread.py, capture html_url
|
|
87
|
+
[ ] Harvest child-comment ids/urls AND thread_node_ids; populate loop_comment_index
|
|
88
|
+
[ ] Write outcome XML
|
|
89
|
+
</self_audit_checklist>
|
|
77
90
|
|
|
78
91
|
1. Audit the diff against the 11 categories above. Buffer the findings
|
|
79
92
|
in memory; all posting happens at step 4 once anchors are validated.
|
|
@@ -83,58 +96,132 @@ cd into `<worktree_path>` before any git or file operation.
|
|
|
83
96
|
line. Populate the `<excerpt>` element in the outcome XML with it. Validate
|
|
84
97
|
every finding's (file, line) against the captured diff. Split findings into two
|
|
85
98
|
buckets: anchored (line is in the diff) and unanchored (line is not in the diff
|
|
86
|
-
—
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
99
|
+
— surfaced in the calling skill's user-facing output rather than as inline
|
|
100
|
+
anchored comments).
|
|
101
|
+
|
|
102
|
+
Each anchored finding contributes one entry to the JSON payload built
|
|
103
|
+
in step 4. The payload schema is
|
|
104
|
+
`{path, line, side, severity, description, fix_summary}`; the audit
|
|
105
|
+
teammate populates `description` (the failure narrative) and
|
|
106
|
+
`fix_summary` (the `Fix:` / `Validation:` text) from the
|
|
107
|
+
finding's `failure_mode` per the mapping in step 4. The audit
|
|
108
|
+
teammate does NOT author the inline-comment body directly:
|
|
109
|
+
`post_audit_thread.py` renders every body from
|
|
110
|
+
`INLINE_COMMENT_BODY_TEMPLATE` (defined in
|
|
111
|
+
[`_shared/pr-loop/scripts/config/post_audit_thread_constants.py`](../../_shared/pr-loop/scripts/config/post_audit_thread_constants.py))
|
|
112
|
+
— the template prepends `**[<severity>] <Skill> audit finding**`
|
|
113
|
+
and renders the suggested-fix block, so a teammate who hand-formats
|
|
114
|
+
a title or footer wastes the work.
|
|
115
|
+
|
|
116
|
+
4. **Before posting, read the full review once as if you were the PR
|
|
117
|
+
author.** Ask: would I understand what to fix and why? Do any two
|
|
118
|
+
findings describe the same problem in different words — merge them. Does
|
|
119
|
+
any finding miss its mark — rewrite or drop it. Does the review feel
|
|
120
|
+
coherent as a whole? The review's job is to make the PR author want to
|
|
121
|
+
fix these bugs, not to demonstrate that the rubric ran. Rearrange,
|
|
122
|
+
merge, or rephrase anything that would confuse the author. Then
|
|
123
|
+
proceed with the mechanical script invocation below.
|
|
124
|
+
|
|
125
|
+
Post ONE review per loop via `post_audit_thread.py` per
|
|
126
|
+
[SKILL.md § Audit posting](SKILL.md#audit-posting). Serialize the
|
|
127
|
+
anchored findings to a JSON file shaped as a list of
|
|
128
|
+
`{path, line, side, severity, description, fix_summary}` entries.
|
|
129
|
+
Map each finding's `file` → `path`; split each finding's
|
|
130
|
+
`failure_mode` at the literal `Fix:` heading so the failure
|
|
131
|
+
narrative becomes `description` and the suffix beginning at `Fix:`
|
|
132
|
+
(including the trailing `Validation:` clause) becomes
|
|
133
|
+
`fix_summary`. When the agent omits the `Fix:` heading on a given
|
|
134
|
+
finding, write the full `failure_mode` text to BOTH `description`
|
|
135
|
+
and `fix_summary`. Set `side="RIGHT"` for every entry. Zero
|
|
136
|
+
anchored findings → `--state CLEAN` with the findings file holding
|
|
137
|
+
an empty array (`[]`); one or more → `--state DIRTY` with the full
|
|
138
|
+
list.
|
|
139
|
+
|
|
140
|
+
```
|
|
141
|
+
python "${CLAUDE_SKILL_DIR}/../../_shared/pr-loop/scripts/post_audit_thread.py" \
|
|
142
|
+
--skill bugteam \
|
|
143
|
+
--owner <O> \
|
|
144
|
+
--repo <R> \
|
|
145
|
+
--pr-number <N> \
|
|
146
|
+
--commit <head_sha> \
|
|
147
|
+
--state <CLEAN|DIRTY> \
|
|
148
|
+
--findings-json <path>
|
|
149
|
+
```
|
|
150
|
+
|
|
151
|
+
The script POSTs a single review with `event=APPROVE` on CLEAN
|
|
152
|
+
(the request event; GitHub stores it as `state=APPROVED`; empty
|
|
153
|
+
`comments[]`, body documents "no findings") or
|
|
154
|
+
`event=REQUEST_CHANGES` on DIRTY (one inline anchored comment per
|
|
155
|
+
finding; each becomes its own resolvable thread on the PR). It
|
|
156
|
+
handles retries internally (1s / 4s / 16s backoff across four
|
|
157
|
+
attempts). Exit codes:
|
|
158
|
+
|
|
159
|
+
- `0` — review posted; the new review's `html_url` is on stdout.
|
|
160
|
+
Capture this URL as the parent review URL.
|
|
161
|
+
- `1` — user input error (bad arguments, malformed findings JSON,
|
|
162
|
+
missing template).
|
|
163
|
+
- `2` — retry exhaustion. Hard blocker; halt and exit
|
|
164
|
+
`error: post_audit_thread retry exhausted` without retrying and
|
|
165
|
+
without falling back to a flat issue comment. There is no
|
|
166
|
+
fallback path — a hard blocker on the audit-posting path is a
|
|
167
|
+
halt condition.
|
|
168
|
+
|
|
169
|
+
Exit 0 emits the new review's `html_url` on stdout. Extract the
|
|
170
|
+
numeric review id from that URL's `#pullrequestreview-<id>` suffix
|
|
171
|
+
(the trailing URL fragment, the part after `#`). Then harvest child-comment URLs
|
|
172
|
+
**and PR review thread node ids** via
|
|
173
|
+
`pull_request_read(method="get_review_comments", owner=<O>,
|
|
174
|
+
repo=<R>, pullNumber=<N>)` filtered to that review id.
|
|
175
|
+
Match children to findings in the order they appear in the findings
|
|
176
|
+
JSON. Each `loop_comment_index[finding_id]` entry must carry both
|
|
177
|
+
`finding_comment_id` (numeric, used by `add_reply_to_pull_request_comment`)
|
|
178
|
+
and `thread_node_id` (e.g. `PRRT_kwDOxxx`, used by
|
|
179
|
+
`resolve_thread`) so the FIX teammate can reply and resolve.
|
|
180
|
+
|
|
181
|
+
The findings JSON is serialized to a temp file and passed by path; the
|
|
182
|
+
review-body content is read from `audit-reply-template.md` at runtime by
|
|
183
|
+
`post_audit_thread.py`, not passed in by the caller. No body-content
|
|
184
|
+
temp files, no jq, no shell pipes.
|
|
105
185
|
</comment_posting>
|
|
106
186
|
|
|
107
187
|
<output_format>
|
|
108
|
-
|
|
109
|
-
|
|
188
|
+
Run `python scripts/write_audit_outcomes.py` to write the outcome XML.
|
|
189
|
+
The script owns the canonical path, filename, and format.
|
|
110
190
|
</output_format>
|
|
111
191
|
```
|
|
112
192
|
|
|
113
|
-
## AUDIT outcome XML schema
|
|
193
|
+
## AUDIT outcome XML schema
|
|
194
|
+
|
|
195
|
+
`write_audit_outcomes.py` reads the findings JSON (list of finding dicts) and
|
|
196
|
+
emits this shape. Scalar finding fields become XML attributes on
|
|
197
|
+
`<finding>`; the body fields `title`, `excerpt`, and `description` become
|
|
198
|
+
child elements. The root carries `pr`, `loop`, and `review_url` as
|
|
199
|
+
attributes.
|
|
114
200
|
|
|
115
201
|
```xml
|
|
116
|
-
<bugteam_audit loop="<L>" review_url="<url>">
|
|
117
|
-
<
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
</verified_clean>
|
|
202
|
+
<bugteam_audit pr="<N>" loop="<L>" review_url="<url>">
|
|
203
|
+
<findings>
|
|
204
|
+
<finding
|
|
205
|
+
finding_id="loop<L>-<K>"
|
|
206
|
+
severity="P0|P1|P2"
|
|
207
|
+
category="<letter>"
|
|
208
|
+
file="<path>"
|
|
209
|
+
line="<int>"
|
|
210
|
+
finding_comment_id="<gh child comment id, or empty if unanchored>"
|
|
211
|
+
finding_comment_url="<url of child comment, OR review_url if unanchored>"
|
|
212
|
+
thread_node_id="<PR review thread node id (PRRT_kwDOxxx), or empty if unanchored>"
|
|
213
|
+
>
|
|
214
|
+
<title>one-line title</title>
|
|
215
|
+
<excerpt>verbatim source line or snippet from the file at the cited line</excerpt>
|
|
216
|
+
<description>2-3 sentence description with concrete trace</description>
|
|
217
|
+
</finding>
|
|
218
|
+
</findings>
|
|
134
219
|
</bugteam_audit>
|
|
135
220
|
```
|
|
136
221
|
|
|
137
|
-
|
|
222
|
+
Verified-clean evidence per A–K category is surfaced in the agent's text-mode
|
|
223
|
+
final report, not in this outcome XML (the writer accepts a flat findings list
|
|
224
|
+
only).
|
|
138
225
|
|
|
139
226
|
## FIX spawn-prompt XML (bugfix teammate)
|
|
140
227
|
|
|
@@ -159,14 +246,33 @@ cd into `<worktree_path>` before any git or file operation.
|
|
|
159
246
|
file="<path>"
|
|
160
247
|
line="<int>"
|
|
161
248
|
category="<letter>"
|
|
162
|
-
finding_comment_id="<id>"
|
|
249
|
+
finding_comment_id="<numeric comment id>"
|
|
163
250
|
finding_comment_url="<url>"
|
|
251
|
+
thread_node_id="<PR review thread node id (PRRT_kwDOxxx)>"
|
|
164
252
|
>
|
|
165
253
|
<description>...</description>
|
|
166
254
|
</bug>
|
|
167
255
|
</bugs_to_fix>
|
|
168
256
|
|
|
169
257
|
<execution>
|
|
258
|
+
Before starting, create one task per checklist item via TaskCreate. Use
|
|
259
|
+
TaskUpdate to mark each in_progress as you begin it and completed when
|
|
260
|
+
done.
|
|
261
|
+
|
|
262
|
+
<self_audit_checklist>
|
|
263
|
+
[ ] Read each referenced file
|
|
264
|
+
[ ] Apply all addressable fixes
|
|
265
|
+
[ ] py_compile on every modified file
|
|
266
|
+
[ ] Test suite passes
|
|
267
|
+
[ ] Post-fix violation count ≤ previous loop total (skip on L=1)
|
|
268
|
+
[ ] git add + commit
|
|
269
|
+
[ ] git push
|
|
270
|
+
[ ] Per finding: atomically post the unified-template reply, then call resolve_thread (no yield between them)
|
|
271
|
+
[ ] Publish fix summary via /doc-gist, capture URL
|
|
272
|
+
[ ] Append fix summary URL to parent review via add_reply_to_pull_request_comment
|
|
273
|
+
[ ] Write fix outcomes XML
|
|
274
|
+
</self_audit_checklist>
|
|
275
|
+
|
|
170
276
|
1. Read each referenced file before editing.
|
|
171
277
|
2. Apply each fix you can address.
|
|
172
278
|
3. Run `python -m py_compile` (or language-equivalent) on every modified file.
|
|
@@ -178,28 +284,82 @@ cd into `<worktree_path>` before any git or file operation.
|
|
|
178
284
|
(the commit was atomic; if it failed, no finding was applied), populate hook_output
|
|
179
285
|
on each outcome, and return WITHOUT retrying. The lead will treat this loop as no-progress.
|
|
180
286
|
7. git push with a plain fast-forward push (the default, no flag overrides).
|
|
181
|
-
8. For each
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
287
|
+
8. For each finding, atomically (a) post the fix reply and
|
|
288
|
+
(b) call `resolve_thread`. The two calls form one logical action
|
|
289
|
+
per thread — do not yield to the lead between them, and do not
|
|
290
|
+
batch all replies before any resolves.
|
|
291
|
+
|
|
292
|
+
(a) Reply via
|
|
293
|
+
`add_reply_to_pull_request_comment(commentId=<finding_comment_id>,
|
|
294
|
+
body=<reply_body>, owner=<O>, repo=<R>, pullNumber=<N>)`. The
|
|
295
|
+
reply body uses the unified template at
|
|
296
|
+
[`../../_shared/pr-loop/audit-reply-template.md`](../../_shared/pr-loop/audit-reply-template.md).
|
|
297
|
+
Skeleton (identical across all paths):
|
|
298
|
+
|
|
299
|
+
```
|
|
300
|
+
**Claude finished @<reviewer>'s task** —— <status_line>
|
|
301
|
+
|
|
302
|
+
---
|
|
303
|
+
### <action_heading> ✅
|
|
304
|
+
|
|
305
|
+
<1–2 paragraph plain-language explanation>
|
|
306
|
+
|
|
307
|
+
**`<file>:<line>`:**
|
|
308
|
+
- <bullet describing change or rationale>
|
|
309
|
+
- <bullet describing change or rationale>
|
|
310
|
+
|
|
311
|
+
<closing paragraph>
|
|
312
|
+
```
|
|
313
|
+
|
|
314
|
+
Per-path `<status_line>` / `<action_heading>`:
|
|
315
|
+
- `status=fixed`: `Fixed in <short_sha>` (first 7 chars) /
|
|
316
|
+
finding-specific action verb (e.g.,
|
|
317
|
+
`Replaced Any with concrete type`).
|
|
318
|
+
- `status=could_not_address`: `Could not address this loop` /
|
|
319
|
+
one-line reason text.
|
|
320
|
+
- `status=hook_blocked`: `Hook blocked the fix commit` /
|
|
321
|
+
one-line hook summary.
|
|
322
|
+
|
|
323
|
+
Body text is passed directly as string parameters — no temp files,
|
|
324
|
+
no jq, no shell pipes.
|
|
325
|
+
|
|
326
|
+
(b) Immediately call
|
|
327
|
+
`pull_request_review_write(method="resolve_thread",
|
|
328
|
+
threadId=<thread_node_id>, owner=<O>, repo=<R>, pullNumber=<N>)`
|
|
329
|
+
for the same thread (this is the PR review thread node ID —
|
|
330
|
+
`PRRT_kwDOxxx` — distinct from the numeric comment ID; the AUDIT
|
|
331
|
+
teammate captures it at audit time when calling
|
|
332
|
+
`get_review_comments` and stores it on each
|
|
333
|
+
`loop_comment_index` entry alongside `finding_comment_id`, see
|
|
334
|
+
[reference/obstacles/fix-resolve-thread.md](reference/obstacles/fix-resolve-thread.md)).
|
|
335
|
+
|
|
336
|
+
9. Publish the fix summary gist via `/doc-gist`. Pass the fix report
|
|
337
|
+
(what was fixed, what was skipped, what was left unaddressed) as the
|
|
338
|
+
gist body. Capture the returned gist URL.
|
|
339
|
+
|
|
340
|
+
10. Append the fix summary gist URL (from step 9) to the parent review
|
|
341
|
+
via `add_reply_to_pull_request_comment(commentId=<id>, body=...,
|
|
342
|
+
owner=<O>, repo=<R>, pullNumber=<N>)`. The body carries the
|
|
343
|
+
gist URL plus a one-line summary of fixes applied this loop.
|
|
344
|
+
|
|
345
|
+
11. Write `.bugteam-pr<N>-loop<L>.fix-outcomes.xml` inside
|
|
346
|
+
`<worktree_path>` (schema below) and return its path.
|
|
189
347
|
</execution>
|
|
190
348
|
|
|
191
349
|
<outcome_xml_schema>
|
|
192
|
-
<bugteam_fix loop="<L>" commit_sha="<sha or empty if no commit>">
|
|
193
|
-
<
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
350
|
+
<bugteam_fix pr="<N>" loop="<L>" commit_sha="<sha or empty if no commit>">
|
|
351
|
+
<outcomes>
|
|
352
|
+
<outcome
|
|
353
|
+
finding_id="loop<L>-<K>"
|
|
354
|
+
status="fixed|could_not_address|hook_blocked|unverified_fixed"
|
|
355
|
+
commit_sha="<sha if fixed, empty otherwise>"
|
|
356
|
+
reply_comment_id="<id of the reply posted>"
|
|
357
|
+
reply_comment_url="<url of the reply posted>"
|
|
358
|
+
>
|
|
359
|
+
<reason>only present when status=could_not_address; one-line reason text</reason>
|
|
360
|
+
<hook_output>only present when status=hook_blocked; verbatim stderr from the blocked hook</hook_output>
|
|
361
|
+
</outcome>
|
|
362
|
+
</outcomes>
|
|
203
363
|
</bugteam_fix>
|
|
204
364
|
</outcome_xml_schema>
|
|
205
365
|
|