claude-dev-env 1.92.0 → 1.93.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 +5 -39
- package/_shared/CLAUDE.md +2 -1
- package/_shared/advisor/CLAUDE.md +21 -0
- package/_shared/advisor/advisor-protocol.md +142 -0
- package/_shared/advisor/scripts/config/advisor_scripts_constants/__init__.py +1 -0
- package/_shared/advisor/scripts/config/advisor_scripts_constants/model_tier_run_validator_constants.py +86 -0
- package/_shared/advisor/scripts/model_tier_run_validator.py +246 -0
- package/_shared/advisor/scripts/pyproject.toml +3 -0
- package/_shared/advisor/scripts/tests/test_model_tier_run_validator.py +302 -0
- package/_shared/advisor/scripts/tests/test_tier_model_ids.py +180 -0
- package/_shared/advisor/scripts/tier_model_ids.py +164 -0
- package/_shared/pr-loop/CLAUDE.md +1 -0
- package/_shared/pr-loop/precatch-rubric.md +65 -0
- package/_shared/pr-loop/scripts/CLAUDE.md +1 -1
- package/_shared/pr-loop/scripts/code_rules_gate.py +137 -5
- package/_shared/pr-loop/scripts/post_audit_thread.py +1 -1
- package/_shared/pr-loop/scripts/pr_loop_shared_constants/CLAUDE.md +1 -1
- package/_shared/pr-loop/scripts/pr_loop_shared_constants/code_rules_gate_constants.py +16 -0
- package/_shared/pr-loop/scripts/pr_loop_shared_constants/reviews_disabled_constants.py +2 -1
- package/_shared/pr-loop/scripts/reviewer_availability.py +42 -12
- package/_shared/pr-loop/scripts/reviews_disabled.py +65 -21
- package/_shared/pr-loop/scripts/terminology_sweep.py +69 -21
- package/_shared/pr-loop/scripts/tests/CLAUDE.md +1 -1
- package/_shared/pr-loop/scripts/tests/fixtures/{copilot_internal_user_jonecho.json → copilot_internal_user_example.json} +1 -1
- package/_shared/pr-loop/scripts/tests/test_agent_config_carveout.py +1 -1
- package/_shared/pr-loop/scripts/tests/test_code_rules_gate.py +146 -2
- package/_shared/pr-loop/scripts/tests/test_copilot_quota.py +8 -8
- package/_shared/pr-loop/scripts/tests/test_reviewer_availability.py +18 -5
- package/_shared/pr-loop/scripts/tests/test_reviews_disabled.py +56 -5
- package/_shared/pr-loop/scripts/tests/test_terminology_sweep.py +104 -17
- package/agents/CLAUDE.md +3 -2
- package/agents/clasp-deployment-orchestrator.md +2 -2
- package/agents/code-advisor.md +7 -5
- package/agents/code-verifier.md +6 -2
- package/agents/session-advisor.md +27 -0
- package/audit-rubrics/category_rubrics/category-j-code-rules-compliance.md +1 -1
- package/audit-rubrics/category_rubrics/category-k-codebase-conflicts.md +1 -1
- package/audit-rubrics/prompts/category-a-api-contracts.md +2 -2
- package/audit-rubrics/prompts/category-b-selector-engine-compat.md +2 -2
- package/audit-rubrics/prompts/category-c-resource-cleanup.md +2 -2
- package/audit-rubrics/prompts/category-d-scoping-and-ordering.md +2 -2
- package/audit-rubrics/prompts/category-e-dead-code.md +2 -2
- package/audit-rubrics/prompts/category-f-silent-failures.md +2 -2
- package/audit-rubrics/prompts/category-g-bounds-and-overflow.md +2 -2
- package/audit-rubrics/prompts/category-h-security-boundaries.md +2 -2
- package/audit-rubrics/prompts/category-i-concurrency.md +2 -2
- package/audit-rubrics/prompts/category-j-code-rules-compliance.md +2 -2
- package/audit-rubrics/prompts/category-k-codebase-conflicts.md +2 -2
- package/audit-rubrics/prompts/category-l-behavior-equivalence.md +2 -2
- package/audit-rubrics/prompts/category-m-producer-consumer-cardinality.md +2 -2
- package/audit-rubrics/prompts/category-n-test-name-scenario-verifier.md +2 -2
- package/audit-rubrics/prompts/category-o-docstring-vs-impl-drift.md +2 -2
- package/audit-rubrics/prompts/category-p-name-vs-behavior-contract.md +2 -2
- package/bin/CLAUDE.md +1 -0
- package/bin/expand_home_directory_tokens.mjs +75 -0
- package/bin/install.mjs +21 -7
- package/bin/install.test.mjs +220 -10
- package/hooks/CLAUDE.md +1 -1
- package/hooks/blocking/CLAUDE.md +4 -1
- package/hooks/blocking/_path_setup.py +13 -0
- package/hooks/blocking/bash_pre_tool_use_dispatcher.py +281 -0
- package/hooks/blocking/code_rules_dead_module_constant.py +88 -16
- package/hooks/blocking/code_rules_enforcer.py +6 -0
- package/hooks/blocking/code_rules_imports_logging.py +34 -1
- package/hooks/blocking/code_rules_paths_syspath.py +1 -1
- package/hooks/blocking/code_rules_test_layout.py +272 -0
- package/hooks/blocking/nas_ssh_binary_enforcer.py +22 -12
- package/hooks/blocking/pii_prevention_blocker.py +781 -0
- package/hooks/blocking/pii_scanner.py +340 -0
- package/hooks/blocking/pre_tool_use_dispatcher.py +3 -3
- package/hooks/blocking/stop_dispatcher.py +84 -0
- package/hooks/blocking/test__path_setup.py +39 -0
- package/hooks/blocking/test_bash_dispatcher_interpreter_starts.py +61 -0
- package/hooks/blocking/test_bash_pre_tool_use_dispatcher.py +294 -0
- package/hooks/blocking/test_code_rules_enforcer_cross_skill_duplicate.py +1 -1
- package/hooks/blocking/test_code_rules_enforcer_dead_module_constant.py +51 -0
- package/hooks/blocking/test_code_rules_enforcer_dead_module_constant_read_cap.py +103 -0
- package/hooks/blocking/test_code_rules_enforcer_dot_test_pattern.py +1 -1
- package/hooks/blocking/test_code_rules_enforcer_file_global_constants.py +1 -1
- package/hooks/blocking/test_code_rules_enforcer_hardcoded_user_path.py +11 -11
- package/hooks/blocking/test_code_rules_enforcer_naive_datetime.py +1 -1
- package/hooks/blocking/test_code_rules_enforcer_same_file_inline_duplicate.py +1 -1
- package/hooks/blocking/test_code_rules_enforcer_test_layout.py +111 -0
- package/hooks/blocking/test_code_rules_enforcer_type_checking_scope.py +76 -0
- package/hooks/blocking/test_destructive_command_blocker.py +29 -9
- package/hooks/blocking/test_gh_body_arg_blocker.py +3 -3
- package/hooks/blocking/test_nas_ssh_binary_enforcer.py +96 -39
- package/hooks/blocking/test_pii_prevention_blocker.py +905 -0
- package/hooks/blocking/test_pii_prevention_windows_git_path.py +41 -0
- package/hooks/blocking/test_pii_scanner.py +165 -0
- package/hooks/blocking/test_pr_description_enforcer_pr_number.py +1 -1
- package/hooks/blocking/test_pre_tool_use_dispatcher.py +14 -13
- package/hooks/blocking/test_stop_dispatcher.py +187 -0
- package/hooks/blocking/test_verdict_directory_write_blocker.py +1 -1
- package/hooks/blocking/test_volatile_path_in_post_blocker.py +3 -3
- package/hooks/blocking/volatile_path_in_post_blocker.py +54 -5
- package/hooks/diagnostic/migrations/README.md +25 -26
- package/hooks/diagnostic/test_hook_log_extractor.py +10 -10
- package/hooks/hooks.json +10 -120
- package/hooks/hooks_constants/CLAUDE.md +12 -3
- package/hooks/hooks_constants/bash_pre_tool_use_dispatcher_constants.py +78 -0
- package/hooks/hooks_constants/dead_module_constant_constants.py +1 -0
- package/hooks/hooks_constants/hosted_hook_runner.py +73 -0
- package/hooks/hooks_constants/local_identity.py +182 -0
- package/hooks/hooks_constants/nas_ssh_binary_enforcer_constants.py +4 -37
- package/hooks/hooks_constants/pii_prevention_constants.py +299 -0
- package/hooks/hooks_constants/pre_tool_use_dispatcher_constants.py +4 -0
- package/hooks/hooks_constants/python_style_checks_constants.py +15 -0
- package/hooks/hooks_constants/stop_dispatcher_constants.py +26 -0
- package/hooks/hooks_constants/test_bash_pre_tool_use_dispatcher_constants.py +87 -0
- package/hooks/hooks_constants/test_hardcoded_user_path_constants.py +2 -2
- package/hooks/hooks_constants/test_hosted_hook_runner.py +101 -0
- package/hooks/hooks_constants/test_layout_constants.py +28 -0
- package/hooks/hooks_constants/test_local_identity.py +88 -0
- package/hooks/hooks_constants/test_session_env_cleanup_constants.py +1 -1
- package/hooks/hooks_constants/test_stop_dispatcher_constants.py +32 -0
- package/hooks/validators/README.md +5 -6
- package/hooks/validators/__init__.py +2 -2
- package/hooks/validators/python_style_checks.py +298 -243
- package/hooks/validators/run_all_validators.py +6 -0
- package/hooks/validators/test_python_style_checks.py +278 -163
- package/package.json +2 -2
- package/rules/CLAUDE.md +7 -1
- package/rules/bdd.md +1 -1
- package/rules/nas-ssh-invocation.md +6 -4
- package/rules/no-justification-noise.md +61 -0
- package/rules/testing.md +0 -2
- package/scripts/test_setup_project_paths.py +1 -1
- package/skills/CLAUDE.md +6 -3
- package/skills/_shared/pr-loop/scripts/_path_resolver.py +2 -2
- package/skills/_shared/pr-loop/scripts/build_audit_prompt.py +1 -1
- package/skills/_shared/pr-loop/scripts/build_fix_prompt.py +1 -1
- package/skills/_shared/pr-loop/scripts/test__path_resolver.py +42 -3
- package/skills/_shared/pr-loop/scripts/test_build_audit_prompt.py +11 -11
- package/skills/_shared/pr-loop/scripts/test_build_fix_prompt.py +26 -3
- package/skills/_shared/pr-loop/scripts/test_preflight_worktree.py +49 -25
- package/skills/autoconverge/CLAUDE.md +3 -3
- package/skills/autoconverge/SKILL.md +113 -35
- package/skills/autoconverge/reference/CLAUDE.md +2 -2
- package/skills/autoconverge/reference/convergence.md +44 -22
- package/skills/autoconverge/reference/gotchas.md +11 -0
- package/skills/autoconverge/reference/stop-conditions.md +23 -13
- package/skills/autoconverge/workflow/CLAUDE.md +2 -1
- package/skills/autoconverge/workflow/converge.clean-audit.test.mjs +15 -19
- package/skills/autoconverge/workflow/converge.contract.test.mjs +43 -42
- package/skills/autoconverge/workflow/converge.copilot-gate.test.mjs +141 -16
- package/skills/autoconverge/workflow/converge.fix-recovery.test.mjs +2 -2
- package/skills/autoconverge/workflow/converge.mjs +329 -68
- package/skills/autoconverge/workflow/converge.path-aware.test.mjs +1 -1
- package/skills/autoconverge/workflow/converge.precatch.test.mjs +152 -0
- package/skills/autoconverge/workflow/converge.run-input.test.mjs +3 -3
- package/skills/autoconverge/workflow/converge_multi.run-input.test.mjs +15 -15
- package/skills/autoconverge/workflow/test_convergence_summary.py +6 -6
- package/skills/bdd-protocol/SKILL.md +4 -5
- package/skills/bdd-protocol/references/anti-patterns.md +1 -1
- package/skills/bugteam/SKILL.md +8 -0
- package/skills/bugteam/reference/copilot-gap-analysis.md +20 -20
- package/skills/bugteam/reference/obstacles/audit-walk-categories.md +1 -1
- package/skills/bugteam/reference/team-setup.md +7 -5
- package/skills/bugteam/scripts/reflow_skill_md.py +1 -1
- package/skills/copilot-finding-triage/SKILL.md +124 -0
- package/skills/copilot-finding-triage/reference/tier-rubric.md +49 -0
- package/skills/copilot-finding-triage/scripts/conftest.py +8 -0
- package/skills/copilot-finding-triage/scripts/copilot_finding_triage_constants/__init__.py +0 -0
- package/skills/copilot-finding-triage/scripts/copilot_finding_triage_constants/config/__init__.py +0 -0
- package/skills/copilot-finding-triage/scripts/copilot_finding_triage_constants/config/notify_ntfy_constants.py +32 -0
- package/skills/copilot-finding-triage/scripts/notify_ntfy.py +192 -0
- package/skills/copilot-finding-triage/scripts/test_notify_ntfy.py +141 -0
- package/skills/copilot-finding-triage/templates/notification.md +34 -0
- package/skills/copilot-review/SKILL.md +8 -6
- package/skills/findbugs/SKILL.md +4 -0
- package/skills/fixbugs/SKILL.md +8 -7
- package/skills/gotcha/CLAUDE.md +2 -2
- package/skills/gotcha/SKILL.md +4 -4
- package/skills/log-audit/SKILL.md +4 -6
- package/skills/monitor-open-prs/CLAUDE.md +1 -1
- package/skills/monitor-open-prs/SKILL.md +6 -1
- package/skills/orchestrator/SKILL.md +184 -0
- package/skills/orchestrator-refresh/SKILL.md +37 -0
- package/skills/post-audit-findings/SKILL.md +5 -9
- package/skills/pr-consistency-audit/SKILL.md +5 -1
- package/skills/pr-converge/CLAUDE.md +1 -1
- package/skills/pr-converge/SKILL.md +86 -47
- package/skills/pr-converge/reference/CLAUDE.md +1 -1
- package/skills/pr-converge/reference/convergence-gates.md +20 -17
- package/skills/pr-converge/reference/examples.md +63 -47
- package/skills/pr-converge/reference/fix-protocol.md +15 -15
- package/skills/pr-converge/reference/ground-rules.md +11 -7
- package/skills/pr-converge/reference/multi-pr-orchestration.md +6 -5
- package/skills/pr-converge/reference/per-tick.md +129 -107
- package/skills/pr-converge/reference/state-schema.md +15 -10
- package/skills/pr-converge/scripts/check_convergence.py +5 -4
- package/skills/pr-converge/scripts/test_check_convergence.py +6 -4
- package/skills/pr-fix-protocol/SKILL.md +3 -8
- package/skills/pr-loop-cloud-transport/SKILL.md +102 -0
- package/skills/pr-loop-cloud-transport/reference/identity-and-hooks.md +40 -0
- package/skills/pr-loop-cloud-transport/reference/substitution-matrix.md +48 -0
- package/skills/pr-loop-lifecycle/SKILL.md +5 -9
- package/skills/pr-scope-resolve/SKILL.md +3 -6
- package/skills/privacy-hygiene/SKILL.md +114 -0
- package/skills/qbug/SKILL.md +8 -8
- package/skills/rebase/SKILL.md +5 -1
- package/skills/refine/SKILL.md +4 -5
- package/skills/reviewer-gates/SKILL.md +7 -11
- package/skills/session-log/SKILL.md +4 -1
- package/skills/skill-builder/SKILL.md +3 -6
- package/skills/structure-prompt/SKILL.md +4 -5
- package/skills/team-advisor/SKILL.md +32 -164
- package/skills/test_markdown_link_integrity.py +10 -6
- package/skills/update/SKILL.md +5 -1
- package/skills/usage-pause/SKILL.md +14 -5
- package/skills/usage-pause/scripts/resolve_usage_window.py +83 -5
- package/skills/usage-pause/scripts/test_resolve_usage_window.py +185 -17
- package/skills/usage-pause/scripts/usage_pause_constants/resolve_usage_window_constants.py +4 -3
- package/skills/verified-build/SKILL.md +4 -9
- package/skills/team-advisor-refresh/SKILL.md +0 -25
|
@@ -1,13 +1,12 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: autoconverge
|
|
3
3
|
description: >-
|
|
4
|
-
Drives one draft PR to convergence in
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
'
|
|
10
|
-
'run the converge workflow', or 'drive the PR to ready autonomously'.
|
|
4
|
+
Drives one draft PR to convergence in one autonomous run: a deterministic static
|
|
5
|
+
sweep, then code review, bug audit, and self-review on one HEAD, all fixes in one
|
|
6
|
+
commit, then Bugbot and Copilot as terminal confirmation gates before ready.
|
|
7
|
+
Use when the user says '/autoconverge', 'autoconverge this PR', 'converge this
|
|
8
|
+
PR in one run', 'run the converge workflow', or 'drive the PR to ready
|
|
9
|
+
autonomously'.
|
|
11
10
|
---
|
|
12
11
|
|
|
13
12
|
# Autoconverge
|
|
@@ -46,6 +45,19 @@ Scan the tool list at the top of this conversation for the literal string
|
|
|
46
45
|
aborting` and stop. The workflow also needs the `gh` CLI authenticated for the
|
|
47
46
|
PR's owner.
|
|
48
47
|
|
|
48
|
+
## Transport check (before any GitHub step)
|
|
49
|
+
|
|
50
|
+
Run `command -v gh`; when it succeeds, run `gh auth status`; once the PR
|
|
51
|
+
scope is resolved, run `gh api repos/<owner>/<repo> --jq .permissions.push`
|
|
52
|
+
and take `true` as the pass. When any check fails, run the
|
|
53
|
+
`pr-loop-cloud-transport` skill first and route every `gh` operation in this
|
|
54
|
+
skill through its substitution matrix. The workflow script
|
|
55
|
+
(`workflow/converge.mjs`) embeds `gh` commands and gh-backed helper scripts in
|
|
56
|
+
its agent prompts, so a cloud run also applies the same substitution to those
|
|
57
|
+
agent prompts when it authors the launch — the transport skill covers the
|
|
58
|
+
orchestrating session's own steps, and the script's agent-prompt text carries
|
|
59
|
+
`gh` calls the spawned agents cannot run in a cloud session.
|
|
60
|
+
|
|
49
61
|
## Pre-flight (main session)
|
|
50
62
|
|
|
51
63
|
1. **Enter a worktree.** Call `EnterWorktree` with no arguments before any
|
|
@@ -80,7 +92,7 @@ PR's owner.
|
|
|
80
92
|
enter the branch worktree. A non-zero exit prints a `PREFLIGHT_OUTCOME` line
|
|
81
93
|
and an `ABORT` line: report that line and stop. Autoconverge runs inside the
|
|
82
94
|
PR's own repo, so a working directory rooted in a different repo (for
|
|
83
|
-
example, `claude-
|
|
95
|
+
example, `claude-dev-env` while the PR lives in `llm-settings`) or in no
|
|
84
96
|
git checkout at all cannot continue.
|
|
85
97
|
|
|
86
98
|
4. **Grant project permissions.** Apply the `pr-loop-lifecycle` skill's Open
|
|
@@ -129,13 +141,40 @@ Write it again when the result lands, so the handoff carries the final run id an
|
|
|
129
141
|
names the teardown phase the fresh session picks up from.
|
|
130
142
|
|
|
131
143
|
The workflow returns
|
|
132
|
-
`{ converged, rounds, finalSha, blocker, standardsNote, copilotNote, reuseNote, deferredPrs }
|
|
144
|
+
`{ converged, rounds, finalSha, blocker, standardsNote, copilotNote, reuseNote, deferredPrs }`,
|
|
145
|
+
plus a `userReview` field on a `blocker: "user-review"` return.
|
|
133
146
|
`deferredPrs` is the list of draft environment-hardening PRs the standards-deferral
|
|
134
147
|
path opened this run, each as `{ owner, repo, prNumber, copilotDisabled, bugbotDisabled }`.
|
|
135
148
|
The two flags carry this run's Copilot and Bugbot availability, so the next generation
|
|
136
149
|
skips a reviewer that is down or out of quota without re-probing. This list is the seed the
|
|
137
150
|
[self-closing loop](#self-closing-loop-converge-the-deferred-prs) converges next.
|
|
138
151
|
|
|
152
|
+
## Copilot findings — two-tier triage
|
|
153
|
+
|
|
154
|
+
The Copilot gate tiers each finding it surfaces. A **self-healing** finding is
|
|
155
|
+
pure style, type hints, misplaced or unused imports, formatting, magic-value
|
|
156
|
+
extraction, a test-only change, a doc-or-description vs code mismatch, or code
|
|
157
|
+
de-duplication — a fix that cannot change observable runtime behavior for
|
|
158
|
+
production callers. Self-healing findings flow into the fix round and count
|
|
159
|
+
toward convergence, with no user notification.
|
|
160
|
+
|
|
161
|
+
A **code-concern** finding is behavior-changing or needs a product decision:
|
|
162
|
+
logic or correctness, security, data handling, error-handling semantics, or
|
|
163
|
+
concurrency. Copilot tiers a finding as code-concern whenever the tier is in
|
|
164
|
+
doubt. When one or more code-concern findings land, the workflow neither
|
|
165
|
+
auto-fixes them nor marks the PR ready. It returns `converged: false`,
|
|
166
|
+
`blocker: "user-review"`, and a `userReview` field carrying
|
|
167
|
+
`{ reviewUrl, findings: [{ file, line, severity, tier, title }] }`.
|
|
168
|
+
|
|
169
|
+
A background workflow cannot hold for a human, so the wait belongs to the
|
|
170
|
+
orchestrating session. On a `blocker: "user-review"` return, run the
|
|
171
|
+
[`copilot-finding-triage`](../copilot-finding-triage/SKILL.md) skill: send the
|
|
172
|
+
ntfy notification (the finding summary plus the `reviewUrl` Copilot review link),
|
|
173
|
+
then hold with a 45-minute `ScheduleWakeup` for the user's response. When the
|
|
174
|
+
user answers within the window, follow their direction. When the window closes
|
|
175
|
+
with no response, run normal teardown and report the code-concern findings
|
|
176
|
+
un-reviewed.
|
|
177
|
+
|
|
139
178
|
## Budget-aware round boundaries
|
|
140
179
|
|
|
141
180
|
The workflow's `budget` API is the pacing signal: when a usage target is
|
|
@@ -173,6 +212,25 @@ On teardown entry, when `~/.claude/runtime/pr-loop/bugteam-pr-<N>/handoff.json`
|
|
|
173
212
|
exists, read its `completed_steps` and skip any checkpoint the list already
|
|
174
213
|
names, so a resumed run performs only the checkpoints left.
|
|
175
214
|
|
|
215
|
+
On a `blocker: "user-review"` return, run the
|
|
216
|
+
[`copilot-finding-triage`](../copilot-finding-triage/SKILL.md) gate before
|
|
217
|
+
teardown: send the ntfy alert with the finding summary and the
|
|
218
|
+
`userReview.reviewUrl` link, then hold with a 45-minute `ScheduleWakeup`. Act on
|
|
219
|
+
the user's direction when it arrives inside the window; when the window closes
|
|
220
|
+
with no response, fall through to normal teardown and report the
|
|
221
|
+
`userReview.findings` un-reviewed. The PR stays a draft in this path — the
|
|
222
|
+
workflow marked nothing ready.
|
|
223
|
+
|
|
224
|
+
Before the checkpoints, when the workflow returned a non-null `copilotNote`
|
|
225
|
+
(the Copilot gate was bypassed), query the PR's reviews once more for a
|
|
226
|
+
`copilot-pull-request-reviewer[bot]` review on the final HEAD
|
|
227
|
+
(`fetch_copilot_reviews.py`, or the GitHub MCP `pull_request_read` method
|
|
228
|
+
`get_reviews`). Copilot typically posts within 10–15 minutes of a request, so
|
|
229
|
+
a review can land between the bypass and teardown. When one exists and
|
|
230
|
+
carries findings, mark the PR draft, route the findings through one fix
|
|
231
|
+
round per the `pr-fix-protocol` skill, re-verify, push, and mark the PR
|
|
232
|
+
ready again — then run the checkpoints.
|
|
233
|
+
|
|
176
234
|
1. **When `converged` is true — build and publish the closing report.**
|
|
177
235
|
Skip this entire step (report, artifact publish, comment, Chrome open) when the
|
|
178
236
|
workflow returned a non-null `blocker`. Per-round live-dashboard refresh is out of
|
|
@@ -300,9 +358,13 @@ Every agent prompt carries a headless-safety preamble: the run is unattended, so
|
|
|
300
358
|
agents never inline a destructive-command literal (`rm -rf`, `git reset --hard`,
|
|
301
359
|
`dd`) into a Bash command — the `destructive_command_blocker` hook matches those
|
|
302
360
|
patterns as raw text, and a confirmation prompt no human can answer would stall
|
|
303
|
-
the run.
|
|
304
|
-
|
|
305
|
-
|
|
361
|
+
the run. The preamble has two forms. Read-only agents — the review, verify, and
|
|
362
|
+
utility spawns that edit nothing — receive a trimmed form that drops the rm-shape
|
|
363
|
+
rules, since a read-only agent never runs `rm`. Edit agents — the fix and commit
|
|
364
|
+
spawns — receive the full form that carries the rm-shape rules described below.
|
|
365
|
+
Agents verify destructive-blocker behavior through the committed test
|
|
366
|
+
suite (`python -m pytest`) and keep scratch work in the OS temp dir. The full
|
|
367
|
+
preamble describes the narrowest rm auto-allow path — a standalone Bash call whose target
|
|
306
368
|
resolves inside the ephemeral namespace (`/tmp`, `/temp`, the OS temp root, or the
|
|
307
369
|
run worktree) — and a compound path that accepts an rm joined with benign
|
|
308
370
|
reporting segments when every rm target is an absolute ephemeral path. Both of
|
|
@@ -323,36 +385,52 @@ helper file and run it as `python <file>.py` — keeping every destructive liter
|
|
|
323
385
|
out of a Bash command string entirely and independent of which auto-allow path
|
|
324
386
|
matches.
|
|
325
387
|
|
|
326
|
-
- **
|
|
327
|
-
the
|
|
328
|
-
`
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
the
|
|
338
|
-
|
|
388
|
+
- **Static sweep:** each round opens with a deterministic static-sweep lens that
|
|
389
|
+
runs the CODE_RULES gate (`code_rules_gate.py --base origin/main`), `ruff`,
|
|
390
|
+
`mypy`, and stem-matched `pytest` over the changed files. Any failure routes
|
|
391
|
+
through the same fix flow and the round re-runs, so the reading lenses only ever
|
|
392
|
+
review sweep-clean code. The sweep uses local commands only, so it runs in any
|
|
393
|
+
session.
|
|
394
|
+
- **Converge:** `parallel([code-review lens, bug-audit lens, self-review lens])`
|
|
395
|
+
on the current HEAD, full `origin/main...HEAD` diff. The bug-audit lens applies
|
|
396
|
+
the A-P rubric and then its adversarial second pass; the self-review lens covers
|
|
397
|
+
the doc-vs-code parity, test-assertion completeness, and PR-description-vs-diff
|
|
398
|
+
parity lanes. The preflight step fetches `origin/main` once for the round and
|
|
399
|
+
enumerates the diff (changed-file list plus diffstat); each lens receives that
|
|
400
|
+
list and reads only the files it needs rather than re-deriving the diff, forming
|
|
401
|
+
its own review judgment. Dedup findings; one `clean-coder` applies the round's
|
|
402
|
+
fixes per the `pr-fix-protocol` skill (`../pr-fix-protocol/SKILL.md`) — fix,
|
|
403
|
+
reply, resolve — landing every fix in one commit per round, which the workflow
|
|
404
|
+
journal records; re-verify next round on the new HEAD. Every edit step ends with
|
|
405
|
+
a pre-commit gate check: before its turn ends, the fixer dry-runs the CODE_RULES
|
|
406
|
+
commit gate (`code_rules_gate.py --staged`) and keeps fixing until that gate
|
|
407
|
+
would accept the commit — it makes no commit itself. When all three internal
|
|
408
|
+
lenses are clean on a stable HEAD, post the CLEAN bugteam audit artifact.
|
|
339
409
|
A round whose findings are ALL code-standard violations (pure CODE_RULES/style,
|
|
340
410
|
no behavioral impact) passes for convergence purposes: the workflow files a
|
|
341
411
|
follow-up issue listing the findings, opens a draft environment-hardening PR
|
|
342
412
|
(hooks/rules that block those violation classes at Write/Edit time), resolves
|
|
343
413
|
any bot threads with a deferral note, and reports the deferral in
|
|
344
414
|
`standardsNote`.
|
|
345
|
-
- **
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
415
|
+
- **Bugbot gate:** the terminal Cursor Bugbot confirmation gate runs once the
|
|
416
|
+
internal lenses are clean. When Bugbot is disabled or opted out for the run (the
|
|
417
|
+
default) or unreachable, the gate spawns no agent and passes straight to the
|
|
418
|
+
Copilot gate. Otherwise it fetches Bugbot's verdict on the HEAD; findings route
|
|
419
|
+
back into Converge, and a clean verdict advances to the Copilot gate.
|
|
420
|
+
- **Copilot gate:** the terminal GitHub Copilot confirmation gate. Request a
|
|
421
|
+
Copilot review, poll up to the configured cap; findings route back into
|
|
422
|
+
Converge. When Copilot is down or out of quota — it posts an out-of-usage notice
|
|
423
|
+
(the requester hit their quota) on the HEAD, or surfaces no review at all after
|
|
424
|
+
the configured cap — the gate logs a notice and the run marks the PR ready with
|
|
425
|
+
the Copilot gate bypassed. `copilotNote` records the bypass.
|
|
350
426
|
- **Convergence check:** `check_convergence.py` is the authoritative gate; one
|
|
351
427
|
agent runs it and, on a full pass, marks `draft=false` in the same turn. Each
|
|
352
|
-
spawned agent runs on the model tier its role needs —
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
428
|
+
spawned agent runs on the model tier its role needs — sonnet/medium for the
|
|
429
|
+
deterministic static sweep, opus/medium for the code-review, bug-audit,
|
|
430
|
+
self-review, reuse, and terminal Bugbot lenses and the code-editing fix steps,
|
|
431
|
+
sonnet/medium for the verify, commit, and recovery steps, and haiku/low for the
|
|
432
|
+
mechanical probes (preflight, Copilot gate, CLEAN-audit post, convergence
|
|
433
|
+
check).
|
|
356
434
|
|
|
357
435
|
## Multiple PRs
|
|
358
436
|
|
|
@@ -471,7 +549,7 @@ so there is nothing to converge. Report that and stop.
|
|
|
471
549
|
Given a non-empty list of deferred PRs `{ owner, repo, prNumber, copilotDisabled, bugbotDisabled }`
|
|
472
550
|
(a generation may span more than one repository — a hardening PR lands in whichever repo owns
|
|
473
551
|
the surface that blocks the deferred class, so `JonEcho/llm-settings` for hooks
|
|
474
|
-
and `jl-cmd/claude-
|
|
552
|
+
and `jl-cmd/claude-dev-env` for rules and skills both appear):
|
|
475
553
|
|
|
476
554
|
1. **Check out each deferred PR.** Run the
|
|
477
555
|
[Multi-PR pre-flight](#multi-pr-pre-flight-main-session) once per deferred PR.
|
|
@@ -6,7 +6,7 @@ Reference documentation for the `autoconverge` skill. The `converge.mjs` workflo
|
|
|
6
6
|
|
|
7
7
|
| File | Role |
|
|
8
8
|
|---|---|
|
|
9
|
-
| `convergence.md` | Round shape: the three parallel lenses (
|
|
10
|
-
| `stop-conditions.md` | Every condition that ends the run short of ready: budget cap, iteration cap, blocker exit, Copilot bypass. |
|
|
9
|
+
| `convergence.md` | Round shape: the static sweep, the three parallel internal lenses (code-review, bug-audit, self-review), deduplication, the fix commit step, the terminal Bugbot and Copilot gates, and the definition of a clean convergence. |
|
|
10
|
+
| `stop-conditions.md` | Every condition that ends the run short of ready: budget cap, iteration cap, blocker exit, static-sweep stall, Bugbot and Copilot bypass. |
|
|
11
11
|
| `gotchas.md` | Hard-won lessons from failed runs: PR title validation, conflicting PRs, worktree branch lock, resumed sessions rerooting, and minter issues. |
|
|
12
12
|
| `closing-report.md` | Specification for the closing HTML convergence report the teardown step builds and publishes. |
|
|
@@ -39,34 +39,45 @@ any improvement that did not land.
|
|
|
39
39
|
|
|
40
40
|
## The round loop
|
|
41
41
|
|
|
42
|
-
The workflow holds
|
|
42
|
+
The workflow holds four states and moves between them until the PR is ready or
|
|
43
43
|
a blocker ends the run. A single iteration counter increments on every pass
|
|
44
44
|
through any phase and caps the whole run at 20 loop iterations; the round counter
|
|
45
|
-
tracks CONVERGE passes only and is never the cap.
|
|
45
|
+
tracks CONVERGE passes only and is never the cap. The internal lenses drive the
|
|
46
|
+
code to clean first; the external reviewers run only after that, as terminal
|
|
47
|
+
confirmation gates that are expected to return zero.
|
|
46
48
|
|
|
47
|
-
**CONVERGE** (one round = one parallel sweep):
|
|
49
|
+
**CONVERGE** (one round = a static sweep then one parallel lens sweep):
|
|
48
50
|
|
|
49
51
|
1. Resolve the current PR HEAD SHA. The same preflight step also fetches
|
|
50
52
|
`origin/main` once for the round and enumerates the diff — the
|
|
51
53
|
`git diff --name-status origin/main...HEAD` changed-file list and the
|
|
52
54
|
`git diff --stat` diffstat — and carries both into the round.
|
|
53
|
-
2. Run
|
|
55
|
+
2. Run the **static-sweep lens** on that HEAD: a deterministic pass that runs the
|
|
56
|
+
CODE_RULES gate (`code_rules_gate.py --base origin/main`), `ruff`, `mypy`, and
|
|
57
|
+
stem-matched `pytest` over the changed files, mapping each failure to a
|
|
58
|
+
finding. It uses local commands only, so it runs in any session. When the sweep
|
|
59
|
+
raises a finding, one `clean-coder` fixes it through the same fix flow below and
|
|
60
|
+
the round re-runs, so the reading lenses only ever review sweep-clean code.
|
|
61
|
+
3. Run three reading lenses in parallel on that HEAD, each over the full
|
|
54
62
|
`origin/main...HEAD` diff. Each lens receives the preflight's changed-file
|
|
55
63
|
list and diffstat and reads only the files it needs from that list rather than
|
|
56
64
|
re-deriving the diff; each lens forms its own review judgment.
|
|
57
|
-
- **Bugbot lens** — drive Cursor Bugbot to a verdict on HEAD (trigger and
|
|
58
|
-
poll its CI check run when needed) and return its findings, or mark itself
|
|
59
|
-
down when Bugbot is opted out or unreachable.
|
|
60
65
|
- **Code-review lens** — a correctness-focused review pass (`code-quality-agent`)
|
|
61
66
|
that reports findings without editing.
|
|
62
67
|
- **Bug-audit lens** — the bug-audit (`code-quality-agent`) applying the
|
|
63
|
-
shared A–P rubric from `_shared/pr-loop/audit-contract.md`,
|
|
68
|
+
shared A–P rubric from `_shared/pr-loop/audit-contract.md`, then its
|
|
69
|
+
adversarial second pass, and the doc-parity, test-assertion, and
|
|
70
|
+
PR-description lanes from `_shared/pr-loop/precatch-rubric.md`, reporting
|
|
64
71
|
findings without editing.
|
|
65
|
-
|
|
72
|
+
- **Self-review lens** — the semantic parity pass (`code-quality-agent`) that
|
|
73
|
+
reads `_shared/pr-loop/precatch-rubric.md` and covers doc-vs-code parity,
|
|
74
|
+
test-assertion completeness, and PR-description-vs-diff parity, reporting
|
|
75
|
+
findings without editing.
|
|
76
|
+
4. Dedup findings across the three lenses by file, line, and title. A collision
|
|
66
77
|
keeps the most severe duplicate's severity (P0 > P1 > P2), unions the detail
|
|
67
78
|
text, and collects every distinct bot thread id so the fix lens resolves all
|
|
68
79
|
colliding threads.
|
|
69
|
-
|
|
80
|
+
5. **Any findings** → one `clean-coder` applies every fix per the
|
|
70
81
|
`pr-fix-protocol` skill (`../../pr-fix-protocol/SKILL.md`): a single
|
|
71
82
|
test-first commit, a push, then a reply and resolve on each finding that
|
|
72
83
|
carries a GitHub review thread. Before its turn ends, the edit step dry-runs
|
|
@@ -79,10 +90,22 @@ tracks CONVERGE passes only and is never the cap.
|
|
|
79
90
|
re-converges on the unchanged HEAD). A round whose fix lens reports neither
|
|
80
91
|
a moved-HEAD push nor a full thread-resolution ends the run with a
|
|
81
92
|
fix-stalled blocker. The next round re-verifies on the current HEAD.
|
|
82
|
-
|
|
83
|
-
for that HEAD, then move to the
|
|
93
|
+
6. **Zero findings on a stable HEAD** → post the CLEAN bugteam audit artifact
|
|
94
|
+
for that HEAD, then move to the terminal Bugbot gate.
|
|
95
|
+
|
|
96
|
+
**BUGBOT** gate (terminal external confirmation):
|
|
97
|
+
|
|
98
|
+
- Runs once the internal lenses are clean. When Bugbot is off for the run — the
|
|
99
|
+
default unless `CLAUDE_REVIEWS_ENABLED` lists `bugbot` — opted out via
|
|
100
|
+
`CLAUDE_REVIEWS_DISABLED`, or unreachable, the gate spawns no agent and moves
|
|
101
|
+
to the Copilot gate with `bugbotDown` set.
|
|
102
|
+
- Otherwise drive Cursor Bugbot to a verdict on HEAD (trigger and poll its CI
|
|
103
|
+
check run when needed).
|
|
104
|
+
- Bugbot findings → fix them and return to CONVERGE on the new HEAD.
|
|
105
|
+
- Bugbot clean or approved → move to the Copilot gate.
|
|
106
|
+
- Bugbot down after the poll cap → move to the Copilot gate with `bugbotDown` set.
|
|
84
107
|
|
|
85
|
-
**COPILOT** gate:
|
|
108
|
+
**COPILOT** gate (terminal external confirmation):
|
|
86
109
|
|
|
87
110
|
- Request a Copilot review on HEAD (skipping a duplicate request), then poll up
|
|
88
111
|
to the configured cap, 360 seconds apart.
|
|
@@ -104,14 +127,11 @@ tracks CONVERGE passes only and is never the cap.
|
|
|
104
127
|
Each spawned agent runs on the model and effort its role needs, so the run spends
|
|
105
128
|
the strongest model only where judgment is dense:
|
|
106
129
|
|
|
107
|
-
- **
|
|
108
|
-
and
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
- **haiku / low** — the mechanical steps: the preflight git-and-availability
|
|
113
|
-
probe, the Copilot gate, the CLEAN-audit post, and the convergence check that
|
|
114
|
-
marks the PR ready.
|
|
130
|
+
- **sonnet** — the deterministic static-sweep lens, and the verify,
|
|
131
|
+
commit, and recovery steps that clear a commit-gate or verdict rejection.
|
|
132
|
+
- **opus** — the reading lenses (code-review, bug-audit, self-review,
|
|
133
|
+
reuse), the terminal Bugbot gate, and the code-editing steps that fix findings
|
|
134
|
+
(fix-edit, conflict-edit, repair-edit, standards-edit).
|
|
115
135
|
|
|
116
136
|
## Full-diff rule
|
|
117
137
|
|
|
@@ -126,7 +146,9 @@ every condition from GitHub and marks the PR ready only when all of these hold o
|
|
|
126
146
|
the current HEAD:
|
|
127
147
|
|
|
128
148
|
1. Bugbot CI check run is completed with a success or neutral conclusion
|
|
129
|
-
(bypassed when Bugbot is
|
|
149
|
+
(bypassed when Bugbot is off for the run — the default unless
|
|
150
|
+
`CLAUDE_REVIEWS_ENABLED` lists `bugbot` — opted out via
|
|
151
|
+
`CLAUDE_REVIEWS_DISABLED`, or proved unreachable this run).
|
|
130
152
|
2. The Bugbot review body on HEAD reports no findings (checked when a Bugbot
|
|
131
153
|
review is present).
|
|
132
154
|
3. A CLEAN bugteam audit review sits on HEAD.
|
|
@@ -60,3 +60,14 @@ fails in a new way.
|
|
|
60
60
|
own. When landing a fix needs it, stop and tell the user the verified-commit
|
|
61
61
|
gate is blocking the push and that going forward needs either a `# verify-skip`
|
|
62
62
|
bypass or a switch to `/pr-converge`, then let the user decide.
|
|
63
|
+
|
|
64
|
+
- **A Copilot "down" verdict is valid only after the full poll budget.** A
|
|
65
|
+
successful review request means the review is in flight — Copilot typically
|
|
66
|
+
posts within 10–15 minutes of the request. A gate agent that returns
|
|
67
|
+
`down:true` on a partial poll misreports an in-flight review as reviewer
|
|
68
|
+
unavailability, and the run marks the PR ready moments before the review
|
|
69
|
+
lands. After a successful request the only valid gate outcomes are a
|
|
70
|
+
received review on HEAD, an out-of-usage notice, or the full poll budget
|
|
71
|
+
spent. The teardown re-checks the PR for a late-arriving Copilot review
|
|
72
|
+
whenever the gate was bypassed, and routes its findings through one more
|
|
73
|
+
fix round.
|
|
@@ -26,7 +26,13 @@ skill still runs teardown (revoke permissions, final report).
|
|
|
26
26
|
stalled HEAD. An all-stale round that makes no commit but resolves every
|
|
27
27
|
finding thread (`resolvedWithoutCommit: true` with at least one thread-bearing
|
|
28
28
|
finding) is not a stall — the run re-converges on the unchanged HEAD and
|
|
29
|
-
reaches the Copilot and convergence gates.
|
|
29
|
+
reaches the terminal Bugbot, Copilot, and convergence gates.
|
|
30
|
+
- **Static-sweep stalled** — the deterministic static sweep (`code_rules_gate.py
|
|
31
|
+
--base origin/main`, `ruff`, `mypy`, stem-matched `pytest`) raises gate or test
|
|
32
|
+
failures the fixer cannot clear on the current HEAD, so HEAD does not move. The
|
|
33
|
+
reading lenses never run on a sweep-dirty HEAD, so the run ends with a
|
|
34
|
+
static-sweep stall `blocker` naming the failure count and the stalled HEAD
|
|
35
|
+
rather than looping to the iteration cap.
|
|
30
36
|
- **Mark-ready failed** — the convergence check passes but the mark-ready step
|
|
31
37
|
cannot confirm the PR left draft state (`gh pr ready` errored, or the draft
|
|
32
38
|
re-query still reports true). The workflow does not report `converged: true`;
|
|
@@ -55,8 +61,12 @@ skill still runs teardown (revoke permissions, final report).
|
|
|
55
61
|
|
|
56
62
|
## Not a blocker (the run continues)
|
|
57
63
|
|
|
58
|
-
- **Bugbot down** —
|
|
59
|
-
|
|
64
|
+
- **Terminal Bugbot gate down or disabled** — the terminal Bugbot gate runs once
|
|
65
|
+
the internal lenses are clean. When Cursor Bugbot is off for the run (the
|
|
66
|
+
default unless `CLAUDE_REVIEWS_ENABLED` lists `bugbot`) or opted out via
|
|
67
|
+
`CLAUDE_REVIEWS_DISABLED`, the gate spawns no agent and passes to the Copilot
|
|
68
|
+
gate with `bugbotDown` set. When Bugbot is enabled but never produces a check
|
|
69
|
+
run or review after the gate poll budget, the gate returns down the same way.
|
|
60
70
|
The run continues, and the convergence check runs with `--bugbot-down` so its
|
|
61
71
|
Bugbot gate is bypassed.
|
|
62
72
|
- **Copilot down or out of quota** — when Copilot posts an out-of-usage notice on
|
|
@@ -66,16 +76,16 @@ skill still runs teardown (revoke permissions, final report).
|
|
|
66
76
|
check with `--copilot-down` (the Copilot review gate and the
|
|
67
77
|
pending-requested-reviews gate bypassed), and marks the PR ready. `copilotNote`
|
|
68
78
|
records the bypass for the final report.
|
|
69
|
-
- **A lens agent dies** — when one parallel lens returns null (a terminal
|
|
70
|
-
failure), the round proceeds on the surviving lenses. A real defect it
|
|
71
|
-
have caught surfaces in a later round or at the convergence check. A dead
|
|
72
|
-
Bugbot
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
- **Every lens agent dies (a single round)** — when all three parallel
|
|
76
|
-
return null in the same round, the round is a failure, not a clean: the
|
|
77
|
-
workflow posts no CLEAN bugteam artifact and does not advance to the
|
|
78
|
-
|
|
79
|
+
- **A lens agent dies** — when one parallel reading lens returns null (a terminal
|
|
80
|
+
agent failure), the round proceeds on the surviving lenses. A real defect it
|
|
81
|
+
would have caught surfaces in a later round or at the convergence check. A dead
|
|
82
|
+
terminal Bugbot gate agent (null result) is a retry rather than an approval, so
|
|
83
|
+
the gate re-runs on the same HEAD rather than treating a dead agent as a clean
|
|
84
|
+
Bugbot verdict.
|
|
85
|
+
- **Every lens agent dies (a single round)** — when all three parallel reading
|
|
86
|
+
lenses return null in the same round, the round is a failure, not a clean: the
|
|
87
|
+
workflow posts no CLEAN bugteam artifact and does not advance to the terminal
|
|
88
|
+
gates. It re-resolves HEAD and retries on the next round. This is a
|
|
79
89
|
no-lens-reviewed round, so consecutive occurrences are bounded by the
|
|
80
90
|
no-review-lens cap in the blockers above, not just the iteration cap.
|
|
81
91
|
|
|
@@ -6,7 +6,7 @@ Workflow scripts and report utilities for the `autoconverge` skill.
|
|
|
6
6
|
|
|
7
7
|
| File | Role |
|
|
8
8
|
|---|---|
|
|
9
|
-
| `converge.mjs` | Main convergence workflow script. Each round runs
|
|
9
|
+
| `converge.mjs` | Main convergence workflow script. Each round runs a deterministic static sweep first, then code-review, bug-audit, and self-review lenses in parallel, deduplicates findings, applies fixes, and pushes; Bugbot and Copilot then run as terminal confirmation gates before it checks convergence and marks the PR ready. Runs via the `Workflow` tool — not directly with Node. |
|
|
10
10
|
| `aggregate_runs.py` | Merges every autoconverge journal for a given PR (matched by run id) into one merged journal. Prints a JSON line with `mergedJournal`, `roundCount`, `finalSha`, and `findingCount`. |
|
|
11
11
|
| `convergence_summary.py` | Builds the convergence-summary agent prompt over the merged journal's findings. The teardown step spawns a `general-purpose` subagent on this prompt. |
|
|
12
12
|
| `render_report.py` | Builds the closing HTML insights report. Takes `--journal`, `--summary-file`, `--out`, `--pr`, `--final-sha`, and `--rounds`. Writes the HTML to `--out` and prints the output path on stdout. |
|
|
@@ -14,6 +14,7 @@ Workflow scripts and report utilities for the `autoconverge` skill.
|
|
|
14
14
|
| `converge.contract.test.mjs` | Contract tests for `converge.mjs` — verify the workflow interface and step ordering. |
|
|
15
15
|
| `converge.clean-audit.test.mjs` | Tests the clean-audit path (all lenses clean on first round). |
|
|
16
16
|
| `converge.copilot-gate.test.mjs` | Tests Copilot gate behavior (bypass on quota exhaustion). |
|
|
17
|
+
| `converge.precatch.test.mjs` | Tests the pre-catch stage: static-sweep ordering and gate coverage, the adversarial second pass, the self-review lens, the terminal Bugbot gate, the read-only/edit preamble split, and the commit-recovery cap. |
|
|
17
18
|
| `converge.fix-progress.test.mjs` | Tests fix-progress tracking across rounds. |
|
|
18
19
|
| `converge.fix-recovery.test.mjs` | Tests recovery when a fix commit fails. |
|
|
19
20
|
| `converge.run-input.test.mjs` | Tests workflow input validation. |
|
|
@@ -53,7 +53,7 @@ const {
|
|
|
53
53
|
|
|
54
54
|
function buildRunGeneralUtilityTask(convergeAgentStub) {
|
|
55
55
|
const factory = new Function(
|
|
56
|
-
'
|
|
56
|
+
'convergeReadOnlyAgent',
|
|
57
57
|
'input',
|
|
58
58
|
'CONFIG',
|
|
59
59
|
'prCoordinates',
|
|
@@ -122,7 +122,7 @@ test('nameLensResults classifies a not-spawned stub, a dead agent, and a ran len
|
|
|
122
122
|
assert.equal(namedLenses[2].status, 'ran');
|
|
123
123
|
assert.equal(namedLenses[2].report, auditReport);
|
|
124
124
|
const allLensNames = namedLenses.map((eachEntry) => eachEntry.lens);
|
|
125
|
-
assert.deepEqual(allLensNames, ['
|
|
125
|
+
assert.deepEqual(allLensNames, ['code-review', 'bug-audit', 'self-review']);
|
|
126
126
|
});
|
|
127
127
|
|
|
128
128
|
test('nameLensResults tags a down lens reported-down only with zero findings, and ran when it produced findings', () => {
|
|
@@ -145,10 +145,10 @@ test('nameLensResults tags a down lens reported-down only with zero findings, an
|
|
|
145
145
|
|
|
146
146
|
test('describeNotRunLens words each not-run status without claiming a review or asserting a poll or timeout', () => {
|
|
147
147
|
assert.match(
|
|
148
|
-
describeNotRunLens({ lens: '
|
|
148
|
+
describeNotRunLens({ lens: 'self-review', status: 'down' }),
|
|
149
149
|
/down\/disabled — did not run/,
|
|
150
150
|
);
|
|
151
|
-
const reportedDownClause = describeNotRunLens({ lens: '
|
|
151
|
+
const reportedDownClause = describeNotRunLens({ lens: 'self-review', status: 'reported-down' });
|
|
152
152
|
assert.match(reportedDownClause, /reported itself down/);
|
|
153
153
|
assert.match(reportedDownClause, /produced no review for this HEAD/);
|
|
154
154
|
assert.doesNotMatch(reportedDownClause, /poll|timeout/i);
|
|
@@ -194,7 +194,7 @@ test('the standards-only branch reaches the deferral filing without a zero-ran g
|
|
|
194
194
|
test('the all-clean zero-ran retry is inlined, registers a no-lens round, and the shared helper is gone', () => {
|
|
195
195
|
const allCleanBranch = convergeSource.slice(
|
|
196
196
|
convergeSource.indexOf('all lenses clean on'),
|
|
197
|
-
convergeSource.indexOf("if (phase === '
|
|
197
|
+
convergeSource.indexOf("if (phase === 'BUGBOT') {"),
|
|
198
198
|
);
|
|
199
199
|
assert.match(allCleanBranch, /if \(auditResult\?\.noLensRan\)/);
|
|
200
200
|
assert.match(allCleanBranch, /registerNoLensRound\(noLensRoundCausesFor\(allCleanNamedLenses\)\)/);
|
|
@@ -209,7 +209,7 @@ test('every no-lens-reviewed round registers one shared counter and every lens-r
|
|
|
209
209
|
const registerSites = loopBody.match(/registerNoLensRound\(/g) || [];
|
|
210
210
|
assert.equal(registerSites.length, 3, 'expected the preflight-no-SHA, all-lenses-dead, and no-lens-ran rounds to register');
|
|
211
211
|
const resetSites = loopBody.match(/resetNoLensRounds\(\)/g) || [];
|
|
212
|
-
assert.equal(resetSites.length,
|
|
212
|
+
assert.equal(resetSites.length, 5, 'expected a reset on the static-sweep, standards, findings, not-clean, and posted lens-ran rounds');
|
|
213
213
|
const deadBranch = convergeSource.slice(
|
|
214
214
|
convergeSource.indexOf('if (roundOutcome.allLensesDead) {'),
|
|
215
215
|
convergeSource.indexOf('const findings = roundOutcome.findings'),
|
|
@@ -554,14 +554,19 @@ test('the standards-only call site relays lens provenance, the deferred standard
|
|
|
554
554
|
assert.match(buildBody, /hardeningPrOpened: wasStandardsHardeningPrOpened/);
|
|
555
555
|
});
|
|
556
556
|
|
|
557
|
-
test('
|
|
557
|
+
test('every standardsDeferralNote call site passes the shared deferral state with no legacy argument', () => {
|
|
558
558
|
const noteCalls = convergeSource.match(/standardsNote = standardsDeferralNote\([^\n]*/g) || [];
|
|
559
|
-
assert.equal(noteCalls.length,
|
|
559
|
+
assert.equal(noteCalls.length, 3);
|
|
560
560
|
assert.equal(
|
|
561
561
|
noteCalls.filter((eachCall) => /standardsDeferralNote\(findings\.length, standardsDeferral\)/.test(eachCall)).length,
|
|
562
562
|
1,
|
|
563
563
|
'expected the converge call site to pass the standardsDeferral local built from buildStandardsDeferral()',
|
|
564
564
|
);
|
|
565
|
+
assert.equal(
|
|
566
|
+
noteCalls.filter((eachCall) => /standardsDeferralNote\(bugbotOutcome\.findings\.length, buildStandardsDeferral\(\)\)/.test(eachCall)).length,
|
|
567
|
+
1,
|
|
568
|
+
'expected the terminal-Bugbot call site to pass buildStandardsDeferral() inline',
|
|
569
|
+
);
|
|
565
570
|
assert.equal(
|
|
566
571
|
noteCalls.filter((eachCall) => /standardsDeferralNote\(copilotOutcome\.findings\.length, buildStandardsDeferral\(\)\)/.test(eachCall)).length,
|
|
567
572
|
1,
|
|
@@ -573,19 +578,10 @@ test('both standardsDeferralNote call sites pass the shared deferral state with
|
|
|
573
578
|
assert.doesNotMatch(convergeSource, /buildStandardsDeferral\(standardsOutcome\)/);
|
|
574
579
|
});
|
|
575
580
|
|
|
576
|
-
test('the parallel lens spawn marks the workflow-synthesized Bugbot down-stub as not-spawned', () => {
|
|
577
|
-
const spawnRegion = convergeSource.slice(
|
|
578
|
-
convergeSource.indexOf('const lenses = await parallel(['),
|
|
579
|
-
convergeSource.indexOf('bugbotDown = lenses[0]'),
|
|
580
|
-
);
|
|
581
|
-
assert.match(spawnRegion, /isBugbotDownPreSpawn \?/);
|
|
582
|
-
assert.match(spawnRegion, /notSpawned: true/);
|
|
583
|
-
});
|
|
584
|
-
|
|
585
581
|
test('the all-clean call site breaks with a clean-audit blocker when the post does not land', () => {
|
|
586
582
|
const branch = convergeSource.slice(
|
|
587
583
|
convergeSource.indexOf('all lenses clean on'),
|
|
588
|
-
convergeSource.indexOf("if (phase === '
|
|
584
|
+
convergeSource.indexOf("if (phase === 'BUGBOT') {"),
|
|
589
585
|
);
|
|
590
586
|
assert.match(branch, /runGeneralUtilityTask\(.*'post-clean-audit'/);
|
|
591
587
|
assert.match(branch, /if \(!auditResult\?\.posted\)/);
|
|
@@ -596,7 +592,7 @@ test('the all-clean call site breaks with a clean-audit blocker when the post do
|
|
|
596
592
|
test('the all-clean call site relays lens provenance into the post-clean-audit context without a postFindings field', () => {
|
|
597
593
|
const branch = convergeSource.slice(
|
|
598
594
|
convergeSource.indexOf('all lenses clean on'),
|
|
599
|
-
convergeSource.indexOf("if (phase === '
|
|
595
|
+
convergeSource.indexOf("if (phase === 'BUGBOT') {"),
|
|
600
596
|
);
|
|
601
597
|
assert.match(branch, /const allCleanNamedLenses = nameLensResults\(lenses\)/);
|
|
602
598
|
assert.match(branch, /lensResults: allCleanNamedLenses/);
|