claude-dev-env 1.82.0 → 1.84.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 +16 -13
- package/_shared/pr-loop/audit-contract.md +24 -12
- package/_shared/pr-loop/scripts/CLAUDE.md +1 -0
- package/_shared/pr-loop/scripts/README.md +1 -0
- package/_shared/pr-loop/scripts/_claude_permissions_common.py +16 -5
- package/_shared/pr-loop/scripts/code_rules_gate.py +2 -3
- package/_shared/pr-loop/scripts/pr_loop_shared_constants/CLAUDE.md +1 -0
- package/_shared/pr-loop/scripts/pr_loop_shared_constants/reviewer_availability_constants.py +12 -0
- package/_shared/pr-loop/scripts/pr_loop_shared_constants/terminology_sweep_constants.py +0 -2
- package/_shared/pr-loop/scripts/reviewer_availability.py +182 -0
- package/_shared/pr-loop/scripts/reviews_disabled.py +2 -0
- package/_shared/pr-loop/scripts/terminology_sweep.py +9 -33
- package/_shared/pr-loop/scripts/tests/CLAUDE.md +2 -0
- package/_shared/pr-loop/scripts/tests/test__claude_permissions_common.py +212 -0
- package/_shared/pr-loop/scripts/tests/test_agent_config_carveout.py +18 -0
- package/_shared/pr-loop/scripts/tests/test_claude_permissions_common.py +18 -0
- package/_shared/pr-loop/scripts/tests/test_code_rules_gate.py +37 -0
- package/_shared/pr-loop/scripts/tests/test_reviewer_availability.py +159 -0
- package/_shared/pr-loop/scripts/tests/test_reviewer_availability_constants.py +36 -0
- package/_shared/pr-loop/scripts/tests/test_reviews_disabled.py +14 -0
- package/_shared/pr-loop/scripts/tests/test_terminology_sweep.py +14 -4
- package/agents/clean-coder.md +3 -0
- package/audit-rubrics/category_rubrics/category-o-docstring-vs-impl-drift.md +1 -1
- package/bin/install.mjs +16 -8
- package/bin/install.test.mjs +17 -6
- package/commands/CLAUDE.md +0 -1
- package/docs/CODE_RULES.md +1 -1
- package/hooks/blocking/CLAUDE.md +2 -4
- package/hooks/blocking/code_rules_constants_config.py +164 -1
- package/hooks/blocking/code_rules_docstrings.py +428 -15
- package/hooks/blocking/code_rules_enforcer.py +33 -0
- package/hooks/blocking/code_rules_imports_logging.py +867 -1
- package/hooks/blocking/code_rules_magic_values.py +5 -0
- package/hooks/blocking/code_rules_naming_collection.py +152 -6
- package/hooks/blocking/code_rules_shared.py +34 -0
- package/hooks/blocking/code_rules_string_magic.py +68 -0
- package/hooks/blocking/duplicate_rmtree_helper_blocker.py +4 -4
- package/hooks/blocking/pre_tool_use_dispatcher.py +3 -3
- package/hooks/blocking/reviewer_spawn_gate.py +182 -0
- package/hooks/blocking/stale_comment_reference_blocker.py +267 -0
- package/hooks/blocking/state_description_blocker.py +96 -5
- package/hooks/blocking/test_code_rules_config_duplicate_path_anchor.py +132 -0
- package/hooks/blocking/test_code_rules_enforcer_cap_meta.py +2 -0
- package/hooks/blocking/test_code_rules_enforcer_docstring_delegation_summary.py +385 -0
- package/hooks/blocking/test_code_rules_enforcer_docstring_prose_wall_illustration.py +197 -0
- package/hooks/blocking/test_code_rules_enforcer_docstring_runon_sentence.py +27 -0
- package/hooks/blocking/test_code_rules_enforcer_join_separator_magic.py +67 -0
- package/hooks/blocking/test_code_rules_enforcer_module_docstring_roster.py +40 -0
- package/hooks/blocking/test_code_rules_enforcer_naive_datetime.py +213 -0
- package/hooks/blocking/test_code_rules_enforcer_referenced_underscore_loop.py +169 -0
- package/hooks/blocking/test_code_rules_enforcer_split_constants_config.py +33 -0
- package/hooks/blocking/test_code_rules_enforcer_split_shared.py +23 -0
- package/hooks/blocking/test_code_rules_js_bare_flag_return_directive.py +266 -0
- package/hooks/blocking/test_code_rules_js_sibling_return_object_key_drift.py +490 -0
- package/hooks/blocking/test_code_rules_logging_adjacent_literals.py +171 -0
- package/hooks/blocking/test_code_rules_magic_values.py +54 -0
- package/hooks/blocking/test_duplicate_rmtree_helper_blocker.py +0 -6
- package/hooks/blocking/test_pr_converge_bugteam_enforcer_state_tolerance.py +184 -0
- package/hooks/blocking/test_pre_tool_use_dispatcher.py +9 -3
- package/hooks/blocking/test_reviewer_spawn_gate.py +230 -0
- package/hooks/blocking/test_shared_stdin_adoption.py +5 -30
- package/hooks/blocking/test_stale_comment_reference_blocker.py +236 -0
- package/hooks/blocking/test_state_description_blocker.py +135 -0
- package/hooks/hooks.json +5 -0
- package/hooks/hooks_constants/CLAUDE.md +3 -4
- package/hooks/hooks_constants/blocking_check_limits.py +46 -0
- package/hooks/hooks_constants/code_rules_enforcer_constants.py +41 -0
- package/hooks/hooks_constants/code_rules_path_utils_constants.py +1 -1
- package/hooks/hooks_constants/duplicate_rmtree_helper_blocker_constants.py +0 -1
- package/hooks/hooks_constants/post_tool_use_dispatcher_constants.py +0 -5
- package/hooks/hooks_constants/pre_tool_use_dispatcher_constants.py +4 -0
- package/hooks/hooks_constants/reviewer_spawn_gate_constants.py +41 -0
- package/hooks/hooks_constants/stale_comment_reference_blocker_constants.py +76 -0
- package/hooks/hooks_constants/state_description_blocker_constants.py +8 -0
- package/hooks/validation/post_tool_use_dispatcher.py +1 -1
- package/hooks/validation/test_post_tool_use_dispatcher.py +51 -35
- package/hooks/workflow/CLAUDE.md +2 -8
- package/package.json +1 -1
- package/rules/CLAUDE.md +5 -2
- package/rules/claude-md-orphan-file.md +5 -0
- package/rules/docstring-prose-matches-implementation.md +10 -1
- package/rules/env-var-table-code-drift.md +5 -0
- package/rules/es-exe-file-search.md +17 -0
- package/rules/no-historical-clutter.md +12 -1
- package/rules/orphan-css-class.md +5 -0
- package/rules/package-inventory-stale-entry.md +10 -0
- package/rules/paired-test-coverage.md +5 -0
- package/rules/plain-illustrative-docstrings.md +40 -1
- package/rules/verify-before-asking.md +7 -0
- package/rules/verify-runtime-state.md +40 -0
- package/rules/windows-filesystem-safe.md +8 -0
- package/rules/workers-done-before-complete.md +33 -0
- package/rules/workflow-substitution-slots.md +5 -0
- package/skills/CLAUDE.md +7 -2
- package/skills/autoconverge/SKILL.md +48 -61
- package/skills/autoconverge/reference/closing-report.md +6 -6
- package/skills/autoconverge/reference/convergence.md +17 -15
- package/skills/autoconverge/reference/gotchas.md +6 -3
- package/skills/autoconverge/workflow/autoconverge_report_constants/render_report_constants.py +2 -9
- package/skills/autoconverge/workflow/converge.contract.test.mjs +153 -10
- package/skills/autoconverge/workflow/converge.copilot-gate.test.mjs +55 -19
- package/skills/autoconverge/workflow/converge.merge-conflict.test.mjs +16 -9
- package/skills/autoconverge/workflow/converge.mjs +167 -106
- package/skills/autoconverge/workflow/render_report.py +7 -11
- package/skills/bugteam/CLAUDE.md +1 -1
- package/skills/bugteam/PROMPTS.md +7 -6
- package/skills/bugteam/SKILL.md +25 -72
- package/skills/bugteam/reference/CLAUDE.md +1 -3
- package/skills/bugteam/reference/README.md +1 -1
- package/skills/bugteam/reference/audit-and-teammates.md +1 -1
- package/skills/bugteam/reference/obstacles/fix-publish-summary.md +1 -1
- package/skills/bugteam/reference/team-setup.md +8 -7
- package/skills/bugteam/scripts/CLAUDE.md +0 -6
- package/skills/bugteam/scripts/README.md +0 -4
- package/skills/bugteam/scripts/bugteam_scripts_constants/CLAUDE.md +0 -1
- package/skills/code/SKILL.md +2 -0
- package/skills/copilot-review/CLAUDE.md +1 -1
- package/skills/copilot-review/SKILL.md +25 -23
- package/skills/everything-search/SKILL.md +5 -0
- package/skills/findbugs/CLAUDE.md +2 -2
- package/skills/findbugs/SKILL.md +22 -83
- package/skills/fixbugs/SKILL.md +2 -4
- package/skills/log-audit/CLAUDE.md +20 -0
- package/skills/log-audit/SKILL.md +68 -0
- package/skills/log-audit/reference/CLAUDE.md +9 -0
- package/skills/log-audit/reference/charter.md +52 -0
- package/skills/log-audit/scripts/CLAUDE.md +27 -0
- package/skills/log-audit/scripts/cluster_recurrences.py +261 -0
- package/skills/log-audit/scripts/collect_log_window.py +199 -0
- package/skills/log-audit/scripts/log_audit_constants/CLAUDE.md +12 -0
- package/skills/log-audit/scripts/log_audit_constants/cluster_recurrences_constants.py +23 -0
- package/skills/log-audit/scripts/log_audit_constants/collect_log_window_constants.py +24 -0
- package/skills/log-audit/scripts/log_audit_constants/mine_copilot_findings_constants.py +49 -0
- package/skills/log-audit/scripts/mine_copilot_findings.py +302 -0
- package/skills/log-audit/scripts/test_cluster_recurrences.py +160 -0
- package/skills/log-audit/scripts/test_collect_log_window.py +111 -0
- package/skills/log-audit/scripts/test_mine_copilot_findings.py +126 -0
- package/skills/monitor-open-prs/SKILL.md +2 -2
- package/skills/post-audit-findings/SKILL.md +84 -0
- package/skills/pr-converge/CLAUDE.md +2 -0
- package/skills/pr-converge/SKILL.md +72 -59
- package/skills/pr-converge/reference/CLAUDE.md +1 -1
- package/skills/pr-converge/reference/convergence-gates.md +16 -19
- package/skills/pr-converge/reference/examples.md +5 -5
- package/skills/pr-converge/reference/fix-protocol.md +16 -43
- package/skills/pr-converge/reference/obstacles/fix-publish-summary.md +1 -1
- package/skills/pr-converge/reference/per-tick.md +24 -45
- package/skills/pr-converge/reference/state-schema.md +15 -0
- package/skills/pr-converge/scripts/README.md +3 -5
- package/skills/pr-fix-protocol/SKILL.md +70 -0
- package/skills/pr-loop-lifecycle/SKILL.md +73 -0
- package/skills/{bugteam → pr-loop-lifecycle}/reference/teardown-publish-permissions.md +22 -24
- package/skills/pr-scope-resolve/SKILL.md +48 -0
- package/skills/qbug/CLAUDE.md +4 -4
- package/skills/qbug/SKILL.md +46 -144
- package/skills/qbug/test_qbug_skill_audit_schema.py +2 -2
- package/skills/qbug/test_qbug_skill_post_fix_audit.py +1 -1
- package/skills/reviewer-gates/SKILL.md +96 -0
- package/skills/session-log/CLAUDE.md +7 -7
- package/skills/session-log/SKILL.md +27 -44
- package/skills/test_markdown_link_integrity.py +103 -0
- package/commands/doc-gist.md +0 -16
- package/hooks/blocking/_md_to_html_blocker_test_support.py +0 -65
- package/hooks/blocking/conftest.py +0 -30
- package/hooks/blocking/md_path_exemptions.py +0 -224
- package/hooks/blocking/md_to_html_blocker.py +0 -155
- package/hooks/blocking/test_md_to_html_blocker_exemptions.py +0 -434
- package/hooks/blocking/test_md_to_html_blocker_extensions.py +0 -157
- package/hooks/blocking/test_md_to_html_blocker_path_resolution.py +0 -336
- package/hooks/hooks_constants/doc_gist_auto_publish_constants.py +0 -18
- package/hooks/hooks_constants/html_companion_constants.py +0 -20
- package/hooks/hooks_constants/md_to_html_blocker_constants.py +0 -76
- package/hooks/hooks_constants/test_md_to_html_blocker_constants.py +0 -125
- package/hooks/workflow/doc_gist_auto_publish.py +0 -144
- package/hooks/workflow/md_to_html_companion.py +0 -358
- package/hooks/workflow/test_doc_gist_auto_publish.py +0 -117
- package/hooks/workflow/test_md_to_html_companion.py +0 -613
- package/skills/bugteam/reference/audit-contract.md +0 -163
- package/skills/bugteam/scripts/_bugteam_permissions_common.py +0 -455
- package/skills/bugteam/scripts/bugteam_scripts_constants/claude_permissions_common_constants.py +0 -69
- package/skills/bugteam/scripts/grant_project_claude_permissions.py +0 -280
- package/skills/bugteam/scripts/revoke_project_claude_permissions.py +0 -266
- package/skills/bugteam/scripts/test__bugteam_permissions_common.py +0 -160
- package/skills/bugteam/scripts/test_agent_config_carveout.py +0 -356
- package/skills/bugteam/scripts/test_bugteam_permissions_common.py +0 -140
- package/skills/doc-gist/CLAUDE.md +0 -25
- package/skills/doc-gist/SKILL.md +0 -97
- package/skills/doc-gist/references/CLAUDE.md +0 -9
- package/skills/doc-gist/references/examples/01-exploration-code-approaches.html +0 -453
- package/skills/doc-gist/references/examples/02-exploration-visual-designs.html +0 -515
- package/skills/doc-gist/references/examples/03-code-review-pr.html +0 -638
- package/skills/doc-gist/references/examples/04-code-understanding.html +0 -491
- package/skills/doc-gist/references/examples/05-design-system.html +0 -629
- package/skills/doc-gist/references/examples/06-component-variants.html +0 -605
- package/skills/doc-gist/references/examples/07-prototype-animation.html +0 -455
- package/skills/doc-gist/references/examples/08-prototype-interaction.html +0 -396
- package/skills/doc-gist/references/examples/09-slide-deck.html +0 -592
- package/skills/doc-gist/references/examples/10-svg-illustrations.html +0 -492
- package/skills/doc-gist/references/examples/11-status-report.html +0 -528
- package/skills/doc-gist/references/examples/12-incident-report.html +0 -596
- package/skills/doc-gist/references/examples/13-flowchart-diagram.html +0 -395
- package/skills/doc-gist/references/examples/14-research-feature-explainer.html +0 -381
- package/skills/doc-gist/references/examples/15-research-concept-explainer.html +0 -368
- package/skills/doc-gist/references/examples/16-implementation-plan.html +0 -702
- package/skills/doc-gist/references/examples/17-pr-writeup.html +0 -595
- package/skills/doc-gist/references/examples/18-editor-triage-board.html +0 -573
- package/skills/doc-gist/references/examples/19-editor-feature-flags.html +0 -663
- package/skills/doc-gist/references/examples/20-editor-prompt-tuner.html +0 -722
- package/skills/doc-gist/references/examples/21-decision-signoff.html +0 -546
- package/skills/doc-gist/references/examples/CLAUDE.md +0 -25
- package/skills/doc-gist/references/examples/README.md +0 -5
- package/skills/doc-gist/scripts/CLAUDE.md +0 -27
- package/skills/doc-gist/scripts/doc_gist_scripts_constants/CLAUDE.md +0 -10
- package/skills/doc-gist/scripts/doc_gist_scripts_constants/gist_upload_constants.py +0 -16
- package/skills/doc-gist/scripts/gist_upload.py +0 -177
- package/skills/doc-gist/scripts/test_gist_upload.py +0 -51
- /package/skills/{doc-gist/scripts/doc_gist_scripts_constants → log-audit/scripts/log_audit_constants}/__init__.py +0 -0
|
@@ -18,9 +18,10 @@ function functionBody(functionName) {
|
|
|
18
18
|
const productionModule = new Function(
|
|
19
19
|
`${functionBody('classifyCopilotOutcome')}\n` +
|
|
20
20
|
`${functionBody('resolveCopilotDown')}\n` +
|
|
21
|
-
'
|
|
21
|
+
`${functionBody('resolveReviewerDown')}\n` +
|
|
22
|
+
'return { classifyCopilotOutcome, resolveCopilotDown, resolveReviewerDown };',
|
|
22
23
|
)();
|
|
23
|
-
const { classifyCopilotOutcome, resolveCopilotDown } = productionModule;
|
|
24
|
+
const { classifyCopilotOutcome, resolveCopilotDown, resolveReviewerDown } = productionModule;
|
|
24
25
|
|
|
25
26
|
function copilotResult(overrides) {
|
|
26
27
|
return {
|
|
@@ -72,7 +73,7 @@ test('Copilot findings route to a fix when Copilot is reachable and not down', (
|
|
|
72
73
|
|
|
73
74
|
test('COPILOT_SCHEMA carries a required down field', () => {
|
|
74
75
|
const schemaStart = convergeSource.indexOf('const COPILOT_SCHEMA =');
|
|
75
|
-
const schemaEnd = convergeSource.indexOf('const
|
|
76
|
+
const schemaEnd = convergeSource.indexOf('const REVIEWER_AVAILABILITY_SCHEMA =');
|
|
76
77
|
assert.notEqual(schemaStart, -1, 'expected COPILOT_SCHEMA to exist');
|
|
77
78
|
const schemaSource = convergeSource.slice(schemaStart, schemaEnd);
|
|
78
79
|
assert.match(schemaSource, /down:\s*\{\s*type:\s*'boolean'/);
|
|
@@ -281,7 +282,7 @@ test('the mark-ready task in runGeneralUtilityTask opts the unflagged convergenc
|
|
|
281
282
|
);
|
|
282
283
|
});
|
|
283
284
|
|
|
284
|
-
test('the COPILOT phase short-circuits on
|
|
285
|
+
test('the COPILOT phase short-circuits on the unified reviewer-down gate before spawning the gate agent', () => {
|
|
285
286
|
const copilotPhaseStart = convergeSource.indexOf("if (phase === 'COPILOT') {");
|
|
286
287
|
assert.notEqual(copilotPhaseStart, -1, 'expected a COPILOT phase block');
|
|
287
288
|
const gateCallIndex = convergeSource.indexOf('await runCopilotGate(head)', copilotPhaseStart);
|
|
@@ -289,8 +290,8 @@ test('the COPILOT phase short-circuits on input.copilotDisabled before spawning
|
|
|
289
290
|
const beforeGate = convergeSource.slice(copilotPhaseStart, gateCallIndex);
|
|
290
291
|
assert.match(
|
|
291
292
|
beforeGate,
|
|
292
|
-
/if \(input\.copilotDisabled\)/,
|
|
293
|
-
'expected the
|
|
293
|
+
/if \(resolveReviewerDown\(reviewerAvailability\?\.copilot, input\.copilotDisabled \|\| false\)\)/,
|
|
294
|
+
'expected the unified resolveReviewerDown gate — fed by the reviewer-availability probe or the input override — to guard the COPILOT phase before any gate agent spawns',
|
|
294
295
|
);
|
|
295
296
|
assert.match(beforeGate, /copilotDown = true/, 'expected the bypass to mark copilotDown');
|
|
296
297
|
assert.match(beforeGate, /copilotNote =/, 'expected the bypass to set a copilotNote');
|
|
@@ -298,6 +299,16 @@ test('the COPILOT phase short-circuits on input.copilotDisabled before spawning
|
|
|
298
299
|
assert.match(beforeGate, /continue/, 'expected the bypass to continue without spawning the gate agent');
|
|
299
300
|
});
|
|
300
301
|
|
|
302
|
+
test('the COPILOT phase pre-spawn gate skips the gate agent via input.copilotDisabled with no probe entry', () => {
|
|
303
|
+
const isDownFromInput = resolveReviewerDown(undefined, true);
|
|
304
|
+
assert.equal(isDownFromInput, true, 'expected the input override alone to report Copilot down with no probe entry');
|
|
305
|
+
});
|
|
306
|
+
|
|
307
|
+
test('the COPILOT phase pre-spawn gate skips the gate agent via a probe down entry with no input override', () => {
|
|
308
|
+
const isDownFromProbe = resolveReviewerDown({ down: true, reason: 'copilot-quota: out of premium-interaction quota' }, false);
|
|
309
|
+
assert.equal(isDownFromProbe, true, 'expected a probe entry reporting down to skip the gate agent with no input override set');
|
|
310
|
+
});
|
|
311
|
+
|
|
301
312
|
test('copilotDown initializes from input.copilotDisabled so the pre-check decision carries into the loop', () => {
|
|
302
313
|
assert.match(
|
|
303
314
|
convergeSource,
|
|
@@ -308,8 +319,11 @@ test('copilotDown initializes from input.copilotDisabled so the pre-check decisi
|
|
|
308
319
|
|
|
309
320
|
test('a copilotDisabled run reaches FINALIZE with --copilot-down', () => {
|
|
310
321
|
const copilotPhaseStart = convergeSource.indexOf("if (phase === 'COPILOT') {");
|
|
311
|
-
const bypassStart = convergeSource.indexOf(
|
|
312
|
-
|
|
322
|
+
const bypassStart = convergeSource.indexOf(
|
|
323
|
+
'if (resolveReviewerDown(reviewerAvailability?.copilot, input.copilotDisabled || false))',
|
|
324
|
+
copilotPhaseStart,
|
|
325
|
+
);
|
|
326
|
+
assert.notEqual(bypassStart, -1, 'expected the unified resolveReviewerDown bypass in the COPILOT phase');
|
|
313
327
|
const bypassBlock = convergeSource.slice(bypassStart, bypassStart + 800);
|
|
314
328
|
assert.match(bypassBlock, /copilotDown = true/, 'expected the bypass to set copilotDown');
|
|
315
329
|
assert.match(bypassBlock, /phase = 'FINALIZE'/, 'expected the bypass to advance to FINALIZE');
|
|
@@ -373,7 +387,7 @@ test('openStandardsFollowUpOnce gates spawnStandardsFollowUp behind the run-once
|
|
|
373
387
|
);
|
|
374
388
|
assert.match(
|
|
375
389
|
onceBody,
|
|
376
|
-
/await spawnStandardsFollowUp\(head, findings, sourceLabel, wasStandardsHardeningPrOpened\)/,
|
|
390
|
+
/await spawnStandardsFollowUp\(head, findings, sourceLabel, wasStandardsHardeningPrOpened, deferredReviewerFlags\)/,
|
|
377
391
|
'expected the helper to pass the remembered hardening state into the spawn so an already-opened PR is never re-opened',
|
|
378
392
|
);
|
|
379
393
|
assert.match(
|
|
@@ -511,8 +525,8 @@ test('a second standards-only round never re-opens a hardening PR after the firs
|
|
|
511
525
|
};
|
|
512
526
|
const runtime = loadStandardsFollowUpRuntime(recordedCalls, issueFailedHardeningStaged);
|
|
513
527
|
|
|
514
|
-
const firstRoundHardeningPr = await runtime.openStandardsFollowUpOnce('sha1', [{ file: 'a.py', line: 1 }], 'converge-round');
|
|
515
|
-
const secondRoundHardeningPr = await runtime.openStandardsFollowUpOnce('sha1', [{ file: 'a.py', line: 1 }], 'copilot');
|
|
528
|
+
const firstRoundHardeningPr = await runtime.openStandardsFollowUpOnce('sha1', [{ file: 'a.py', line: 1 }], 'converge-round', { copilotDisabled: false, bugbotDisabled: false });
|
|
529
|
+
const secondRoundHardeningPr = await runtime.openStandardsFollowUpOnce('sha1', [{ file: 'a.py', line: 1 }], 'copilot', { copilotDisabled: false, bugbotDisabled: false });
|
|
516
530
|
|
|
517
531
|
const hardeningCommitCalls = recordedCalls.filter((call) => call.task === 'hardening-commit').length;
|
|
518
532
|
assert.equal(
|
|
@@ -545,8 +559,8 @@ test('a hardening-commit that opens a PR but returns an unparseable URL still la
|
|
|
545
559
|
const unparseableUrlHardeningCommitResult = { hardeningPrUrl: 'draft-hardening-pr-opened', summary: 'opened' };
|
|
546
560
|
const runtime = loadStandardsFollowUpRuntime(recordedCalls, issueFailedHardeningStaged, unparseableUrlHardeningCommitResult);
|
|
547
561
|
|
|
548
|
-
const firstRoundHardeningPr = await runtime.openStandardsFollowUpOnce('sha1', [{ file: 'a.py', line: 1 }], 'converge-round');
|
|
549
|
-
const secondRoundHardeningPr = await runtime.openStandardsFollowUpOnce('sha1', [{ file: 'a.py', line: 1 }], 'copilot');
|
|
562
|
+
const firstRoundHardeningPr = await runtime.openStandardsFollowUpOnce('sha1', [{ file: 'a.py', line: 1 }], 'converge-round', { copilotDisabled: false, bugbotDisabled: false });
|
|
563
|
+
const secondRoundHardeningPr = await runtime.openStandardsFollowUpOnce('sha1', [{ file: 'a.py', line: 1 }], 'copilot', { copilotDisabled: false, bugbotDisabled: false });
|
|
550
564
|
|
|
551
565
|
const hardeningCommitCalls = recordedCalls.filter((call) => call.task === 'hardening-commit').length;
|
|
552
566
|
assert.equal(
|
|
@@ -575,8 +589,8 @@ test('a hardening-commit that opens no PR (empty hardeningPrUrl) leaves the run-
|
|
|
575
589
|
const noPrHardeningCommitResult = { hardeningPrUrl: '', summary: 'no PR opened' };
|
|
576
590
|
const runtime = loadStandardsFollowUpRuntime(recordedCalls, issueFailedHardeningStaged, noPrHardeningCommitResult);
|
|
577
591
|
|
|
578
|
-
const firstRoundHardeningPr = await runtime.openStandardsFollowUpOnce('sha1', [{ file: 'a.py', line: 1 }], 'converge-round');
|
|
579
|
-
const secondRoundHardeningPr = await runtime.openStandardsFollowUpOnce('sha1', [{ file: 'a.py', line: 1 }], 'copilot');
|
|
592
|
+
const firstRoundHardeningPr = await runtime.openStandardsFollowUpOnce('sha1', [{ file: 'a.py', line: 1 }], 'converge-round', { copilotDisabled: false, bugbotDisabled: false });
|
|
593
|
+
const secondRoundHardeningPr = await runtime.openStandardsFollowUpOnce('sha1', [{ file: 'a.py', line: 1 }], 'copilot', { copilotDisabled: false, bugbotDisabled: false });
|
|
580
594
|
|
|
581
595
|
const hardeningCommitCalls = recordedCalls.filter((call) => call.task === 'hardening-commit').length;
|
|
582
596
|
assert.equal(
|
|
@@ -603,8 +617,8 @@ test('a later standards-only round resolves its own review threads after the fol
|
|
|
603
617
|
};
|
|
604
618
|
const runtime = loadStandardsFollowUpRuntime(recordedCalls, issueFiledNoHardening);
|
|
605
619
|
|
|
606
|
-
await runtime.openStandardsFollowUpOnce('sha1', [{ file: 'a.py', line: 1, replyToCommentId: null }], 'converge-round');
|
|
607
|
-
await runtime.openStandardsFollowUpOnce('sha1', [{ file: 'b.py', line: 2, replyToCommentId: 42 }], 'copilot');
|
|
620
|
+
await runtime.openStandardsFollowUpOnce('sha1', [{ file: 'a.py', line: 1, replyToCommentId: null }], 'converge-round', { copilotDisabled: false, bugbotDisabled: false });
|
|
621
|
+
await runtime.openStandardsFollowUpOnce('sha1', [{ file: 'b.py', line: 2, replyToCommentId: 42 }], 'copilot', { copilotDisabled: false, bugbotDisabled: false });
|
|
608
622
|
|
|
609
623
|
const standardsEditCalls = recordedCalls.filter((call) => call.task === 'standards-edit');
|
|
610
624
|
assert.equal(standardsEditCalls.length, 1, 'expected the follow-up issue to be filed exactly once across the run');
|
|
@@ -633,8 +647,8 @@ test('a reuse-path standards round carrying no review threads spawns no thread-r
|
|
|
633
647
|
};
|
|
634
648
|
const runtime = loadStandardsFollowUpRuntime(recordedCalls, issueFiledNoHardening);
|
|
635
649
|
|
|
636
|
-
await runtime.openStandardsFollowUpOnce('sha1', [{ file: 'a.py', line: 1, replyToCommentId: null }], 'converge-round');
|
|
637
|
-
await runtime.openStandardsFollowUpOnce('sha1', [{ file: 'b.py', line: 2, replyToCommentId: null }], 'copilot');
|
|
650
|
+
await runtime.openStandardsFollowUpOnce('sha1', [{ file: 'a.py', line: 1, replyToCommentId: null }], 'converge-round', { copilotDisabled: false, bugbotDisabled: false });
|
|
651
|
+
await runtime.openStandardsFollowUpOnce('sha1', [{ file: 'b.py', line: 2, replyToCommentId: null }], 'copilot', { copilotDisabled: false, bugbotDisabled: false });
|
|
638
652
|
|
|
639
653
|
const resolveCalls = recordedCalls.filter((call) => call.task === 'standards-resolve-threads');
|
|
640
654
|
assert.equal(
|
|
@@ -644,3 +658,25 @@ test('a reuse-path standards round carrying no review threads spawns no thread-r
|
|
|
644
658
|
);
|
|
645
659
|
});
|
|
646
660
|
|
|
661
|
+
test('resolveReviewerDown is the single reviewer-down gate; resolveBugbotDown no longer exists', () => {
|
|
662
|
+
assert.doesNotMatch(
|
|
663
|
+
convergeSource,
|
|
664
|
+
/function resolveBugbotDown\(/,
|
|
665
|
+
'expected resolveBugbotDown to be removed in favor of the shared resolveReviewerDown gate',
|
|
666
|
+
);
|
|
667
|
+
assert.match(convergeSource, /function resolveReviewerDown\(/, 'expected the shared resolveReviewerDown gate to exist');
|
|
668
|
+
});
|
|
669
|
+
|
|
670
|
+
test('resolveReviewerDown reports down when the input override is set, even with an available probe entry', () => {
|
|
671
|
+
assert.equal(resolveReviewerDown({ down: false, reason: 'available' }, true), true);
|
|
672
|
+
});
|
|
673
|
+
|
|
674
|
+
test('resolveReviewerDown reports available (fail-open) when the probe entry is missing and no input override is set', () => {
|
|
675
|
+
assert.equal(resolveReviewerDown(null, false), false);
|
|
676
|
+
assert.equal(resolveReviewerDown(undefined, false), false);
|
|
677
|
+
});
|
|
678
|
+
|
|
679
|
+
test('resolveReviewerDown reports available when the probe entry explicitly reports available', () => {
|
|
680
|
+
assert.equal(resolveReviewerDown({ down: false, reason: 'available' }, false), false);
|
|
681
|
+
});
|
|
682
|
+
|
|
@@ -39,7 +39,7 @@ test('the git agent handles merge-conflict checks with a Monitor-based poll', ()
|
|
|
39
39
|
/do not edit, commit, push, or rebase|read only/i,
|
|
40
40
|
'expected the git agent merge check to be read-only',
|
|
41
41
|
);
|
|
42
|
-
assert.match(gitBody, /
|
|
42
|
+
assert.match(gitBody, /PREFLIGHT_GIT_SCHEMA/, 'expected the git agent to return PREFLIGHT_GIT_SCHEMA');
|
|
43
43
|
assert.match(gitBody, /Monitor tool/, 'expected a Monitor-based poll delay, not a foreground sleep');
|
|
44
44
|
});
|
|
45
45
|
|
|
@@ -53,31 +53,38 @@ test('runCodeEditorTask conflict-edit path rebases onto origin/main and makes no
|
|
|
53
53
|
);
|
|
54
54
|
});
|
|
55
55
|
|
|
56
|
-
test('resolveMergeConflicts runs
|
|
56
|
+
test('resolveMergeConflicts runs edit -> verify -> commit and gates the push on the verdict', () => {
|
|
57
57
|
const body = functionBody('resolveMergeConflicts');
|
|
58
|
-
const checkIndex = body.indexOf("runGitTask('check-merge-conflicts'");
|
|
59
58
|
const editIndex = body.indexOf("runCodeEditorTask('conflict-edit'");
|
|
60
59
|
const verifyIndex = body.indexOf('runVerifierTask(');
|
|
61
60
|
const commitIndex = body.indexOf('commitWithRecovery(');
|
|
62
|
-
assert.notEqual(checkIndex, -1, 'expected the conflict check to run');
|
|
63
61
|
assert.notEqual(editIndex, -1, 'expected the edit step to run');
|
|
64
62
|
assert.notEqual(verifyIndex, -1, 'expected the verify step to run');
|
|
65
63
|
assert.notEqual(commitIndex, -1, 'expected the commit step to run');
|
|
66
64
|
assert.ok(
|
|
67
|
-
|
|
68
|
-
'expected the order
|
|
65
|
+
editIndex < verifyIndex && verifyIndex < commitIndex,
|
|
66
|
+
'expected the order edit -> verify -> commit',
|
|
69
67
|
);
|
|
70
68
|
assert.match(body, /verdictPassed\(/, 'expected the verifier verdict to gate the force-push');
|
|
69
|
+
assert.doesNotMatch(
|
|
70
|
+
body,
|
|
71
|
+
/runGitTask\(/,
|
|
72
|
+
'expected the conflict decision to come from the merged preflight-git probe, with no mergeability agent spawned here',
|
|
73
|
+
);
|
|
71
74
|
});
|
|
72
75
|
|
|
73
|
-
test('resolveMergeConflicts rebases only when the
|
|
76
|
+
test('resolveMergeConflicts rebases only when the caller-supplied preflight decision reports a conflict', () => {
|
|
74
77
|
const body = functionBody('resolveMergeConflicts');
|
|
75
|
-
assert.match(body, /isMergeConflicting\(/, 'expected the orchestrator to branch on the conflict decision');
|
|
76
78
|
assert.match(
|
|
77
79
|
body,
|
|
78
|
-
/if \(!
|
|
80
|
+
/if \(!isConflicting\) return head/,
|
|
79
81
|
'expected a clean PR to return the unchanged HEAD without rebasing',
|
|
80
82
|
);
|
|
83
|
+
assert.match(
|
|
84
|
+
convergeSource,
|
|
85
|
+
/resolveMergeConflicts\(preflight\.sha, isMergeConflicting\(preflight\)\)/,
|
|
86
|
+
'expected the call site to derive the conflict decision from the merged preflight-git result',
|
|
87
|
+
);
|
|
81
88
|
});
|
|
82
89
|
|
|
83
90
|
test('the merge-conflict pre-flight runs once before the round loop, ahead of the parallel bug-check lenses', () => {
|