dev-loops 0.1.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/.pi/dev-loop/defaults.yaml +477 -0
- package/AGENTS.md +25 -0
- package/CHANGELOG.md +18 -0
- package/LICENSE +21 -0
- package/README.md +178 -0
- package/agents/dev-loop.agent.md +82 -0
- package/agents/developer.agent.md +37 -0
- package/agents/docs.agent.md +33 -0
- package/agents/fixer.agent.md +53 -0
- package/agents/quality.agent.md +28 -0
- package/agents/refiner.agent.md +87 -0
- package/agents/review.agent.md +64 -0
- package/cli/index.mjs +424 -0
- package/extension/README.md +233 -0
- package/extension/checks.ts +94 -0
- package/extension/index.ts +131 -0
- package/extension/post-merge-update.ts +512 -0
- package/extension/presentation.ts +107 -0
- package/lib/dev-loops-core.mjs +284 -0
- package/package.json +103 -0
- package/scripts/README.md +1007 -0
- package/scripts/_cli-primitives.mjs +10 -0
- package/scripts/_core-helpers.mjs +30 -0
- package/scripts/docs/validate-links.mjs +567 -0
- package/scripts/docs/validate-no-duplicate-rules.mjs +250 -0
- package/scripts/github/_review-thread-mutations.mjs +214 -0
- package/scripts/github/capture-review-threads.mjs +180 -0
- package/scripts/github/create-draft-pr.mjs +108 -0
- package/scripts/github/detect-checkpoint-evidence.mjs +393 -0
- package/scripts/github/detect-linked-issue-pr.mjs +331 -0
- package/scripts/github/manage-sub-issues.mjs +394 -0
- package/scripts/github/probe-copilot-review.mjs +323 -0
- package/scripts/github/ready-for-review.mjs +93 -0
- package/scripts/github/reconcile-draft-gate.mjs +328 -0
- package/scripts/github/reply-resolve-review-thread.mjs +42 -0
- package/scripts/github/reply-resolve-review-threads.mjs +329 -0
- package/scripts/github/request-copilot-review.mjs +551 -0
- package/scripts/github/resolve-tracker-local-spec.mjs +205 -0
- package/scripts/github/stage-reviewer-draft.mjs +191 -0
- package/scripts/github/upsert-checkpoint-verdict.mjs +694 -0
- package/scripts/github/verify-fresh-review-context.mjs +125 -0
- package/scripts/github/write-gate-findings-log.mjs +212 -0
- package/scripts/loop/_checkpoint-io.mjs +55 -0
- package/scripts/loop/_checkpoint-paths.mjs +28 -0
- package/scripts/loop/_handoff-contract.mjs +230 -0
- package/scripts/loop/_inspect-run-viewer-adapter.mjs +345 -0
- package/scripts/loop/_loop-evidence.mjs +32 -0
- package/scripts/loop/_pr-runner-coordination.mjs +611 -0
- package/scripts/loop/_stale-runner-detection.mjs +145 -0
- package/scripts/loop/_steering-state-file.mjs +134 -0
- package/scripts/loop/build-handoff-envelope.mjs +181 -0
- package/scripts/loop/checkpoint-contract.mjs +49 -0
- package/scripts/loop/conductor-monitor.mjs +1850 -0
- package/scripts/loop/conductor.mjs +214 -0
- package/scripts/loop/copilot-pr-handoff.mjs +493 -0
- package/scripts/loop/debt-remediate.mjs +304 -0
- package/scripts/loop/detect-change-scope.mjs +102 -0
- package/scripts/loop/detect-copilot-loop-state.mjs +454 -0
- package/scripts/loop/detect-copilot-session-activity.mjs +186 -0
- package/scripts/loop/detect-initial-copilot-pr-state.mjs +318 -0
- package/scripts/loop/detect-internal-only-pr.mjs +270 -0
- package/scripts/loop/detect-issue-refinement-artifact.mjs +163 -0
- package/scripts/loop/detect-pr-gate-coordination-state.mjs +509 -0
- package/scripts/loop/detect-reviewer-loop-state.mjs +231 -0
- package/scripts/loop/detect-stale-runner.mjs +250 -0
- package/scripts/loop/detect-tracker-first-loop-state.mjs +76 -0
- package/scripts/loop/detect-tracker-pr-state.mjs +102 -0
- package/scripts/loop/info.mjs +267 -0
- package/scripts/loop/inspect-run-viewer/cli.mjs +117 -0
- package/scripts/loop/inspect-run-viewer/constants.mjs +80 -0
- package/scripts/loop/inspect-run-viewer/graph.mjs +757 -0
- package/scripts/loop/inspect-run-viewer/handoff-envelope-renderer.mjs +398 -0
- package/scripts/loop/inspect-run-viewer/inbox.mjs +308 -0
- package/scripts/loop/inspect-run-viewer/managed-instance.mjs +750 -0
- package/scripts/loop/inspect-run-viewer/rendering.mjs +411 -0
- package/scripts/loop/inspect-run-viewer/server.mjs +638 -0
- package/scripts/loop/inspect-run-viewer/shared.mjs +103 -0
- package/scripts/loop/inspect-run-viewer/status.mjs +715 -0
- package/scripts/loop/inspect-run-viewer-ci-changes.mjs +77 -0
- package/scripts/loop/inspect-run-viewer.mjs +82 -0
- package/scripts/loop/inspect-run.mjs +382 -0
- package/scripts/loop/outer-loop.mjs +419 -0
- package/scripts/loop/pr-runner-coordination.mjs +143 -0
- package/scripts/loop/pre-commit-branch-guard.mjs +68 -0
- package/scripts/loop/pre-flight-gate.mjs +236 -0
- package/scripts/loop/pre-pr-ready-gate.mjs +183 -0
- package/scripts/loop/pre-push-main-guard.mjs +103 -0
- package/scripts/loop/pre-write-remote-freshness-guard.mjs +32 -0
- package/scripts/loop/print-gates.mjs +42 -0
- package/scripts/loop/resolve-dev-loop-startup.mjs +533 -0
- package/scripts/loop/run-conductor-cycle.mjs +322 -0
- package/scripts/loop/run-queue.mjs +124 -0
- package/scripts/loop/run-refinement-audit.mjs +513 -0
- package/scripts/loop/run-watch-cycle.mjs +358 -0
- package/scripts/loop/steer-loop.mjs +841 -0
- package/scripts/loop/ui-designer-review-contract.mjs +76 -0
- package/scripts/loop/watch-initial-copilot-pr.mjs +253 -0
- package/scripts/projects/add-queue-item.mjs +528 -0
- package/scripts/projects/ensure-queue-board.mjs +837 -0
- package/scripts/projects/list-queue-items.mjs +489 -0
- package/scripts/projects/move-queue-item.mjs +549 -0
- package/scripts/projects/reorder-queue-item.mjs +518 -0
- package/scripts/refine/_refine-helpers.mjs +258 -0
- package/scripts/refine/prose-linkage-detector.mjs +92 -0
- package/scripts/refine/refinement-completeness-checker.mjs +88 -0
- package/scripts/refine/scope-boundary-cross-checker.mjs +163 -0
- package/scripts/refine/tree-integrity-validator.mjs +211 -0
- package/scripts/refine/verify.mjs +178 -0
- package/scripts/repo-wiki-local.mjs +156 -0
- package/scripts/repo-wiki.mjs +119 -0
- package/skills/copilot-pr-followup/SKILL.md +380 -0
- package/skills/dev-loop/SKILL.md +141 -0
- package/skills/dev-loop/scripts/dev-mode-context.mjs +152 -0
- package/skills/dev-loop/scripts/dev-mode-context.test.mjs +80 -0
- package/skills/dev-loop/scripts/init-phase.mjs +71 -0
- package/skills/dev-loop/scripts/log-bash-exit-1.mjs +25 -0
- package/skills/dev-loop/scripts/phase-files.mjs +29 -0
- package/skills/dev-loop/scripts/post-gate-verdict-fallback.mjs +480 -0
- package/skills/dev-loop/scripts/post-gate-verdict-fallback.test.mjs +732 -0
- package/skills/dev-loop/scripts/render-template.mjs +82 -0
- package/skills/dev-loop/scripts/render-template.test.mjs +63 -0
- package/skills/dev-loop/templates/bootstrap-agents.md +26 -0
- package/skills/dev-loop/templates/bootstrap-implementation-state.md +31 -0
- package/skills/dev-loop/templates/bootstrap-implementation-workflow.md +17 -0
- package/skills/dev-loop/templates/dev-mode-retrospective.md +15 -0
- package/skills/dev-loop/templates/dev-mode-review.md +17 -0
- package/skills/dev-loop/templates/dev-mode-skill-changes.md +11 -0
- package/skills/dev-loop/templates/merged-phase-plan.md +19 -0
- package/skills/dev-loop/templates/phase-doc.md +27 -0
- package/skills/dev-loop/templates/phase-summary.md +13 -0
- package/skills/dev-loop/templates/phase-variant.md +15 -0
- package/skills/dev-loop/templates/retrospective.md +11 -0
- package/skills/dev-loop/templates/review.md +32 -0
- package/skills/dev-loop/templates/ui-vision-review.md +55 -0
- package/skills/docs/acceptance-criteria-verification.md +21 -0
- package/skills/docs/anti-patterns.md +21 -0
- package/skills/docs/artifact-authority-contract.md +119 -0
- package/skills/docs/confirmation-rules.md +28 -0
- package/skills/docs/copilot-ci-status-contract.md +52 -0
- package/skills/docs/copilot-loop-operations.md +233 -0
- package/skills/docs/debt-remediation-contract.md +107 -0
- package/skills/docs/entrypoint-strategies.md +115 -0
- package/skills/docs/epic-tree-refinement-procedure.md +234 -0
- package/skills/docs/issue-intake-procedure.md +235 -0
- package/skills/docs/main-agent-contract.md +72 -0
- package/skills/docs/merge-preconditions.md +29 -0
- package/skills/docs/pr-lifecycle-contract.md +209 -0
- package/skills/docs/public-dev-loop-contract.md +497 -0
- package/skills/docs/retrospective-checkpoint-contract.md +159 -0
- package/skills/docs/stop-conditions.md +29 -0
- package/skills/docs/structural-quality.md +42 -0
- package/skills/docs/tracker-first-loop-state.md +281 -0
- package/skills/docs/validation-policy.md +27 -0
- package/skills/docs/workflow-handoff-contract.md +135 -0
- package/skills/final-approval/SKILL.md +19 -0
- package/skills/local-implementation/SKILL.md +640 -0
|
@@ -0,0 +1,234 @@
|
|
|
1
|
+
# Epic tree refinement procedure
|
|
2
|
+
|
|
3
|
+
This document is the canonical procedure for depth-first, top-down-then-bottom-up refinement of
|
|
4
|
+
an existing GitHub sub-issue tree (parent → children → grandchildren).
|
|
5
|
+
|
|
6
|
+
Use it together with:
|
|
7
|
+
- [Issue Intake Procedure](./issue-intake-procedure.md) — Phase 3b calls this procedure for epic decomposition
|
|
8
|
+
- [Sub-Issue Tree Contract](../../docs/sub-issue-tree-contract.md) — authoritative sub-issue tooling (source-repo reference)
|
|
9
|
+
|
|
10
|
+
When you have a tree of GitHub issues that already exists and you need to align AC, DoD, scope
|
|
11
|
+
boundaries, and delegation contracts across all levels, follow this procedure. It is deterministic
|
|
12
|
+
enough that a fresh agent can run it without prior context about the tree.
|
|
13
|
+
|
|
14
|
+
---
|
|
15
|
+
|
|
16
|
+
## Definitions
|
|
17
|
+
|
|
18
|
+
| Term | Meaning |
|
|
19
|
+
|---|---|
|
|
20
|
+
| **Root** | The umbrella/epic issue at the top of the tree |
|
|
21
|
+
| **Parent** | Any issue that has at least one sub-issue child |
|
|
22
|
+
| **Child** | A direct sub-issue of a parent |
|
|
23
|
+
| **Leaf** | An issue with no sub-issue children |
|
|
24
|
+
| **Phase table** | A section of the root/parent body that names each child and what it owns vs excludes |
|
|
25
|
+
| **Scope boundary** | Explicit text in an issue body: `"This issue owns X. It does NOT own Y (#NNN)."` |
|
|
26
|
+
| **AC/DoD matrix** | A two-column table mapping each acceptance criterion to its corresponding DoD checklist item(s) |
|
|
27
|
+
|
|
28
|
+
---
|
|
29
|
+
|
|
30
|
+
## Prerequisites
|
|
31
|
+
|
|
32
|
+
Before starting, verify:
|
|
33
|
+
|
|
34
|
+
1. The root issue and all intended children/grandchildren exist as GitHub issues in the repo.
|
|
35
|
+
2. The sub-issue tree is attached (run `node <resolved-skill-scripts>/github/manage-sub-issues.mjs list --repo <repo> --issue <root>` to inspect it).
|
|
36
|
+
3. You have the resolved repo slug (`owner/name`).
|
|
37
|
+
|
|
38
|
+
Optional but recommended before and after edits:
|
|
39
|
+
|
|
40
|
+
```sh
|
|
41
|
+
dev-loops refine verify --issue <root> --repo <repo>
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
This verification command checks linkage policy, sibling scope boundaries, refinement completeness,
|
|
45
|
+
and tree integrity in one deterministic pass.
|
|
46
|
+
|
|
47
|
+
If the sub-issue tree does not yet exist, use [Issue Intake Procedure](./issue-intake-procedure.md) Phase 3b to decompose and attach it first.
|
|
48
|
+
|
|
49
|
+
---
|
|
50
|
+
|
|
51
|
+
## Phases
|
|
52
|
+
|
|
53
|
+
### Phase A — Root refinement (serial)
|
|
54
|
+
|
|
55
|
+
Refine the root issue **first** before touching any child.
|
|
56
|
+
|
|
57
|
+
For the root issue:
|
|
58
|
+
1. Read the current body: `gh issue view <root> --repo <repo> --json number,title,body`
|
|
59
|
+
2. Confirm the problem statement is clear and scoped
|
|
60
|
+
3. Confirm a **phase scope table** exists — one row per immediate child naming what each child
|
|
61
|
+
owns and what it excludes; add or update this table if missing
|
|
62
|
+
4. Confirm **AC checklist** covers the end-to-end goal (not the implementation details owned by children)
|
|
63
|
+
5. Confirm **DoD checklist** — merge-ready condition for the root issue as a whole
|
|
64
|
+
6. Confirm **AC/DoD matrix** — each AC maps to at least one DoD item
|
|
65
|
+
7. Confirm **non-goals** section — prevents scope creep into adjacent areas
|
|
66
|
+
8. Write the updated body to a tmp file: `tmp/issues/<root>/refinement/root-body.md`
|
|
67
|
+
9. Show the diff and obtain confirmation before mutating GitHub
|
|
68
|
+
10. Apply: `gh issue edit <root> --repo <repo> --body-file tmp/issues/<root>/refinement/root-body.md`
|
|
69
|
+
|
|
70
|
+
**Gate:** Phase B must not start until Phase A is complete and the root body is updated on GitHub.
|
|
71
|
+
|
|
72
|
+
---
|
|
73
|
+
|
|
74
|
+
### Phase B — Descend: refine children against parent (parallel fan-out per level)
|
|
75
|
+
|
|
76
|
+
For **each level** of the tree (breadth-first traversal of levels, depth-first traversal within
|
|
77
|
+
a single branch), refine all siblings in parallel — siblings are independent and only need the
|
|
78
|
+
parent's updated body, not each other's output.
|
|
79
|
+
|
|
80
|
+
**For each issue at this level:**
|
|
81
|
+
|
|
82
|
+
1. Read the parent's updated body: `gh issue view <parent> --repo <repo> --json number,title,body`
|
|
83
|
+
2. Read the current child body: `gh issue view <child> --repo <repo> --json number,title,body`
|
|
84
|
+
3. Verify the child's scope matches what the parent's phase table delegates to it
|
|
85
|
+
4. Identify any overlap with sibling issues (read sibling titles/bodies if needed)
|
|
86
|
+
5. Refine the child body with:
|
|
87
|
+
- **Scope boundary** (explicit): `"This issue owns X. It does NOT own Y (#NNN) or Z (#MMM)."`
|
|
88
|
+
- **AC checklist** specific to this child's bounded scope
|
|
89
|
+
- **DoD checklist** — when is this child independently closable?
|
|
90
|
+
- **AC/DoD matrix**
|
|
91
|
+
- **Non-goals** — what this child intentionally excludes
|
|
92
|
+
6. Write refined body to `tmp/issues/<child>/refinement/child-body.md`
|
|
93
|
+
7. Show the diff and obtain confirmation before mutating (unless running unattended with explicit authorization)
|
|
94
|
+
8. Apply: `gh issue edit <child> --repo <repo> --body-file tmp/issues/<child>/refinement/child-body.md`
|
|
95
|
+
|
|
96
|
+
**Parallelism rule:** All siblings at the same level can be refined concurrently. No child needs
|
|
97
|
+
another child's output; each child only reads the parent's contract and its own current body.
|
|
98
|
+
|
|
99
|
+
**Serial gate between levels:** All children at level N must complete before descending to level N+1.
|
|
100
|
+
|
|
101
|
+
Repeat Phase B until all leaves are refined.
|
|
102
|
+
|
|
103
|
+
---
|
|
104
|
+
|
|
105
|
+
### Phase C — Ascend: reconcile parents with children (parallel fan-out per level)
|
|
106
|
+
|
|
107
|
+
After all children under a given parent are refined, reconcile that parent. Work bottom-up.
|
|
108
|
+
|
|
109
|
+
All parents at the same depth can be reconciled in parallel (they only need their own children's
|
|
110
|
+
updated bodies, not sibling parents).
|
|
111
|
+
|
|
112
|
+
**For each parent (bottom-up):**
|
|
113
|
+
|
|
114
|
+
1. Re-read the parent body: `gh issue view <parent> --repo <repo> --json number,title,body`
|
|
115
|
+
2. Re-read all direct children bodies
|
|
116
|
+
3. Verify:
|
|
117
|
+
- The parent's phase scope table still matches what the children now claim to own
|
|
118
|
+
- No orphaned responsibilities (parent promised something no child owns)
|
|
119
|
+
- No duplicate ownership (two children claiming the same thing)
|
|
120
|
+
4. Update the parent's phase scope table and AC/DoD as needed to reflect what children now explicitly own
|
|
121
|
+
5. Write refined body to `tmp/issues/<parent>/refinement/parent-reconciled-body.md`
|
|
122
|
+
6. Show the diff and obtain confirmation before mutating
|
|
123
|
+
7. Apply: `gh issue edit <parent> --repo <repo> --body-file tmp/issues/<parent>/refinement/parent-reconciled-body.md`
|
|
124
|
+
|
|
125
|
+
**Serial gate between levels:** All parents at depth N must complete reconciliation before ascending to depth N-1.
|
|
126
|
+
|
|
127
|
+
---
|
|
128
|
+
|
|
129
|
+
### Phase D — Root final reconcile (serial)
|
|
130
|
+
|
|
131
|
+
After all immediate children of the root have been reconciled:
|
|
132
|
+
|
|
133
|
+
1. Re-read the root body: `gh issue view <root> --repo <repo> --json number,title,body`
|
|
134
|
+
2. Re-read all immediate children bodies
|
|
135
|
+
3. Verify:
|
|
136
|
+
- Phase scope table matches actual child scope
|
|
137
|
+
- Dependency chain is correct (does execution order in the sub-issue tree match dependencies?)
|
|
138
|
+
- No orphaned responsibilities; no duplicate ownership
|
|
139
|
+
4. Update the root body with the final reconciled phase scope table and AC/DoD
|
|
140
|
+
5. Write to `tmp/issues/<root>/refinement/root-final-body.md`
|
|
141
|
+
6. Show the diff and obtain confirmation before mutating
|
|
142
|
+
7. Apply: `gh issue edit <root> --repo <repo> --body-file tmp/issues/<root>/refinement/root-final-body.md`
|
|
143
|
+
8. Verify the sub-issue tree still reflects the correct execution order:
|
|
144
|
+
```sh
|
|
145
|
+
node <resolved-skill-scripts>/github/manage-sub-issues.mjs verify \
|
|
146
|
+
--repo <repo> --issue <root> --expected <n1,n2,...> --ordered
|
|
147
|
+
```
|
|
148
|
+
|
|
149
|
+
**Gate:** Root final reconcile completes the procedure. All issues in the tree must now have:
|
|
150
|
+
- AC checklist, DoD checklist, AC/DoD matrix, non-goals, explicit scope boundary
|
|
151
|
+
|
|
152
|
+
---
|
|
153
|
+
|
|
154
|
+
## Rules
|
|
155
|
+
|
|
156
|
+
- **No implementation, no PRs, no Copilot assignment** — this procedure is refinement-only
|
|
157
|
+
- **Use `gh issue edit`** to apply changes directly — do not create new issues or PRs
|
|
158
|
+
- **No prose parent/child links in bodies** — GitHub sub-issues API handles hierarchy
|
|
159
|
+
- **Each issue must have:** AC checklist, DoD checklist, non-goals, AC/DoD matrix, scope boundary
|
|
160
|
+
- **Scope boundary format:** `"This issue owns X. It does NOT own Y (#NNN) or Z (#MMM)."`
|
|
161
|
+
- **Show the diff** and get confirmation before each `gh issue edit` mutation (unless unattended with explicit authorization)
|
|
162
|
+
- **Write tmp artifacts** under `tmp/issues/<number>/refinement/` before applying
|
|
163
|
+
- **Do not duplicate** the child list in parent bodies — the sub-issue tree API owns hierarchy
|
|
164
|
+
|
|
165
|
+
---
|
|
166
|
+
|
|
167
|
+
## Parallelism model
|
|
168
|
+
|
|
169
|
+
Sibling refinements are independent: siblings only need the parent's contract, not each other's
|
|
170
|
+
output. The wall-clock complexity is O(depth), not O(nodes).
|
|
171
|
+
|
|
172
|
+
```text
|
|
173
|
+
Phase A: [root] serial (1 step)
|
|
174
|
+
Phase B: [child1 || child2 || child3] parallel per level (1 step per level)
|
|
175
|
+
[gc1a || gc1b || gc2a || gc3a] parallel per level (1 step per level)
|
|
176
|
+
Phase C: [child1 || child2 || child3] parallel per level (1 step per level)
|
|
177
|
+
Phase D: [root] serial (1 step)
|
|
178
|
+
```
|
|
179
|
+
|
|
180
|
+
Total serial steps for a tree with depth D: `1 + (D-1) + (D-1) + 1 = 2D`
|
|
181
|
+
|
|
182
|
+
**Fan-out rule:** At any level, when a parent is refined, ALL its children can be refined in parallel.
|
|
183
|
+
|
|
184
|
+
**Serial gates:**
|
|
185
|
+
- Root refinement must complete before any child starts
|
|
186
|
+
- A parent's reconciliation must wait for ALL its children to finish
|
|
187
|
+
- Root reconciliation must wait for all immediate children to reconcile
|
|
188
|
+
|
|
189
|
+
---
|
|
190
|
+
|
|
191
|
+
## Completion criteria
|
|
192
|
+
|
|
193
|
+
The procedure is complete when all issues in the tree satisfy:
|
|
194
|
+
|
|
195
|
+
| Check | How to verify |
|
|
196
|
+
|---|---|
|
|
197
|
+
| AC checklist present | Issue body contains `## Acceptance Criteria` with at least one `- [ ]` item |
|
|
198
|
+
| DoD checklist present | Issue body contains `## Definition of Done` with at least one `- [ ]` item |
|
|
199
|
+
| AC/DoD matrix present | Issue body contains a two-column table mapping AC items to DoD items |
|
|
200
|
+
| Non-goals present | Issue body contains `## Non-goals` section |
|
|
201
|
+
| Scope boundary present | Issue body contains explicit `"This issue owns ... It does NOT own ..."` text |
|
|
202
|
+
| No orphaned responsibilities | Each thing the parent delegates maps to exactly one child |
|
|
203
|
+
| No duplicate ownership | No two siblings claim the same responsibility |
|
|
204
|
+
| Sub-issue tree order valid | `manage-sub-issues.mjs verify --ordered` exits 0 |
|
|
205
|
+
|
|
206
|
+
---
|
|
207
|
+
|
|
208
|
+
## Example traversal for a 3-level tree
|
|
209
|
+
|
|
210
|
+
For root #715 with children #716, #717, #718 and grandchildren #720–#729:
|
|
211
|
+
|
|
212
|
+
```
|
|
213
|
+
Phase A: #715 refine
|
|
214
|
+
Phase B level 2 (parallel): #716 refine ‖ #717 refine ‖ #718 refine
|
|
215
|
+
Phase B level 3 (parallel): #720 ‖ #721 ‖ #722 (under #716)
|
|
216
|
+
#723 ‖ #724 (under #717)
|
|
217
|
+
#726 ‖ #729 ‖ #727 ‖ #728 (under #718)
|
|
218
|
+
Phase C level 2 (parallel): #716 reconcile ‖ #717 reconcile ‖ #718 reconcile
|
|
219
|
+
Phase D: #715 root reconcile
|
|
220
|
+
```
|
|
221
|
+
|
|
222
|
+
Wall-clock serial steps: 5 (not 17).
|
|
223
|
+
|
|
224
|
+
---
|
|
225
|
+
|
|
226
|
+
## Relationship to other procedures
|
|
227
|
+
|
|
228
|
+
| Procedure | When to use it |
|
|
229
|
+
|---|---|
|
|
230
|
+
| [Issue Intake Procedure](./issue-intake-procedure.md) Phase 3b | *Creating* a new sub-issue tree from an umbrella issue |
|
|
231
|
+
| **This procedure** | *Refining* an existing sub-issue tree to align scope, AC, DoD, and delegation contracts |
|
|
232
|
+
| [Sub-Issue Tree Contract](../../docs/sub-issue-tree-contract.md) | Tooling for listing, attaching, ordering, and verifying sub-issue trees |
|
|
233
|
+
|
|
234
|
+
These are complementary. Phase 3b creates the structure; this procedure aligns the contracts.
|
|
@@ -0,0 +1,235 @@
|
|
|
1
|
+
# Issue intake procedure
|
|
2
|
+
|
|
3
|
+
This document is the canonical owner of the routed `issue_intake` procedure behind the public `dev-loop` façade.
|
|
4
|
+
|
|
5
|
+
Use it together with:
|
|
6
|
+
- [Copilot PR Follow-up Skill](../copilot-pr-followup/SKILL.md)
|
|
7
|
+
- [Public Dev Loop Contract](./public-dev-loop-contract.md)
|
|
8
|
+
- [Retrospective Checkpoint Contract](./retrospective-checkpoint-contract.md) when the current step depends on async start/resume/status or retrospective enforcement
|
|
9
|
+
|
|
10
|
+
When routed work is issue-first rather than already in active PR follow-up, use the procedure below before entering the shared post-PR loop. Treat this document as the issue-refinement specialist procedure for the routed `issue_intake` seam.
|
|
11
|
+
|
|
12
|
+
## New-idea safety layer (default contract in this repo)
|
|
13
|
+
|
|
14
|
+
For **all new ideas** that are not already anchored to an existing issue (including abstract ideas such as plain-language requests without an issue number or plan-doc path), apply this procedure-owned intake contract before any GitHub mutation:
|
|
15
|
+
|
|
16
|
+
- procedure owns classification; human operator gates all mutations
|
|
17
|
+
- run classification in fresh context by default
|
|
18
|
+
- run classification asynchronously when practical
|
|
19
|
+
- run async fan-out / fan-in proposal generation by default when practical
|
|
20
|
+
- emit a proposal artifact before any GitHub state-changing mutation, including create/edit/retitle/collapse/link operations
|
|
21
|
+
- default to create-new over overwrite/update when a new tracked artifact is justified
|
|
22
|
+
- do not repurpose/retitle/collapse/overwrite an existing issue unless that exact mutation is explicitly proposed and explicitly approved
|
|
23
|
+
- after approval, run a second async mutation pass (dispatched via the procedure) instead of mutating directly from inherited context
|
|
24
|
+
- verify post-mutation artifact state and record what actually changed
|
|
25
|
+
|
|
26
|
+
Deterministic intake + mutation-gate state machine:
|
|
27
|
+
|
|
28
|
+
```text
|
|
29
|
+
idea_received
|
|
30
|
+
-> fresh_context_started
|
|
31
|
+
-> fanout_started
|
|
32
|
+
-> fanin_complete
|
|
33
|
+
-> artifact_scan_complete
|
|
34
|
+
-> classified
|
|
35
|
+
-> proposal_emitted
|
|
36
|
+
-> awaiting_user_approval
|
|
37
|
+
-> ready_for_mutation
|
|
38
|
+
-> mutation_executed
|
|
39
|
+
-> mutation_verified
|
|
40
|
+
-> done
|
|
41
|
+
|
|
42
|
+
stop states:
|
|
43
|
+
- stopped_overlap_needs_decision
|
|
44
|
+
- stopped_low_confidence
|
|
45
|
+
- stopped_explicit_reject
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
Proposal artifact contract:
|
|
49
|
+
- human-readable Markdown proposal
|
|
50
|
+
- machine-readable JSON snapshot
|
|
51
|
+
- write temporary artifacts under `Proposal` (`tmp/new-idea-intake/<run-id>/proposal.md`) and `tmp/new-idea-intake/<run-id>/proposal.json`
|
|
52
|
+
|
|
53
|
+
If the Phase 1 preflight verdict is `pause_for_clarification`, stop and ask.
|
|
54
|
+
If the intake state machine stops at `stopped_overlap_needs_decision` or `stopped_low_confidence`, stop and ask.
|
|
55
|
+
If the intake state machine stops at `stopped_explicit_reject`, stop and record that the proposal was rejected; do not mutate GitHub.
|
|
56
|
+
After approval, start a separate async mutation pass (dispatched via the procedure) that consumes the approved proposal and emits a post-mutation verification artifact. Emit a concise post-mutation verification artifact and record what the mutation pass actually changed and verify the resulting issue/artifact state.
|
|
57
|
+
|
|
58
|
+
## Unattended issue-first execution and automatic re-entry
|
|
59
|
+
|
|
60
|
+
When the user explicitly authorizes unattended execution for a specific issue/PR scope, continue through the normal loop mutations for that scope without stopping at every intermediate phase boundary.
|
|
61
|
+
|
|
62
|
+
Under that unattended execution contract:
|
|
63
|
+
- automatically detect the current lifecycle entrypoint from existing GitHub state
|
|
64
|
+
- use the deterministic helper/state-machine surface as the authority for current-state routing and next-step selection
|
|
65
|
+
- if local facts, GitHub facts, and helper/state-machine output do not agree, or the state is materially unclear, contradictory, off-trail, or not cleanly covered, stop and ask for human direction rather than guessing
|
|
66
|
+
- a pre-existing PR is not a stop-by-default condition
|
|
67
|
+
- If a PR already exists, classify the post-assignment seam before follow-up
|
|
68
|
+
- `waiting_for_initial_copilot_implementation`: keep waiting
|
|
69
|
+
- `linked_pr_ready_for_followup`: route to the existing PR follow-up path immediately; resume from that PR
|
|
70
|
+
- when routing leaves bootstrap wait for `linked_pr_ready_for_followup`, do not stop only because local isolation is required; re-enter the same PR follow-up from a safe isolated checkout/worktree
|
|
71
|
+
- When the draft PR appears, classify whether it is still the bootstrap-only Copilot draft before entering normal follow-up
|
|
72
|
+
- if a child async run exits while the deterministic state is still non-terminal (for example `waiting_for_copilot_review`), automatically resume/restart follow-up when continuation is feasible instead of requiring manual operator restart
|
|
73
|
+
- continue unattended until the human approval checkpoint unless a genuine stop condition is reached
|
|
74
|
+
- stop for a human approval decision by default
|
|
75
|
+
- after approval, report `waiting_for_merge_authorization` and stop again unless merge has been explicitly authorized
|
|
76
|
+
- this does **not** imply unattended merge by default
|
|
77
|
+
|
|
78
|
+
Issue-first shorthand such as `auto dev loop on issue <n>` should preserve this same stop boundary and human approval checkpoint default.
|
|
79
|
+
|
|
80
|
+
## Phase 1 — Preflight intake
|
|
81
|
+
|
|
82
|
+
Before any automation, answer these questions:
|
|
83
|
+
1. smallest executable work item
|
|
84
|
+
2. existing issue check
|
|
85
|
+
3. scope clarity
|
|
86
|
+
4. acceptance criteria
|
|
87
|
+
5. verification path
|
|
88
|
+
6. active PR check
|
|
89
|
+
|
|
90
|
+
Accepted input types:
|
|
91
|
+
- GitHub issue number or URL
|
|
92
|
+
- plan-doc path
|
|
93
|
+
- abstract roadmap idea
|
|
94
|
+
|
|
95
|
+
Preflight verdicts:
|
|
96
|
+
- `proceed`
|
|
97
|
+
- `proceed_with_assumptions`
|
|
98
|
+
- `pause_for_clarification`
|
|
99
|
+
|
|
100
|
+
## Phase 2 — Input normalization
|
|
101
|
+
|
|
102
|
+
### From a GitHub issue number or URL
|
|
103
|
+
|
|
104
|
+
- if the input is a full GitHub issue URL, parse `<owner/name>` and `<number>`
|
|
105
|
+
- fetch with `gh issue view <number> --repo <owner/name> --json number,title,body,state,labels,assignees,milestone`
|
|
106
|
+
- If the issue is closed, stop for a user decision before proceeding
|
|
107
|
+
- detect an existing linked PR with the deterministic linked-PR helper:
|
|
108
|
+
`node <resolved-skill-scripts>/github/detect-linked-issue-pr.mjs --repo <resolved-repo> --issue <number>`
|
|
109
|
+
- treat the helper output as authoritative for linked-PR detection/selection
|
|
110
|
+
- do not re-implement linked-event query behavior, pagination, repo filtering, or tie-break logic
|
|
111
|
+
- do not rely only on PR title/body containing a literal issue number
|
|
112
|
+
- treat an open linked PR as the active implementation for this issue
|
|
113
|
+
- once an open linked PR exists, that PR is the only canonical follow-up artifact for the issue; attach follow-up work to it and do not open another PR unless the prior PR was explicitly superseded and reconciled first
|
|
114
|
+
- if a PR already exists, classify bootstrap-wait versus follow-up:
|
|
115
|
+
`node <resolved-skill-scripts>/loop/detect-initial-copilot-pr-state.mjs --repo <resolved-repo> --issue <number>`
|
|
116
|
+
- `waiting_for_initial_copilot_implementation`: keep waiting; in durable-auto mode use:
|
|
117
|
+
```sh
|
|
118
|
+
node <resolved-skill-scripts>/loop/watch-initial-copilot-pr.mjs --repo <resolved-repo> --issue <number>
|
|
119
|
+
```
|
|
120
|
+
- must use the dedicated `watch-initial-copilot-pr.mjs` watcher and its default 1-hour watch budget
|
|
121
|
+
- quiet/no-activity watch observations alone are non-terminal
|
|
122
|
+
- `ready_for_followup`: linked PR has become substantive; resume from that PR
|
|
123
|
+
- `timed_out`: observational first; refresh authoritative state
|
|
124
|
+
- if refreshed state is still `waiting_for_initial_copilot_implementation`, remain attached to the same durable wait seam and continue waiting
|
|
125
|
+
- if the refreshed state exits this seam, route based on that refreshed state instead of surfacing timeout attention
|
|
126
|
+
- when the refreshed state is `linked_pr_ready_for_followup`, re-enter normal PR follow-up; if the follow-up handoff carries `conductorRouting.handoffEnvelope.requiresLocalIsolation=true`, perform the expected isolated-checkout/worktree handoff and continue
|
|
127
|
+
- only surface timeout attention when the seam's durable watch budget is actually exhausted
|
|
128
|
+
- for explicit inspect/status requests, report the still-waiting state and exit normally
|
|
129
|
+
- carry that resolved repo slug through every later GitHub issue/PR command
|
|
130
|
+
|
|
131
|
+
### From a plan-doc path
|
|
132
|
+
|
|
133
|
+
- Resolve the target repository slug for this work item before any GitHub search or mutation
|
|
134
|
+
- default to the current repository slug
|
|
135
|
+
- if the plan-doc reference explicitly points at another GitHub repository, resolve `<resolved-repo>` first
|
|
136
|
+
- search existing issues with:
|
|
137
|
+
```sh
|
|
138
|
+
gh issue list --repo <resolved-repo> --state all --search "<title keywords>"
|
|
139
|
+
```
|
|
140
|
+
- If a matching issue exists:
|
|
141
|
+
- if the matching issue is closed, stop for a user decision before proceeding
|
|
142
|
+
- if that matching issue turns out to be closed, stop for a user decision
|
|
143
|
+
- if a PR already exists, classify bootstrap-wait versus follow-up
|
|
144
|
+
- if a governing plan doc or roadmap section actually applies, follow the plan-doc normalization path above
|
|
145
|
+
|
|
146
|
+
### From an abstract idea
|
|
147
|
+
|
|
148
|
+
- otherwise search existing issues directly
|
|
149
|
+
- if a matching issue exists, follow the issue-number/URL normalization path
|
|
150
|
+
- resolve `<resolved-repo>` for this work item using the same rule as the plan-doc path
|
|
151
|
+
|
|
152
|
+
## Phase 3 — Async issue refinement
|
|
153
|
+
|
|
154
|
+
Before updating or assigning the issue, refine it asynchronously when practical. Keep issue refinement separate from the phase-scoped refiner used by the local implementation workflow. Use the `refiner` agent for this review-only issue-refinement chain, including the consolidation/fan-in step; do not route those comparison/synthesis steps through `dev-loop` + `local_implementation` (the strategy loaded by `skills/local-implementation`).
|
|
155
|
+
|
|
156
|
+
When issue refinement would benefit from structural/slop discovery and the likely code/doc surface is knowable, run the bounded audit first.
|
|
157
|
+
- write the issue-refinement audit artifact to `tmp/issues/issue-<number>/audit/refinement-audit-summary.json`
|
|
158
|
+
- use the same audit artifact shape as local phase refinement
|
|
159
|
+
- keep the audit bounded to the named files/areas for this issue; do not widen into a full-repo scan
|
|
160
|
+
- pass a concise audit summary into refiner fan-out and fan-in
|
|
161
|
+
- require the issue-refinement write-up to translate audit findings into scope, AC/DoD, risks, and explicit non-goals without silently broadening the issue
|
|
162
|
+
|
|
163
|
+
## Phase 3b — Epic decomposition with GitHub sub-issue trees
|
|
164
|
+
|
|
165
|
+
When the work item is an umbrella/epic issue that must be decomposed into bounded child slices,
|
|
166
|
+
use **real GitHub sub-issue trees** as the default durable output — not body checklists, not
|
|
167
|
+
a manual follow-up linking step.
|
|
168
|
+
|
|
169
|
+
Prefer real sub-issue linkage over parent-body checklists when a work tree is intended.
|
|
170
|
+
A parent issue body should stay lean once the tree exists: keep scope, acceptance criteria, and
|
|
171
|
+
non-goals there, but do **not** duplicate the ordered child list in the body.
|
|
172
|
+
|
|
173
|
+
Full decomposition flow:
|
|
174
|
+
|
|
175
|
+
1. refine umbrella issue framing (scope, acceptance criteria, non-goals)
|
|
176
|
+
2. define bounded child slices — each slice must be independently closable
|
|
177
|
+
3. create child issues with `gh issue create --repo <resolved-repo> --assignee @me`
|
|
178
|
+
4. attach each child as a real sub-issue:
|
|
179
|
+
```sh
|
|
180
|
+
node <resolved-skill-scripts>/github/manage-sub-issues.mjs add \
|
|
181
|
+
--repo <resolved-repo> --issue <parent-number> --child <child-number>
|
|
182
|
+
```
|
|
183
|
+
5. set execution order (highest priority first):
|
|
184
|
+
```sh
|
|
185
|
+
node <resolved-skill-scripts>/github/manage-sub-issues.mjs reorder \
|
|
186
|
+
--repo <resolved-repo> --issue <parent-number> --order <n1,n2,...>
|
|
187
|
+
```
|
|
188
|
+
6. verify the resulting tree:
|
|
189
|
+
```sh
|
|
190
|
+
node <resolved-skill-scripts>/github/manage-sub-issues.mjs verify \
|
|
191
|
+
--repo <resolved-repo> --issue <parent-number> --expected <n1,n2,...> [--ordered]
|
|
192
|
+
```
|
|
193
|
+
7. keep the parent issue body lean — sequencing and progress now live in the sub-issue tree
|
|
194
|
+
|
|
195
|
+
To inspect the current tree at any time:
|
|
196
|
+
```sh
|
|
197
|
+
node <resolved-skill-scripts>/github/manage-sub-issues.mjs list \
|
|
198
|
+
--repo <resolved-repo> --issue <parent-number>
|
|
199
|
+
```
|
|
200
|
+
|
|
201
|
+
Do **not** re-implement sub-issue management ad hoc or bypass `manage-sub-issues.mjs`.
|
|
202
|
+
Do **not** maintain a body checklist that duplicates the sub-issue tree.
|
|
203
|
+
|
|
204
|
+
For the full `manage-sub-issues.mjs` contract, use [Sub-Issue Tree Contract](../../docs/sub-issue-tree-contract.md) when working in the `dev-loops` source repository. That contract is a source-repo reference, not part of the bundled installed skill-doc surface. For installed or normalized skill copies, inspect the target repository docs/source directly instead of assuming a bundled shared-doc copy exists.
|
|
205
|
+
|
|
206
|
+
When an existing sub-issue tree needs **scope alignment, AC/DoD contracts, and delegation boundary refinement** across all levels (parent → children → grandchildren), use the [Epic Tree Refinement Procedure](./epic-tree-refinement-procedure.md) — it owns the deterministic depth-first, top-down-then-bottom-up refinement protocol.
|
|
207
|
+
|
|
208
|
+
## Phase 4 — Copilot handoff and bootstrap wait
|
|
209
|
+
|
|
210
|
+
Before updating the GitHub issue body, show the diff and get explicit confirmation. Then use:
|
|
211
|
+
```sh
|
|
212
|
+
gh issue edit <number> --repo <resolved-repo> --body-file <updated-body-file>
|
|
213
|
+
gh issue edit <number> --repo <resolved-repo> --add-assignee copilot-swe-agent
|
|
214
|
+
```
|
|
215
|
+
Verify assignment with:
|
|
216
|
+
```sh
|
|
217
|
+
gh issue view <number> --repo <resolved-repo> --json assignees
|
|
218
|
+
```
|
|
219
|
+
|
|
220
|
+
When the linked PR becomes substantive, keep the shared loop scoped to the resolved repo, for example:
|
|
221
|
+
```sh
|
|
222
|
+
node <resolved-skill-scripts>/loop/copilot-pr-handoff.mjs --repo <resolved-repo> --pr <number>
|
|
223
|
+
gh pr edit <pr-number> --repo <resolved-repo> --title "..." --body-file <body-file>
|
|
224
|
+
gh pr ready <pr-number> --repo <resolved-repo>
|
|
225
|
+
gh pr review <pr-number> --repo <resolved-repo> --approve --body "..."
|
|
226
|
+
node <resolved-skill-scripts>/github/detect-checkpoint-evidence.mjs --repo <resolved-repo> --pr <pr-number>
|
|
227
|
+
gh pr merge <pr-number> --repo <resolved-repo> --squash --delete-branch
|
|
228
|
+
```
|
|
229
|
+
|
|
230
|
+
Bootstrap-wait interpretation remains fail-closed and observational-first:
|
|
231
|
+
- `ready_for_followup`: linked PR has become substantive; resume from that PR
|
|
232
|
+
- `timed_out`: observational first; refresh authoritative state
|
|
233
|
+
- if refreshed state is still `waiting_for_initial_copilot_implementation`, remain attached to the same durable wait seam and continue waiting
|
|
234
|
+
- if refreshed state exits that seam, route based on refreshed state instead of surfacing timeout attention
|
|
235
|
+
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
# Main-agent delegation contract
|
|
2
|
+
|
|
3
|
+
> **Absolute read-only boundary.** The main agent must never mutate files tracked by the repository.
|
|
4
|
+
> All mutations flow through the `dev-loop` async subagent.
|
|
5
|
+
|
|
6
|
+
## Contract
|
|
7
|
+
|
|
8
|
+
The main agent is **read-only** for every file tracked by the repository. Every
|
|
9
|
+
write, edit, delete, commit, branch, push, and PR lifecycle operation must flow
|
|
10
|
+
through the `dev-loop` async subagent.
|
|
11
|
+
|
|
12
|
+
This contract is a hard rule, not a default or guideline. The main agent must
|
|
13
|
+
never rationalize a direct mutation — not because the work is small, not
|
|
14
|
+
because "the user said yes," not because it is running from a worktree.
|
|
15
|
+
|
|
16
|
+
## Main agent owns (allowed)
|
|
17
|
+
|
|
18
|
+
- Read, inspect, search any repo file
|
|
19
|
+
- `git worktree list`, `git status`, `git log` (read-only git). `git fetch` is also allowed (updates local refs but does not touch tracked working-tree files).
|
|
20
|
+
- `gh issue view / create / edit / comment / close` (GitHub API, not file mutations)
|
|
21
|
+
- `gh pr view / list` (read-only GitHub API)
|
|
22
|
+
- Write to `/tmp` or other non-repo paths (e.g., issue body drafts)
|
|
23
|
+
- Delegate to the `dev-loop` agent (async, with worktree cwd)
|
|
24
|
+
- Report findings, ask questions, get confirmation
|
|
25
|
+
- `npm test`, `npm run verify` (read-only validation)
|
|
26
|
+
|
|
27
|
+
## Main agent must NEVER
|
|
28
|
+
|
|
29
|
+
- `write`, `edit`, or delete any file tracked by the repo
|
|
30
|
+
- `git commit`, `git push`, create branches, create worktrees
|
|
31
|
+
- Run state-changing dev-loops CLI subcommands (`gate`, any state-changing `loop` subcommand, `pr` commands — those belong inside `dev-loop`).
|
|
32
|
+
- Delegate implementation to any agent other than `dev-loop`
|
|
33
|
+
|
|
34
|
+
## Dev-loop agent (async) owns
|
|
35
|
+
|
|
36
|
+
- ALL file mutations in the repo (write, edit, delete)
|
|
37
|
+
- ALL git operations (branch, commit, push)
|
|
38
|
+
- ALL PR lifecycle (create, draft, review, merge)
|
|
39
|
+
- Sub-delegation to developer, fixer, review, quality agents
|
|
40
|
+
|
|
41
|
+
## Boundary examples
|
|
42
|
+
|
|
43
|
+
| Operation | Verdict |
|
|
44
|
+
|---|---|
|
|
45
|
+
| `gh issue create --title "..." --body "..."` | Allowed — mutates GitHub, not files tracked by the repository |
|
|
46
|
+
| Write to `/tmp/issue-body.md` | Allowed — outside the repo |
|
|
47
|
+
| Write to `packages/core/src/foo.mjs` | **BREACH** — must delegate to `dev-loop` |
|
|
48
|
+
| `git status` | Allowed — read-only |
|
|
49
|
+
| `git commit -m "..."` | **BREACH** — must delegate to `dev-loop` |
|
|
50
|
+
| `subagent dev-loop` | Allowed — correct delegation |
|
|
51
|
+
| `subagent fixer` | Allowed only when called from within `dev-loop`; describe the task as part of the message |
|
|
52
|
+
|
|
53
|
+
## Dev-loop startup
|
|
54
|
+
|
|
55
|
+
When a user triggers the dev loop, the main agent must immediately dispatch the
|
|
56
|
+
`dev-loop` async subagent. The subagent owns the startup resolver, route selection,
|
|
57
|
+
and all subsequent implementation steps. The main agent never runs `dev-loops loop startup`
|
|
58
|
+
directly.
|
|
59
|
+
|
|
60
|
+
## Enforcement posture
|
|
61
|
+
|
|
62
|
+
- This contract is enforced by convention and review, not by tool-level guards.
|
|
63
|
+
- Mechanical enforcement (pre-commit hooks, tool-level write guards) is a
|
|
64
|
+
non-goal for this document and may be addressed in follow-up work.
|
|
65
|
+
- A `dev-loop` async subagent should reject delegation attempts that bypass
|
|
66
|
+
the contract (e.g., direct mutation requests from the main agent).
|
|
67
|
+
|
|
68
|
+
## Non-goals
|
|
69
|
+
|
|
70
|
+
- Tool-level enforcement (file-write guards, pre-commit hooks)
|
|
71
|
+
- Changing dev-loop resolver behavior
|
|
72
|
+
- Modifying the subagent API itself
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
# Merge preconditions
|
|
2
|
+
|
|
3
|
+
Canonical owner for merge preconditions across all workflow families.
|
|
4
|
+
|
|
5
|
+
## Required before merge
|
|
6
|
+
|
|
7
|
+
1. ✅ CI green on current head (or crediblyGreen via `--local-validation-head-sha`)
|
|
8
|
+
2. ✅ Draft gate satisfied (clean verdict)
|
|
9
|
+
3. ✅ Pre-approval gate satisfied (clean verdict, current head)
|
|
10
|
+
4. ✅ All review threads resolved
|
|
11
|
+
5. ✅ Explicit merge authorization from operator
|
|
12
|
+
6. ✅ PR body contains `Closes #N` or `Fixes #N`
|
|
13
|
+
|
|
14
|
+
## Merge authorization
|
|
15
|
+
|
|
16
|
+
- Must be explicit for the active issue/PR scope
|
|
17
|
+
- `"Merge authorized if gates green"` is valid explicit authorization
|
|
18
|
+
- Implied approval from prior turns is not sufficient
|
|
19
|
+
|
|
20
|
+
## Post-merge
|
|
21
|
+
|
|
22
|
+
- Remove merged worktree: `git worktree remove --force <path> && git worktree prune`
|
|
23
|
+
- Clean up stale branches
|
|
24
|
+
|
|
25
|
+
## Cross-references
|
|
26
|
+
|
|
27
|
+
- [Confirmation rules](confirmation-rules.md)
|
|
28
|
+
- [Validation policy](validation-policy.md)
|
|
29
|
+
- [Stop conditions](stop-conditions.md)
|