dev-loops 0.6.0 → 0.7.2
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/.claude-plugin/plugin.json +1 -1
- package/.claude/agents/dev-loop.md +8 -7
- package/.claude/agents/fixer.md +1 -0
- package/.claude/agents/refiner.md +2 -2
- package/.claude/agents/review.md +4 -3
- package/.claude/commands/{auto.md → loop-auto.md} +1 -1
- package/.claude/commands/loop-continue.md +15 -0
- package/.claude/commands/loop-enqueue.md +22 -0
- package/.claude/commands/loop-grill.md +17 -0
- package/.claude/commands/{info.md → loop-info.md} +2 -2
- package/.claude/commands/loop-queue-status.md +24 -0
- package/.claude/commands/{start-spike.md → loop-start-spike.md} +2 -2
- package/.claude/commands/{start.md → loop-start.md} +1 -1
- package/.claude/commands/{status.md → loop-status.md} +1 -1
- package/.claude/hooks/_bash-command-classify.mjs +333 -29
- package/.claude/hooks/_hook-decisions.mjs +138 -15
- package/.claude/hooks/pre-tool-use-bash-gate.mjs +36 -15
- package/.claude/skills/copilot-pr-followup/SKILL.md +60 -34
- package/.claude/skills/dev-loop/SKILL.md +16 -12
- package/.claude/skills/docs/acceptance-criteria-verification.md +8 -3
- package/.claude/skills/docs/anti-patterns.md +5 -3
- package/.claude/skills/docs/artifact-authority-contract.md +30 -11
- package/.claude/skills/docs/confirmation-rules.md +1 -0
- package/.claude/skills/docs/contract-style-guide.md +37 -0
- package/.claude/skills/docs/copilot-loop-operations.md +19 -15
- package/.claude/skills/docs/cross-harness-regression-contract.md +60 -0
- package/.claude/skills/docs/debt-remediation-contract.md +1 -1
- package/.claude/skills/docs/epic-tree-refinement-procedure.md +25 -22
- package/.claude/skills/docs/issue-intake-procedure.md +26 -19
- package/.claude/skills/docs/local-planning-flow.md +1 -1
- package/.claude/skills/docs/local-planning-worked-example.md +1 -1
- package/.claude/skills/docs/merge-preconditions.md +30 -12
- package/.claude/skills/docs/plan-file-contract.md +1 -1
- package/.claude/skills/docs/pr-lifecycle-contract.md +44 -35
- package/.claude/skills/docs/public-dev-loop-contract.md +60 -44
- package/.claude/skills/docs/retrospective-checkpoint-contract.md +106 -79
- package/.claude/skills/docs/spike-mode-contract.md +14 -7
- package/.claude/skills/docs/stop-conditions.md +30 -15
- package/.claude/skills/docs/tracker-first-loop-state.md +13 -8
- package/.claude/skills/docs/ui-e2e-scoping-step.md +32 -0
- package/.claude/skills/docs/validation-policy.md +4 -5
- package/.claude/skills/docs/workflow-handoff-contract.md +39 -0
- package/.claude/skills/local-implementation/SKILL.md +62 -145
- package/.claude/skills/loop-grill/SKILL.md +163 -0
- package/AGENTS.md +1 -0
- package/CHANGELOG.md +101 -0
- package/README.md +9 -9
- package/agents/dev-loop.agent.md +11 -10
- package/agents/developer.agent.md +1 -1
- package/agents/docs.agent.md +1 -1
- package/agents/fixer.agent.md +2 -1
- package/agents/quality.agent.md +1 -1
- package/agents/refiner.agent.md +3 -3
- package/agents/review.agent.md +5 -4
- package/cli/index.mjs +35 -42
- package/extension/README.md +4 -4
- package/extension/checks.ts +1 -5
- package/extension/harness-types.ts +1 -0
- package/extension/index.ts +6 -0
- package/extension/pi-extension-adapter.ts +2 -0
- package/extension/presentation.ts +7 -19
- package/package.json +12 -12
- package/scripts/_core-helpers.mjs +2 -0
- package/scripts/claude/headless-dev-loop.mjs +1 -1
- package/scripts/docs/validate-rule-ownership.mjs +442 -0
- package/scripts/docs/validate-state-machine-conformance.mjs +1092 -0
- package/scripts/github/_review-thread-mutations.mjs +5 -2
- package/scripts/github/capture-review-threads.mjs +2 -9
- package/scripts/github/comment-issue.mjs +2 -9
- package/scripts/github/create-label.mjs +133 -0
- package/scripts/github/create-pr.mjs +119 -10
- package/scripts/github/detect-checkpoint-evidence.mjs +259 -18
- package/scripts/github/detect-linked-issue-pr.mjs +22 -6
- package/scripts/github/edit-pr.mjs +259 -0
- package/scripts/github/fetch-ci-logs.mjs +2 -9
- package/scripts/github/list-issues.mjs +2 -9
- package/scripts/github/list-review-threads.mjs +277 -0
- package/scripts/github/manage-sub-issues.mjs +46 -10
- package/scripts/github/offer-human-handoff.mjs +8 -5
- package/scripts/github/post-gate-findings.mjs +20 -5
- package/scripts/github/probe-ci-status.mjs +8 -2
- package/scripts/github/probe-copilot-review.mjs +21 -14
- package/scripts/github/ready-for-review.mjs +26 -8
- package/scripts/github/reconcile-draft-gate.mjs +7 -3
- package/scripts/github/reply-resolve-review-thread.mjs +16 -5
- package/scripts/github/reply-resolve-review-threads.mjs +69 -7
- package/scripts/github/request-copilot-review.mjs +98 -26
- package/scripts/github/resolve-handoff-candidates.mjs +7 -3
- package/scripts/github/resolve-tracker-local-spec.mjs +9 -3
- package/scripts/github/stage-reviewer-draft.mjs +10 -2
- package/scripts/github/tick-verified-checkboxes.mjs +202 -0
- package/scripts/github/upsert-checkpoint-verdict.mjs +105 -15
- package/scripts/github/verify-briefing-prefixes.mjs +191 -0
- package/scripts/github/verify-fresh-review-context.mjs +226 -32
- package/scripts/github/view-pr.mjs +150 -0
- package/scripts/github/wait-pr-checks.mjs +171 -0
- package/scripts/github/write-gate-context.mjs +458 -65
- package/scripts/github/write-gate-findings-log.mjs +128 -2
- package/scripts/lib/jq-output.mjs +18 -0
- package/scripts/loop/_post-convergence-change.mjs +211 -0
- package/scripts/loop/_pr-runner-coordination.mjs +70 -0
- package/scripts/loop/_repo-root-resolver.mjs +47 -0
- package/scripts/loop/build-handoff-envelope.mjs +14 -4
- package/scripts/loop/check-retro-tooling.mjs +14 -3
- package/scripts/loop/checkpoint-contract.mjs +7 -4
- package/scripts/loop/cleanup-worktree.mjs +12 -3
- package/scripts/loop/conductor-monitor.mjs +12 -18
- package/scripts/loop/copilot-pr-handoff.mjs +162 -14
- package/scripts/loop/debt-remediate.mjs +24 -12
- package/scripts/loop/detect-change-scope.mjs +38 -9
- package/scripts/loop/detect-copilot-loop-state.mjs +34 -8
- package/scripts/loop/detect-copilot-session-activity.mjs +7 -3
- package/scripts/loop/detect-initial-copilot-pr-state.mjs +7 -3
- package/scripts/loop/detect-internal-only-pr.mjs +8 -2
- package/scripts/loop/detect-issue-refinement-artifact.mjs +6 -3
- package/scripts/loop/detect-pr-gate-coordination-state.mjs +184 -69
- package/scripts/loop/detect-reviewer-loop-state.mjs +12 -2
- package/scripts/loop/detect-tracker-first-loop-state.mjs +9 -1
- package/scripts/loop/detect-tracker-pr-state.mjs +10 -3
- package/scripts/loop/ensure-worktree.mjs +8 -3
- package/scripts/loop/info.mjs +12 -4
- package/scripts/loop/inspect-run-viewer/constants.mjs +4 -18
- package/scripts/loop/inspect-run-viewer/vendor/mermaid.min.js +3405 -0
- package/scripts/loop/inspect-run-viewer-ci-changes.mjs +18 -6
- package/scripts/loop/inspect-run-viewer.mjs +67 -4
- package/scripts/loop/inspect-run.mjs +8 -2
- package/scripts/loop/outer-loop.mjs +8 -4
- package/scripts/loop/pr-runner-coordination.mjs +2 -9
- package/scripts/loop/pre-commit-branch-guard.mjs +16 -10
- package/scripts/loop/pre-flight-gate.mjs +9 -9
- package/scripts/loop/pre-pr-ready-gate.mjs +8 -4
- package/scripts/loop/pre-write-remote-freshness-guard.mjs +13 -4
- package/scripts/loop/provision-worktree.mjs +74 -3
- package/scripts/loop/resolve-dev-loop-startup.mjs +216 -10
- package/scripts/loop/resolve-gate-dispatch.mjs +134 -0
- package/scripts/loop/resolve-pr-conflicts.mjs +14 -7
- package/scripts/loop/run-conductor-cycle.mjs +8 -2
- package/scripts/loop/run-queue.mjs +18 -9
- package/scripts/loop/run-refinement-audit.mjs +8 -9
- package/scripts/loop/run-watch-cycle.mjs +2 -9
- package/scripts/loop/sanctioned-commands.mjs +106 -0
- package/scripts/loop/steer-loop.mjs +29 -16
- package/scripts/loop/validate-pr-body-spec.mjs +223 -0
- package/scripts/loop/watch-initial-copilot-pr.mjs +8 -3
- package/scripts/pages/build-site.mjs +59 -8
- package/scripts/pages/build-state-atlas.mjs +443 -0
- package/scripts/projects/_resolve-project.mjs +1 -0
- package/scripts/projects/add-queue-item.mjs +60 -54
- package/scripts/projects/archive-done-items.mjs +49 -84
- package/scripts/projects/ensure-queue-board.mjs +10 -36
- package/scripts/projects/list-queue-items.mjs +59 -382
- package/scripts/projects/move-queue-item.mjs +21 -449
- package/scripts/projects/reconcile-queue.mjs +253 -0
- package/scripts/projects/reorder-queue-item.mjs +43 -68
- package/scripts/projects/resolve-active-board-item.mjs +108 -46
- package/scripts/projects/sync-item-status.mjs +15 -10
- package/scripts/refine/_refine-helpers.mjs +21 -5
- package/scripts/refine/exit-spike.mjs +18 -8
- package/scripts/refine/promote-plan.mjs +22 -16
- package/scripts/refine/prose-linkage-detector.mjs +1 -1
- package/scripts/refine/refine-plan-file.mjs +13 -4
- package/scripts/refine/refinement-completeness-checker.mjs +1 -1
- package/scripts/refine/scaffold-spike-file.mjs +4 -8
- package/scripts/refine/scope-boundary-cross-checker.mjs +1 -1
- package/scripts/refine/tree-integrity-validator.mjs +1 -1
- package/scripts/refine/validate-plan-file.mjs +1 -1
- package/scripts/refine/validate-spike-file.mjs +1 -1
- package/scripts/refine/verify.mjs +11 -6
- package/scripts/release/assert-core-dependency-version.mjs +123 -0
- package/scripts/release/extract-changelog-section.mjs +16 -2
- package/skills/copilot-pr-followup/SKILL.md +60 -34
- package/skills/dev-loop/SKILL.md +11 -7
- package/skills/docs/acceptance-criteria-verification.md +8 -3
- package/skills/docs/anti-patterns.md +5 -3
- package/skills/docs/artifact-authority-contract.md +30 -11
- package/skills/docs/confirmation-rules.md +1 -0
- package/skills/docs/contract-style-guide.md +37 -0
- package/skills/docs/copilot-loop-operations.md +19 -15
- package/skills/docs/cross-harness-regression-contract.md +60 -0
- package/skills/docs/debt-remediation-contract.md +1 -1
- package/skills/docs/epic-tree-refinement-procedure.md +25 -22
- package/skills/docs/issue-intake-procedure.md +26 -19
- package/skills/docs/local-planning-flow.md +1 -1
- package/skills/docs/local-planning-worked-example.md +1 -1
- package/skills/docs/merge-preconditions.md +30 -12
- package/skills/docs/plan-file-contract.md +1 -1
- package/skills/docs/pr-lifecycle-contract.md +44 -35
- package/skills/docs/public-dev-loop-contract.md +60 -44
- package/skills/docs/required-rules.json +149 -0
- package/skills/docs/retrospective-checkpoint-contract.md +106 -79
- package/skills/docs/spike-mode-contract.md +14 -7
- package/skills/docs/stop-conditions.md +30 -15
- package/skills/docs/tracker-first-loop-state.md +13 -8
- package/skills/docs/ui-e2e-scoping-step.md +32 -0
- package/skills/docs/validation-policy.md +4 -5
- package/skills/docs/workflow-handoff-contract.md +39 -0
- package/skills/local-implementation/SKILL.md +62 -145
- package/skills/loop-grill/SKILL.md +165 -0
- package/.claude/commands/continue.md +0 -15
- package/scripts/docs/validate-no-duplicate-rules.mjs +0 -250
- package/scripts/loop/conductor.mjs +0 -233
- package/scripts/loop/detect-stale-runner.mjs +0 -265
- package/scripts/loop/pre-push-main-guard.mjs +0 -117
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
# Public dev-loop contract
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
Canonical owner for the public `dev-loop` entrypoint: routed semantics, accepted shorthand, and the rule that internal strategy names stay behind the façade.
|
|
4
4
|
|
|
5
5
|
This canonical owner lives in the shipped `skills/docs/` surface because installed skill/runtime consumers reliably own the skills subtree. In installed layouts, read the same contract via [Public Dev Loop Contract](../docs/public-dev-loop-contract.md) from the installed skill directory.
|
|
6
6
|
|
|
7
|
-
Other repo docs
|
|
7
|
+
Other repo docs MAY summarize or link this contract; they MUST NOT redefine it.
|
|
8
8
|
|
|
9
9
|
## Public surface
|
|
10
10
|
|
|
@@ -12,7 +12,7 @@ The single public entrypoint is:
|
|
|
12
12
|
|
|
13
13
|
- `dev-loop`
|
|
14
14
|
|
|
15
|
-
|
|
15
|
+
`dev-loop` MUST be callable from the user-facing workflow surfaces, including:
|
|
16
16
|
|
|
17
17
|
- `subagent dev-loop`
|
|
18
18
|
- `/skill:dev-loop`
|
|
@@ -28,8 +28,6 @@ Day-one user-intent forms:
|
|
|
28
28
|
- auto dev loop on issue `<n>`
|
|
29
29
|
- what state is the dev loop in?
|
|
30
30
|
|
|
31
|
-
Users should not have to choose `dev-loop` vs internal seam names up front.
|
|
32
|
-
|
|
33
31
|
## Issue-based shorthand auto trigger contract
|
|
34
32
|
|
|
35
33
|
This shorthand form is explicitly accepted and resolves to the same bounded public `dev-loop` intent:
|
|
@@ -44,7 +42,7 @@ Canonical mapping:
|
|
|
44
42
|
|
|
45
43
|
Stop-boundary contract for this shorthand:
|
|
46
44
|
|
|
47
|
-
1. continue through the normal GitHub/Copilot loop (assignment, PR watch, draft
|
|
45
|
+
1. continue through the normal GitHub/Copilot loop (assignment, PR watch, draft/Copilot review-fix, final pre-approval) unless a genuine stop condition is reached
|
|
48
46
|
2. stop at the final human approval decision by default
|
|
49
47
|
3. after formal approval, stop again in `waiting_for_merge_authorization` unless merge authorization is explicitly granted for the active issue/PR scope
|
|
50
48
|
4. merge only after explicit merge authorization for the active issue/PR scope
|
|
@@ -76,7 +74,8 @@ Use this taxonomy consistently across docs, discovery surfaces, and tests:
|
|
|
76
74
|
|
|
77
75
|
Any remaining specialized Copilot behavior stays internal-only behind `dev-loop`.
|
|
78
76
|
|
|
79
|
-
|
|
77
|
+
<!-- rule: FACADE-TAXONOMY-DRIFT-TEST -->
|
|
78
|
+
`FACADE-TAXONOMY-DRIFT-TEST`: Regression tests MUST fail if this taxonomy drifts in wording or surfaced entrypoint assets.
|
|
80
79
|
|
|
81
80
|
## Canonical current state
|
|
82
81
|
|
|
@@ -90,17 +89,7 @@ The public router consumes one canonical current state with these top-level dime
|
|
|
90
89
|
| `status` | `active` \| `waiting` \| `blocked` \| `approval_ready` \| `merge_ready` \| `done` |
|
|
91
90
|
| `authorization` | `authorized` \| `needs_confirmation` \| `not_authorized` |
|
|
92
91
|
|
|
93
|
-
The authoritative first-slice evaluator
|
|
94
|
-
|
|
95
|
-
- `packages/core/src/loop/public-dev-loop-routing.mjs`
|
|
96
|
-
|
|
97
|
-
Authoritative status-report helper:
|
|
98
|
-
|
|
99
|
-
- `resolveAuthoritativeDevLoopStatus()` in `packages/core/src/loop/public-dev-loop-routing.mjs`
|
|
100
|
-
|
|
101
|
-
Authoritative startup/resume bundle helper:
|
|
102
|
-
|
|
103
|
-
- `resolveAuthoritativeStartupResumeBundle()` in `packages/core/src/loop/public-dev-loop-routing.mjs`
|
|
92
|
+
The authoritative first-slice evaluator, status-report helper (`resolveAuthoritativeDevLoopStatus()`), and startup/resume bundle helper (`resolveAuthoritativeStartupResumeBundle()`) all live in `packages/core/src/loop/public-dev-loop-routing.mjs`.
|
|
104
93
|
|
|
105
94
|
Its tests are:
|
|
106
95
|
|
|
@@ -118,7 +107,8 @@ Before answering status/progress/readiness/merge-state/next-step questions, cons
|
|
|
118
107
|
|
|
119
108
|
Prior chat context is only a hint, never state authority.
|
|
120
109
|
|
|
121
|
-
|
|
110
|
+
<!-- rule: FACADE-STATUS-AUTHORITATIVE-FAIL-CLOSED -->
|
|
111
|
+
`FACADE-STATUS-AUTHORITATIVE-FAIL-CLOSED`: If authoritative identity/state (including issue↔PR linkage when relevant) cannot be resolved confidently, consumers MUST fail closed to reconcile/unknown instead of guessing.
|
|
122
112
|
For async/durable-auto flows, do not claim that `dev-loop` has started or is running unless a visible Pi-managed async run id has also been resolved.
|
|
123
113
|
|
|
124
114
|
When the routed next step requires confirmation for a mutation, the status/startup next action should name that concrete pending mutation (for example issue assignment to `copilot-swe-agent`) instead of generic "approval gate" wording.
|
|
@@ -140,10 +130,8 @@ Required authoritative inputs:
|
|
|
140
130
|
- `auto_continue_current` always resolves to `durable_auto`
|
|
141
131
|
- `issueLinkageResolution` (`resolved_linked_pr` \| `resolved_no_open_pr` \| `not_applicable`)
|
|
142
132
|
- required when `currentState.target.kind === issue`
|
|
143
|
-
- `issueReadiness` (`ready` \| `needs_clarification` \| `not_applicable`)
|
|
144
|
-
- required for Copilot-first issue targets with `issueLinkageResolution=resolved_no_open_pr`
|
|
145
|
-
- `issueAssignmentState` (`unassigned` \| `assigned_to_copilot` \| `not_applicable`)
|
|
146
|
-
- required for Copilot-first issue targets with `issueLinkageResolution=resolved_no_open_pr`
|
|
133
|
+
- `issueReadiness` (`ready` \| `needs_clarification` \| `not_applicable`) and `issueAssignmentState` (`unassigned` \| `assigned_to_copilot` \| `not_applicable`)
|
|
134
|
+
- both required for Copilot-first issue targets with `issueLinkageResolution=resolved_no_open_pr`
|
|
147
135
|
- `artifactState` (`open` \| `closed` \| `merged` \| `not_applicable`)
|
|
148
136
|
- explicit resolved `loopState` (`unknown` is not authoritative input)
|
|
149
137
|
- required for async/durable-auto startup or status paths: `asyncRun`
|
|
@@ -151,8 +139,8 @@ Required authoritative inputs:
|
|
|
151
139
|
- durable-auto success requires `kind=pi_managed_run`, a non-empty visible `runId`, and `visible=true`
|
|
152
140
|
- when `inspectionState` is provided as `hidden`, `stale`, or `uninspectable`, durable-auto must fail closed with that state surfaced in diagnostics
|
|
153
141
|
- detached local processes are diagnostic-only evidence and must fail closed instead of being treated as a successful async start
|
|
154
|
-
-
|
|
155
|
-
-
|
|
142
|
+
- refreshed `linked_pr_ready_for_followup` for an issue target with a resolved linked PR: promote stale bootstrap waiting to the linked PR follow-up path, or fail closed if the linked-PR facts are incomplete/contradictory, instead of preserving the old bootstrap wait route
|
|
143
|
+
- refreshed `prior_linked_pr_closed_unmerged` for a Copilot-owned issue target with `issueLinkageResolution=resolved_no_open_pr`: fail closed to reconcile instead of treating the issue as a healthy bootstrap wait or fresh issue-intake path
|
|
156
144
|
|
|
157
145
|
Resolved bundle output shape:
|
|
158
146
|
|
|
@@ -222,8 +210,8 @@ Resolved bundle output shape:
|
|
|
222
210
|
|
|
223
211
|
Dev-mode observability requirement:
|
|
224
212
|
|
|
225
|
-
- saved artifacts
|
|
226
|
-
- wait/watch artifacts
|
|
213
|
+
- saved artifacts MUST preserve the `contractTrace` decision, wait strategy, state-refresh boundary, and stop classification so a fresh session can explain a re-attach, stop, or fail-closed without replaying the run
|
|
214
|
+
- wait/watch artifacts MUST record the effective timeout budget and whether the seam ran as `persistent_watch` or `one_shot_probe`; a surface without a poll interval MAY record `effectivePollIntervalMs=null` instead of inventing one
|
|
227
215
|
|
|
228
216
|
Fail-closed semantics:
|
|
229
217
|
|
|
@@ -271,7 +259,7 @@ Internal strategy naming is implementation detail; normal orchestration always s
|
|
|
271
259
|
|
|
272
260
|
Tracker-backed local implementation is an input-source addition to the existing `local_implementation` strategy. It does **not** create a new routing mode, strategy family, or public workflow entrypoint.
|
|
273
261
|
|
|
274
|
-
For tracker-backed local sessions, the tracker issue is canonical
|
|
262
|
+
For tracker-backed local sessions, the tracker issue is canonical; the no-duplicate-phase-doc rule is owned by `ARTIFACT-TRACKER-FIRST-NO-DUP` in [Artifact Authority Contract](artifact-authority-contract.md).
|
|
275
263
|
|
|
276
264
|
Deterministic GitHub-backed spec resolution:
|
|
277
265
|
|
|
@@ -284,13 +272,13 @@ Deterministic GitHub-backed spec resolution:
|
|
|
284
272
|
State-sync expectations for this slice:
|
|
285
273
|
|
|
286
274
|
- local branch state and `tmp/` artifacts remain local execution state
|
|
287
|
-
- durable scope / acceptance / status changes discovered during local execution
|
|
275
|
+
- durable scope / acceptance / status changes discovered during local execution SHOULD sync back to the tracker issue
|
|
288
276
|
- this slice does **not** introduce full bidirectional tracker sync or tracker-provider adapters beyond the bounded GitHub-backed helper path above
|
|
289
277
|
|
|
290
278
|
Non-duplication rule:
|
|
291
279
|
|
|
292
280
|
- do not create, read, or update `docs/phases/phase-<n>.md` for the same tracker-backed session
|
|
293
|
-
- if a duplicate local phase doc already exists
|
|
281
|
+
- if a duplicate local phase doc already exists, reconcile explicitly before continuing rather than keeping two durable spec surfaces alive
|
|
294
282
|
|
|
295
283
|
## Copilot-first issue-assignment seam (unassigned issues)
|
|
296
284
|
|
|
@@ -330,7 +318,7 @@ For issue targets, authoritative issue↔PR linkage resolution remains part of s
|
|
|
330
318
|
|
|
331
319
|
- when canonical issue state includes `linkedPr`, route selection first uses that linked PR as the authoritative routable artifact
|
|
332
320
|
- when canonical issue state does **not** include `linkedPr`, status/reporting consumers must still require explicit authoritative linkage resolution before asserting there is no open linked PR
|
|
333
|
-
- when authoritative linkage resolves an already-open linked PR, that PR is the only canonical active artifact for the issue during follow-up; startup/status/follow-up
|
|
321
|
+
- <!-- rule: FACADE-LINKED-PR-SINGLE-ARTIFACT --> `FACADE-LINKED-PR-SINGLE-ARTIFACT`: when authoritative linkage resolves an already-open linked PR, that PR is the only canonical active artifact for the issue during follow-up; startup/status/follow-up MUST reuse it and MUST fail closed against opening another PR until the prior state is explicitly reconciled
|
|
334
322
|
|
|
335
323
|
## Deterministic routing order
|
|
336
324
|
|
|
@@ -349,6 +337,28 @@ First-match-wins routing posture:
|
|
|
349
337
|
11. PR owned by Copilot -> `copilot_pr_followup`
|
|
350
338
|
12. anything else -> fail closed to `needs_reconcile`
|
|
351
339
|
|
|
340
|
+
## Required transitions
|
|
341
|
+
|
|
342
|
+
The gate graph (`DEV_LOOP_GATE` / `PUBLIC_DEV_LOOP_GATE_CONTRACT` in
|
|
343
|
+
`public-dev-loop-routing.mjs`) is stateless per cycle: each `evaluatePublicDevLoopRouting`
|
|
344
|
+
call re-derives one gate from fresh authoritative state, so every non-terminal (route/wait)
|
|
345
|
+
gate can be followed, on the next cycle, by any of the gates.
|
|
346
|
+
|
|
347
|
+
- `final_approval` -> any dev-loop gate
|
|
348
|
+
- `wait_watch` -> any dev-loop gate
|
|
349
|
+
- `local_implementation` -> any dev-loop gate
|
|
350
|
+
- `issue_intake` -> any dev-loop gate
|
|
351
|
+
- `external_pr_followup` -> any dev-loop gate
|
|
352
|
+
- `reviewer_fixer` -> any dev-loop gate
|
|
353
|
+
- `copilot_pr_followup` -> any dev-loop gate
|
|
354
|
+
|
|
355
|
+
Terminal gates (`stop_blocked_or_not_authorized`, `stop_done_terminal`,
|
|
356
|
+
`waiting_for_merge_authorization`, `fail_closed_reconcile`) have no outgoing transitions —
|
|
357
|
+
reaching one ends the current evaluation cycle. Their route-kind classification
|
|
358
|
+
(`stop` / `needs_reconcile`) is the authoritative terminal marker; the route/wait gates above
|
|
359
|
+
are the authoritative non-terminal set. This machine is wired into the L2/L3 state-machine
|
|
360
|
+
conformance harness (`validate-state-machine-conformance.mjs`).
|
|
361
|
+
|
|
352
362
|
## Conflict reconciliation path (`CONFLICTING` / `DIRTY`)
|
|
353
363
|
|
|
354
364
|
When an open linked PR reports merge conflict against `main`, treat this as an explicit bounded local-agent reconciliation path, not as a blind merge/update step:
|
|
@@ -360,27 +370,33 @@ When an open linked PR reports merge conflict against `main`, treat this as an e
|
|
|
360
370
|
- issue/PR scope and acceptance criteria
|
|
361
371
|
- current-head gate evidence and relevant unresolved review feedback
|
|
362
372
|
- local validation surface for the touched conflict slice
|
|
363
|
-
3. if required authoritative context is missing, stale for the current head, or contradictory, fail closed to reconcile
|
|
373
|
+
3. <!-- rule: FACADE-CONFLICT-CONTEXT-FAIL-CLOSED --> `FACADE-CONFLICT-CONTEXT-FAIL-CLOSED`: if required authoritative context is missing, stale for the current head, or contradictory, orchestration MUST fail closed to reconcile
|
|
364
374
|
4. only when that context is complete for one current head, resolve the conflict locally on the PR branch
|
|
365
|
-
5. after conflict resolution, rerun required local validation, gate checks, and required CI checks for the new head before approval/merge evaluation
|
|
375
|
+
5. <!-- rule: FACADE-CONFLICT-REVALIDATE-NEW-HEAD --> `FACADE-CONFLICT-REVALIDATE-NEW-HEAD`: after conflict resolution, orchestration MUST rerun required local validation, gate checks, and required CI checks for the new head before approval/merge evaluation
|
|
366
376
|
|
|
367
377
|
## `auto dev loop` durable auto contract
|
|
368
378
|
|
|
369
|
-
When the public intent is `auto dev loop`, the router
|
|
379
|
+
When the public intent is `auto dev loop`, the router MUST:
|
|
370
380
|
|
|
371
381
|
1. require canonical current state resolution first
|
|
372
382
|
2. route to the same detected internal strategy as normal state-based routing
|
|
373
383
|
3. mark execution mode as durable auto ownership (`durable_auto`)
|
|
374
384
|
4. keep waiting/watch states in healthy-wait semantics (`auto_healthy_wait`)
|
|
375
385
|
|
|
376
|
-
In healthy waiting states, quiet watcher observations (for example `timeout` or `idle`) are observational only and
|
|
386
|
+
In healthy waiting states, quiet watcher observations (for example `timeout` or `idle`) are observational only and MUST NOT be surfaced as attention by themselves. Escalation is still expected for true blocked/authorization/reconcile states.
|
|
377
387
|
|
|
378
|
-
|
|
379
|
-
When refreshed authoritative bootstrap state instead resolves `prior_linked_pr_closed_unmerged`, that is not a healthy wait seam: the routed outcome must fail closed to reconcile so status/startup answers surface the prior closed-unmerged PR decision rather than implying normal watch continuity.
|
|
388
|
+
Bootstrap-only exception to the general blocked-escalation rule for `waiting_for_initial_copilot_implementation`:
|
|
380
389
|
|
|
381
|
-
|
|
390
|
+
| Rule ID | Condition | Outcome |
|
|
391
|
+
|---|---|---|
|
|
392
|
+
| <!-- rule: FACADE-BOOTSTRAP-WATCH-ROUTE --> `FACADE-BOOTSTRAP-WATCH-ROUTE` | durable-auto ownership of this seam | ownership MUST route to the dedicated `watch-initial-copilot-pr.mjs` watcher with its default 1-hour watch budget |
|
|
393
|
+
| <!-- rule: FACADE-BOOTSTRAP-QUIET-NO-EJECT --> `FACADE-BOOTSTRAP-QUIET-NO-EJECT` | quiet/no-activity observation while refreshed state still resolves this seam | durable ownership MUST NOT be ejected; inspect/status intents MAY still summarize that state and exit normally |
|
|
394
|
+
| <!-- rule: FACADE-BOOTSTRAP-ACTION-REQUIRED-NONBLOCKING --> `FACADE-BOOTSTRAP-ACTION-REQUIRED-NONBLOCKING` | bootstrap-only linked PR; approval-gated Actions/Copilot run reports `action_required` (a run conclusion, not a lifecycle state) | treated as a non-blocking observational signal (concluded session activity); MUST NOT by itself force stop/escalation |
|
|
395
|
+
| <!-- rule: FACADE-BOOTSTRAP-CLOSED-UNMERGED-RECONCILE --> `FACADE-BOOTSTRAP-CLOSED-UNMERGED-RECONCILE` | refreshed bootstrap state resolves `prior_linked_pr_closed_unmerged` | MUST fail closed to reconcile so status/startup surfaces the prior closed-unmerged decision instead of normal watch continuity |
|
|
396
|
+
| <!-- rule: FACADE-BOOTSTRAP-FOLLOWUP-REENTRY --> `FACADE-BOOTSTRAP-FOLLOWUP-REENTRY` | refreshed seam state advances to `linked_pr_ready_for_followup` | durable-auto continuation MUST re-enter the same linked PR follow-up path |
|
|
397
|
+
| <!-- rule: FACADE-BOOTSTRAP-ISOLATED-WORKTREE-CONTINUATION --> `FACADE-BOOTSTRAP-ISOLATED-WORKTREE-CONTINUATION` | follow-up handoff carries `conductorRouting.handoffEnvelope.requiresLocalIsolation=true` | orchestration SHOULD continue through an isolated checkout/worktree transition rather than treat that boundary as final completion (the runtime surfaces the flag; it does not enforce re-entry) |
|
|
382
398
|
|
|
383
|
-
Main conductor orchestration
|
|
399
|
+
Main conductor orchestration MUST treat non-terminal follow-up/wait states (for example `waiting_for_copilot_review`) as continuation boundaries rather than clean completion. If an async child exits before the requested stop boundary and continuation is feasible, re-dispatch via the main session driver (the subagent exits on external wait; the main session re-dispatches); otherwise surface the concrete blocker.
|
|
384
400
|
|
|
385
401
|
## Internal / external model
|
|
386
402
|
|
|
@@ -413,9 +429,9 @@ flowchart TD
|
|
|
413
429
|
|
|
414
430
|
- `dev-loop` is the only intended public workflow entrypoint.
|
|
415
431
|
- any remaining specialized Copilot behavior is internal-only and non-user-invocable behind the canonical internal route-pack surface (`issue-intake`, `copilot-pr-followup`, `local-implementation`, `final-approval`).
|
|
416
|
-
- Documentation and examples
|
|
417
|
-
-
|
|
418
|
-
- User-visible variation
|
|
432
|
+
- Documentation and examples SHOULD lead with `dev-loop` and explain routed behavior.
|
|
433
|
+
- Workflow branching SHOULD converge into deterministic state-machine/tooling surfaces behind `dev-loop`.
|
|
434
|
+
- User-visible variation SHOULD be expressed through the `dev-loop` API/parameters or settings, not multiple public workflow names or legacy compatibility seams.
|
|
419
435
|
|
|
420
436
|
## Bounded variation parameter contract
|
|
421
437
|
|
|
@@ -437,7 +453,7 @@ Any conflict that would materially change artifact identity, ownership truth, or
|
|
|
437
453
|
| `mode` | `bounded_handoff` (default) \| `durable_auto` | Steers execution mode; `durable_auto` uses the same durable-auto execution-mode semantics as `auto_continue_current`, without replacing the selected intent |
|
|
438
454
|
| `watch` | boolean | Explicitly request wait/watch semantics; fails closed for otherwise-successful non-wait routed results, while preserving authoritative `stop` and `needs_reconcile` outcomes |
|
|
439
455
|
| `intent` | any existing public `dev-loop` intent | Disambiguates the supported public intent; maps to existing contract values |
|
|
440
|
-
| `targetPreference` | `
|
|
456
|
+
| `targetPreference` | `prefer_local` (default) \| `prefer_github_first` | Steers routing preference; must not override authoritative linked-PR or active-artifact truth |
|
|
441
457
|
|
|
442
458
|
The bounded allow-list is exported from `packages/core/src/loop/public-dev-loop-routing.mjs` as `DEV_LOOP_VARIATION_PARAMETER_CONTRACT`.
|
|
443
459
|
|
|
@@ -461,7 +477,7 @@ The following parameter/state combinations fail closed to `needs_reconcile` inst
|
|
|
461
477
|
| `mode=bounded_handoff` + `intent=auto_continue_current` | `auto_continue_current` always requires durable auto execution mode |
|
|
462
478
|
| Unrecognized `mode` value | Value not on the bounded allow-list |
|
|
463
479
|
| Unrecognized `targetPreference` value | Value not on the bounded allow-list |
|
|
464
|
-
| `watch=true` when an otherwise-successful routed result is not wait/watch-eligible | Watch semantics require a routed wait result (`routeKind=wait`), not just `selectedGate=wait_watch`;
|
|
480
|
+
| `watch=true` when an otherwise-successful routed result is not wait/watch-eligible | Watch semantics require a routed wait result (`routeKind=wait`), not just `selectedGate=wait_watch`; `stop`/`needs_reconcile` outcomes stay authoritative |
|
|
465
481
|
| Non-boolean `watch` value | Value is outside the bounded boolean allow-list and must fail closed |
|
|
466
482
|
| `targetPreference=prefer_local` when authoritative state has a linked PR or active PR artifact | Preference must not override authoritative PR/linked-PR active artifact truth |
|
|
467
483
|
| `mode=durable_auto` without authoritative current state | Durable auto requires authoritative current state to route from |
|
|
@@ -0,0 +1,149 @@
|
|
|
1
|
+
{
|
|
2
|
+
"requiredRules": [
|
|
3
|
+
"ACCEPT-CRITERIA-VERIFY-AND-REFLECT",
|
|
4
|
+
"ARTIFACT-LIGHTWEIGHT-BODY-INVARIANTS",
|
|
5
|
+
"ARTIFACT-LIGHTWEIGHT-PLAN-FILE-EXCLUSIVE",
|
|
6
|
+
"ARTIFACT-STRATEGY-ENUM-FAIL-CLOSED",
|
|
7
|
+
"ARTIFACT-TRACKER-FIRST-NO-DUP",
|
|
8
|
+
"ARTIFACT-TWO-TIER-EXCLUSIVE",
|
|
9
|
+
"ASSET-PATH-INSTALLED-NO-ASSUME",
|
|
10
|
+
"ASSET-PATH-SOURCE-NO-REPO-LOCAL",
|
|
11
|
+
"CONFIRM-CORE-EXPLICIT",
|
|
12
|
+
"COPILOT-FOLLOWUP-ADVERSARIAL-BRIEFING",
|
|
13
|
+
"COPILOT-FOLLOWUP-GATE-COMMENT-CANONICAL",
|
|
14
|
+
"COPILOT-FOLLOWUP-REPLY-RESOLVE-HELPER",
|
|
15
|
+
"COPILOT-FOLLOWUP-REQUEST-BRANCHING",
|
|
16
|
+
"COPILOT-FOLLOWUP-REQUEST-HELPER-ONLY",
|
|
17
|
+
"COPILOT-FOLLOWUP-ROUND-CAP",
|
|
18
|
+
"COPILOT-FOLLOWUP-WAIT-TOOLS",
|
|
19
|
+
"COPILOT-STATE-ACTIVE-REQUEST-WAIT",
|
|
20
|
+
"COPILOT-STATE-REPLY-BEFORE-REREQUEST",
|
|
21
|
+
"COPILOT-STATE-TERMINAL-STOP",
|
|
22
|
+
"COPILOT-STATE-UNRESOLVED-PRIORITY",
|
|
23
|
+
"COPILOT-STATE-WATCH-PERSISTENCE",
|
|
24
|
+
"EPIC-REFINEMENT-CONFIRM-BEFORE-MUTATE",
|
|
25
|
+
"EPIC-REFINEMENT-REQUIRED-CONTRACTS",
|
|
26
|
+
"EPIC-REFINEMENT-SCOPE-BOUNDARY",
|
|
27
|
+
"EPIC-REFINEMENT-SERIAL-PHASE-GATE",
|
|
28
|
+
"FACADE-BOOTSTRAP-ACTION-REQUIRED-NONBLOCKING",
|
|
29
|
+
"FACADE-BOOTSTRAP-CLOSED-UNMERGED-RECONCILE",
|
|
30
|
+
"FACADE-BOOTSTRAP-FOLLOWUP-REENTRY",
|
|
31
|
+
"FACADE-BOOTSTRAP-ISOLATED-WORKTREE-CONTINUATION",
|
|
32
|
+
"FACADE-BOOTSTRAP-QUIET-NO-EJECT",
|
|
33
|
+
"FACADE-BOOTSTRAP-WATCH-ROUTE",
|
|
34
|
+
"FACADE-CONFLICT-CONTEXT-FAIL-CLOSED",
|
|
35
|
+
"FACADE-CONFLICT-REVALIDATE-NEW-HEAD",
|
|
36
|
+
"FACADE-LINKED-PR-SINGLE-ARTIFACT",
|
|
37
|
+
"FACADE-STATUS-AUTHORITATIVE-FAIL-CLOSED",
|
|
38
|
+
"FACADE-TAXONOMY-DRIFT-TEST",
|
|
39
|
+
"GATE-COMMENT-DRAFT-REQUIREMENTS",
|
|
40
|
+
"GATE-COMMENT-FAIL-CLOSED",
|
|
41
|
+
"GATE-COMMENT-NON-SUBSTITUTION",
|
|
42
|
+
"GATE-COMMENT-PREAPPROVAL-REQUIREMENTS",
|
|
43
|
+
"GATE-COMMENT-REQUIRED-FIELDS",
|
|
44
|
+
"GATE-COMMENT-RERUN-RULES",
|
|
45
|
+
"GATE-COMMENT-SCOPE-ONLY",
|
|
46
|
+
"GATE-COMMENT-VALIDATION-REPORTING",
|
|
47
|
+
"GATE-COMMENT-VERDICT-VALUES",
|
|
48
|
+
"GATE-EXEC-ANGLE-COVERAGE",
|
|
49
|
+
"GATE-EXEC-BRIEFING-PREFIX",
|
|
50
|
+
"GATE-EXEC-BUILD-ONCE-SEED",
|
|
51
|
+
"GATE-EXEC-DISPOSITION-LEDGER",
|
|
52
|
+
"GATE-EXEC-FANOUT-SEQUENTIAL-FALLBACK",
|
|
53
|
+
"GATE-EXEC-LIGHT-ESCALATION",
|
|
54
|
+
"GATE-EXEC-NON-SUBSTITUTION",
|
|
55
|
+
"GATE-EXEC-POST-BEFORE-FIX",
|
|
56
|
+
"GATE-EXEC-REGATE-MANDATORY",
|
|
57
|
+
"GATE-EXEC-SEPARATE-CHAINS",
|
|
58
|
+
"GATE-SKIP-NOT-RECOVERABLE-BY-CONVERGENCE",
|
|
59
|
+
"INTAKE-LINKED-PR-HELPER-DELEGATION",
|
|
60
|
+
"INTAKE-NEW-IDEA-SAFETY",
|
|
61
|
+
"INTAKE-STOP-STATES",
|
|
62
|
+
"LIFECYCLE-CONFLICT-BLOCKS-PROGRESS",
|
|
63
|
+
"LIFECYCLE-FAIL-CLOSED",
|
|
64
|
+
"LIFECYCLE-ONE-STATE",
|
|
65
|
+
"LOCAL-COMMIT-BEFORE-EXIT",
|
|
66
|
+
"LOCAL-DELEGATION-TABLE",
|
|
67
|
+
"LOCAL-FAILURE-TRIAGE-ORDER",
|
|
68
|
+
"LOCAL-LIGHT-MODE-CONFIG-SURFACE",
|
|
69
|
+
"LOCAL-PHASE-ONE-AT-A-TIME",
|
|
70
|
+
"LOCAL-PLAN-REVIEW-GATE",
|
|
71
|
+
"LOCAL-PR-CREATE-CANONICAL",
|
|
72
|
+
"LOCAL-PREFLIGHT-GATE-MANDATORY",
|
|
73
|
+
"LOCAL-RETROSPECTIVE-REQUIRED",
|
|
74
|
+
"LOCAL-TEST-FIRST-COVERAGE",
|
|
75
|
+
"LOCAL-TMP-EPHEMERAL-STATE",
|
|
76
|
+
"LOCAL-TRACKER-NO-DIRECT-MERGE",
|
|
77
|
+
"MERGE-PRECOND-REQUIRED",
|
|
78
|
+
"OPS-DRAFT-FIRST-PR",
|
|
79
|
+
"OPS-NO-INLINE-INTERPRETER",
|
|
80
|
+
"QUEUE-BOARD-LINKED",
|
|
81
|
+
"QUEUE-BOARD-QUERY-FAIL-CLOSED",
|
|
82
|
+
"QUEUE-BOOTSTRAP-ONLY-MUTATOR",
|
|
83
|
+
"QUEUE-COLUMN-CANONICAL",
|
|
84
|
+
"QUEUE-COLUMN-NO-REMOVE",
|
|
85
|
+
"QUEUE-LIVE-PICKUP-SOURCE",
|
|
86
|
+
"QUEUE-NEXTUP-EMPTY-FAIL-CLOSED",
|
|
87
|
+
"QUEUE-NEXTUP-SOURCE",
|
|
88
|
+
"QUEUE-NEXTUP-TARGET-MISSING-FAIL-CLOSED",
|
|
89
|
+
"QUEUE-RENAME-CONFLICT-NO-MUTATION",
|
|
90
|
+
"RETRO-ADVISORY-NEVER-GATE",
|
|
91
|
+
"RETRO-ENFORCEMENT-CONFIG-GATED",
|
|
92
|
+
"RETRO-FINDINGS-ENVELOPE-CARRY",
|
|
93
|
+
"RETRO-GATE-FAIL-CLOSED",
|
|
94
|
+
"REVIEWER-BOUNDARY-CONTRACT",
|
|
95
|
+
"REVIEWER-STATE-GATE-ANGLE-MAPPING",
|
|
96
|
+
"ROUTING-EVALUATOR-AUTHORITY",
|
|
97
|
+
"ROUTING-FAIL-CLOSED-RECONCILE",
|
|
98
|
+
"ROUTING-LOCAL-ISOLATION-PASSTHROUGH",
|
|
99
|
+
"ROUTING-PRIORITY-ORDER",
|
|
100
|
+
"SPIKE-DISCARD-ZERO-MUTATION",
|
|
101
|
+
"SPIKE-EXIT-ELIGIBILITY",
|
|
102
|
+
"SPIKE-GRADUATE-PLAN-FILE-REQUIRED",
|
|
103
|
+
"SPIKE-RELAXED-GATE-PROFILE",
|
|
104
|
+
"SPIKE-STARTUP-SCAFFOLD-GATE",
|
|
105
|
+
"STEERING-EXTERNAL-SCOPE-NARROW",
|
|
106
|
+
"STEERING-HARD-CONSTRAINT-DEDUP",
|
|
107
|
+
"STEERING-LIVE-ADVERTISEMENT-FAIL-CLOSED",
|
|
108
|
+
"STEERING-SEQ-MONOTONIC",
|
|
109
|
+
"STOP-APPROVAL-001",
|
|
110
|
+
"STOP-BLOCKED-001",
|
|
111
|
+
"STOP-COPILOT-REVIEW-001",
|
|
112
|
+
"STOP-DONE-001",
|
|
113
|
+
"STOP-HUMAN-MERGE-001",
|
|
114
|
+
"STOP-INITIAL-COPILOT-001",
|
|
115
|
+
"STOP-MERGE-AUTH-001",
|
|
116
|
+
"STOP-QUIET-WATCHER-001",
|
|
117
|
+
"STOP-RECONCILE-001",
|
|
118
|
+
"STOP-STARTUP-INPUTS-001",
|
|
119
|
+
"STOP-WAIT-001",
|
|
120
|
+
"STYLE-CANONICAL-OPENER",
|
|
121
|
+
"STYLE-CONTRADICTION-LENS",
|
|
122
|
+
"STYLE-DEFINED-TERMS",
|
|
123
|
+
"STYLE-ID-SCHEME",
|
|
124
|
+
"STYLE-ID-STABILITY",
|
|
125
|
+
"STYLE-LEXICAL-SCAN-LIMIT",
|
|
126
|
+
"STYLE-PRECEDENCE-CONFLICT",
|
|
127
|
+
"STYLE-REFERENCE-BY-ID",
|
|
128
|
+
"STYLE-RFC2119-KEYWORDS",
|
|
129
|
+
"STYLE-RULE-MARKER",
|
|
130
|
+
"STYLE-SINGLE-OWNER",
|
|
131
|
+
"STYLE-TERM-MARKER",
|
|
132
|
+
"SUBISSUE-LEAN-BODY-NO-DUPLICATE",
|
|
133
|
+
"SUBISSUE-NO-ADHOC-BYPASS",
|
|
134
|
+
"TRACKER-BLOCKED-FAIL-CLOSED",
|
|
135
|
+
"TRACKER-ONE-ACTIVE-PR",
|
|
136
|
+
"TRACKER-PROJECTION-IDEMPOTENT",
|
|
137
|
+
"TRACKER-PROJECTION-REQUIRED-METADATA",
|
|
138
|
+
"VALIDATE-COVERAGE-THRESHOLD",
|
|
139
|
+
"VALIDATE-VERIFY-BEFORE-GATE",
|
|
140
|
+
"WORKFLOW-DOCS-NO-REDEFINE-HELPER",
|
|
141
|
+
"WORKTREE-CANONICAL-PATH",
|
|
142
|
+
"WORKTREE-CLEANUP",
|
|
143
|
+
"WORKTREE-CREATE-PROVISION",
|
|
144
|
+
"WORKTREE-DEDUPE",
|
|
145
|
+
"WORKTREE-DEFAULT-USE",
|
|
146
|
+
"WORKTREE-DEPS-ISOLATED",
|
|
147
|
+
"WORKTREE-FALLBACK"
|
|
148
|
+
]
|
|
149
|
+
}
|