dev-loops 0.7.2 → 0.8.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.claude/.claude-plugin/plugin.json +1 -1
- package/.claude/agents/dev-loop.md +1 -1
- package/.claude/agents/refiner.md +2 -2
- package/.claude/agents/review.md +9 -12
- package/.claude/commands/loop-continue.md +2 -1
- package/.claude/commands/loop-enqueue.md +8 -1
- package/.claude/commands/loop-info.md +1 -1
- package/.claude/hooks/_bash-command-classify.mjs +7 -6
- package/.claude/hooks/_hook-decisions.mjs +5 -4
- package/.claude/skills/copilot-pr-followup/SKILL.md +5 -5
- package/.claude/skills/dev-loop/SKILL.md +7 -7
- package/.claude/skills/docs/acceptance-criteria-verification.md +12 -4
- package/.claude/skills/docs/anti-patterns.md +3 -3
- package/.claude/skills/docs/artifact-authority-contract.md +6 -4
- package/.claude/skills/docs/confirmation-rules.md +1 -1
- package/.claude/skills/docs/copilot-loop-operations.md +4 -2
- package/.claude/skills/docs/issue-intake-procedure.md +12 -3
- package/.claude/skills/docs/merge-preconditions.md +5 -3
- package/.claude/skills/docs/pr-lifecycle-contract.md +1 -1
- package/.claude/skills/docs/public-dev-loop-contract.md +2 -1
- package/.claude/skills/docs/retrospective-checkpoint-contract.md +9 -6
- package/.claude/skills/docs/validation-policy.md +1 -1
- package/.claude/skills/local-implementation/SKILL.md +3 -3
- package/.claude/skills/loop-grill/SKILL.md +34 -14
- package/AGENTS.md +1 -1
- package/CHANGELOG.md +30 -0
- package/README.md +95 -189
- package/agents/refiner.agent.md +2 -2
- package/agents/review.agent.md +9 -12
- package/extension/README.md +5 -4
- package/package.json +5 -4
- package/scripts/docs/validate-state-machine-conformance.mjs +78 -1
- package/scripts/github/_gate-names.mjs +5 -0
- package/scripts/github/capture-review-threads.mjs +2 -2
- package/scripts/github/detect-checkpoint-evidence.mjs +7 -7
- package/scripts/github/edit-issue.mjs +259 -0
- package/scripts/github/probe-ci-status.mjs +18 -0
- package/scripts/github/probe-copilot-review.mjs +24 -3
- package/scripts/github/reconcile-draft-gate.mjs +13 -13
- package/scripts/github/request-copilot-review.mjs +17 -16
- package/scripts/github/upsert-checkpoint-verdict.mjs +25 -23
- package/scripts/github/verify-briefing-prefixes.mjs +224 -33
- package/scripts/github/write-gate-context.mjs +8 -4
- package/scripts/loop/_post-convergence-change.mjs +2 -2
- package/scripts/loop/_pr-runner-coordination.mjs +112 -13
- package/scripts/loop/check-retro-tooling.mjs +14 -9
- package/scripts/loop/copilot-pr-handoff.mjs +18 -14
- package/scripts/loop/detect-copilot-loop-state.mjs +11 -11
- package/scripts/loop/detect-internal-only-pr.mjs +6 -6
- package/scripts/loop/detect-pr-gate-coordination-state.mjs +117 -15
- package/scripts/loop/detect-refinement-grill-state.mjs +136 -0
- package/scripts/loop/run-watch-cycle.mjs +42 -7
- package/scripts/loop/sanctioned-commands.mjs +1 -0
- package/scripts/pages/build-state-atlas.mjs +15 -0
- package/scripts/projects/add-queue-item.mjs +87 -4
- package/skills/copilot-pr-followup/SKILL.md +5 -5
- package/skills/dev-loop/SKILL.md +2 -2
- package/skills/docs/acceptance-criteria-verification.md +12 -4
- package/skills/docs/anti-patterns.md +3 -3
- package/skills/docs/artifact-authority-contract.md +6 -4
- package/skills/docs/confirmation-rules.md +1 -1
- package/skills/docs/copilot-loop-operations.md +4 -2
- package/skills/docs/issue-intake-procedure.md +12 -3
- package/skills/docs/merge-preconditions.md +5 -3
- package/skills/docs/pr-lifecycle-contract.md +1 -1
- package/skills/docs/public-dev-loop-contract.md +2 -1
- package/skills/docs/required-rules.json +17 -1
- package/skills/docs/retrospective-checkpoint-contract.md +9 -6
- package/skills/docs/validation-policy.md +1 -1
- package/skills/local-implementation/SKILL.md +3 -3
- package/skills/loop-grill/SKILL.md +38 -17
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"requiredRules": [
|
|
3
3
|
"ACCEPT-CRITERIA-VERIFY-AND-REFLECT",
|
|
4
|
+
"ANTIPATTERN-FANIN-WAIT",
|
|
4
5
|
"ARTIFACT-LIGHTWEIGHT-BODY-INVARIANTS",
|
|
5
6
|
"ARTIFACT-LIGHTWEIGHT-PLAN-FILE-EXCLUSIVE",
|
|
6
7
|
"ARTIFACT-STRATEGY-ENUM-FAIL-CLOSED",
|
|
@@ -56,6 +57,10 @@
|
|
|
56
57
|
"GATE-EXEC-REGATE-MANDATORY",
|
|
57
58
|
"GATE-EXEC-SEPARATE-CHAINS",
|
|
58
59
|
"GATE-SKIP-NOT-RECOVERABLE-BY-CONVERGENCE",
|
|
60
|
+
"GRILL-SUBLOOP-HONEST-HANDOFF",
|
|
61
|
+
"GRILL-SUBLOOP-ITERATE-TO-CLEAN",
|
|
62
|
+
"GRILL-SUBLOOP-NO-EMBED-SYNTHESIS",
|
|
63
|
+
"GRILL-SUBLOOP-STATE-MACHINE",
|
|
59
64
|
"INTAKE-LINKED-PR-HELPER-DELEGATION",
|
|
60
65
|
"INTAKE-NEW-IDEA-SAFETY",
|
|
61
66
|
"INTAKE-STOP-STATES",
|
|
@@ -79,9 +84,11 @@
|
|
|
79
84
|
"OPS-NO-INLINE-INTERPRETER",
|
|
80
85
|
"QUEUE-BOARD-LINKED",
|
|
81
86
|
"QUEUE-BOARD-QUERY-FAIL-CLOSED",
|
|
87
|
+
"QUEUE-BOARD-SYNC-CONTINUOUS",
|
|
82
88
|
"QUEUE-BOOTSTRAP-ONLY-MUTATOR",
|
|
83
89
|
"QUEUE-COLUMN-CANONICAL",
|
|
84
90
|
"QUEUE-COLUMN-NO-REMOVE",
|
|
91
|
+
"QUEUE-ENQUEUE-REFINEMENT-GATE",
|
|
85
92
|
"QUEUE-LIVE-PICKUP-SOURCE",
|
|
86
93
|
"QUEUE-NEXTUP-EMPTY-FAIL-CLOSED",
|
|
87
94
|
"QUEUE-NEXTUP-SOURCE",
|
|
@@ -144,6 +151,15 @@
|
|
|
144
151
|
"WORKTREE-DEDUPE",
|
|
145
152
|
"WORKTREE-DEFAULT-USE",
|
|
146
153
|
"WORKTREE-DEPS-ISOLATED",
|
|
147
|
-
"WORKTREE-FALLBACK"
|
|
154
|
+
"WORKTREE-FALLBACK",
|
|
155
|
+
"COPILOT-FOLLOWUP-VERIFY-BEFORE-RESOLVE",
|
|
156
|
+
"INTAKE-TIMEOUT-ROUTE-ON-SEAM-EXIT",
|
|
157
|
+
"INTAKE-TIMEOUT-SURFACE-BUDGET-EXHAUSTED",
|
|
158
|
+
"INTAKE-REPO-SLUG-RESOLVE-FIRST",
|
|
159
|
+
"FACADE-COPILOT-INTERNAL-ONLY",
|
|
160
|
+
"REFINER-DOD-PROPOSED-SUBSECTION",
|
|
161
|
+
"REFINER-NO-INVENT-AUDIT-FINDINGS",
|
|
162
|
+
"COPILOT-FOLLOWUP-REREQUEST-GREEN-GATE",
|
|
163
|
+
"COPILOT-FOLLOWUP-RESOLVE-AFTER-REPLY"
|
|
148
164
|
]
|
|
149
165
|
}
|
|
@@ -96,8 +96,8 @@ If the gate result is `needs_reconcile`, the caller MUST NOT proceed with the pr
|
|
|
96
96
|
<!-- rule: RETRO-ADVISORY-NEVER-GATE -->
|
|
97
97
|
The retrospective is **advisory**: it runs, records flagged raw-call / discipline
|
|
98
98
|
observations honestly, and passes them back to the conductor (main agent) to
|
|
99
|
-
**decide** what to do with them — but it MUST NOT block a merge or any lifecycle
|
|
100
|
-
transition. The pre-merge retrospective gate (`evaluateRetrospectiveMergeApproval`
|
|
99
|
+
**decide** what to do with them — but it MUST NOT block a merge or any PR-lifecycle
|
|
100
|
+
transition of the current run. The pre-merge retrospective gate (`evaluateRetrospectiveMergeApproval`
|
|
101
101
|
and the `requireRetrospectiveGate` / `requireRetrospectiveInternalTooling` config
|
|
102
102
|
keys) has been **removed**. There is no `retrospective_gate_pending` / `blocked`
|
|
103
103
|
disposition on account of the internal-tooling raw-call record.
|
|
@@ -135,10 +135,13 @@ scripts legitimately call `gh`/GraphQL internally; that is the tooling. The rule
|
|
|
135
135
|
targets the agent's own top-level shell calls, not a script's internals.
|
|
136
136
|
|
|
137
137
|
**Write-op allowlist (verifier only):** `gh pr merge`, `gh pr ready`,
|
|
138
|
-
`gh issue create
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
138
|
+
`gh issue create` have no internal wrapper today. `gh issue edit` now has one
|
|
139
|
+
(`scripts/github/edit-issue.mjs`) and stays as a belt-and-suspenders entry — like
|
|
140
|
+
`gh label create` (`scripts/github/create-label.mjs`) — so a bare invocation
|
|
141
|
+
surfaced from the wrapper's own subprocess is not miscounted as a breach. The
|
|
142
|
+
deterministic verifier records all of these as `allowedWriteOps` rather than
|
|
143
|
+
violations so they are surfaced distinctly, not as breaches. Close the gap with a
|
|
144
|
+
wrapper to remove or reframe a no-wrapper entry. None of these block anything.
|
|
142
145
|
|
|
143
146
|
**Inline-interpreter check item:** the raw-call scan below mechanically catches
|
|
144
147
|
`node -e`/`python3 -c`/heredoc calls as a `rawCallViolations` entry — the same
|
|
@@ -17,7 +17,7 @@ Canonical owner for validation requirements across all workflow families.
|
|
|
17
17
|
## Coverage requirements
|
|
18
18
|
|
|
19
19
|
<!-- rule: VALIDATE-COVERAGE-THRESHOLD -->
|
|
20
|
-
`VALIDATE-COVERAGE-THRESHOLD`: Changed files
|
|
20
|
+
`VALIDATE-COVERAGE-THRESHOLD`: Changed files SHOULD maintain ≥90% coverage for lines, statements, functions, and branches (not enforced by the shipped verify config; treat it as the working target), and non-trivial logic MUST be test-first.
|
|
21
21
|
|
|
22
22
|
## Cross-references
|
|
23
23
|
|
|
@@ -13,7 +13,7 @@ user-invocable: false
|
|
|
13
13
|
|
|
14
14
|
# Local Implementation
|
|
15
15
|
|
|
16
|
-
|
|
16
|
+
Canonical owner for the internal `local_implementation` route behind the public `dev-loop` façade.
|
|
17
17
|
|
|
18
18
|
Use it only after the public dispatcher has already resolved `selectedStrategy: local_implementation`. This skill owns the local phase procedure and artifact discipline for that route; it does not redefine the shipped runtime semantics of helper CLIs, shared loop logic, or extension commands.
|
|
19
19
|
|
|
@@ -65,7 +65,7 @@ When the local spec already lives in a tracker issue:
|
|
|
65
65
|
- sync durable scope / acceptance / status changes back to the tracker issue rather than maintaining a duplicate local phase doc
|
|
66
66
|
- keep `tmp/` as temporary local execution state only; it does not become a second durable spec surface
|
|
67
67
|
- for tracker-backed sessions, the handoff path is always: push the working branch → open a PR → merge via GitHub
|
|
68
|
-
- <!-- 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
|
|
68
|
+
- <!-- 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 always-draft creation mechanism is owned by [`OPS-DRAFT-FIRST-PR`](../docs/copilot-loop-operations.md) — `create-pr.mjs` is unconditionally draft-only regardless of the toggle, which separately governs whether the draft-gate boundary is enforced before ready.
|
|
69
69
|
- <!-- 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
|
|
70
70
|
|
|
71
71
|
## Primary execution rules
|
|
@@ -108,7 +108,7 @@ Follow [Anti-patterns](../docs/anti-patterns.md) for the general tooling-interna
|
|
|
108
108
|
|
|
109
109
|
- <!-- 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.
|
|
110
110
|
- Use the `refiner` agent for phase-refinement work when subagents are available; escalate RFC-worthy technical decisions to the parent session / human operator.
|
|
111
|
-
- <!-- rule: LOCAL-TEST-FIRST-COVERAGE --> You MUST work **test-first** for all non-trivial logic
|
|
111
|
+
- <!-- rule: LOCAL-TEST-FIRST-COVERAGE --> You MUST work **test-first** for all non-trivial logic; coverage thresholds are owned by [VALIDATE-COVERAGE-THRESHOLD](../docs/validation-policy.md).
|
|
112
112
|
- Log detailed iteration artifacts under `tmp/` using the required structure below.
|
|
113
113
|
- Spec-of-record split (phase-doc-backed vs. tracker-backed vs. lightweight): see [Tracker-backed local implementation](#tracker-backed-local-implementation) above.
|
|
114
114
|
- 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.
|
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: loop-grill
|
|
3
3
|
description: >-
|
|
4
|
-
Standalone pre-loop Socratic Q&A grill for issues (tracker-first)
|
|
5
|
-
plan files (local-planning). Detects spec gaps, asks clarifying
|
|
6
|
-
(interactive) or self-answers them from codebase context (--auto),
|
|
7
|
-
|
|
4
|
+
Standalone pre-loop Socratic Q&A grill for issues (tracker-first), PR bodies,
|
|
5
|
+
or local plan files (local-planning). Detects spec gaps, asks clarifying
|
|
6
|
+
questions (interactive) or self-answers them from codebase context (--auto),
|
|
7
|
+
then synthesizes Acceptance criteria / Definition of done / Non-goals into the
|
|
8
|
+
body while keeping the raw Q&A only in an ephemeral tmp artifact.
|
|
8
9
|
allowed-tools: read bash edit write
|
|
9
10
|
user-invocable: false
|
|
10
11
|
---
|
|
@@ -14,15 +15,23 @@ A standalone, on-demand pre-loop grilling skill. Run it against an issue or a lo
|
|
|
14
15
|
|
|
15
16
|
It is entirely separate from the in-loop docs-grill (`docs/docs-grill-step.md`), which audits code/doc drift while the loop runs. This skill operates on the *spec* before any implementation begins.
|
|
16
17
|
|
|
18
|
+
## State machine
|
|
19
|
+
|
|
20
|
+
This grill is the bounded, closed sub-loop modeled by `packages/core/src/loop/refinement-grill-state.mjs` (detector `scripts/loop/detect-refinement-grill-state.mjs`), rendered on the State atlas; see `docs/refinement-grill-state-graph.md`. It obeys `GRILL-SUBLOOP-STATE-MACHINE`, `GRILL-SUBLOOP-ITERATE-TO-CLEAN`, `GRILL-SUBLOOP-NO-EMBED-SYNTHESIS`, and `GRILL-SUBLOOP-HONEST-HANDOFF`. Iteration lives in the transition graph; the answer/synthesis is the bounded input consumed at the `await_answers` state.
|
|
21
|
+
|
|
17
22
|
## Interface
|
|
18
23
|
|
|
19
24
|
```
|
|
20
25
|
/loop-grill <issue-number> # tracker-first, interactive
|
|
21
26
|
/loop-grill <issue-number> --auto # tracker-first, auto-answer
|
|
27
|
+
/loop-grill <pr-url-or-number> # PR body, interactive
|
|
28
|
+
/loop-grill <pr-url-or-number> --auto # PR body, auto-answer
|
|
22
29
|
/loop-grill <path/to/plan.md> # local-planning, interactive
|
|
23
30
|
/loop-grill <path/to/plan.md> --auto # local-planning, auto-answer
|
|
24
31
|
```
|
|
25
32
|
|
|
33
|
+
PR bodies are supported the same way as issues: fetch/edit the PR body via the existing PR wrappers (`scripts/github/view-pr.mjs` / `scripts/github/edit-pr.mjs`), never raw `gh`.
|
|
34
|
+
|
|
26
35
|
## Argument validation (fail-closed)
|
|
27
36
|
|
|
28
37
|
Before doing anything else:
|
|
@@ -35,9 +44,12 @@ Before doing anything else:
|
|
|
35
44
|
|
|
36
45
|
## Step 1 — Load the target
|
|
37
46
|
|
|
38
|
-
- **Tracker-first:** fetch the issue body (title + description
|
|
47
|
+
- **Tracker-first:** fetch the issue body (title + description).
|
|
48
|
+
- **PR body:** fetch the PR body via `scripts/github/view-pr.mjs` (never raw `gh`).
|
|
39
49
|
- **Local-planning:** read the plan file from disk.
|
|
40
50
|
|
|
51
|
+
"Is it refined" is decided by `detectIssueRefinementArtifact` (`packages/core/src/loop/issue-refinement-artifact.mjs`) — the single source of truth, same as the enqueue gate; do not add a divergent check. An already-refined artifact (AC/DoD present) is a zero-iteration `grill_clean`: do not rewrite the body.
|
|
52
|
+
|
|
41
53
|
## Step 1b — Surface external resources
|
|
42
54
|
|
|
43
55
|
Before detecting gaps, scan the loaded content for external resource references: links, other repo URLs, API endpoints, doc URLs, screenshots, or Playwright navigation descriptors.
|
|
@@ -91,15 +103,20 @@ Record the evidence source for every answer. Flag a question as **`unresolved`**
|
|
|
91
103
|
|
|
92
104
|
Do not silently guess an `inferred` answer when no evidence can be cited — flag it `unresolved` instead.
|
|
93
105
|
|
|
94
|
-
## Step 4 — Write back (
|
|
106
|
+
## Step 4 — Write back (synthesize sections; raw Q&A to tmp only)
|
|
95
107
|
|
|
96
|
-
|
|
108
|
+
Synthesize the answers into the body as sharpened `## Acceptance criteria`, `## Definition of done`, and `## Non-goals` sections. Per canonical heading, use **replace-section** semantics:
|
|
97
109
|
|
|
98
|
-
- **Find** the existing
|
|
99
|
-
- **Replace** that range in place with the
|
|
100
|
-
- If no `## Grill findings` section exists, **append** it.
|
|
110
|
+
- **Find** the existing section: the range from that `##`-level heading through the next `##`-level heading (exclusive) or end of file.
|
|
111
|
+
- **Replace** that range in place with the synthesized content; if the section is absent, **append** it.
|
|
101
112
|
- This makes re-runs idempotent — no accumulated noise, no duplicate sections.
|
|
102
|
-
- If parsing
|
|
113
|
+
- If parsing a section boundary fails, **abort with an error** rather than silently truncating.
|
|
114
|
+
|
|
115
|
+
The body carries ONLY the synthesized sharpened sections. Do NOT write a `## Grill findings` section and do NOT embed the raw Q&A table in the body (`GRILL-SUBLOOP-NO-EMBED-SYNTHESIS`).
|
|
116
|
+
|
|
117
|
+
If a body migrated from older embed behavior still carries a `## Grill findings` section, **remove** it as part of write-back — strip from that heading through the next `##`-level heading (exclusive) or end of file, using the same replace-section boundary logic. This is a removal-only migration, never a re-introduction of the embed.
|
|
118
|
+
|
|
119
|
+
Write the raw Q&A transcript ONLY to the gitignored, ephemeral, session-scoped artifact `tmp/issues/issue-<n>/grill/<timestamp>.md` (`tmp/` is already gitignored; never committed). For PR-body and plan-file surfaces, use the same tmp path shape scoped by surface (issues: `tmp/issues/issue-<n>/grill/`; a parallel `tmp/...` path for PR/plan).
|
|
103
120
|
|
|
104
121
|
**Tracker-first write-back:** update the GitHub issue body using:
|
|
105
122
|
|
|
@@ -107,19 +124,23 @@ Write a `## Grill findings` section back to the source artifact using **replace-
|
|
|
107
124
|
gh issue edit <n> --repo <owner/repo> --body-file <tmp-path>
|
|
108
125
|
```
|
|
109
126
|
|
|
110
|
-
The
|
|
127
|
+
The synthesized sections live in the issue body, not as a comment. Do not use `comment-issue.mjs` here — that creates a comment, not a body update.
|
|
128
|
+
|
|
129
|
+
**PR-body write-back:** update the PR body via `scripts/github/edit-pr.mjs` (never raw `gh`), same replace-section semantics.
|
|
111
130
|
|
|
112
|
-
**GitHub body size guard:** issue bodies are capped at 65,536 characters. Before writing back, check whether the updated body would exceed this limit. If so, warn: `Warning: updated body would exceed GitHub's 65,536-character limit — write-back skipped.
|
|
131
|
+
**GitHub body size guard:** issue/PR bodies are capped at 65,536 characters. Before writing back, check whether the updated body would exceed this limit. If so, warn: `Warning: updated body would exceed GitHub's 65,536-character limit — write-back skipped. Sharpen the sections or the body manually.` Do not silently truncate.
|
|
113
132
|
|
|
114
133
|
**Local-planning write-back:** update the plan file in place using the edit tool.
|
|
115
134
|
|
|
116
135
|
## Output artifact format
|
|
117
136
|
|
|
118
|
-
|
|
137
|
+
Two distinct artifacts:
|
|
119
138
|
|
|
120
|
-
|
|
121
|
-
## Grill findings
|
|
139
|
+
1. **Synthesized body sections** (issue/PR/plan body): only `## Acceptance criteria`, `## Definition of done`, and `## Non-goals`, sharpened from the answers. No raw Q&A.
|
|
122
140
|
|
|
141
|
+
2. **Raw Q&A transcript** (ephemeral `tmp/issues/issue-<n>/grill/<timestamp>.md` only — never the body):
|
|
142
|
+
|
|
143
|
+
```markdown
|
|
123
144
|
<!-- loop-grill: <timestamp> mode:<interactive|auto> -->
|
|
124
145
|
|
|
125
146
|
### Resolved gaps
|
|
@@ -154,7 +175,7 @@ When `CONTEXT.md` is absent from the repo root, skip the context-source check si
|
|
|
154
175
|
|
|
155
176
|
## Idempotency guarantee
|
|
156
177
|
|
|
157
|
-
Running `/loop-grill` twice on the same target must
|
|
178
|
+
Running `/loop-grill` twice on the same target must not accumulate duplicate sections: the per-heading replace-section logic replaces the synthesized `## Acceptance criteria` / `## Definition of done` / `## Non-goals` sections in place. An already-refined target is a zero-iteration `grill_clean` and its body is left unchanged. The raw Q&A transcript is written to a fresh timestamped tmp file per run; the body never carries it.
|
|
158
179
|
|
|
159
180
|
## Non-goals
|
|
160
181
|
|