taip-connect 0.5.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/README.md +11 -0
- package/bin/connect.js +8994 -0
- package/package.json +19 -0
- package/packs/process/skills/taip-workflow-acceptance-testing/SKILL.md +159 -0
- package/packs/process/skills/taip-workflow-git-init/SKILL.md +131 -0
- package/packs/process/skills/taip-workflow-git-pr/SKILL.md +113 -0
- package/packs/process/skills/taip-workflow-plane-init/SKILL.md +188 -0
- package/packs/process/skills/taip-workflow-plane-task/SKILL.md +356 -0
- package/packs/process/skills/taip-workflow-planning/SKILL.md +159 -0
- package/packs/process/skills/taip-workflow-release/SKILL.md +134 -0
|
@@ -0,0 +1,356 @@
|
|
|
1
|
+
---
|
|
2
|
+
id: process/skills/taip-workflow-plane-task
|
|
3
|
+
version: 1.2.0
|
|
4
|
+
trigger: "plane task|start plane|pick up issue|plane issue|close plane|done plane|plane start|plane done|file plane|plane backlog|park task"
|
|
5
|
+
description: >
|
|
6
|
+
Plane issue lifecycle skill. Covers three phases: START (pick up an issue from the active
|
|
7
|
+
cycle, transition to In Progress, create branch, scaffold plan file pre-filled from the
|
|
8
|
+
issue), FILE (plan-first: create an issue from a completed plan with the handover embedded,
|
|
9
|
+
park it in a non-running cycle, then close via a three-way choice — runner / park /
|
|
10
|
+
implement-now) and DONE (post PR as comment, transition to Done). Implements the close half of
|
|
11
|
+
process/planning/plan-phase-exit. Requires the Plane tool binding (integrations/tools/plane).
|
|
12
|
+
user-invocable: true
|
|
13
|
+
tags: [plane, project-management, workflow, sprint, agile]
|
|
14
|
+
attribution:
|
|
15
|
+
source: original
|
|
16
|
+
license: brain-official
|
|
17
|
+
author: brain Official
|
|
18
|
+
---
|
|
19
|
+
|
|
20
|
+
# taip-workflow-plane-task
|
|
21
|
+
|
|
22
|
+
Plane issue lifecycle: START (pick up → branch → plan) | FILE (plan → issue+handover → close:
|
|
23
|
+
runner/park/implement-now) | DONE (PR comment → transition).
|
|
24
|
+
|
|
25
|
+
Requires the `integrations/tools/plane` tool binding to be active. If Plane is not configured,
|
|
26
|
+
tell the user and stop.
|
|
27
|
+
|
|
28
|
+
---
|
|
29
|
+
|
|
30
|
+
## Detect phase
|
|
31
|
+
|
|
32
|
+
Parse the user's invocation to determine which phase:
|
|
33
|
+
|
|
34
|
+
- Keywords: "start", "pick up", "begin", "take", "assign" → **START phase**
|
|
35
|
+
- Keywords: "file", "backlog", "register", "park", "plan to plane" → **FILE phase**
|
|
36
|
+
(also entered automatically after plan mode — see `taip-workflow-planning` Step 4 and the
|
|
37
|
+
`PostToolUse:ExitPlanMode` hook)
|
|
38
|
+
- Keywords: "done", "close", "complete", "finish", "mark done" → **DONE phase**
|
|
39
|
+
|
|
40
|
+
If ambiguous, ask: "Do you want to START a Plane issue from the active sprint, FILE a planned task into a non-running sprint, or mark the current task DONE?"
|
|
41
|
+
|
|
42
|
+
---
|
|
43
|
+
|
|
44
|
+
## START phase
|
|
45
|
+
|
|
46
|
+
### Step S1 — Identify the issue
|
|
47
|
+
|
|
48
|
+
**If an issue ID or title was provided in the invocation:** use it directly → go to S3.
|
|
49
|
+
|
|
50
|
+
**If no issue specified:** fetch the active sprint:
|
|
51
|
+
|
|
52
|
+
```
|
|
53
|
+
mcp-plane_list_cycles → find active cycle
|
|
54
|
+
mcp-plane_list_cycle_issues → list issues (exclude Done/Cancelled states)
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
Display as a numbered list:
|
|
58
|
+
```
|
|
59
|
+
Active sprint issues:
|
|
60
|
+
1. [PROJ-12] Fix login redirect loop
|
|
61
|
+
2. [PROJ-15] Add export to CSV
|
|
62
|
+
...
|
|
63
|
+
Which issue do you want to start? (number or ID)
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
WAIT for user selection.
|
|
67
|
+
|
|
68
|
+
### Step S2 — Confirm the issue
|
|
69
|
+
|
|
70
|
+
Fetch full issue details:
|
|
71
|
+
```
|
|
72
|
+
mcp-plane_get_issue → title, description, state, labels, assignee
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
Display:
|
|
76
|
+
```
|
|
77
|
+
Issue: [PROJ-{seq}] {title}
|
|
78
|
+
State: {current state}
|
|
79
|
+
Labels: {labels}
|
|
80
|
+
|
|
81
|
+
{description (first 300 chars)}
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
Ask: "Start work on this issue? (Y/N)"
|
|
85
|
+
|
|
86
|
+
WAIT for confirmation.
|
|
87
|
+
|
|
88
|
+
### Step S3 — Create feature branch
|
|
89
|
+
|
|
90
|
+
Derive branch name: `feature/{slug}-{sequence_id}`
|
|
91
|
+
|
|
92
|
+
- `slug`: kebab-case from issue title, max 5 words
|
|
93
|
+
- `sequence_id`: issue sequence number from Plane
|
|
94
|
+
|
|
95
|
+
```bash
|
|
96
|
+
git checkout -b feature/{slug}-{sequence_id}
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
If branch already exists: `git checkout feature/{slug}-{sequence_id}` and warn the user.
|
|
100
|
+
|
|
101
|
+
### Step S4 — Transition issue to In Progress
|
|
102
|
+
|
|
103
|
+
```
|
|
104
|
+
mcp-plane_update_issue → state: <In Progress state id>
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
Fetch available states first with `mcp-plane_list_states` to resolve the "In Progress" state ID.
|
|
108
|
+
|
|
109
|
+
Post a start comment:
|
|
110
|
+
```
|
|
111
|
+
mcp-plane_add_comment → "🚀 Work started on branch `feature/{slug}-{sequence_id}`"
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
### Step S5 — Scaffold plan file
|
|
115
|
+
|
|
116
|
+
Run the `taip-workflow-planning` skill with the issue content pre-filled:
|
|
117
|
+
|
|
118
|
+
- **Title**: issue title
|
|
119
|
+
- **What**: issue description (trimmed to 2–4 sentences)
|
|
120
|
+
- **Requirements**: parsed from issue description `## Acceptance Criteria` section if present
|
|
121
|
+
- **Branch**: `feature/{slug}-{sequence_id}`
|
|
122
|
+
|
|
123
|
+
Create plan at: `docs/plans/YYYY-MM-DD-{slug}.md`
|
|
124
|
+
|
|
125
|
+
Ask: "Create plan at `docs/plans/YYYY-MM-DD-{slug}.md`? (Y to confirm)"
|
|
126
|
+
|
|
127
|
+
WAIT for confirmation, then create the file with the pre-filled template.
|
|
128
|
+
|
|
129
|
+
### Step S6 — Hand off
|
|
130
|
+
|
|
131
|
+
Print:
|
|
132
|
+
```
|
|
133
|
+
✅ Issue [PROJ-{seq}] picked up.
|
|
134
|
+
Branch: feature/{slug}-{sequence_id}
|
|
135
|
+
Plan: docs/plans/YYYY-MM-DD-{slug}.md
|
|
136
|
+
|
|
137
|
+
Next:
|
|
138
|
+
1. Fill in ## Requirements and ## Acceptance Tests in the plan file
|
|
139
|
+
2. Implement
|
|
140
|
+
3. Run /taip-workflow-acceptance-testing when ready
|
|
141
|
+
4. Run /taip-workflow-plane-task done to close the issue
|
|
142
|
+
```
|
|
143
|
+
|
|
144
|
+
---
|
|
145
|
+
|
|
146
|
+
## FILE phase
|
|
147
|
+
|
|
148
|
+
Plan-first direction: a plan already exists (you just finished plan mode), so create the Plane
|
|
149
|
+
issue **from the plan** (with the `## Handover` block embedded in its description) and park it in
|
|
150
|
+
a **non-running** cycle, then offer the three-way close — **runner / park / implement-now**. This
|
|
151
|
+
is the close half of the `process/planning/plan-phase-exit` gate.
|
|
152
|
+
|
|
153
|
+
Why a non-running sprint: the autonomous `plane-sprint-runner` only executes `ai-task` issues in
|
|
154
|
+
the **active** cycle, and its filter skips only `done/cancelled/completed` — not `In Progress`.
|
|
155
|
+
Parking the task in an upcoming/Backlog cycle records it (eligible for a *future* sprint) while
|
|
156
|
+
guaranteeing the runner never grabs it until you promote it.
|
|
157
|
+
|
|
158
|
+
### Step F1 — Pre-requisites
|
|
159
|
+
|
|
160
|
+
- The Plane tool binding MUST be active (else stop — see Hard fails).
|
|
161
|
+
- A plan file MUST exist under `docs/plans/` with **both** `## Requirements` and
|
|
162
|
+
`## Acceptance Tests` populated (at least one requirement and one Given/When/Then row).
|
|
163
|
+
If either is empty, stop and print:
|
|
164
|
+
> "## Requirements and ## Acceptance Tests must be filled in before I can file this task.
|
|
165
|
+
> This is a hard gate — please populate both sections in the plan first."
|
|
166
|
+
|
|
167
|
+
### Step F2 — Resolve the non-running cycle
|
|
168
|
+
|
|
169
|
+
```
|
|
170
|
+
mcp-plane_list_cycles → all cycles
|
|
171
|
+
```
|
|
172
|
+
|
|
173
|
+
- Drop any cycle where `status === 'current'` OR `is_active === true` (those are the running
|
|
174
|
+
sprint — the runner reads them).
|
|
175
|
+
- From the remainder, pick the nearest **upcoming** cycle (`status === 'upcoming'`, earliest
|
|
176
|
+
future `start_date`).
|
|
177
|
+
- If no non-running cycle exists, create a persistent **"Backlog"** cycle with future dates.
|
|
178
|
+
Cycle creation is not in the MCP capability set — reuse the REST pattern from
|
|
179
|
+
`openclaw/sprint/setup-plane-projects.sh`:
|
|
180
|
+
```bash
|
|
181
|
+
curl -s -X POST "${PLANE_API_URL}/api/v1/workspaces/${SLUG}/projects/${PROJECT_ID}/cycles/" \
|
|
182
|
+
-H "X-Api-Key: ${PLANE_TOKEN}" \
|
|
183
|
+
-d "$(jq -n --arg n "Backlog" --arg s "<future-start>" --arg e "<future-end>" --arg pid "$PROJECT_ID" \
|
|
184
|
+
'{name: $n, start_date: $s, end_date: $e, project_id: $pid}')"
|
|
185
|
+
```
|
|
186
|
+
|
|
187
|
+
Remember the resolved `cycleId` and `cycleName`.
|
|
188
|
+
|
|
189
|
+
### Step F3 — Create the issue from the plan
|
|
190
|
+
|
|
191
|
+
```
|
|
192
|
+
mcp-plane_create_issue → title: <plan title>
|
|
193
|
+
description: <assembled from the plan, see below>
|
|
194
|
+
label: ai-task
|
|
195
|
+
cycle: <F2 cycleId>
|
|
196
|
+
```
|
|
197
|
+
|
|
198
|
+
Assemble the description from the plan file sections:
|
|
199
|
+
- `## What` → issue summary paragraph
|
|
200
|
+
- `## Requirements` → a "Requirements" list
|
|
201
|
+
- `## Acceptance Tests` → an "## Acceptance Criteria" block (so a later START pre-fill round-trips)
|
|
202
|
+
- `## Handover` → embed the `## Handover` block **verbatim** into the issue description, so a fresh
|
|
203
|
+
session or the sprint runner can resume from the issue alone (required by `plan-phase-exit`)
|
|
204
|
+
|
|
205
|
+
If `mcp-plane_create_issue` does not accept a cycle field, create the issue first, then assign it
|
|
206
|
+
to the cycle via the REST cycle-issues endpoint:
|
|
207
|
+
```
|
|
208
|
+
POST /api/v1/workspaces/{slug}/projects/{projectId}/cycles/{cycleId}/cycle-issues/
|
|
209
|
+
body: { "issues": ["<new-issue-id>"] }
|
|
210
|
+
```
|
|
211
|
+
|
|
212
|
+
Verify the issue is **not** in the active cycle before continuing.
|
|
213
|
+
|
|
214
|
+
### Step F4 — Close: runner / park / implement-now (ask each time)
|
|
215
|
+
|
|
216
|
+
```
|
|
217
|
+
✅ Filed [PROJ-{seq}] {title}
|
|
218
|
+
Cycle: {cycleName} (non-running — the runner will not pick this up)
|
|
219
|
+
Label: ai-task
|
|
220
|
+
|
|
221
|
+
How do you want to proceed? (ask this every time — never assume)
|
|
222
|
+
[R] runner — promote to the ACTIVE cycle, keep the ai-task label; plane-sprint-runner
|
|
223
|
+
executes it autonomously (opens the branch + PR). → Step F7
|
|
224
|
+
[P] park — leave it in '{cycleName}' with the handover; pick it up in a future sprint. → Step F6
|
|
225
|
+
[I] implement-now — implement interactively in THIS session (escape hatch). → Step F5
|
|
226
|
+
```
|
|
227
|
+
|
|
228
|
+
WAIT for the answer. Only these three outcomes; do not begin any edits before the user chooses.
|
|
229
|
+
|
|
230
|
+
### Step F5 — [I] implement-now: implement out-of-band
|
|
231
|
+
|
|
232
|
+
- Fetch states: `mcp-plane_list_states` → resolve the "In Progress" state ID.
|
|
233
|
+
- `mcp-plane_update_issue → state: <In Progress state id>`.
|
|
234
|
+
- Post a start comment:
|
|
235
|
+
```
|
|
236
|
+
mcp-plane_add_comment → "🚀 Implementing out-of-band on branch `{branch}`.
|
|
237
|
+
Left in cycle '{cycleName}' so the sprint runner skips it."
|
|
238
|
+
```
|
|
239
|
+
- Ensure a feature branch is checked out (it usually already exists from plan mode). If on
|
|
240
|
+
`main`/`master`, create `feature/{slug}-{sequence_id}` and warn.
|
|
241
|
+
- The issue **stays in the non-running cycle** — do not move it to the active cycle.
|
|
242
|
+
- Hand off to implementation:
|
|
243
|
+
```
|
|
244
|
+
Requirements and acceptance tests confirmed. Ready to begin implementation.
|
|
245
|
+
```
|
|
246
|
+
|
|
247
|
+
### Step F6 — [P] park: leave it parked
|
|
248
|
+
|
|
249
|
+
```
|
|
250
|
+
📥 [PROJ-{seq}] parked in '{cycleName}' (Todo) with the handover in its description.
|
|
251
|
+
Promote it to the active cycle to let the sprint runner execute it,
|
|
252
|
+
or run /taip-workflow-plane-task file again and choose runner or implement-now.
|
|
253
|
+
```
|
|
254
|
+
|
|
255
|
+
Do not change the issue state and do not start any code. Stop here.
|
|
256
|
+
|
|
257
|
+
### Step F7 — [R] runner: hand to the sprint runner
|
|
258
|
+
|
|
259
|
+
Promote the parked issue into the **active** cycle so `plane-sprint-runner` picks it up (it reads
|
|
260
|
+
only the active cycle). Keep the `ai-task` label and the embedded `## Handover` — that block is the
|
|
261
|
+
runner's implementation prompt.
|
|
262
|
+
|
|
263
|
+
- Resolve the active cycle: `mcp-plane_list_cycles` → the one with `status === 'current'` / `is_active`.
|
|
264
|
+
- Move the issue into it (remove it from '{cycleName}' first if the cycle is exclusive):
|
|
265
|
+
```
|
|
266
|
+
mcp-plane_transfer_cycle_issues (or REST: POST .../cycles/{activeCycleId}/cycle-issues/ { "issues": ["<id>"] })
|
|
267
|
+
```
|
|
268
|
+
- Leave the state at **Todo** (do NOT set In Progress — the runner transitions it when it starts).
|
|
269
|
+
- Post a comment: `mcp-plane_add_comment → "🤖 Handed to plane-sprint-runner (active cycle). Handover is in the description."`
|
|
270
|
+
- Print:
|
|
271
|
+
```
|
|
272
|
+
🤖 [PROJ-{seq}] promoted to the active cycle for the sprint runner. Keeping ai-task.
|
|
273
|
+
The runner will open feature/{slug}-{seq} and a PR from the handover.
|
|
274
|
+
```
|
|
275
|
+
|
|
276
|
+
Do not start any code in this session. Stop here.
|
|
277
|
+
|
|
278
|
+
---
|
|
279
|
+
|
|
280
|
+
## DONE phase
|
|
281
|
+
|
|
282
|
+
### Step D1 — Resolve the issue
|
|
283
|
+
|
|
284
|
+
**If an issue ID was provided:** use it.
|
|
285
|
+
|
|
286
|
+
**If not:** infer from current branch name.
|
|
287
|
+
- Parse `feature/{slug}-{sequence_id}` → extract `sequence_id`
|
|
288
|
+
- Fetch issue by sequence ID via `mcp-plane_get_issue`
|
|
289
|
+
|
|
290
|
+
If cannot resolve: ask "Which Plane issue does this work close? (issue ID)"
|
|
291
|
+
|
|
292
|
+
### Step D2 — Verify PR exists
|
|
293
|
+
|
|
294
|
+
Check that a PR has been created for the current branch:
|
|
295
|
+
```bash
|
|
296
|
+
gh pr view --json url,title,state 2>/dev/null
|
|
297
|
+
```
|
|
298
|
+
|
|
299
|
+
If no PR: "No open PR found for this branch. Run /taip-workflow-git-pr first, then come back."
|
|
300
|
+
|
|
301
|
+
Stop here if no PR.
|
|
302
|
+
|
|
303
|
+
### Step D3 — Post PR comment on Plane issue
|
|
304
|
+
|
|
305
|
+
```
|
|
306
|
+
mcp-plane_add_comment → body:
|
|
307
|
+
"✅ Work complete. PR: {pr_url}
|
|
308
|
+
|
|
309
|
+
**{pr_title}**
|
|
310
|
+
|
|
311
|
+
Branch: `{branch}`"
|
|
312
|
+
```
|
|
313
|
+
|
|
314
|
+
### Step D4 — Transition to Done (gated on AT)
|
|
315
|
+
|
|
316
|
+
Check if acceptance testing has been run (look for a file matching `docs/tests/AT-*-{slug}*.md`).
|
|
317
|
+
|
|
318
|
+
**If AT report exists and verdict is PASS:**
|
|
319
|
+
- Fetch states: `mcp-plane_list_states`
|
|
320
|
+
- Resolve the "Done" state ID
|
|
321
|
+
- `mcp-plane_update_issue` → state: Done state ID
|
|
322
|
+
- Print: "✅ Issue [PROJ-{seq}] marked Done."
|
|
323
|
+
|
|
324
|
+
**If AT report exists and verdict is FAIL:**
|
|
325
|
+
- Do NOT transition. Print:
|
|
326
|
+
> "❌ AT report shows failures. Fix the issues and re-run /taip-workflow-acceptance-testing before closing."
|
|
327
|
+
|
|
328
|
+
**If no AT report found:**
|
|
329
|
+
- Ask: "No AT report found. Has acceptance testing been completed? (Y to transition / N to run AT first)"
|
|
330
|
+
- If Y: transition to Done (user takes responsibility)
|
|
331
|
+
- If N: "Run /taip-workflow-acceptance-testing first."
|
|
332
|
+
|
|
333
|
+
### Step D5 — Summary
|
|
334
|
+
|
|
335
|
+
Print:
|
|
336
|
+
```
|
|
337
|
+
🎉 Issue [PROJ-{seq}] closed.
|
|
338
|
+
PR: {pr_url}
|
|
339
|
+
Branch: {branch}
|
|
340
|
+
Plan: docs/plans/YYYY-MM-DD-{slug}.md
|
|
341
|
+
```
|
|
342
|
+
|
|
343
|
+
---
|
|
344
|
+
|
|
345
|
+
## Hard fails
|
|
346
|
+
|
|
347
|
+
- MUST NOT start work on an issue already in Done or Cancelled state
|
|
348
|
+
- MUST NOT create a PR without a plan file existing under `docs/plans/`
|
|
349
|
+
- MUST NOT transition issue to Done if any AT result is Fail or Blocked
|
|
350
|
+
- MUST NOT skip the branch creation step — branch name must match `feature/{slug}-{sequence_id}`
|
|
351
|
+
- **FILE phase:** MUST create (file) the task in a non-running cycle — never in the active/current
|
|
352
|
+
cycle. Promotion to the active cycle happens only via the explicit **runner** close choice (F7).
|
|
353
|
+
- **FILE phase:** MUST NOT file a task whose plan lacks populated `## Requirements` or `## Acceptance Tests`
|
|
354
|
+
- **FILE phase:** MUST embed the plan's `## Handover` block in the issue description, and MUST ask
|
|
355
|
+
the three-way close (runner / park / implement-now) each time — never auto-pick implement-now
|
|
356
|
+
- If Plane MCP tool is not active: stop and print "Plane tool binding not active. Check integrations/tools/plane config."
|
|
@@ -0,0 +1,159 @@
|
|
|
1
|
+
---
|
|
2
|
+
id: process/planning/plan-file-scaffold
|
|
3
|
+
version: 2.1.0
|
|
4
|
+
trigger: "create plan|make plan|plan this|plan file|planning"
|
|
5
|
+
description: >
|
|
6
|
+
Scaffolds a plan file for a new development task. Checks for a feature branch,
|
|
7
|
+
proposes a filename under docs/plans/, waits for user confirmation, then creates
|
|
8
|
+
the plan with What, Requirements, Steps, Files, Excluded, Acceptance Tests,
|
|
9
|
+
Verification, Decisions, and Handover sections.
|
|
10
|
+
Blocks implementation until ## Requirements and ## Acceptance Tests are populated,
|
|
11
|
+
then exits the planning phase via a written ## Handover per process/planning/plan-phase-exit.
|
|
12
|
+
user-invocable: true
|
|
13
|
+
tags: [planning, workflow, process]
|
|
14
|
+
attribution:
|
|
15
|
+
source: original
|
|
16
|
+
license: brain-official
|
|
17
|
+
author: brain Official
|
|
18
|
+
---
|
|
19
|
+
|
|
20
|
+
# taip-workflow-planning
|
|
21
|
+
|
|
22
|
+
Plan file scaffold: branch check → propose filename → confirm → create.
|
|
23
|
+
Implementation is blocked until `## Requirements` and `## Acceptance Tests` are populated.
|
|
24
|
+
|
|
25
|
+
## Pre-conditions
|
|
26
|
+
|
|
27
|
+
**Check 1 — Feature branch:**
|
|
28
|
+
Verify a feature branch exists and is the current working branch.
|
|
29
|
+
If on `main` or `master`: stop and ask the user to create a feature branch first.
|
|
30
|
+
|
|
31
|
+
## Step 1 — Propose plan filename
|
|
32
|
+
|
|
33
|
+
Propose: `docs/plans/YYYY-MM-DD-<short-slug>.md`
|
|
34
|
+
|
|
35
|
+
- Use today's date
|
|
36
|
+
- Slug: 3–5 words from the task description, kebab-case
|
|
37
|
+
- Example: `docs/plans/2026-06-03-brain-agent-crypto.md`
|
|
38
|
+
|
|
39
|
+
Ask: "Create plan at `docs/plans/YYYY-MM-DD-<slug>.md`? (Y to confirm or provide a different name)"
|
|
40
|
+
|
|
41
|
+
WAIT for explicit confirmation. Do NOT auto-create.
|
|
42
|
+
|
|
43
|
+
If a file already exists at that path: "A file already exists at that path. Please choose a different name."
|
|
44
|
+
|
|
45
|
+
## Step 2 — Create plan file
|
|
46
|
+
|
|
47
|
+
On confirmation, create with this template:
|
|
48
|
+
|
|
49
|
+
```markdown
|
|
50
|
+
# Plan: <Title>
|
|
51
|
+
|
|
52
|
+
**Date:** YYYY-MM-DD
|
|
53
|
+
**Status:** Draft
|
|
54
|
+
**Branch:** `<current-branch>`
|
|
55
|
+
|
|
56
|
+
## What
|
|
57
|
+
|
|
58
|
+
<Goal and scope — 2–4 sentences>
|
|
59
|
+
|
|
60
|
+
## Requirements
|
|
61
|
+
|
|
62
|
+
<!-- Link to docs/requirements/ SR-ids, or list inline for lite tasks -->
|
|
63
|
+
<!-- Lite: bullet each requirement directly here -->
|
|
64
|
+
<!-- Full: - [SR-001](../requirements/software-requirements.md#sr-001) -->
|
|
65
|
+
|
|
66
|
+
- [ ] <requirement or link>
|
|
67
|
+
|
|
68
|
+
## Steps
|
|
69
|
+
|
|
70
|
+
- [ ] Step one (depends on: none)
|
|
71
|
+
- [ ] Step two (depends on: step 1)
|
|
72
|
+
|
|
73
|
+
## Files
|
|
74
|
+
|
|
75
|
+
- `path/to/file` — what changes and why
|
|
76
|
+
|
|
77
|
+
## Excluded
|
|
78
|
+
|
|
79
|
+
- What is explicitly not in scope
|
|
80
|
+
|
|
81
|
+
## Acceptance Tests
|
|
82
|
+
|
|
83
|
+
<!-- MUST be populated before implementation begins. -->
|
|
84
|
+
<!-- Given/When/Then — one row per acceptance criterion. -->
|
|
85
|
+
<!-- Link to docs/tests/ file if a full test case file exists. -->
|
|
86
|
+
|
|
87
|
+
| # | Given | When | Then | Pass criterion |
|
|
88
|
+
|---|---|---|---|---|
|
|
89
|
+
| AC1 | <precondition> | <action> | <expected outcome> | <observable pass> |
|
|
90
|
+
|
|
91
|
+
## Verification
|
|
92
|
+
|
|
93
|
+
1. Command or check to confirm success
|
|
94
|
+
|
|
95
|
+
## Decisions
|
|
96
|
+
|
|
97
|
+
- Notes on decisions made during implementation
|
|
98
|
+
|
|
99
|
+
## Handover
|
|
100
|
+
|
|
101
|
+
<!-- Populated at the phase-exit gate (Step 4), before closing the planning session. -->
|
|
102
|
+
<!-- Everything a fresh session or the sprint runner needs to resume with full context. -->
|
|
103
|
+
|
|
104
|
+
**Start here:** <one-line goal>
|
|
105
|
+
**Plan:** `docs/plans/YYYY-MM-DD-<slug>.md` **Task:** <PROJ-seq, or "none">
|
|
106
|
+
**Branch:** `feature/<slug>` (off `develop`)
|
|
107
|
+
**Acceptance tests:** <one-line summary, or "AC1–ACn above">
|
|
108
|
+
**Decisions/constraints:** <key decisions and hard constraints>
|
|
109
|
+
**Next command:** <exact next command, e.g. /taip-workflow-plane-task start PROJ-seq>
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
Fill `## What` from the task description. Leave other sections as scaffolding with the comments;
|
|
113
|
+
`## Handover` is filled at Step 4.
|
|
114
|
+
|
|
115
|
+
## Step 3 — Gate on Requirements + Acceptance Tests
|
|
116
|
+
|
|
117
|
+
After the plan file is created, show it to the user and print:
|
|
118
|
+
|
|
119
|
+
```
|
|
120
|
+
Next: populate ## Requirements and ## Acceptance Tests before beginning implementation.
|
|
121
|
+
Implementation MUST NOT start until both sections are filled in.
|
|
122
|
+
```
|
|
123
|
+
|
|
124
|
+
Do NOT proceed to any file edits until the user confirms both sections are populated.
|
|
125
|
+
|
|
126
|
+
If the user asks to start coding before populating them, remind:
|
|
127
|
+
> "## Requirements and ## Acceptance Tests must be filled in before I can make any code changes.
|
|
128
|
+
> This is a hard gate — please add at least one requirement and one Given/When/Then row."
|
|
129
|
+
|
|
130
|
+
## Step 4 — Phase exit (write handover → close)
|
|
131
|
+
|
|
132
|
+
This is the exit gate between the planning phase and the implementation phase
|
|
133
|
+
(`process/planning/plan-phase-exit`). Once `## Requirements` and `## Acceptance Tests` are populated:
|
|
134
|
+
|
|
135
|
+
1. **Write the `## Handover` section** in the plan file — fill every field (start-here goal, plan
|
|
136
|
+
path, task id(s), branch, acceptance tests, decisions/constraints, exact next command).
|
|
137
|
+
|
|
138
|
+
2. **If the Plane tool binding (`integrations/tools/plane`) is active:**
|
|
139
|
+
Hand off to the `taip-workflow-plane-task` **FILE phase**. It creates a Plane issue from this
|
|
140
|
+
plan with the `## Handover` block embedded in the description, parks it in a **non-running**
|
|
141
|
+
cycle, then offers the three-way close (runner / park / implement-now). Do this before any edits.
|
|
142
|
+
|
|
143
|
+
3. **Print the handover in chat and STOP.** Do NOT begin implementation in this session —
|
|
144
|
+
implementation starts deliberately in a fresh session or via the sprint runner.
|
|
145
|
+
|
|
146
|
+
**Escape hatch:** if the user explicitly says "implement now", continue in this session — but the
|
|
147
|
+
plan file + `## Handover` (and the filed task when Plane is active) MUST already exist first.
|
|
148
|
+
|
|
149
|
+
**If Plane is not active:** still write `## Handover`, print it, and stop (unless "implement now").
|
|
150
|
+
|
|
151
|
+
## Rules
|
|
152
|
+
|
|
153
|
+
- Plan file MUST exist before any file edit or multi-step implementation
|
|
154
|
+
- `## Requirements` MUST contain at least one item before implementation
|
|
155
|
+
- `## Acceptance Tests` MUST contain at least one Given/When/Then row before implementation
|
|
156
|
+
- Planning MUST exit via `process/planning/plan-phase-exit`: a written `## Handover` (and a filed
|
|
157
|
+
task carrying it when a PM binding is active), then the session SHOULD close
|
|
158
|
+
- Do NOT delete the plan file after completion — it is the audit trail
|
|
159
|
+
- Update `**Status:**` field as work progresses: Draft → In Progress → Done
|
|
@@ -0,0 +1,134 @@
|
|
|
1
|
+
---
|
|
2
|
+
id: process/git/release-cut
|
|
3
|
+
version: 1.1.0
|
|
4
|
+
trigger: "cut a release|prepare release|tag a version|tag a release|release version|make a release|hotfix release"
|
|
5
|
+
description: >
|
|
6
|
+
Cuts a release per the project's declared git workflow (simplified or gitflow). Detects the
|
|
7
|
+
variant from CLAUDE.md, gates on a pre-tag release record and version==tag-semver, performs the
|
|
8
|
+
variant's branch/merge sequence, creates an annotated semver tag, registers the release, and
|
|
9
|
+
promotes the acceptance-tested artifact through the declared environments.
|
|
10
|
+
Use when the user says "cut a release", "tag a version", "prepare a release", or "hotfix release".
|
|
11
|
+
user-invocable: true
|
|
12
|
+
tags: [git, release, semver, changelog, gitflow, workflow]
|
|
13
|
+
attribution:
|
|
14
|
+
source: original
|
|
15
|
+
license: brain-official
|
|
16
|
+
author: brain Official
|
|
17
|
+
---
|
|
18
|
+
|
|
19
|
+
# taip-workflow-release
|
|
20
|
+
|
|
21
|
+
Release cut: **detect variant → pre-flight → version → record → CHANGELOG+release-notes+bump →
|
|
22
|
+
branch/merge → annotate tag → back-merge (gitflow) → register → push → promote through environments.**
|
|
23
|
+
|
|
24
|
+
## Step 0 — Detect the variant
|
|
25
|
+
|
|
26
|
+
Read the `## Git / Release workflow` line from the project `CLAUDE.md` (written by the `taip-connect`
|
|
27
|
+
installer). Resolve `simplified` or `gitflow`; **default `simplified`** if the section is absent.
|
|
28
|
+
Announce the detected variant and its governing rule:
|
|
29
|
+
|
|
30
|
+
- `simplified` → `process/git/branch-strategy` + `process/git/release-process`
|
|
31
|
+
- `gitflow` → `process/git/gitflow-branch-strategy` + `process/git/gitflow-release-process`
|
|
32
|
+
|
|
33
|
+
Everything below branches on this value.
|
|
34
|
+
|
|
35
|
+
## Pre-conditions
|
|
36
|
+
|
|
37
|
+
- **Clean tree** — `git status` MUST be clean; stop and ask the user to commit/stash otherwise.
|
|
38
|
+
- **CI green** — confirm CI is passing on the source branch; warn if it cannot be determined.
|
|
39
|
+
- **Last tag** — `git describe --tags --abbrev=0` (none → this is the first release).
|
|
40
|
+
- **Version source** — locate the single-source version: `package.json` `version`, fallback `VERSION`.
|
|
41
|
+
|
|
42
|
+
## Step 1 — Next version
|
|
43
|
+
|
|
44
|
+
Derive the next `<semver>` from the Conventional Commits since the last tag (feat → MINOR, fix →
|
|
45
|
+
PATCH, `!`/`BREAKING CHANGE` → MAJOR). Show the proposed version and the changes; **confirm with the
|
|
46
|
+
user** before proceeding.
|
|
47
|
+
|
|
48
|
+
## Step 2 — Set up the release branch (variant-specific)
|
|
49
|
+
|
|
50
|
+
- **simplified:** stay on `develop` (the release is prepared here, then merged to `main`).
|
|
51
|
+
- **gitflow:** `git checkout -b release/X.Y.Z develop` — Steps 3–4 commit onto this branch.
|
|
52
|
+
|
|
53
|
+
## Step 3 — Release record (HARD GATE)
|
|
54
|
+
|
|
55
|
+
Create `docs/releases/<semver>/release-record.md` BEFORE any tag (IEC 62304 §5.8;
|
|
56
|
+
`qms/software-release/software-release`): version + date, changes since last release (with
|
|
57
|
+
change-request/issue IDs), regression-test report reference, SOUP inventory version, known anomalies
|
|
58
|
+
with safety evaluation, approver sign-off. MUST NOT tag until this exists.
|
|
59
|
+
|
|
60
|
+
## Step 4 — CHANGELOG + release notes + version bump
|
|
61
|
+
|
|
62
|
+
Update `CHANGELOG.md` (new version + date) and bump the single-source version so it **equals**
|
|
63
|
+
`<semver>` (`engineering/ci/deterministic-image-tags`). Also write the **user-facing** release notes
|
|
64
|
+
at `docs/releases/<semver>/release-notes.md` — categorized (New features / Improvements / Fixes /
|
|
65
|
+
Breaking changes / Security), with no internal ticket IDs or system names, and a migration note on
|
|
66
|
+
every breaking change (`process/git/release-notes`; draft them with `business/skills/workflow-release-notes`).
|
|
67
|
+
The CHANGELOG (developer-facing) and the release notes (user-facing) are distinct documents. Commit
|
|
68
|
+
all of this on the current branch (`develop` for simplified, `release/X.Y.Z` for gitflow) — in the
|
|
69
|
+
release commit, not a post-tag follow-up.
|
|
70
|
+
|
|
71
|
+
## Step 5 — Merge to `main` + annotated tag (confirm first)
|
|
72
|
+
|
|
73
|
+
Show the exact commands, then on confirmation:
|
|
74
|
+
|
|
75
|
+
- **simplified:**
|
|
76
|
+
```sh
|
|
77
|
+
git checkout main && git merge --no-ff develop -m "chore(release): X.Y.Z"
|
|
78
|
+
git tag -a vX.Y.Z -m "Release vX.Y.Z"
|
|
79
|
+
```
|
|
80
|
+
- **gitflow:**
|
|
81
|
+
```sh
|
|
82
|
+
git checkout main && git merge --no-ff release/X.Y.Z -m "chore(release): X.Y.Z"
|
|
83
|
+
git tag -a vX.Y.Z -m "Release vX.Y.Z"
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
Annotated tags only (`git tag -a`) — no lightweight tags, no pre-release suffixes (`-rc`, `-alpha`).
|
|
87
|
+
|
|
88
|
+
## Step 6 — Back-merge into `develop` (gitflow only)
|
|
89
|
+
|
|
90
|
+
```sh
|
|
91
|
+
git checkout develop && git merge --no-ff release/X.Y.Z && git branch -d release/X.Y.Z
|
|
92
|
+
```
|
|
93
|
+
So `main` and `develop` never diverge. (Simplified skips this — `main` already tracks `develop`.)
|
|
94
|
+
|
|
95
|
+
## Step 7 — Register + push
|
|
96
|
+
|
|
97
|
+
Record the release AND each per-tenant deployment in `taip-infra/deployments/registry.yaml`
|
|
98
|
+
(cross-repo — if the file/repo is absent, note it and continue; do not fail the release). Then push:
|
|
99
|
+
|
|
100
|
+
```sh
|
|
101
|
+
git push origin main vX.Y.Z # simplified
|
|
102
|
+
git push origin main develop vX.Y.Z # gitflow
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
## Step 8 — Promote through environments (build once)
|
|
106
|
+
|
|
107
|
+
Promote the **same** artifact that was tagged — the identical `<semver>-<gitsha>` image, never a
|
|
108
|
+
rebuild — through the tiers declared in `CLAUDE.md` `## Environments` (default **2-tier** if absent;
|
|
109
|
+
see `engineering/ci/environment-promotion`):
|
|
110
|
+
|
|
111
|
+
- **2-tier:** the candidate runs on **integration** (or an ephemeral release-candidate deploy); run
|
|
112
|
+
`/taip-workflow-acceptance-testing`; on sign-off promote the identical digest to **production**.
|
|
113
|
+
- **3-tier:** deploy the candidate to **staging**, run acceptance testing there; on sign-off promote
|
|
114
|
+
the identical `staging` digest to **production**.
|
|
115
|
+
|
|
116
|
+
MUST NOT rebuild between acceptance and production, and MUST NOT promote an artifact that skipped its
|
|
117
|
+
tier's acceptance stage. Record each promotion in `registry.yaml` (Step 7). Note: `develop`→integration
|
|
118
|
+
is continuous (every merge), independent of cutting a release.
|
|
119
|
+
|
|
120
|
+
## Hotfix path (gitflow only)
|
|
121
|
+
|
|
122
|
+
For an urgent production fix: `git checkout -b hotfix/X.Y.Z main` (bump PATCH), run Steps 3–4 on it,
|
|
123
|
+
then merge `--no-ff` into `main` (annotated tag) **and** into `develop`; delete the branch; register.
|
|
124
|
+
|
|
125
|
+
## Rules
|
|
126
|
+
|
|
127
|
+
- MUST NOT tag before `docs/releases/<semver>/release-record.md` exists (both variants).
|
|
128
|
+
- MUST use annotated `vMAJOR.MINOR.PATCH` tags; version source MUST equal the tag semver.
|
|
129
|
+
- MUST update `CHANGELOG.md` in the release commit.
|
|
130
|
+
- MUST ship user-facing `docs/releases/<semver>/release-notes.md` — categorized, no internal identifiers (`process/git/release-notes`).
|
|
131
|
+
- MUST record the release in `taip-infra/deployments/registry.yaml` (degrade gracefully if absent).
|
|
132
|
+
- **gitflow:** MUST merge every release/hotfix into **both** `main` and `develop`; tag only on the `main` merge commit.
|
|
133
|
+
- **simplified:** MUST merge `develop`→`main` and tag on `main`.
|
|
134
|
+
- MUST promote the **same** acceptance-tested image digest to production — never rebuild between acceptance and prod (`engineering/ci/environment-promotion`).
|