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.
Files changed (156) hide show
  1. package/.pi/dev-loop/defaults.yaml +477 -0
  2. package/AGENTS.md +25 -0
  3. package/CHANGELOG.md +18 -0
  4. package/LICENSE +21 -0
  5. package/README.md +178 -0
  6. package/agents/dev-loop.agent.md +82 -0
  7. package/agents/developer.agent.md +37 -0
  8. package/agents/docs.agent.md +33 -0
  9. package/agents/fixer.agent.md +53 -0
  10. package/agents/quality.agent.md +28 -0
  11. package/agents/refiner.agent.md +87 -0
  12. package/agents/review.agent.md +64 -0
  13. package/cli/index.mjs +424 -0
  14. package/extension/README.md +233 -0
  15. package/extension/checks.ts +94 -0
  16. package/extension/index.ts +131 -0
  17. package/extension/post-merge-update.ts +512 -0
  18. package/extension/presentation.ts +107 -0
  19. package/lib/dev-loops-core.mjs +284 -0
  20. package/package.json +103 -0
  21. package/scripts/README.md +1007 -0
  22. package/scripts/_cli-primitives.mjs +10 -0
  23. package/scripts/_core-helpers.mjs +30 -0
  24. package/scripts/docs/validate-links.mjs +567 -0
  25. package/scripts/docs/validate-no-duplicate-rules.mjs +250 -0
  26. package/scripts/github/_review-thread-mutations.mjs +214 -0
  27. package/scripts/github/capture-review-threads.mjs +180 -0
  28. package/scripts/github/create-draft-pr.mjs +108 -0
  29. package/scripts/github/detect-checkpoint-evidence.mjs +393 -0
  30. package/scripts/github/detect-linked-issue-pr.mjs +331 -0
  31. package/scripts/github/manage-sub-issues.mjs +394 -0
  32. package/scripts/github/probe-copilot-review.mjs +323 -0
  33. package/scripts/github/ready-for-review.mjs +93 -0
  34. package/scripts/github/reconcile-draft-gate.mjs +328 -0
  35. package/scripts/github/reply-resolve-review-thread.mjs +42 -0
  36. package/scripts/github/reply-resolve-review-threads.mjs +329 -0
  37. package/scripts/github/request-copilot-review.mjs +551 -0
  38. package/scripts/github/resolve-tracker-local-spec.mjs +205 -0
  39. package/scripts/github/stage-reviewer-draft.mjs +191 -0
  40. package/scripts/github/upsert-checkpoint-verdict.mjs +694 -0
  41. package/scripts/github/verify-fresh-review-context.mjs +125 -0
  42. package/scripts/github/write-gate-findings-log.mjs +212 -0
  43. package/scripts/loop/_checkpoint-io.mjs +55 -0
  44. package/scripts/loop/_checkpoint-paths.mjs +28 -0
  45. package/scripts/loop/_handoff-contract.mjs +230 -0
  46. package/scripts/loop/_inspect-run-viewer-adapter.mjs +345 -0
  47. package/scripts/loop/_loop-evidence.mjs +32 -0
  48. package/scripts/loop/_pr-runner-coordination.mjs +611 -0
  49. package/scripts/loop/_stale-runner-detection.mjs +145 -0
  50. package/scripts/loop/_steering-state-file.mjs +134 -0
  51. package/scripts/loop/build-handoff-envelope.mjs +181 -0
  52. package/scripts/loop/checkpoint-contract.mjs +49 -0
  53. package/scripts/loop/conductor-monitor.mjs +1850 -0
  54. package/scripts/loop/conductor.mjs +214 -0
  55. package/scripts/loop/copilot-pr-handoff.mjs +493 -0
  56. package/scripts/loop/debt-remediate.mjs +304 -0
  57. package/scripts/loop/detect-change-scope.mjs +102 -0
  58. package/scripts/loop/detect-copilot-loop-state.mjs +454 -0
  59. package/scripts/loop/detect-copilot-session-activity.mjs +186 -0
  60. package/scripts/loop/detect-initial-copilot-pr-state.mjs +318 -0
  61. package/scripts/loop/detect-internal-only-pr.mjs +270 -0
  62. package/scripts/loop/detect-issue-refinement-artifact.mjs +163 -0
  63. package/scripts/loop/detect-pr-gate-coordination-state.mjs +509 -0
  64. package/scripts/loop/detect-reviewer-loop-state.mjs +231 -0
  65. package/scripts/loop/detect-stale-runner.mjs +250 -0
  66. package/scripts/loop/detect-tracker-first-loop-state.mjs +76 -0
  67. package/scripts/loop/detect-tracker-pr-state.mjs +102 -0
  68. package/scripts/loop/info.mjs +267 -0
  69. package/scripts/loop/inspect-run-viewer/cli.mjs +117 -0
  70. package/scripts/loop/inspect-run-viewer/constants.mjs +80 -0
  71. package/scripts/loop/inspect-run-viewer/graph.mjs +757 -0
  72. package/scripts/loop/inspect-run-viewer/handoff-envelope-renderer.mjs +398 -0
  73. package/scripts/loop/inspect-run-viewer/inbox.mjs +308 -0
  74. package/scripts/loop/inspect-run-viewer/managed-instance.mjs +750 -0
  75. package/scripts/loop/inspect-run-viewer/rendering.mjs +411 -0
  76. package/scripts/loop/inspect-run-viewer/server.mjs +638 -0
  77. package/scripts/loop/inspect-run-viewer/shared.mjs +103 -0
  78. package/scripts/loop/inspect-run-viewer/status.mjs +715 -0
  79. package/scripts/loop/inspect-run-viewer-ci-changes.mjs +77 -0
  80. package/scripts/loop/inspect-run-viewer.mjs +82 -0
  81. package/scripts/loop/inspect-run.mjs +382 -0
  82. package/scripts/loop/outer-loop.mjs +419 -0
  83. package/scripts/loop/pr-runner-coordination.mjs +143 -0
  84. package/scripts/loop/pre-commit-branch-guard.mjs +68 -0
  85. package/scripts/loop/pre-flight-gate.mjs +236 -0
  86. package/scripts/loop/pre-pr-ready-gate.mjs +183 -0
  87. package/scripts/loop/pre-push-main-guard.mjs +103 -0
  88. package/scripts/loop/pre-write-remote-freshness-guard.mjs +32 -0
  89. package/scripts/loop/print-gates.mjs +42 -0
  90. package/scripts/loop/resolve-dev-loop-startup.mjs +533 -0
  91. package/scripts/loop/run-conductor-cycle.mjs +322 -0
  92. package/scripts/loop/run-queue.mjs +124 -0
  93. package/scripts/loop/run-refinement-audit.mjs +513 -0
  94. package/scripts/loop/run-watch-cycle.mjs +358 -0
  95. package/scripts/loop/steer-loop.mjs +841 -0
  96. package/scripts/loop/ui-designer-review-contract.mjs +76 -0
  97. package/scripts/loop/watch-initial-copilot-pr.mjs +253 -0
  98. package/scripts/projects/add-queue-item.mjs +528 -0
  99. package/scripts/projects/ensure-queue-board.mjs +837 -0
  100. package/scripts/projects/list-queue-items.mjs +489 -0
  101. package/scripts/projects/move-queue-item.mjs +549 -0
  102. package/scripts/projects/reorder-queue-item.mjs +518 -0
  103. package/scripts/refine/_refine-helpers.mjs +258 -0
  104. package/scripts/refine/prose-linkage-detector.mjs +92 -0
  105. package/scripts/refine/refinement-completeness-checker.mjs +88 -0
  106. package/scripts/refine/scope-boundary-cross-checker.mjs +163 -0
  107. package/scripts/refine/tree-integrity-validator.mjs +211 -0
  108. package/scripts/refine/verify.mjs +178 -0
  109. package/scripts/repo-wiki-local.mjs +156 -0
  110. package/scripts/repo-wiki.mjs +119 -0
  111. package/skills/copilot-pr-followup/SKILL.md +380 -0
  112. package/skills/dev-loop/SKILL.md +141 -0
  113. package/skills/dev-loop/scripts/dev-mode-context.mjs +152 -0
  114. package/skills/dev-loop/scripts/dev-mode-context.test.mjs +80 -0
  115. package/skills/dev-loop/scripts/init-phase.mjs +71 -0
  116. package/skills/dev-loop/scripts/log-bash-exit-1.mjs +25 -0
  117. package/skills/dev-loop/scripts/phase-files.mjs +29 -0
  118. package/skills/dev-loop/scripts/post-gate-verdict-fallback.mjs +480 -0
  119. package/skills/dev-loop/scripts/post-gate-verdict-fallback.test.mjs +732 -0
  120. package/skills/dev-loop/scripts/render-template.mjs +82 -0
  121. package/skills/dev-loop/scripts/render-template.test.mjs +63 -0
  122. package/skills/dev-loop/templates/bootstrap-agents.md +26 -0
  123. package/skills/dev-loop/templates/bootstrap-implementation-state.md +31 -0
  124. package/skills/dev-loop/templates/bootstrap-implementation-workflow.md +17 -0
  125. package/skills/dev-loop/templates/dev-mode-retrospective.md +15 -0
  126. package/skills/dev-loop/templates/dev-mode-review.md +17 -0
  127. package/skills/dev-loop/templates/dev-mode-skill-changes.md +11 -0
  128. package/skills/dev-loop/templates/merged-phase-plan.md +19 -0
  129. package/skills/dev-loop/templates/phase-doc.md +27 -0
  130. package/skills/dev-loop/templates/phase-summary.md +13 -0
  131. package/skills/dev-loop/templates/phase-variant.md +15 -0
  132. package/skills/dev-loop/templates/retrospective.md +11 -0
  133. package/skills/dev-loop/templates/review.md +32 -0
  134. package/skills/dev-loop/templates/ui-vision-review.md +55 -0
  135. package/skills/docs/acceptance-criteria-verification.md +21 -0
  136. package/skills/docs/anti-patterns.md +21 -0
  137. package/skills/docs/artifact-authority-contract.md +119 -0
  138. package/skills/docs/confirmation-rules.md +28 -0
  139. package/skills/docs/copilot-ci-status-contract.md +52 -0
  140. package/skills/docs/copilot-loop-operations.md +233 -0
  141. package/skills/docs/debt-remediation-contract.md +107 -0
  142. package/skills/docs/entrypoint-strategies.md +115 -0
  143. package/skills/docs/epic-tree-refinement-procedure.md +234 -0
  144. package/skills/docs/issue-intake-procedure.md +235 -0
  145. package/skills/docs/main-agent-contract.md +72 -0
  146. package/skills/docs/merge-preconditions.md +29 -0
  147. package/skills/docs/pr-lifecycle-contract.md +209 -0
  148. package/skills/docs/public-dev-loop-contract.md +497 -0
  149. package/skills/docs/retrospective-checkpoint-contract.md +159 -0
  150. package/skills/docs/stop-conditions.md +29 -0
  151. package/skills/docs/structural-quality.md +42 -0
  152. package/skills/docs/tracker-first-loop-state.md +281 -0
  153. package/skills/docs/validation-policy.md +27 -0
  154. package/skills/docs/workflow-handoff-contract.md +135 -0
  155. package/skills/final-approval/SKILL.md +19 -0
  156. package/skills/local-implementation/SKILL.md +640 -0
@@ -0,0 +1,52 @@
1
+ # Copilot PR CI/check normalization contract
2
+
3
+ This document is the canonical bundled contract for deterministic interpretation of PR CI/check inputs used by Copilot PR follow-up flows.
4
+
5
+ Installed skill/runtime consumers should read this bundled `skills/docs/` copy via [Copilot CI Status Contract](../docs/copilot-ci-status-contract.md) from the relevant skill directory. Repository-local docs may summarize or link this contract, but they should not redefine it.
6
+
7
+ Implementation surface:
8
+ - `@dev-loops/core/loop/copilot-ci-status`
9
+ - source file: `packages/core/src/loop/copilot-ci-status.mjs`
10
+
11
+ ## Entry points
12
+
13
+ - `normalizeStatusCheckRollupContract(statusCheckRollup)` — normalizes the PR `statusCheckRollup` snapshot from `gh pr view`
14
+ - `normalizeHeadScopedCiContract({ checkRunsStatus, commitStatus })` — normalizes current-head refresh inputs after explicit `check-runs` / commit-status probes
15
+
16
+ Both entry points return the same machine-readable contract shape.
17
+
18
+ ## Inputs
19
+
20
+ ### `normalizeStatusCheckRollupContract(statusCheckRollup)`
21
+
22
+ - `statusCheckRollup` — the raw PR `statusCheckRollup` array from `gh pr view`; entries may be CheckRun-like (`status` + `conclusion`) or legacy StatusContext-like (`state`)
23
+
24
+ ### `normalizeHeadScopedCiContract({ checkRunsStatus, commitStatus })`
25
+
26
+ - `checkRunsStatus` — normalized head-scoped check-runs status (`success` | `failure` | `pending` | `none`)
27
+ - `commitStatus` — normalized head-scoped commit-status status (`success` | `failure` | `pending` | `none`)
28
+ - optional `checkRunsUnsupportedCompleted` — `true` when the current-head check-runs probe observed an unsupported/non-success completed conclusion (for example `CANCELLED`) that must keep the merged result non-green even if commit status separately reports success
29
+
30
+ ## Output
31
+
32
+ The returned object always includes:
33
+
34
+ - `overallStatus` (`success` | `failure` | `pending` | `none`)
35
+ - `rollup` (`success`/`failure`/`pending`/`none` booleans; exactly one true)
36
+ - `semantics.wait` (`true` when `overallStatus` is `pending` or `none`)
37
+ - `semantics.blocked` (`true` when `overallStatus` is `failure`)
38
+ - `semantics.timeoutDisposition` (`remain_waiting` for `pending`/`none`; otherwise `not_applicable`)
39
+
40
+ ## Deterministic precedence
41
+
42
+ The rollup precedence is fixed and policy-agnostic for ordinary normalized status values:
43
+ 1. `failure`
44
+ 2. `pending`
45
+ 3. `success`
46
+ 4. `none`
47
+
48
+ Completed `SKIPPED` and `NEUTRAL` check-run conclusions count as non-blocking success-like signals. A completed `CANCELLED` check does not count as a successful readiness signal by itself; cancelled-only snapshots normalize to `none` so CI-dependent gates do not advance on cancelled work. Legacy successful `StatusContext` rollup entries also normalize to `success` instead of being mistaken for pending work.
49
+
50
+ Merged current-head exception:
51
+ - when `checkRunsUnsupportedCompleted=true`, a `checkRunsStatus: "none"` result caused by unsupported/non-success completed check-runs must remain non-green even if `commitStatus` is `success`
52
+ - in that specific case, the merged `overallStatus` stays `none` rather than letting `success` mask the unsupported completed check-run signal
@@ -0,0 +1,233 @@
1
+ # Copilot loop operations
2
+
3
+ This document is the canonical operational reference for the deterministic Copilot PR follow-up state machine used by the routed `copilot_pr_followup`, `wait_watch`, `reviewer_fixer`, and `final_approval` paths behind `dev-loop`.
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
+ ## Deterministic orchestration authority
11
+
12
+ When operating in PR follow-up or async watch mode, use the deterministic state machines
13
+ as the authoritative source for:
14
+
15
+ - Copilot follow-up loop: `detect-copilot-loop-state.mjs` from the resolved skill scripts directory
16
+ - reviewer-side PR review loop: `detect-reviewer-loop-state.mjs` from the resolved skill scripts directory
17
+
18
+ Resolve those helper paths from the skill asset layout described by the main skill. In the `dev-loops`
19
+ source repository the skill scripts directory is `../../scripts/` relative to `skills/copilot-pr-followup/SKILL.md`; in normalized
20
+ installed copies it may instead be `scripts/` inside the installed skill directory when that layout bundles the helper scripts.
21
+
22
+ Use the machines to answer:
23
+ - what state the PR/loop is in right now
24
+ - what transitions are currently allowed
25
+ - what the next required action is
26
+ - when to stop instead of guessing
27
+
28
+ Each machine captures an observable snapshot from GitHub facts (plus explicit bounded local loop
29
+ metadata when required) and interprets it into exactly one current state plus allowed next
30
+ transitions. In the `dev-loops` source repository, the supporting source-authority references are [Copilot Loop State Graph](../../docs/copilot-loop-state-graph.md) and [Reviewer Loop State Graph](../../docs/reviewer-loop-state-graph.md) under `../../docs/` relative to `skills/copilot-pr-followup/SKILL.md`. Treat those links as source-repo references, not bundled installed-skill docs.
31
+
32
+ For tracker-first MVP `story -> PR -> tracker sync` work, the source-repo reference is [Tracker-First Story-to-PR Contract](../../docs/tracker-story-pr-contract.md). That source doc inherits source-of-truth ownership, the required work item <-> PR link, and reverse-sync semantics from `#21`; it only adds the mutually exclusive workflow-family states and post-merge sync-verification states for this narrower MVP slice.
33
+
34
+ ## Key guarantees from the state machine
35
+
36
+ - `unresolvedThreadCount > 0` always routes to fix/reply-resolve — never to a wait/watch state
37
+ - `snapshot.copilotReviewRequestStatus === "unavailable"` or `snapshot.copilotReviewRequestStatus === "failed"` routes to a terminal stop state — never to sleep or watch
38
+ - `agentFixStatus === "applied"` with unresolved threads routes to `already_fixed_needs_reply_resolve` — reply/resolve on GitHub is required before re-requesting review
39
+ - Copilot being in `requested_reviewers` (`"requested"` or `"already-requested"`) routes to `waiting_for_copilot_review`
40
+
41
+ ## How to use the state machine in practice
42
+
43
+ 1. Run `node <resolved-skill-scripts>/loop/detect-copilot-loop-state.mjs --repo <owner/name> --pr <number>`
44
+ to get the current Copilot-loop state, decisive snapshot fields, and recommended next action.
45
+
46
+ 2. If you already ran `<resolved-skill-scripts>/github/request-copilot-review.mjs` and got a known status,
47
+ inject it without re-probing: add `--review-request-status <status>`.
48
+
49
+ 3. When the agent has applied a fix and wants to signal reply/resolve is next, build a snapshot
50
+ with `agentFixStatus: "applied"` and use `--input <snapshot.json>` for interpretation.
51
+
52
+ 4. Branch on the detector output instead of inventing a polling loop:
53
+ - `state=waiting_for_copilot_review` with `snapshot.copilotReviewOnCurrentHead=false`: do **not** poll manually; either run `node <resolved-skill-scripts>/loop/run-watch-cycle.mjs --repo <owner/name> --pr <number>` for persistent async waiting or report the wait state and resume later after the single detector call
54
+ - `state=waiting_for_ci` with `snapshot.ciStatus` in `{ "pending", "none" }`: do **not** poll manually by default; use `gh run watch <run-id> --repo <owner/name>` when the current-head run id is already known, otherwise report pending CI and resume later after the single detector refresh. Bounded exception: if GitHub created zero current-head check suites/statuses, the previous head rollup was green, and local `npm run verify` already passed for the same current head, rerun `detect-copilot-loop-state.mjs` with `--local-validation-head-sha <current-head-sha>` so the detector can promote that exact zero-suite case to `snapshot.ciStatus="crediblyGreen"` instead of waiting forever on raw `none`.
55
+ - `snapshot.ciStatus="failure"` remains a stop/fix state, never a wait loop
56
+
57
+ 5. For reviewer-side draft-review work, run `node <resolved-skill-scripts>/loop/detect-reviewer-loop-state.mjs --repo <owner/name> --pr <number> [--reviewer-login <login>] [--local-state <path>]`.
58
+ If the state reaches `draft_review_ready`, stage the pending review with
59
+ `node <resolved-skill-scripts>/github/stage-reviewer-draft.mjs --repo <owner/name> --pr <number> --review-file <merged-review.json> --local-state-output <state.json>`,
60
+ then re-run the detector with `--local-state <state.json>`.
61
+
62
+ 6. Follow the `nextAction` from the machine output. For stop states (`review_request_unavailable`,
63
+ `blocked_needs_user_decision`), report to the user and do not proceed.
64
+
65
+ ## Judgment calls that remain in the agent layer
66
+
67
+ - Whether a comment should be accepted, deferred, or disagreed with
68
+ - Whether the code change is already sufficient (→ sets `agentFixStatus: "applied"`)
69
+ - What the narrowest valid fix is
70
+ - Whether another Copilot pass is desired (→ triggers re-request or selects `done`)
71
+
72
+ ## Workflow overview
73
+
74
+ ```text
75
+ ready issue -> confirm scope -> Copilot branch/PR -> async review/watch -> Pi follow-up fixes -> validation -> confirm verdict/action -> merge when authorized
76
+ ```
77
+
78
+ Use the resolved `detect-copilot-loop-state.mjs` helper from the skill scripts directory at each
79
+ decision point in this flow to determine the current state and route to the correct next step
80
+ deterministically.
81
+
82
+ ## Pre-follow-up working rules
83
+
84
+ > **Phase boundary:** Steps 1-4 apply when no PR exists yet (issue intake).
85
+ > If a PR already exists, skip to [Deterministic orchestration authority](#deterministic-orchestration-authority) —
86
+ > the state machine owns all post-PR routing.
87
+
88
+ ### Step 1: Choose the work item
89
+
90
+ Prefer a GitHub issue over an ad hoc local TODO.
91
+
92
+ When selecting the next item:
93
+ - prefer `type:task` issues under the relevant epic
94
+ - prefer `status:ready`
95
+ - inspect milestone, labels, and acceptance criteria
96
+ - confirm whether a PR already exists for the issue before proposing new execution
97
+
98
+ Useful checks:
99
+ - `gh issue list --state open`
100
+ - `gh issue view <number>`
101
+ - `gh pr list --state open`
102
+
103
+ If the user asks for status/progress/readiness/merge-state/next-step (including “what is next”):
104
+ - resolve authoritative active artifact identity first (issue/PR, plus branch/head SHA when useful)
105
+ - for issue targets, do not assert "no open PR" until authoritative issue↔PR linkage is resolved via the startup resolver (`dev-loops loop startup --issue <number>`, run inside the `dev-loop` async subagent) — do not run `detect-linked-issue-pr.mjs` manually
106
+ - resolve artifact state (`open`/`closed`/`merged`/`not_applicable`)
107
+ - resolve current loop state and next action from deterministic helper/state output
108
+ - include explicit resolved artifact identity in the answer
109
+ - if identity/state cannot be resolved confidently, stop with reconcile/unknown instead of guessing from chat context
110
+
111
+ ### Step 2: Confirm issue scope before execution
112
+
113
+ Before handing work to Copilot or doing follow-up fixes, summarize:
114
+ - issue number and title
115
+ - parent epic if present
116
+ - milestone
117
+ - labels
118
+ - exact acceptance criteria
119
+ - intended narrow scope
120
+ - non-goals inferred from the issue and plan
121
+
122
+ If the work item is phase-like, ambiguous, or likely to shape more than one downstream step, default to a short fan-out / fan-in refinement pass before implementation:
123
+ - generate 2-3 plan variants in parallel when practical
124
+ - compare the variants explicitly
125
+ - merge them into one bounded execution plan
126
+ - only then proceed with GitHub execution
127
+
128
+ If the issue text is too vague, stop and ask a short clarification question rather than guessing.
129
+
130
+ ### Step 3: Decide whether Copilot or Pi should act next
131
+
132
+ Use this heuristic:
133
+
134
+ #### Prefer Copilot when
135
+ - there is a ready implementation issue with clear acceptance criteria
136
+ - no PR exists yet for that issue
137
+ - the user wants the repository's normal GitHub/Copilot path
138
+ - the next step is “start work” rather than “finish this already-open PR right now”
139
+
140
+ #### Prefer Pi follow-up when
141
+ - a PR already exists
142
+ - Copilot has already pushed work and now needs review/fix follow-up
143
+ - there are unresolved comments or failing checks
144
+ - the user wants async in-session watching and response
145
+
146
+ #### Prefer plain analysis only when
147
+ - the user is asking what should happen next
148
+ - authorization for GitHub state changes has not been given yet
149
+ - the issue/PR state is unclear and needs inspection first
150
+
151
+ ### Step 4: Copilot handoff rules
152
+
153
+ When preparing work for Copilot:
154
+ - use the GitHub issue as the source of truth
155
+ - preserve the issue's acceptance criteria
156
+ - keep the requested scope narrow
157
+ - do not broaden into adjacent backlog items
158
+ - prefer one issue per PR unless the user explicitly wants bundling
159
+
160
+ Before any GitHub mutation such as assigning the issue, posting instructions, or changing labels, confirm first unless explicitly authorized.
161
+
162
+ When you do hand work to Copilot:
163
+ - assign `copilot-swe-agent`
164
+ - reference the issue number and acceptance criteria clearly
165
+ - keep instructions implementation-focused and test-aware
166
+
167
+ ## PR description contract
168
+
169
+ Follow the PR description contract (see [Agent Instructions](../../AGENTS.md) if present; otherwise use the structure below): detailed structured descriptions, not thin placeholders. At minimum include change summary, scope/context, explicit acceptance criteria, explicit definition of done, and explicit non-goals, and `Closes #N` (or `Fixes #N`) for the linked issue so GitHub auto-closes it on merge.
170
+
171
+ Checkbox rule: acceptance criteria, definition-of-done items, and any task list must be rendered as real GitHub markdown checkboxes inside list items (`- [ ]` / `- [x]`, also `* [ ]` / `* [x]`). Do not wrap checkbox markers (e.g. `[x]`) in backticks. Do not place checkbox markers inside table cells — task lists are not interactive there even with a leading `- `.
172
+
173
+ New PRs in this workflow must be opened as **draft** PRs first when the repository enables `.devloops` at repo root `workflow.requireDraftFirst`. The built-in shipped default remains permissive; this repo opts in. Do not create a fresh PR directly in ready-for-review state unless the user explicitly overrides that policy for the current PR scope. The draft gate inspection is a real workflow boundary, so a new PR must exist in draft before `gh pr ready` is even eligible.
174
+
175
+ Only use `node <resolved-skill-scripts>/github/create-draft-pr.mjs` when authoritative issue↔PR resolution says there is no already-open linked PR. If a PR already exists, reuse/update that canonical PR instead of opening another one. This wrapper preserves the underlying `gh pr create` output contract while enforcing draft-first mechanically.
176
+
177
+ MUST use `node <resolved-skill-scripts>/github/create-draft-pr.mjs --repo <owner/name> --assignee @me --base <base> --head <head> --title "..." --body-file <body-file>`.
178
+
179
+ ## Timeout and watch policy
180
+
181
+ This workflow is intentionally long-lived, but one Copilot review watch boundary must still be capped.
182
+
183
+ Preferred defaults for this repo:
184
+ - poll interval for review/activity watchers: **1 minute** (derived from `packages/core/src/loop/policy-constants.mjs` DEFAULT_POLL_INTERVAL_MS)
185
+ - max watch timeout per Copilot review boundary: **30 minutes** (derived from `packages/core/src/loop/policy-constants.mjs` COPILOT_REVIEW_WAIT_TIMEOUT_MS)
186
+ - if that 30-minute watch budget expires, refresh authoritative state once; if the refreshed state still resolves `waiting_for_copilot_review`, stop with `watch timeout — PR #<number> needs manual attention`
187
+ - do not silently extend that 30-minute cap unless the user or conductor explicitly authorizes a longer watch budget for the active PR
188
+ - parent/subagent no-activity threshold for watcher-style runs: at least **15 minutes**
189
+ - active-long-running notice threshold for watcher-style runs: about **30 minutes**
190
+
191
+ These are the defaults built into `probe-copilot-review.mjs`, `run-watch-cycle.mjs`, and the `watchArgs` emitted by `copilot-pr-handoff.mjs`. Do not pass removed CLI policy flags (`--poll-interval-ms`, `--timeout-ms`, `--probe-only`) — helpers hard-error when they are provided. Timeouts and intervals are derived from `packages/core/src/loop/policy-constants.mjs`.
192
+
193
+ ### Outer-loop checkpoint: canonical re-attachment artifact
194
+
195
+ The outer-loop checkpoint (`tmp/copilot-loop/<owner>/<repo>/pr-<n>/outer-loop-state.json`)
196
+ is the canonical re-attachment artifact for async subagent runs. It is written by
197
+ `outer-loop.mjs` at every conductor cycle and records:
198
+
199
+ | Field | Meaning |
200
+ |---|---|
201
+ | `pr` | PR number |
202
+ | `repo` | Repository slug (`owner/name`; lowercased by `outer-loop.mjs`) |
203
+ | `outerAction` | Next action: `continue_wait`, `reenter_copilot_loop`, `reenter_reviewer_loop`, `stop`, `done` |
204
+ | `copilotState` | Current copilot inner-loop state |
205
+ | `reviewerState` | Current reviewer inner-loop state |
206
+ | `reviewerScope` | Reviewer scope mode (always present; e.g. `all_reviewers` or `single_reviewer`) |
207
+ | `reviewerLogin` | Reviewer GitHub login (always present; `null` unless single-reviewer scope) |
208
+ | `reason` | Stop reason (`null` when `outerAction` is not `stop`) |
209
+ | `timestamp` | ISO 8601 timestamp of checkpoint write |
210
+ | `waitCycles` | Number of wait cycles accumulated |
211
+ | `headSha` | PR head SHA at checkpoint time (`null` when unavailable) |
212
+
213
+ ### Re-attachment contract
214
+
215
+ When a fresh `dev-loop` async subagent starts on a PR that already has an outer-loop
216
+ checkpoint, it must read the checkpoint before entering any intake or follow-up procedure:
217
+
218
+ 1. If `outerAction` is `continue_wait` or `reenter_copilot_loop`: auto-resume the loop
219
+ rather than treating the start as fresh intake.
220
+ 2. If `outerAction` is `reenter_reviewer_loop`: enter the reviewer-loop path.
221
+ 3. If `outerAction` is `stop`: the loop is blocked or needs a human decision; report the `reason` and ask for direction.
222
+ 4. If no checkpoint or `outerAction` is `done`: `done` means the PR is merged/closed; normal fresh startup.
223
+
224
+ The checkpoint is the only source of truth for re-attachment. Do not rely on chat context
225
+ or local notes to determine "where we left off."
226
+
227
+ ## Hard rule: no agent-authored shell polling
228
+
229
+ Helper-owned sleep inside `run-watch-cycle.mjs`, `probe-copilot-review.mjs`, or `watch-initial-copilot-pr.mjs` is allowed. Agent-authored shell polling (`sleep`, `for`, `while`, `timeout` wrappers around tool invocations) is a contract breach. This rule applies to ALL repos using the dev-loop workflow, not just the source repo.
230
+
231
+ A watcher sleeping between polls is expected behavior, not a blocker.
232
+
233
+ If the polling interval is 1 minute, do not treat silence shorter than one full poll interval as suspicious, and do not configure needs-attention thresholds close to a few seconds for this loop.
@@ -0,0 +1,107 @@
1
+ # Debt remediation contract
2
+
3
+ Canonical authority for the debt remediation pipeline and its integration with the `dev-loop` execution path.
4
+
5
+ ## Pipeline
6
+
7
+ ```
8
+ debt_signals → cluster → score → shape → remediation_item → GitHub issue → dev-loop
9
+ ```
10
+
11
+ Core pipeline stages under `packages/core/src/debt/`:
12
+
13
+ | Module | Role | Side effects |
14
+ |---|---|---|
15
+ | `debt-signal.mjs` | Signal schema and validation | None |
16
+ | `cluster.mjs` | Group signals into findings by file, module, theme | None |
17
+ | `score.mjs` | 0-100 score from frequency, severity, impact | None |
18
+ | `shape.mjs` | Classify findings: remediation_item, debt_epic, defer, watch, dismiss | None |
19
+ | `remediation-to-issue.mjs` | Convert remediation_item to GitHub issue payload; create via `gh issue create` | `gh issue create` call |
20
+
21
+ The cluster, score, and shape stages are deterministic pure functions.
22
+ `remediation-to-issue.mjs` performs a side effect (`gh issue create`) and requires GitHub auth.
23
+
24
+ ## CLI entrypoint
25
+
26
+ `scripts/loop/debt-remediate.mjs` is the single CLI entrypoint routed under `dev-loops loop debt-remediate`.
27
+
28
+ ```
29
+ dev-loops loop debt-remediate --input <signals.json> [--repo <owner/name>] [--dry-run]
30
+ ```
31
+
32
+ ### Contract
33
+
34
+ - **Input**: JSON array of `debt_signal` objects (validated against `DebtSignalSchema`)
35
+ - **Pipeline**: cluster → score → shape → issue creation
36
+ - **Issue creation**: calls `gh issue create --assignee @me` for each `remediation_item`
37
+ - **Output**: JSON report with counts, issue URLs, and summary
38
+ - **Exit codes**: 0 (success — all remediation issue creations succeeded), 1 (argument error, input validation failure, or any issue creation failure)
39
+ - **Dry run**: `--dry-run` runs the full pipeline and validates but skips issue creation
40
+
41
+ ### Output shape
42
+
43
+ ```json
44
+ {
45
+ "ok": true,
46
+ "dryRun": false,
47
+ "repo": "owner/name",
48
+ "signals": 5,
49
+ "findings": 2,
50
+ "remediationItems": 1,
51
+ "debtEpics": 0,
52
+ "deferred": 1,
53
+ "watching": 0,
54
+ "dismissed": 0,
55
+ "issues": [
56
+ {
57
+ "findingId": "uuid",
58
+ "title": "...",
59
+ "created": true,
60
+ "issueNumber": 123,
61
+ "issueUrl": "https://github.com/owner/name/issues/123",
62
+ "error": null
63
+ }
64
+ ],
65
+ "summary": "5 signals → 2 findings; 1 remediation items (1 issues created, 0 failed); ..."
66
+ }
67
+ ```
68
+
69
+ ## Integration with dev-loop
70
+
71
+ Once a remediation issue is created, it is a standard GitHub issue that feeds into the existing `dev-loop` execution path:
72
+
73
+ 1. `dev-loops loop startup --issue <n>` resolves the issue
74
+ 2. Standard `copilot-pr-followup` or `issue_intake` strategy takes over
75
+ 3. PR → review → merge as normal
76
+
77
+ This closes the remediation execution loop: `remediation_item → issue → dev-loop → PR → merge`.
78
+
79
+ ## Shape thresholds
80
+
81
+ Thresholds are hardcoded constants in `shape.mjs`. The outcome for a finding is determined by the combined thresholds:
82
+
83
+ | Threshold | Value | Outcome |
84
+ |---|---|---|
85
+ | `EPIC_SIGNAL_COUNT_THRESHOLD` | 3 | When `signalCount > 3` and score ≥ `ITEM_THRESHOLD`, the finding becomes a `debt_epic` instead of `remediation_item` |
86
+ | `ITEM_THRESHOLD` | 65 | `remediation_item` (unless signal count pushes to `debt_epic`) |
87
+ | `DEFER_THRESHOLD` | 50 | `defer` |
88
+ | `WATCH_THRESHOLD` | 30 | `watch` |
89
+ | (below) | <30 | `dismiss` |
90
+
91
+ The `EPIC_SIGNAL_COUNT_THRESHOLD` takes precedence: a finding with score ≥ `ITEM_THRESHOLD` and `signalCount > 3` becomes a `debt_epic`, not a `remediation_item`.
92
+
93
+ ## Scoring model
94
+
95
+ Three dimensions, weighted:
96
+
97
+ | Dimension | Weight | Description |
98
+ |---|---|---|
99
+ | Frequency | 0.35 | Signal count, logarithmic cap |
100
+ | Severity | 0.40 | Average severity hint (info=1..critical=5) |
101
+ | Impact | 0.25 | File presence, confidence, category diversity |
102
+
103
+ Clamped to 0-100.
104
+
105
+ ## Labels
106
+
107
+ Created issues receive the `workflow` label by default. This keeps them discoverable in the standard dev-loop issue tracking surface.
@@ -0,0 +1,115 @@
1
+ # Entrypoint strategies
2
+
3
+ This document replaces the seven individual `entrypoint-briefing-*.md` files with a single per-strategy-section reference. Each section preserves the state vocabulary and key operational content for that strategy.
4
+
5
+ ## Copilot PR follow-up
6
+
7
+ State vocabulary: `waiting_for_initial_copilot_implementation`, `waiting_for_copilot_review`, `review_feedback_received`, `linked_pr_ready_for_followup`, `blocked_needs_user_decision`
8
+
9
+ Next-action sentence: "Load PR state from `detect-copilot-loop-state.mjs`, resolve gate coordination, then execute the appropriate follow-up action (fix, review, wait, or escalate)."
10
+
11
+ Helpers to run first:
12
+ 1. `dev-loops loop loop-state --repo <owner/name> --pr <N>` — resolve loop state
13
+ 2. `dev-loops loop gate-coordination --repo <owner/name> --pr <N>` — resolve gate state
14
+ 3. `dev-loops gate upsert-verdict` — post/update gate comments
15
+
16
+ Required reading:
17
+ - [Public Dev Loop Contract](public-dev-loop-contract.md)
18
+ - [Copilot Loop Operations](copilot-loop-operations.md)
19
+ - [Confirmation rules](confirmation-rules.md)
20
+ - [Stop conditions](stop-conditions.md)
21
+ - [Validation policy](validation-policy.md)
22
+
23
+ ## External PR follow-up
24
+
25
+ State vocabulary: Same as Copilot PR follow-up but with external-human ownership.
26
+
27
+ Next-action sentence: "Load PR state, check for external review cycles, then route to reviewer/fixer or maintenance workflow."
28
+
29
+ Helpers to run first: Same as [Copilot PR follow-up](#copilot-pr-follow-up).
30
+
31
+ Required reading: Same as [Copilot PR follow-up](#copilot-pr-follow-up).
32
+
33
+ ## Final approval
34
+
35
+ State vocabulary: `approval_ready`, `merge_ready`, `waiting_for_merge_authorization`
36
+
37
+ Next-action sentence: "Verify pre_approval_gate evidence, confirm CI green + resolved threads, then request explicit merge authorization."
38
+
39
+ Helpers to run first:
40
+ 1. `dev-loops gate detect-evidence --repo <owner/name> --pr <N>` — verify gate evidence
41
+ 2. `dev-loops gate upsert-verdict` — post pre_approval_gate
42
+
43
+ Required reading:
44
+ - [Public Dev Loop Contract](public-dev-loop-contract.md)
45
+ - [Final Approval SKILL](../final-approval/SKILL.md)
46
+ - [Merge preconditions](merge-preconditions.md)
47
+ - [Confirmation rules](confirmation-rules.md)
48
+
49
+ ## Issue intake
50
+
51
+ State vocabulary: `waiting_for_initial_copilot_implementation`, `needs_refinement`, `ready_needs_assignment_confirmation`, `ready_assign_now`, `assigned_to_copilot`
52
+
53
+ Next-action sentence: "Resolve issue readiness, handle assignment seam, then bootstrap PR creation or wait for Copilot implementation."
54
+
55
+ Helpers to run first:
56
+ 1. `dev-loops loop linked-issue-pr --repo <owner/name> --issue <N>` — resolve issue↔PR linkage
57
+ 2. `dev-loops loop startup` — resolve routing
58
+
59
+ Required reading:
60
+ - [Public Dev Loop Contract](public-dev-loop-contract.md)
61
+ - [Issue Intake Procedure](issue-intake-procedure.md)
62
+ - [Confirmation rules](confirmation-rules.md)
63
+ - [Stop conditions](stop-conditions.md)
64
+
65
+ ## Local implementation
66
+
67
+ State vocabulary: `local_branch`, `local_phase`, `in_progress`, `review`, `merge_ready`
68
+
69
+ Next-action sentence: "Fan-out refinement (unless light-mode), implement phase, validate, then create PR or continue to next phase."
70
+
71
+ Helpers to run first:
72
+ 1. `dev-loops loop startup` — resolve routing
73
+ 2. `node scripts/loop/pre-commit-branch-guard.mjs --expected-branch <name> [--require-worktree] [--block-main-checkout]` — verify isolation (no CLI route; use script path)
74
+
75
+ Required reading:
76
+ - [Public Dev Loop Contract](public-dev-loop-contract.md)
77
+ - [Local Implementation SKILL](../local-implementation/SKILL.md)
78
+ - [Anti-patterns](anti-patterns.md)
79
+ - [Structural quality](structural-quality.md)
80
+ - [Validation policy](validation-policy.md)
81
+
82
+ ## Tracker-first
83
+
84
+ **Strategy:** `tracker_first` (reserved for future `dev-loop` routing when tracker context detected)
85
+
86
+ **Purpose:** Tracker-first workflow for story/epic tracker items that follow a PR-based GitHub execution path.
87
+
88
+ **Routing status:** Routing integration in `resolve-dev-loop-startup.mjs` is deferred (no `tracker_first` route exists yet). This briefing documents the intended contract surface; the state machine and detector are implemented and tested.
89
+
90
+ **Key artifacts:**
91
+ - Tracker issue (canonical spec)
92
+ - [Tracker-First Loop State](tracker-first-loop-state.md) — state machine doc
93
+ - `detect-tracker-first-loop-state.mjs` — loop state detector
94
+ - `detect-tracker-pr-state.mjs` — PR-level state detector
95
+
96
+ **Routing:** `dev-loop` will resolve to tracker-first when a tracker context is detected (issue has tracker labels, is a tracker-backed issue). Fail-closed: unknown tracker state → `needs_triage`.
97
+
98
+ **State vocabulary:** `drafting`, `needs_triage`, `in_progress`, `in_review`, `merge_ready`, `blocked`, `completed`, `unknown`
99
+
100
+ **Interface contract:** Same as Copilot loop: `{ ok, state, snapshot, allowedTransitions, nextAction }`
101
+
102
+ ## Wait / watch
103
+
104
+ State vocabulary: `waiting`, `waiting_for_initial_copilot_implementation`, `waiting_for_copilot_review`
105
+
106
+ Next-action sentence: "Enter healthy-watch mode with configured timeout; escalate only on genuine blocked/authorization/reconcile states."
107
+
108
+ Helpers to run first:
109
+ 1. `dev-loops loop watch-initial --repo <owner/name> --issue <N>` — bootstrap watcher
110
+ 2. `dev-loops loop watch-cycle --repo <owner/name> --pr <N>` — cycle watcher
111
+
112
+ Required reading:
113
+ - [Public Dev Loop Contract](public-dev-loop-contract.md)
114
+ - [Copilot Loop Operations](copilot-loop-operations.md)
115
+ - [Stop conditions](stop-conditions.md)