dev-loops 0.7.1 → 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.
Files changed (86) hide show
  1. package/.claude/.claude-plugin/plugin.json +1 -1
  2. package/.claude/agents/dev-loop.md +7 -7
  3. package/.claude/agents/fixer.md +1 -0
  4. package/.claude/agents/refiner.md +2 -2
  5. package/.claude/agents/review.md +2 -2
  6. package/.claude/commands/loop-enqueue.md +1 -1
  7. package/.claude/commands/loop-info.md +1 -1
  8. package/.claude/commands/loop-start-spike.md +1 -1
  9. package/.claude/skills/copilot-pr-followup/SKILL.md +37 -23
  10. package/.claude/skills/dev-loop/SKILL.md +6 -6
  11. package/.claude/skills/docs/acceptance-criteria-verification.md +3 -2
  12. package/.claude/skills/docs/anti-patterns.md +3 -2
  13. package/.claude/skills/docs/artifact-authority-contract.md +12 -11
  14. package/.claude/skills/docs/confirmation-rules.md +1 -0
  15. package/.claude/skills/docs/contract-style-guide.md +37 -0
  16. package/.claude/skills/docs/copilot-loop-operations.md +18 -14
  17. package/.claude/skills/docs/cross-harness-regression-contract.md +2 -2
  18. package/.claude/skills/docs/debt-remediation-contract.md +1 -1
  19. package/.claude/skills/docs/epic-tree-refinement-procedure.md +25 -22
  20. package/.claude/skills/docs/issue-intake-procedure.md +25 -19
  21. package/.claude/skills/docs/merge-preconditions.md +13 -11
  22. package/.claude/skills/docs/pr-lifecycle-contract.md +44 -35
  23. package/.claude/skills/docs/public-dev-loop-contract.md +59 -43
  24. package/.claude/skills/docs/retrospective-checkpoint-contract.md +18 -5
  25. package/.claude/skills/docs/spike-mode-contract.md +14 -7
  26. package/.claude/skills/docs/stop-conditions.md +30 -15
  27. package/.claude/skills/docs/tracker-first-loop-state.md +13 -8
  28. package/.claude/skills/docs/validation-policy.md +4 -5
  29. package/.claude/skills/local-implementation/SKILL.md +48 -142
  30. package/CHANGELOG.md +6 -0
  31. package/agents/dev-loop.agent.md +8 -8
  32. package/agents/fixer.agent.md +1 -0
  33. package/agents/refiner.agent.md +2 -2
  34. package/agents/review.agent.md +2 -2
  35. package/package.json +5 -4
  36. package/scripts/_core-helpers.mjs +2 -0
  37. package/scripts/claude/headless-dev-loop.mjs +1 -1
  38. package/scripts/docs/validate-rule-ownership.mjs +442 -0
  39. package/scripts/docs/validate-state-machine-conformance.mjs +1092 -0
  40. package/scripts/github/_review-thread-mutations.mjs +5 -2
  41. package/scripts/github/create-pr.mjs +119 -10
  42. package/scripts/github/detect-checkpoint-evidence.mjs +102 -17
  43. package/scripts/github/list-review-threads.mjs +277 -0
  44. package/scripts/github/post-gate-findings.mjs +6 -3
  45. package/scripts/github/request-copilot-review.mjs +92 -26
  46. package/scripts/github/upsert-checkpoint-verdict.mjs +74 -5
  47. package/scripts/github/verify-briefing-prefixes.mjs +191 -0
  48. package/scripts/github/verify-fresh-review-context.mjs +78 -3
  49. package/scripts/github/wait-pr-checks.mjs +171 -0
  50. package/scripts/github/write-gate-context.mjs +213 -7
  51. package/scripts/github/write-gate-findings-log.mjs +54 -2
  52. package/scripts/loop/copilot-pr-handoff.mjs +29 -2
  53. package/scripts/loop/detect-change-scope.mjs +2 -2
  54. package/scripts/loop/detect-copilot-loop-state.mjs +23 -3
  55. package/scripts/loop/detect-pr-gate-coordination-state.mjs +35 -3
  56. package/scripts/loop/resolve-dev-loop-startup.mjs +145 -8
  57. package/scripts/loop/sanctioned-commands.mjs +2 -0
  58. package/scripts/loop/validate-pr-body-spec.mjs +21 -5
  59. package/scripts/pages/build-state-atlas.mjs +50 -48
  60. package/scripts/projects/_resolve-project.mjs +1 -148
  61. package/scripts/projects/list-queue-items.mjs +3 -377
  62. package/scripts/projects/move-queue-item.mjs +3 -410
  63. package/scripts/projects/reorder-queue-item.mjs +3 -22
  64. package/skills/copilot-pr-followup/SKILL.md +37 -23
  65. package/skills/dev-loop/SKILL.md +1 -1
  66. package/skills/docs/acceptance-criteria-verification.md +3 -2
  67. package/skills/docs/anti-patterns.md +3 -2
  68. package/skills/docs/artifact-authority-contract.md +12 -11
  69. package/skills/docs/confirmation-rules.md +1 -0
  70. package/skills/docs/contract-style-guide.md +37 -0
  71. package/skills/docs/copilot-loop-operations.md +18 -14
  72. package/skills/docs/cross-harness-regression-contract.md +2 -2
  73. package/skills/docs/debt-remediation-contract.md +1 -1
  74. package/skills/docs/epic-tree-refinement-procedure.md +25 -22
  75. package/skills/docs/issue-intake-procedure.md +25 -19
  76. package/skills/docs/merge-preconditions.md +13 -11
  77. package/skills/docs/pr-lifecycle-contract.md +44 -35
  78. package/skills/docs/public-dev-loop-contract.md +59 -43
  79. package/skills/docs/required-rules.json +149 -0
  80. package/skills/docs/retrospective-checkpoint-contract.md +18 -5
  81. package/skills/docs/spike-mode-contract.md +14 -7
  82. package/skills/docs/stop-conditions.md +30 -15
  83. package/skills/docs/tracker-first-loop-state.md +13 -8
  84. package/skills/docs/validation-policy.md +4 -5
  85. package/skills/local-implementation/SKILL.md +48 -142
  86. package/scripts/docs/validate-no-duplicate-rules.mjs +0 -250
@@ -57,47 +57,38 @@ When the local spec already lives in a tracker issue:
57
57
  - resolve the tracker reference deterministically from a GitHub issue URL or explicit `<owner/name>` + issue number
58
58
  - use the bounded GitHub helper `scripts/github/resolve-tracker-local-spec.mjs` when you need a machine-readable spec bundle
59
59
  - treat the tracker issue title/body/url/state as the durable local spec bundle
60
- - do not create or read [Phase Plan](../../docs/phases/phase-x.md) for that same tracker-backed session
60
+ - the no-duplicate-phase-doc rule is owned by `ARTIFACT-TRACKER-FIRST-NO-DUP` in [Artifact Authority Contract](../docs/artifact-authority-contract.md); do not read [Phase Plan](../../docs/phases/phase-x.md) for that same tracker-backed session either
61
61
  - sync durable scope / acceptance / status changes back to the tracker issue rather than maintaining a duplicate local phase doc
62
62
  - keep `tmp/` as temporary local execution state only; it does not become a second durable spec surface
63
63
  - for tracker-backed sessions, the handoff path is always: push the working branch → open a PR → merge via GitHub
64
- - for tracker-backed sessions, always open PRs through the canonical `dev-loops pr create` path, which is ALWAYS draft and always assigned — self-assigned by default (`--assignee @me` when none is given; honors an explicit `--assignee <login>` / `-a <login>`), never via raw `gh pr create`. The PR body must contain `Closes #N` (or `Fixes #N`) for the linked issue so GitHub auto-closes it on merge. When `.devloops` sets `workflow.requireDraftFirst` to true, use `dev-loops pr create --assignee @me ...`. 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.
65
- - do not suggest a direct local-main merge for tracker-backed sessions; do not merge the working branch into local `main` at phase completion
64
+ - <!-- rule: LOCAL-PR-CREATE-CANONICAL --> for tracker-backed sessions, you MUST open PRs through the canonical `dev-loops pr create` path always draft and always assigned — self-assigned by default (`--assignee @me` when none is given; honors an explicit `--assignee <login>` / `-a <login>`) and MUST NOT open them via raw `gh pr create`. The PR body MUST contain `Closes #N` (or `Fixes #N`) for the linked issue so GitHub auto-closes it on merge. When `.devloops` sets `workflow.requireDraftFirst` to true, use `dev-loops pr create --assignee @me ...`; the draft-first requirement itself is owned by [`OPS-DRAFT-FIRST-PR`](../docs/copilot-loop-operations.md).
65
+ - <!-- rule: LOCAL-TRACKER-NO-DIRECT-MERGE --> `LOCAL-TRACKER-NO-DIRECT-MERGE`: for tracker-backed sessions, agents MUST NOT suggest a direct local-main merge and MUST NOT merge the working branch into local `main` at phase completion
66
66
 
67
67
  ## Primary execution rules
68
68
 
69
69
  ### Step 0: Pre-flight gate (mandatory for local_implementation)
70
70
 
71
- For the `local_implementation` strategy, before any planning or implementation mutation, run the pre-flight gate:
71
+ <!-- rule: LOCAL-PREFLIGHT-GATE-MANDATORY -->
72
+ For the `local_implementation` strategy, before any planning or implementation mutation, you MUST run the pre-flight gate:
72
73
 
73
74
  ```sh
74
75
  node scripts/loop/pre-flight-gate.mjs --expected-branch <working-branch> --check-subagents
75
76
  ```
76
77
 
77
- Before creating or reusing a worktree for local implementation, use the canonical lifecycle entrypoint, which fetches the base remote, then creates-or-reuses the worktree at its namespaced path and provisions it in one step:
78
+ Before creating or reusing a worktree for local implementation, use the canonical lifecycle entrypoint (`WORKTREE-CREATE-PROVISION`, see [Worktree usage guidance](../../docs/worktree-guidance.md#create-or-reuse--provision-ensure-worktreemjs)):
78
79
 
79
80
  ```sh
80
81
  node scripts/loop/ensure-worktree.mjs --repo-root <main> --issue <n>
81
82
  ```
82
83
 
83
- This creates (or reuses) the worktree at `tmp/worktrees/dev-loops/<kind>-<n>` from a freshly fetched `origin/main` (the authoritative base for all worktree creation) and provisions its gitignored runtime files. Raw `git worktree add -b <branch> tmp/worktrees/dev-loops/<kind>-<n> origin/main` is the underlying mechanism `ensure-worktree.mjs` runs for you. See [worktree guidance](../../docs/worktree-guidance.md).
84
+ This validates worktree isolation (current directory under `tmp/worktrees/`) and branch identity (current branch matches the working branch); `--check-subagents` only reports subagent availability and is advisory (fails-open, does not block the gate). If the gate fails, **stop and fix the violation** before proceeding do not bypass it in normal workflow execution.
84
85
 
85
- This validates:
86
- - Worktree isolation (current directory is under `tmp/worktrees/`)
87
- - Branch identity (current branch matches the working branch)
88
- - Subagent availability (subagents should be used for fan-out when available)
89
-
90
- If the gate fails, **stop and fix the violation** before proceeding. Do not bypass the gate in normal workflow execution.
91
-
92
- Note: `--check-subagents` is advisory — it reports availability but does not block the gate. The worktree and branch checks are the mandatory gates.
93
-
94
- This gate does **not** apply to other routed strategies (`copilot_pr_followup`, `external_pr_followup`, `reviewer_fixer`, `wait_watch`, `final_approval`, `issue_intake`). Those strategies have their own execution rules and may edit code from any checkout as needed.
95
-
96
- Development-only bypass (`DEVLOOPS_PREFLIGHT_BYPASS=1`) exists for testing the gate itself but must not be used in production workflow runs. The bypass variable is a testing convenience, not an operational escape hatch.
86
+ This gate does **not** apply to other routed strategies (`copilot_pr_followup`, `external_pr_followup`, `reviewer_fixer`, `wait_watch`, `final_approval`, `issue_intake`); those strategies have their own execution rules and may edit code from any checkout as needed. The development-only bypass (`DEVLOOPS_PREFLIGHT_BYPASS=1`) exists for testing the gate itself and MUST NOT be used in production workflow runs — it is a testing convenience, not an operational escape hatch.
97
87
 
98
88
  ## Narrow failure-triage fast path
99
89
 
100
- When resuming local implementation with dirty work or an observed failing command, use this path before broad discovery:
90
+ <!-- rule: LOCAL-FAILURE-TRIAGE-ORDER -->
91
+ When resuming local implementation with dirty work or an observed failing command, you MUST follow this ordered path before broad discovery:
101
92
 
102
93
  1. run startup once from the relevant worktree/context
103
94
  2. inspect current state with `git status` and the changed files
@@ -111,20 +102,13 @@ Follow [Anti-patterns](../docs/anti-patterns.md) for the general tooling-interna
111
102
 
112
103
  ### Step 1
113
104
 
114
- - Implement **one phase at a time**.
115
- - Do not refine later phases in detail before the current phase is complete.
105
+ - <!-- rule: LOCAL-PHASE-ONE-AT-A-TIME --> You MUST implement **one phase at a time** and MUST NOT refine later phases in detail before the current phase is complete.
116
106
  - Use the `refiner` agent for phase-refinement work when subagents are available; escalate RFC-worthy technical decisions to the parent session / human operator.
117
- - Work **test-first** for all non-trivial logic.
118
- - Maintain **90% coverage** thresholds.
107
+ - <!-- rule: LOCAL-TEST-FIRST-COVERAGE --> You MUST work **test-first** for all non-trivial logic and SHOULD maintain **90% coverage** thresholds (coverage is not enforced by the shipped verify config; treat it as the working target).
119
108
  - Log detailed iteration artifacts under `tmp/` using the required structure below.
120
- - For phase-doc-backed local sessions, keep durable phase intent and acceptance criteria in [Phase Plan](../../docs/phases/phase-x.md); for tracker-backed local sessions, keep that durable intent in the tracker issue and do not duplicate it into [Phase Plan](../../docs/phases/phase-x.md). Keep detailed execution artifacts in `tmp/`.
121
- - Treat `tmp/` as temporary local execution state. Do not rely on it as durable repo history and do not force-add it to git unless the user explicitly wants checked-in examples or fixtures.
109
+ - Spec-of-record split (phase-doc-backed vs. tracker-backed vs. lightweight): see [Tracker-backed local implementation](#tracker-backed-local-implementation) above.
122
110
  - When a phase changes durable product truth in ways `PLAN.md` should express (for example command surface, accepted product decisions, resolved open questions, or scope changes), update [Project Plan](../../PLAN.md) before closing the phase.
123
- - Do implementation work on a dedicated local branch, not directly on `main`.
124
- - If the repo has no commits yet, still create the working branch first so the first commits land off `main`; only move `main` forward after review and validation.
125
- - Use small atomic local commits as progress checkpoints whenever a coherent slice is green and reviewable.
126
- - Before a branch is considered review-complete, approval-ready, merge-ready, or ready for final handoff, run the default pre-approval gate as a full review / fix loop with the review angles resolved from config (`resolveGateAngles(config, "preApproval")`), then apply accepted fixes and rerun validation. Shipped defaults include the `deep` angle.
127
- - A phase is only fully complete when its scoped work, required support files, artifacts, validation, review/fix pass, commit(s), and finalization (merge into local `main` for phase-doc-backed sessions; PR merge for tracker-backed sessions) are done, or when the only remaining step is an explicitly noted authorization-gated finalization action.
111
+ - Branch, commit, pre-approval-gate, and finalization mechanics: see [Branch / review / merge policy](#branch--review--merge-policy), [Commit policy](#commit-policy), and [Implementation loop for the phase](#implementation-loop-for-the-phase) below.
128
112
  - When subagents are used, log what each subagent was asked to do and what it concluded.
129
113
  - If [Project Plan](../../PLAN.md) is too rough or ambiguous to safely start the current phase, do not guess: run a clarification/interview step with the user first.
130
114
 
@@ -134,32 +118,14 @@ Apply [Structural Quality](../docs/structural-quality.md) from the `deep` review
134
118
 
135
119
  ## Light mode (small changes)
136
120
 
137
- Light mode is wired into gate dispatch. A PR that is **under threshold** (≤ `maxLines` lines changed AND ≤ `maxFiles` files, per `.devloops` field `localImplementation.lightMode` — this repo sets `maxLines: 20`, `maxFiles: 2`; the shipped built-in default has light mode disabled (`enabled: false`); if enabled without explicit values it falls back to `maxFiles: 3` / `maxLines: 200`) AND carries no `gate:full` label collapses BOTH `draft_gate` and `pre_approval_gate` to a single inline single-agent correctness + no-op check. The Copilot review request and its polling are skipped.
138
-
139
- **Escalation:**
140
- 1. Auto-escalate — if the inline check surfaces any finding whose severity is in the gate's `blockCleanOnFindingSeverities` (i.e. ≥ `worth-fixing-now`), dispatch escalates to full fan-out.
141
- 2. Label override — the `gate:full` label forces full fan-out regardless of PR size.
142
-
143
- The `draft_gate` boundary (draft → ready) is still recorded because `requireDraftFirst` is honored: light mode only changes HOW the gate runs (inline vs fan-out), not WHETHER the draft boundary exists.
144
-
145
- Dispatch is resolved deterministically via `resolveGateDispatchMode(config, gate, { scope, hasFullLabel, inlineFindingSeverities })` from `@dev-loops/core/config`. `scripts/loop/resolve-gate-dispatch.mjs` is the CLI wrapper the orchestrator calls, combining `detect-change-scope.mjs` output with the `gate:full` label fact.
121
+ <!-- rule: LOCAL-LIGHT-MODE-CONFIG-SURFACE -->
122
+ `localImplementation.lightMode` (`.devloops` field; this repo sets `maxLines: 20`, `maxFiles: 2`) is this skill's config surface for light-mode gate dispatch. Gate-collapse mechanics, escalation, and dispatch resolution (`resolveGateDispatchMode`, `scripts/loop/resolve-gate-dispatch.mjs`) are owned by [Light-mode inline acceptance](../../docs/gate-review-sub-loop-contract.md#light-mode-inline-acceptance-under-threshold-micro-prs); this skill MUST NOT redefine them.
146
123
 
147
124
  Use `scripts/loop/detect-change-scope.mjs` to determine scope:
148
125
  ```sh
149
126
  node scripts/loop/detect-change-scope.mjs
150
127
  ```
151
128
 
152
- **Override threshold:**
153
- ```yaml
154
- localImplementation:
155
- lightMode:
156
- enabled: true
157
- maxFiles: 2
158
- maxLines: 20
159
- ```
160
-
161
- Scope above threshold falls back to the full fan-out/fan-in path.
162
-
163
129
  ## Deterministic logging structure
164
130
 
165
131
  Treat the workflow as three layers:
@@ -405,7 +371,8 @@ If the review finds real issues, revise the merged plan and briefly update the r
405
371
 
406
372
  ### 6. Only then start implementation
407
373
 
408
- Do not begin coding before the merged phase plan has passed review.
374
+ <!-- rule: LOCAL-PLAN-REVIEW-GATE -->
375
+ You MUST NOT begin coding before the merged phase plan has passed review.
409
376
  Update `manifest.json` to show that phase implementation has started.
410
377
 
411
378
  ## Task breakdown & delegation
@@ -424,7 +391,8 @@ into parallel executable tasks and dispatch them to the right specialist subagen
424
391
 
425
392
  ### Delegation contract
426
393
 
427
- Dispatch implementation tasks to dedicated specialist agents:
394
+ <!-- rule: LOCAL-DELEGATION-TABLE -->
395
+ Implementation tasks MUST be dispatched to dedicated specialist agents per this table:
428
396
 
429
397
  | Task type | Delegate to |
430
398
  |---|---|
@@ -524,7 +492,7 @@ After the phase plan passes review:
524
492
  5. Run the default pre-approval gate as a full review / fix loop on the branch before calling it review-complete, approval-ready, merge-ready, or ready for final handoff:
525
493
  - resolve review angles from config: `resolveGateAngles(config, "preApproval")` from `@dev-loops/core/config` (shipped defaults enable all 11 pre-approval gate angle families; consumer repos may opt out individual angles via `excludeAngles`); run via the chain prescription below
526
494
  - run the resolved angle-focused passes in parallel with fresh context when practical
527
- - if parallel execution is impractical (for example due to tooling or resource constraints), run all angles sequentially and explicitly record why parallel execution was impractical in `Phase Review` (`tmp/phases/phase-x/review.md`) (or the equivalent merged review artifact)
495
+ - the sequential-fallback rule is owned by `GATE-EXEC-FANOUT-SEQUENTIAL-FALLBACK` in [Gate Review Sub-Loop Contract](../../docs/gate-review-sub-loop-contract.md); when it applies, record the fallback in `Phase Review` (`tmp/phases/phase-x/review.md`) (or the equivalent merged review artifact)
528
496
  - for each angle, resolve its persona and prompt via `resolveReviewerRole(config, angle)` — start each reviewer in fresh context with a concise briefing including the angle-specific prompt, the branch/phase, intended behavior, acceptance criteria, relevant files or artifacts, and current validation status
529
497
  - run the mandatory chain defined in [Gate Review Sub-Loop Contract](../../docs/gate-review-sub-loop-contract.md). Retry rule: in subsequent cycles, only re-run reviewers that produced findings in the previous pass. Do not fork the parent session for parallel reviewers; write a compact handoff artifact under `tmp/` and point the reviewer at it.
530
498
  - when reviewer subagents stumble on raw source-tree reads (for example unresolved build artifacts or import assumptions), generate a deterministic diff/review artifact under `tmp/` and have reviewers inspect that artifact instead of the raw file set
@@ -538,8 +506,8 @@ After the phase plan passes review:
538
506
  9. Write `Retrospective` (`tmp/phases/phase-x/retrospective.md`) using [Retrospective Template](../dev-loop/templates/retrospective.md).
539
507
  10. Update `tmp/phases/phase-x/manifest.json` and `tmp/phases/index.json`.
540
508
  11. Update [Implementation State](../../docs/IMPLEMENTATION_STATE.md).
541
- 12. **Exit validation gate — no uncommitted changes.** Before the subagent session terminates, run `git status --porcelain` and verify the output is empty. If uncommitted changes exist, first determine whether they are intended implementation changes or unintended/post-validation deltas. Revert any unintended or speculative changes. For intended changes, rerun the narrowest justified validation (`npm run verify` or equivalent) before staging and committing with an appropriate message; for tracker-backed sessions, also push the branch. A subagent session that exits with uncommitted changes in the worktree is a workflow defect and must not be treated as a clean completion. After committing, verify `git status --porcelain` is empty before declaring phase completion.
542
- 13. For tracker-backed sessions, create the PR from the working branch using the canonical `dev-loops pr create --assignee @me --repo <owner/name> --base main --head <branch> --title "..." --body-file <body-file>` (always draft, self-assigned by default; `--assignee @me` is the default and is shown here for clarity). When the `dev-loops` CLI helper is unavailable, use the equivalent `create-pr.mjs` script directly: `node <resolved-skill-scripts>/github/create-pr.mjs --repo <owner/name> --assignee @me --base main --head <branch> --title "..." --body-file <body-file>`. Never open a PR with raw `gh pr create`. The PR body must contain `Closes #N` (or `Fixes #N`) for the linked issue. Do not create a fresh PR directly in ready-for-review state unless the user explicitly overrides that policy.
509
+ 12. <!-- rule: LOCAL-COMMIT-BEFORE-EXIT --> **Exit validation gate — no uncommitted changes.** Before the subagent session terminates, run `git status --porcelain` and verify the output is empty. If uncommitted changes exist, first determine whether they are intended implementation changes or unintended/post-validation deltas. Revert any unintended or speculative changes. For intended changes, rerun the narrowest justified validation (`npm run verify` or equivalent) before staging and committing with an appropriate message; for tracker-backed sessions, also push the branch. A subagent session that exits with uncommitted changes in the worktree is a workflow defect and MUST NOT be treated as a clean completion. After committing, verify `git status --porcelain` is empty before declaring phase completion.
510
+ 13. For tracker-backed sessions, create the PR from the working branch: `dev-loops pr create --assignee @me --repo <owner/name> --base main --head <branch> --title "..." --body-file <body-file>` (fallback when the CLI helper is unavailable: `node <resolved-skill-scripts>/github/create-pr.mjs --repo <owner/name> --assignee @me --base main --head <branch> --title "..." --body-file <body-file>`); never raw `gh pr create`. Draft/assignment/`Closes #N` policy: [LOCAL-PR-CREATE-CANONICAL](#tracker-backed-local-implementation) above.
543
511
  14. If authorized, merge the fully reviewed, locally validated phase branch back into local `main` (phase-doc-backed sessions) or proceed through the PR gate pipeline (tracker-backed sessions).
544
512
  15. If authorization for PR creation or merge is still pending (commit authorization is already enforced by the exit validation gate in step 12), mark the phase as `awaiting-finalization` rather than `completed`, and record exactly which finalization step is pending.
545
513
 
@@ -552,85 +520,32 @@ The retrospective must capture:
552
520
  - what should change in the skill or workflow next time
553
521
  - what a fresh session should know before the next phase
554
522
 
555
- This is the infrastructure for self-improvement. Do not skip it.
523
+ <!-- rule: LOCAL-RETROSPECTIVE-REQUIRED -->
524
+ This is the infrastructure for self-improvement; you MUST NOT skip it.
556
525
 
557
526
  ## Dev mode
558
527
 
559
- Dev mode is for improving the local implementation loop itself while using it.
560
-
561
- A repository may also declare a formal-dev-mode default through `.devloops` field `workflow.devModeDefault`. Treat that config as the policy source of truth when present, but explicit user opt-in or opt-out for the current run still wins. Runtime consumption of that config may be staged separately from this documentation update.
562
-
563
- Trigger it when the user explicitly asks for dev mode, self-improvement mode, or says they want the skill to refine itself as it goes.
564
-
565
- In dev mode, after the normal phase summary and retrospective are written, run one extra bounded self-improvement pass before moving on:
566
-
567
- 1. collect a deterministic context bundle for the phase using:
568
- - `../dev-loop/scripts/dev-mode-context.mjs`
569
- - output to `tmp/phases/phase-x/dev-mode-context.json`
570
- 2. review the phase artifacts and logs with emphasis on the workflow itself:
571
- - planning quality
572
- - review quality
573
- - validation friction
574
- - bash exit-code-1 patterns
575
- - places where skill or agent prompts should be tightened
576
- - places where deterministic tooling should replace ad hoc work
577
- 3. write `Dev Mode Retrospective` (`tmp/phases/phase-x/dev-mode-retrospective.md`)
578
- - this is the required dev-mode retrospective artifact
579
- - it should name the highest-value prompt/workflow follow-ups revealed by the phase
580
- 4. optionally write `Dev Mode Review` (`tmp/phases/phase-x/dev-mode-review.md`) when separate analytical notes help support the retrospective
581
- 5. apply at least one bounded follow-up update to a relevant skill and/or agent prompt
582
- - deterministic tooling, docs, templates, or tests may accompany that change
583
- - but they do not replace the required prompt update
584
- - keep the change phase-bounded and tied directly to the retrospective findings
585
- 6. write `Dev Mode Skill Changes` (`tmp/phases/phase-x/dev-mode-skill-changes.md`)
586
- - record which skill and/or agent prompts changed
587
- - record any supporting tooling/docs/template changes that accompanied them
588
- - if no prompt update can be justified safely, stop and report that dev-mode exit criteria were not met
589
- 7. if skill scripts or deterministic tooling changed, rerun the skill-local tests
590
- 8. stop after this bounded self-improvement pass; do not recurse into endless self-editing loops
591
-
592
- Dev mode is still phase-bounded. It improves the loop around the completed phase; it does not authorize work on the next product phase.
528
+ Dev mode improves the local implementation loop itself while using it. A repo may declare a default via `.devloops` field `workflow.devModeDefault`; explicit user opt-in/opt-out for the current run still wins over that default. Trigger it when the user explicitly asks for dev mode, self-improvement mode, or says they want the skill to refine itself as it goes.
593
529
 
594
- ## tmp/ logging requirements
530
+ After the normal phase summary and retrospective, run one extra bounded self-improvement pass:
595
531
 
596
- At minimum, each phase should leave behind:
597
- - a durable phase doc at [Phase Plan](../../docs/phases/phase-x.md)
598
- - local `tmp/` execution artifacts needed to resume and audit the phase, including:
599
- - `manifest.json`
600
- - `Variant A` (`tmp/phases/phase-x/variant-a.md`)
601
- - `Variant B` (`tmp/phases/phase-x/variant-b.md`)
602
- - `merged-plan.md`
603
- - `review.md`
604
- - `summary.md`
605
- - `retrospective.md`
606
- - optional `Variant C` (`tmp/phases/phase-x/variant-c.md`) when a third variant was actually useful
607
- - `bash-exit-1.jsonl` when any bash call during the phase exited with code `1`
608
- - `clarification.md` when a plan-sufficiency interview or auto-clarification step was needed
609
- - subagent summaries when subagents were used
610
- - raw subagent outputs only when they were saved separately on purpose
611
- - in dev mode: `dev-mode-context.json`, `dev-mode-retrospective.md`, and `dev-mode-skill-changes.md`
612
- - optional in dev mode: `dev-mode-review.md` when separate analytical notes were useful
613
-
614
- These `tmp/` artifacts are normally temporary and do not need to be checked into git.
615
-
616
- Also log validation output summaries and notable decisions if they help evaluate the local dev loop later.
617
-
618
- Additionally, append every bash call that exits with code `1` to:
619
- - `tmp/phases/phase-x/bash-exit-1.jsonl`
532
+ 1. Collect a deterministic context bundle: `../dev-loop/scripts/dev-mode-context.mjs` → `tmp/phases/phase-x/dev-mode-context.json`.
533
+ 2. Review the phase artifacts/logs for planning quality, review quality, validation friction, bash exit-code-1 patterns, and places where prompts or deterministic tooling should improve.
534
+ 3. Write `Dev Mode Retrospective` (`tmp/phases/phase-x/dev-mode-retrospective.md`) required; name the highest-value prompt/workflow follow-ups revealed by the phase.
535
+ 4. Optionally write `Dev Mode Review` (`tmp/phases/phase-x/dev-mode-review.md`) when separate analytical notes help.
536
+ 5. Apply at least one bounded follow-up update to a relevant skill and/or agent prompt (supporting tooling/docs/template changes may accompany it but do not replace the prompt update), kept phase-bounded and tied directly to the retrospective findings.
537
+ 6. Write `Dev Mode Skill Changes` (`tmp/phases/phase-x/dev-mode-skill-changes.md`) recording which prompts and supporting changes landed; if no prompt update can be justified safely, stop and report that dev-mode exit criteria were not met.
538
+ 7. If skill scripts or deterministic tooling changed, rerun the skill-local tests.
539
+ 8. Stop after this bounded pass — do not recurse into endless self-editing loops.
540
+
541
+ Dev mode is still phase-bounded: it improves the loop around the completed phase and does not authorize work on the next product phase.
620
542
 
621
- Use the deterministic helper:
622
- - `../dev-loop/scripts/log-bash-exit-1.mjs`
543
+ ## tmp/ logging requirements
623
544
 
624
- Each line should be one JSON object with at least:
625
- - `timestamp`
626
- - `phase`
627
- - `cwd`
628
- - `command`
629
- - `exitCode`
630
- - `purpose`
631
- - `summary`
545
+ <!-- rule: LOCAL-TMP-EPHEMERAL-STATE -->
546
+ The required durable-doc + `tmp/` artifact set for a phase is defined once in [Deterministic logging structure](#deterministic-logging-structure); this section MUST NOT duplicate that list. Those artifacts are normally temporary and do not need to be checked into git; do not force-add them unless the user explicitly wants checked-in examples or fixtures. Also log validation output summaries and notable decisions if they help evaluate the local dev loop later.
632
547
 
633
- If useful, also include truncated `stdout` and `stderr` fields or a path to a larger saved artifact. This log is for improving the local dev loop itself, so do not skip it just because the command was exploratory.
548
+ Additionally, append every bash call that exits with code `1` to `tmp/phases/phase-x/bash-exit-1.jsonl` using the deterministic helper `../dev-loop/scripts/log-bash-exit-1.mjs`. Each line is one JSON object with at least `timestamp`, `phase`, `cwd`, `command`, `exitCode`, `purpose`, `summary` (optionally truncated `stdout`/`stderr` or a path to a larger saved artifact). This log improves the local dev loop itself, so do not skip it just because the command was exploratory.
634
549
 
635
550
  ## Stop conditions
636
551
 
@@ -638,29 +553,20 @@ See [Stop Conditions](../docs/stop-conditions.md). Local-specific stops: phase c
638
553
 
639
554
  ## Branch / review / merge policy
640
555
 
641
- - Do not implement directly on `main`.
642
- - Start or switch to a dedicated local working branch before the first mutating step.
643
- - If the repository is unborn (no commits yet), still create the working branch first and make the initial atomic commits there.
644
- - Use atomic local commits to log progress, but only for coherent reviewable slices.
645
- - Before merging, run a full parallel review / fix loop and resolve accepted findings on the same branch.
646
- - Rerun validation after review-driven fixes.
647
- - A phase is not operationally closed until its branch state is captured in commit history and the reviewed branch has been finalized according to session type (merged into local `main` for phase-doc-backed sessions; merged via GitHub PR for tracker-backed sessions), unless authorization for that finalization is still pending.
648
- - For tracker-backed sessions, the handoff path is always: push the working branch → open a PR → merge via GitHub; never merge the working branch into local `main`.
649
- - PR creation always goes through `dev-loops pr create`, which is ALWAYS draft and always assigned — self-assigned by default (`--assignee @me` when none is given; honors an explicit `--assignee <login>` / `-a <login>`), never via raw `gh pr create`, and the PR body must contain `Closes #N` (or `Fixes #N`) for the linked issue so GitHub auto-closes it on merge. When `.devloops` sets `workflow.requireDraftFirst` to true, use `dev-loops pr create --assignee @me ...`. 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 eligible.
650
- - When authorization is pending, record the phase as `awaiting-finalization` and describe the exact missing step.
556
+ - Implement on a dedicated local working branch, never directly on `main`, switching to it before the first mutating step; if the repo is unborn (no commits yet), still create the working branch first and make the initial atomic commits there.
557
+ - Use atomic local commits to log progress, but only for coherent reviewable slices [Commit policy](#commit-policy) below governs commit timing/authorization.
558
+ - Before merging, run a full parallel review / fix loop and resolve accepted findings on the same branch; rerun validation after review-driven fixes.
559
+ - A phase is not operationally closed until its branch state is captured in commit history and the reviewed branch has been finalized according to session type (merged into local `main` for phase-doc-backed sessions; merged via GitHub PR for tracker-backed sessions); when authorization for that finalization is still pending, record the phase as `awaiting-finalization` and describe the exact missing step.
560
+ - For tracker-backed sessions, the handoff path is always: push the working branch open a PR → merge via GitHub; never merge the working branch into local `main`. PR creation follows [LOCAL-PR-CREATE-CANONICAL](#tracker-backed-local-implementation) above; a new PR must exist in draft before `gh pr ready` is eligible.
651
561
  - For phase-doc-backed sessions, merge the fully reviewed, locally validated branch back into local `main` when authorized.
652
562
  - Behind-branch integration before merge (for example a sibling PR merged first and both touch shared files): prefer a merge commit (`git merge origin/main`) over rebase + force-push. Since dev-loop PRs are squash-merged, intermediate branch history is discarded at merge time, so a merge commit lands an identical result on `main` while avoiding a non-fast-forward push to the remote. Force-push (`--force-with-lease` only, never bare `--force`) remains acceptable only for a branch the loop solely owns and where no integration alternative exists (rare); document that carve-out rather than leaving it implicit. After any integration that changes the head SHA, re-verify gate evidence at the new head (existing behavior — see [Merge Preconditions](../docs/merge-preconditions.md#required-before-merge)).
653
563
 
654
564
  ## Commit policy
655
565
 
656
- - Do not commit speculative work.
657
- - Do not commit before the relevant validation for that slice passes.
566
+ - Do not commit speculative work or before the relevant validation for that slice passes.
658
567
  - Immediately before every `git add && git commit` sequence, assert branch identity with `git branch --show-current` and stop if it does not match the intended local working branch.
659
- - Keep commits small and phase-bounded.
660
- - Do not leave completed phase work stranded off `main`; once the reviewed branch is ready and authorized, finalize it according to session type (merge into local `main` for phase-doc-backed sessions; complete via PR merge for tracker-backed sessions).
661
- - Commit only when the coordination/main agent has decided the slice or phase is ready. **Exception:** in non-interactive subagent sessions, commit authorization is implicit — the subagent was dispatched to implement and must commit before exiting (see the commit sub-bullet under implementation loop step 3 and the exit validation gate in step 12).
568
+ - Commit only when the coordination/main agent has decided the slice or phase is ready. **Exception:** in non-interactive subagent sessions, commit authorization is implicit — the subagent was dispatched to implement and must commit before exiting, enforced by [LOCAL-COMMIT-BEFORE-EXIT](#implementation-loop-for-the-phase) (implementation loop step 12; `git status --porcelain` must be empty before the session terminates).
662
569
  - If commit/merge authorization has not yet been given, do not call the phase `completed`; call it `awaiting-finalization` instead.
663
- - **Subagent exit contract:** before a subagent session terminates, the exit validation gate (implementation loop step 12) must pass — `git status --porcelain` must be empty. A subagent that exits with uncommitted changes in the worktree has not completed its task, regardless of what was implemented.
664
570
 
665
571
  ## Anti-patterns
666
572
 
package/CHANGELOG.md CHANGED
@@ -4,6 +4,12 @@ All notable changes to this project will be documented in this file.
4
4
 
5
5
  ## Unreleased
6
6
 
7
+ ## 0.7.2 - 2026-07-06
8
+
9
+ ### Fixed
10
+
11
+ - **Package-escaping imports in `@dev-loops/core` broke every consumer install (#1241).** `queue-board-sync.mjs` and `queue-board-ordering.mjs` imported `move-queue-item`/`list-queue-items` via `../../../../scripts/projects/*`, paths outside the package root that the published tarball (src/**+bin/** only) cannot resolve — so `resolve-active-board-item` (loop startup) and `ready-for-review` threw `ERR_MODULE_NOT_FOUND` on install for every release from 0.3.0 to 0.7.1. The `main` implementations now live in `@dev-loops/core` (`src/projects/`, exported via the package map); the two `scripts/projects/*` files are thin CLI wrappers importing core by package name. A packaged-install smoke test (`test:pack`) npm-packs both packages, installs them in a temp dir, imports every `@dev-loops/core` export-map entry, and runs the affected CLIs with `--help` — closing the artifact-layout gap that let five releases ship broken.
12
+
7
13
  ## 0.7.1 - 2026-07-05
8
14
 
9
15
  ### Changed
@@ -16,12 +16,12 @@ Your job is to provide the callable `dev-loop` public façade and route to the c
16
16
 
17
17
  ## Handoff envelope mandate (first action)
18
18
 
19
- The agent's first action after resolving authoritative state must be to build the handoff envelope via `buildDevLoopHandoffEnvelope()` from `@dev-loops/core`.
19
+ The agent's first action after resolving authoritative state MUST be to build the handoff envelope via `buildDevLoopHandoffEnvelope()` from `@dev-loops/core`.
20
20
 
21
21
  The envelope is the primary handoff artifact — it is derived from resolver output, settings, and gate state, and it determines:
22
22
  - `requiredReads` — the canonical ordered list of files to load
23
23
  - `nextAction` — the bounded task to execute
24
- - `stopRules` — stop boundaries that must not be crossed without authorization
24
+ - `stopRules` — stop boundaries that MUST NOT be crossed without authorization
25
25
  - `acceptance` — self-validation criteria for declaring completion
26
26
  - `sanctionedCommands` — the operation → wrapper command map (reads/edits/lifecycle), plus the forbidden and orchestrator-owned lists. Carried by DEFAULT on every build so you never re-derive which wrapper performs a GitHub/loop operation. Do NOT restate the map here — the single source of truth is `scripts/loop/sanctioned-commands.mjs`, surfaced verbatim in the envelope.
27
27
 
@@ -44,7 +44,7 @@ NEVER fall back to `find /` or any unbounded filesystem walk to locate the CLI
44
44
  5. Load every path listed in `requiredReads` (in order).
45
45
  6. Execute `nextAction` constrained by `stopRules` and `acceptance`.
46
46
 
47
- **The agent must not load skills, route packs, or delegate work before the envelope is built and read.** The derivation contract is [Workflow Handoff Contract](../skills/docs/workflow-handoff-contract.md).
47
+ **The agent MUST NOT load skills, route packs, or delegate work before the envelope is built and read.** The derivation contract is [Workflow Handoff Contract](../skills/docs/workflow-handoff-contract.md).
48
48
 
49
49
  Prose task composition is a fallback only when `buildDevLoopHandoffEnvelope()` is unavailable (missing `@dev-loops/core` package) — the handoff contract in `skills/docs/workflow-handoff-contract.md` applies in that fallback case.
50
50
 
@@ -54,7 +54,7 @@ After the handoff envelope is built and read, load the `dev-loop` skill ([Dev Lo
54
54
 
55
55
  When that skill is not available at the expected path, resolve it from the skill installation layout (see the skill's "Skill asset path resolution" section).
56
56
 
57
- This entrypoint must stay thin: do not restate the skill's phase sequencing or workflow policy here. The envelope owns handoff sequencing; the skill owns routed strategy execution procedures.
57
+ This entrypoint MUST stay thin: do not restate the skill's phase sequencing or workflow policy here. The envelope owns handoff sequencing; the skill owns routed strategy execution procedures.
58
58
 
59
59
  Treat the deterministic public routing contract in [Public Dev Loop Contract](../skills/docs/public-dev-loop-contract.md) and the `dev-loop` skill as the authority for choosing the current execution path. Do not force users to choose internal strategy names up front.
60
60
 
@@ -75,9 +75,9 @@ If local facts, GitHub facts, and helper/state-machine output do not agree well
75
75
  This agent's frontmatter `tools:` comma-token scalar includes `subagent` (single-line comma form, no brackets — see #1111) and it sets `maxSubagentDepth: 3` to allow orchestrating parallel review, chains, and staged fix passes.
76
76
  <!-- /pi-only -->
77
77
 
78
- All delegation must originate from the handoff envelope: the envelope's `nextAction`, `requiredReads`, `stopRules`, and `acceptance` define the bounded task. The envelope is passed to child subagents as their primary handoff artifact.
78
+ All delegation MUST originate from the handoff envelope: the envelope's `nextAction`, `requiredReads`, `stopRules`, and `acceptance` define the bounded task. The envelope is passed to child subagents as their primary handoff artifact.
79
79
 
80
- The pi-subagents skill is parent-only, so delegated subagents do not receive orchestration patterns. This section exists as the minimal locally-enforced subset needed for correct delegation — it is not a restatement of the full policy. The `dev-loop` skill owns all procedural rules; this section only declares the invariants the agent must follow when it cannot defer to the skill:
80
+ The pi-subagents skill is parent-only, so delegated subagents do not receive orchestration patterns. This section exists as the minimal locally-enforced subset needed for correct delegation — it is not a restatement of the full policy. The `dev-loop` skill owns all procedural rules; this section only declares the invariants the agent MUST follow when it cannot defer to the skill:
81
81
  - One writer thread; `async: true` default; `context: "fresh"` for reviewers.
82
82
  - No child subagent spawning beyond assigned fanout work.
83
83
  - Bounded tasks with concrete scope, exit conditions, and validation expectations.
@@ -87,8 +87,8 @@ The pi-subagents skill is parent-only, so delegated subagents do not receive orc
87
87
 
88
88
  - **Prefer `intercom` when available.** If the `pi-intercom` extension is active, use `intercom({ action: "ask", ... })` instead of `contact_supervisor`. The `intercom` tool uses message-based delivery (no blocking tool-call state) — see the pi documentation for `intercom({ action: "ask", ... })` parameters and reply conventions.
89
89
  - **When `intercom` is unavailable,** do not call `contact_supervisor`. Instead, brief the supervisor to include the decision in the resume message when re-dispatching. The subagent states what it needs in the task description; the supervisor provides the answer on resume. This avoids the broken response path entirely.
90
- - **If `contact_supervisor` was already called** (legacy code or unavoidable): expect a ~60s idle timeout followed by a pause. On resume, the supervisor must inject the decision in the resume message — do not rely on `intercom` on resume when it was unavailable at call time.
91
- - **Timeout detection (supervisor-side):** if a `contact_supervisor` call has been pending for >30s, the supervisor should treat it as a probable timeout and prepare to inject the decision in the resume message on re-dispatch. The subagent cannot execute this detection while blocked inside `contact_supervisor`; the supervisor must observe the pending duration externally.
90
+ - **If `contact_supervisor` was already called** (legacy code or unavoidable): expect a ~60s idle timeout followed by a pause. On resume, the supervisor MUST inject the decision in the resume message — do not rely on `intercom` on resume when it was unavailable at call time.
91
+ - **Timeout detection (supervisor-side):** if a `contact_supervisor` call has been pending for >30s, the supervisor SHOULD treat it as a probable timeout and prepare to inject the decision in the resume message on re-dispatch. The subagent cannot execute this detection while blocked inside `contact_supervisor`; the supervisor MUST observe the pending duration externally.
92
92
  <!-- /pi-only -->
93
93
 
94
94
  ## Output
@@ -28,6 +28,7 @@ You are a focused review-fix agent. You take an existing pull request with revie
28
28
 
29
29
  ## Review Workflow
30
30
  1. Read unresolved review threads and any general review comments.
31
+ - Prefer the deterministic helper `scripts/github/list-review-threads.mjs --unresolved-only` to enumerate threads with their reply/resolve ids, rather than hand-writing a GraphQL query.
31
32
  2. Group related comments by file and identify the underlying concern behind each comment.
32
33
  3. Decide the best resolution for each concern: exact requested change, better alternative fix, explanation-only resolution, or escalation for expert judgment.
33
34
  4. If expert input is needed, stop before editing or resolving the thread and report the question, evidence, and options.
@@ -40,7 +40,7 @@ For the active phase, require and produce:
40
40
  - if no explicit definition of done exists, add a `Proposed DoD` subsection before the matrix
41
41
  - explicit risks, watchpoints, and unresolved questions
42
42
  - validation steps and tests to write first
43
- - durable decisions that should be preserved in the phase doc
43
+ - durable decisions that SHOULD be preserved in the phase doc
44
44
  - when the phase includes a bounded audit or scan: prioritized findings, the highest-value follow-up candidates, and an explicit statement of what the current phase will not rewrite or broaden
45
45
  - When an audit artifact is provided, treat it as a first-class planning input: summarize the audited scope, list prioritized findings, include the highest-value follow-up candidates, and classify each meaningful finding as exactly one of current-phase scope/AC, DoD expectation, explicit non-goal / defer, or risk/watchpoint
46
46
  - Do not invent audit findings when no audit artifact was provided
@@ -85,4 +85,4 @@ Return:
85
85
 
86
86
  ## Completion quality bar
87
87
  - A refinement is complete only when no item in the AC/DoD/Non-goal coverage matrix has status `Partial`, `Unmet`, or `Unverified`.
88
- - Any `Partial`, `Unmet`, or `Unverified` item means the refinement is still incomplete and must not be presented as ready.
88
+ - Any `Partial`, `Unmet`, or `Unverified` item means the refinement is still incomplete and MUST NOT be presented as ready.
@@ -37,7 +37,7 @@ You are in scoped angle-review mode when the invocation supplies a single review
37
37
  - **Fresh-context guard (mandatory):** run `node scripts/github/verify-fresh-review-context.mjs --scope <angle> --context-path <gate-context-artifact-path>` at startup. If it reports `fresh: false` (exit 1) or any error — including a missing gate-context artifact (`gateContextPresent: false`), which is the fail-closed signal that you're not in the right worktree/head — refuse to proceed and report the failure; do not review on inherited context or without seeded context. "Fresh" here means your context is the **neutral builder artifact + your angle**, and explicitly NOT the main agent's conversation/state or a prior reviewer session's state. The injected neutral bundle is the INTENDED seed (allowed); main-agent or cross-session state bleed still fails closed.
38
38
  - **Use the PROVIDED neutral bundle as your base; do NOT re-derive it from scratch:** the gate-context artifact carries the diff (`scope.diffPath`) and a deterministic, neutral adjacent-code bundle in `adjacentCode` (each changed file plus its 1-hop import in/out-edges, with a `stripped`/`truncated`/`missing` manifest). Start from this bundle — it is the build-once, work-deduped seed shared verbatim across all reviewers. Only widen (load more files) per-angle when the bundle genuinely lacks something your angle needs; do not re-build the whole diff/adjacent-code graph yourself.
39
39
  - **Single-angle scope:** review ONLY the supplied angle's concern. Read the gate-context artifact for the resolved angle set, change scope (branch, head SHA, touched files), acceptance-criteria pointer, and validation posture. Do not review other angles; the fan-in pass consolidates across angles.
40
- - **Read the FULL diff, not just hunks:** the gate-context artifact records `scope.diffPath` (a repo-relative path to the complete captured diff) and `scope.changedFiles` (full repo-relative paths). Read the entire diff from `scope.diffPath`; if it is `null` or missing, reconstruct it yourself with `git diff` against the change's base (e.g. `git diff origin/main...HEAD` or the branch/head SHA in `scope`). Do not review off a partial or summarized hunk list — you must see every changed line for your angle.
40
+ - **Read the FULL diff, not just hunks:** the gate-context artifact records `scope.diffPath` (a repo-relative path to the complete captured diff) and `scope.changedFiles` (full repo-relative paths). Read the entire diff from `scope.diffPath`; if it is `null` or missing, reconstruct it yourself with `git diff` against the change's base (e.g. `git diff origin/main...HEAD` or the branch/head SHA in `scope`). Do not review off a partial or summarized hunk list — you MUST see every changed line for your angle.
41
41
  - **Reason about ADJACENT related code from the bundle first:** the `adjacentCode` bundle already includes the changed files' callers, callees, and imports (1-hop). Read those entries before opening anything else. For each changed function, trace the real call paths a defect would flow through, and confirm that caller and callee contracts still match (argument shapes, return shapes, error/null conventions, units). If the bundle truncated or stripped a file you need (see its `truncated`/`stripped` manifest), open that file directly to widen.
42
42
  - **Review ADVERSARIALLY — hunt concrete defects:** actively try to break the changed code. Hunt for edge cases, missing or wrong input validation, numeric coercion bugs (NaN, Infinity, floats where integers are assumed, negative values, string-to-number coercion), null/undefined handling, off-by-one and boundary conditions, mismatched caller/callee contracts, and dedup/identity bugs (wrong key, reference vs. value equality, unstable ordering). For every finding, give the concrete `file:line` plus the specific failing scenario or input that triggers the defect — not high-altitude "is there a test?" commentary.
43
43
  - **Strictly read-only, but WIDEN SCOPE when needed:** never edit files, stage, commit, push, request reviews, resolve threads, or post PR comments. Findings are returned via the output artifact only; fixes are applied later by the fix cycle, not by this agent. Because you are read-only, you MAY open any additional repository files required to judge your angle (callers, callees, contracts, sibling modules, configs, tests) — widening to read adjacent code is expected and safe. Record every file/module you consulted beyond the briefing's `changedFiles`/`diffPath` in the optional `contextWidened` field on your output artifact.
@@ -76,7 +76,7 @@ When NOT given an angle scope, behave exactly as the full-PR review agent descri
76
76
  - Prefer concrete findings with file references and impact over generic style commentary.
77
77
  - Distinguish clearly between must-fix findings, lower-severity risks, and informational gaps.
78
78
  - If the PR description omits required sections, is too thin to ground review without reconstructing intent from commits, or includes verdict status, evidence, or changelog content, treat that as a first-class review issue.
79
- - The review verdict must carry the acceptance-criteria and definition-of-done assessment in explicit markdown verification tables, including status plus concise evidence for each row.
79
+ - The review verdict MUST carry the acceptance-criteria and definition-of-done assessment in explicit markdown verification tables, including status plus concise evidence for each row.
80
80
  - For follow-up reviews on the same PR, do not repost full AC/DoD tables: include only delta rows where status or supporting evidence changed, and explicitly note when there are no AC/DoD deltas.
81
81
  - When changelog coverage is needed, include a dedicated `## Changelog` section in the review verdict comment so post-merge automation can consume it without reading the PR description.
82
82
 
package/package.json CHANGED
@@ -22,7 +22,7 @@
22
22
  ],
23
23
  "scripts": {
24
24
  "verify": "npm test && npm run test:dev-loop",
25
- "test": "npm run test:assets && npm run test:extension && npm run test:scripts && npm run test:core && npm run test:docs",
25
+ "test": "npm run test:assets && npm run test:extension && npm run test:scripts && npm run test:core && npm run test:docs && npm run test:pack",
26
26
  "test:assets": "node --test --test-reporter ./test/failure-summary-reporter.mjs test/dev-loop-init-phase-smoke.test.mjs test/contracts/*.test.mjs test/workflow-handoff-contract.test.mjs",
27
27
  "test:extension": "node --import tsx --test --test-reporter ./test/failure-summary-reporter.mjs test/extension-checks.test.mjs test/extension-post-merge-update.test.mjs test/extension-command-contract.test.mjs test/extension-package-contract.test.mjs test/extension-pi-adapter.test.mjs test/dev-loops-core.test.mjs test/dev-loops-cli.test.mjs",
28
28
  "test:scripts": "GIT_CONFIG_COUNT=2 GIT_CONFIG_KEY_0=core.fsync GIT_CONFIG_VALUE_0=none GIT_CONFIG_KEY_1=core.fsyncObjectFiles GIT_CONFIG_VALUE_1=false node --test --test-reporter ./test/failure-summary-reporter.mjs test/github/*.test.mjs test/loop/*.test.mjs test/docs/*.test.mjs test/projects/*.test.mjs test/pages/*.test.mjs",
@@ -34,7 +34,8 @@
34
34
  "test:playwright:intro-article": "PW_UI_SLICE=intro-article playwright test --project=intro-article",
35
35
  "test:playwright:deep-dive-article": "PW_UI_SLICE=deep-dive-article playwright test --project=deep-dive-article",
36
36
  "smoke:headless": "node scripts/claude/headless-info-smoke.mjs",
37
- "test:docs": "node scripts/docs/validate-links.mjs && node scripts/docs/validate-no-duplicate-rules.mjs",
37
+ "test:docs": "node scripts/docs/validate-links.mjs && node scripts/docs/validate-rule-ownership.mjs",
38
+ "test:pack": "node --test --test-reporter ./test/failure-summary-reporter.mjs test/packaged-install-smoke.test.mjs",
38
39
  "repo-wiki": "node scripts/repo-wiki.mjs",
39
40
  "repo-wiki:bootstrap": "node scripts/repo-wiki.mjs scan --repo . && node scripts/repo-wiki.mjs plan --repo . && node scripts/repo-wiki.mjs compile --repo .",
40
41
  "repo-wiki:scan": "node scripts/repo-wiki.mjs scan --repo .",
@@ -71,7 +72,7 @@
71
72
  ]
72
73
  },
73
74
  "dependencies": {
74
- "@dev-loops/core": "^0.7.1"
75
+ "@dev-loops/core": "^0.7.2"
75
76
  },
76
77
  "repository": {
77
78
  "type": "git",
@@ -81,7 +82,7 @@
81
82
  "url": "https://github.com/mfittko/dev-loops/issues"
82
83
  },
83
84
  "homepage": "https://github.com/mfittko/dev-loops#readme",
84
- "version": "0.7.1",
85
+ "version": "0.7.2",
85
86
  "files": [
86
87
  "cli/",
87
88
  "lib/",
@@ -14,12 +14,14 @@ export {
14
14
  } from "@dev-loops/core/loop/phase-files";
15
15
 
16
16
  export {
17
+ containsBareCopilotSummon,
17
18
  extractReviewCommitSha,
18
19
  isCopilotLogin,
19
20
  normalizeTimestamp,
20
21
  parseGateReviewCommentBody,
21
22
  parseGateReviewCommentMarkerBody,
22
23
  resolveDraftGateRoundResetMs,
24
+ sanitizeCopilotSummonTokens,
23
25
  summarizeCopilotReviews,
24
26
  summarizeGateReviewCommentMarkers,
25
27
  summarizeGateReviewComments,
@@ -101,7 +101,7 @@ function main(argv) {
101
101
  const repoRoot = path.resolve(fileURLToPath(new URL("../../", import.meta.url)));
102
102
 
103
103
  // --dry-run is side-effect-free: mint a run id in-memory without persisting the state file.
104
- const { runId } = ensureRunId({ env: process.env, root: opts.dryRun ? undefined : repoRoot });
104
+ const { runId } = ensureRunId({ env: opts.dryRun ? {} : process.env, root: opts.dryRun ? undefined : repoRoot });
105
105
  const prompt = opts.prompt ?? buildDevLoopPrompt({ issue: opts.issue, pr: opts.pr });
106
106
  const { command, args, env } = buildHeadlessClaudeInvocation({
107
107
  prompt,