dev-loops 0.2.2 → 0.2.3

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.
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "dev-loops",
3
- "version": "0.2.2",
3
+ "version": "0.2.3",
4
4
  "description": "Agent-harness-agnostic dev-loop: agents, skills, and hooks for GitHub/Copilot-driven development loops.",
5
5
  "author": {
6
6
  "name": "Manuel Fittko",
@@ -225,6 +225,7 @@ When unresolved feedback exists, use a narrow follow-up loop:
225
225
  - if the refreshed snapshot reports unresolved threads, re-enter the reply/resolve loop for the missed threads
226
226
  12. only after GitHub-side reply/resolve work is done for the addressed threads and the refreshed thread snapshot proves zero unresolved threads remain, decide whether another Copilot pass is desired
227
227
  - resolve the review-round cap from config via `resolveRefinementConfig(config, "maxCopilotRounds")` from `@dev-loops/core/config`; default config ships `maxCopilotRounds: 5`
228
+ - **Opt out entirely:** `maxCopilotRounds: 0` disables the external Copilot review gate for the repo — the loop runs `draft_gate → pre_approval_gate` with the local harness only, never requesting or waiting on Copilot. Use this when the repo has no Copilot reviewer configured or prefers local-harness-only review.
228
229
  - use the completed Copilot review-round count from `detect-copilot-loop-state.mjs` / `copilot-pr-handoff.mjs` as the current PR's review-round count
229
230
  - if completed review rounds have reached the maximum (default: 5), do **not** re-request Copilot review
230
231
  - when the round limit is reached **and** the refreshed thread snapshot proves zero unresolved threads **and** current-head CI is green or credibly green, treat that clean state as eligible for `pre_approval_gate` fallback instead of deadlocking on another Copilot rerequest
package/CHANGELOG.md CHANGED
@@ -2,6 +2,19 @@
2
2
 
3
3
  All notable changes to this project will be documented in this file.
4
4
 
5
+ ## 0.2.3
6
+
7
+ ### Added
8
+
9
+ - **Opt out of the Copilot review gate via `refinement.maxCopilotRounds: 0`** (#832). For repos
10
+ without a Copilot reviewer configured (or that prefer local-harness-only review), setting
11
+ `maxCopilotRounds: 0` disables the external Copilot review cycle entirely — the loop runs
12
+ `draft_gate → pre_approval_gate` with no Copilot request or wait. The config schema now accepts
13
+ `0` (`nonnegative`; negative still rejected); `evaluatePrGateCoordination` routes `0` through the
14
+ existing `internal_only` path, `shouldGuardCopilotReviewRequest` never forces a request at `0`,
15
+ and the watch-cycle handoff (`copilot-pr-handoff`) skips the request too. Default (`5`) unchanged.
16
+ Documented in the README, extension config docs, and the `copilot-pr-followup` skill.
17
+
5
18
  ## 0.2.2
6
19
 
7
20
  ### Fixed
package/README.md CHANGED
@@ -193,7 +193,7 @@ npx dev-loops gates # see what reviewers will check
193
193
  Key surfaces:
194
194
  - **Gate angles** — which review lenses run at draft and pre-approval gates
195
195
  - **Persona prompts** — focused instructions per angle (DRY, KISS, YAGNI, SRP, SoC, and more)
196
- - **Refinement** — fan-out count and mode for parallel review variants
196
+ - **Refinement** — fan-out count and mode for parallel review variants; `refinement.maxCopilotRounds` caps Copilot re-review rounds (default `5`), and **`maxCopilotRounds: 0` disables the Copilot review gate entirely** for local-harness-only review (`draft_gate → pre_approval_gate`, no Copilot) — useful when the repo has no Copilot reviewer configured
197
197
  - **Autonomy** — which gates require operator confirmation
198
198
  - **Workflow defaults** — retrospective enforcement, draft-first posture, dev-mode policy
199
199
 
@@ -133,7 +133,9 @@ personas:
133
133
 
134
134
  # Override gate requirements
135
135
  refinement:
136
- fanOut: 5 # run 5 parallel review variants instead of 3
136
+ fanOut: 5 # run 5 parallel review variants instead of 3
137
+ maxCopilotRounds: 0 # 0 disables the Copilot review gate entirely (local-harness-only
138
+ # review: draft_gate → pre_approval_gate, no Copilot). Default: 5.
137
139
 
138
140
  autonomy:
139
141
  stopAt:
package/package.json CHANGED
@@ -68,7 +68,7 @@
68
68
  },
69
69
  "dependencies": {
70
70
  "mermaid": "11.15.0",
71
- "@dev-loops/core": "^0.2.2"
71
+ "@dev-loops/core": "^0.2.3"
72
72
  },
73
73
  "repository": {
74
74
  "type": "git",
@@ -78,7 +78,7 @@
78
78
  "url": "https://github.com/mfittko/dev-loops/issues"
79
79
  },
80
80
  "homepage": "https://github.com/mfittko/dev-loops#readme",
81
- "version": "0.2.2",
81
+ "version": "0.2.3",
82
82
  "files": [
83
83
  "cli/",
84
84
  "lib/",
@@ -366,12 +366,31 @@ export async function runHandoff(options, { env = process.env, ghCommand = "gh"
366
366
  // Detect internal tooling PRs — suppress Copilot review request step entirely.
367
367
  // Internal-only PRs (scripts/docs/tests/config) skip the request, not just the wait.
368
368
  let internalOnlySkipCopilot = false;
369
- // Skip internal detection in sequential stub/test mode to avoid consuming stub entries.
370
- // Claims-mode stubs handle interleaved calls; detection runs normally.
371
- if (!env.GH_SEQUENCE_PATH || env.GH_STUB_MODE === "claims") {
372
- if (options.watchStatus === undefined &&
369
+ // Config opt-out (#832): maxCopilotRounds: 0 disables the external Copilot review
370
+ // gate for the repo (local-harness-only review). Treat it like an internal-only PR
371
+ // skip the request, not just the wait — regardless of stub/sequence mode. This
372
+ // mirrors the gate-coordination side, which routes maxCopilotRounds: 0 to internal_only.
373
+ if (refinementConfig?.maxCopilotRounds === 0 &&
374
+ options.watchStatus === undefined &&
373
375
  (interpretation.state === STATE.PR_READY_NO_FEEDBACK ||
374
376
  interpretation.state === STATE.READY_TO_REREQUEST_REVIEW)) {
377
+ internalOnlySkipCopilot = true;
378
+ interpretation = {
379
+ ...interpretation,
380
+ state: STATE.INTERNAL_TOOLING_DIRECT_GATE,
381
+ nextAction: NEXT_ACTIONS[STATE.INTERNAL_TOOLING_DIRECT_GATE],
382
+ allowedTransitions: TRANSITIONS[STATE.INTERNAL_TOOLING_DIRECT_GATE] || [STATE.DONE],
383
+ };
384
+ }
385
+ // Skip internal detection in sequential stub/test mode to avoid consuming stub entries.
386
+ // Claims-mode stubs handle interleaved calls; detection runs normally.
387
+ if (
388
+ !internalOnlySkipCopilot &&
389
+ (!env.GH_SEQUENCE_PATH || env.GH_STUB_MODE === "claims") &&
390
+ options.watchStatus === undefined &&
391
+ (interpretation.state === STATE.PR_READY_NO_FEEDBACK ||
392
+ interpretation.state === STATE.READY_TO_REREQUEST_REVIEW)
393
+ ) {
375
394
  try {
376
395
  const internalCheck = await detectPrInternalOnly(options, { env, ghCommand });
377
396
  if (internalCheck.ok && internalCheck.internalOnly) {
@@ -387,7 +406,6 @@ export async function runHandoff(options, { env = process.env, ghCommand = "gh"
387
406
  // Best-effort: if detection fails, fall through to normal request behavior
388
407
  }
389
408
  }
390
- }
391
409
 
392
410
  let reviewRequestStatus;
393
411
  const shouldRequestReview = !internalOnlySkipCopilot && options.watchStatus === undefined
@@ -229,6 +229,7 @@ When unresolved feedback exists, use a narrow follow-up loop:
229
229
  - if the refreshed snapshot reports unresolved threads, re-enter the reply/resolve loop for the missed threads
230
230
  12. only after GitHub-side reply/resolve work is done for the addressed threads and the refreshed thread snapshot proves zero unresolved threads remain, decide whether another Copilot pass is desired
231
231
  - resolve the review-round cap from config via `resolveRefinementConfig(config, "maxCopilotRounds")` from `@dev-loops/core/config`; default config ships `maxCopilotRounds: 5`
232
+ - **Opt out entirely:** `maxCopilotRounds: 0` disables the external Copilot review gate for the repo — the loop runs `draft_gate → pre_approval_gate` with the local harness only, never requesting or waiting on Copilot. Use this when the repo has no Copilot reviewer configured or prefers local-harness-only review.
232
233
  - use the completed Copilot review-round count from `detect-copilot-loop-state.mjs` / `copilot-pr-handoff.mjs` as the current PR's review-round count
233
234
  - if completed review rounds have reached the maximum (default: 5), do **not** re-request Copilot review
234
235
  - when the round limit is reached **and** the refreshed thread snapshot proves zero unresolved threads **and** current-head CI is green or credibly green, treat that clean state as eligible for `pre_approval_gate` fallback instead of deadlocking on another Copilot rerequest