chief-clancy 0.8.22 → 0.9.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (94) hide show
  1. package/bin/clancy.js +153 -0
  2. package/package.json +8 -88
  3. package/README.md +0 -292
  4. package/dist/bundle/clancy-afk.js +0 -6
  5. package/dist/bundle/clancy-once.js +0 -239
  6. package/dist/installer/file-ops/file-ops.d.ts +0 -32
  7. package/dist/installer/file-ops/file-ops.d.ts.map +0 -1
  8. package/dist/installer/file-ops/file-ops.js +0 -58
  9. package/dist/installer/file-ops/file-ops.js.map +0 -1
  10. package/dist/installer/hook-installer/hook-installer.d.ts +0 -31
  11. package/dist/installer/hook-installer/hook-installer.d.ts.map +0 -1
  12. package/dist/installer/hook-installer/hook-installer.js +0 -137
  13. package/dist/installer/hook-installer/hook-installer.js.map +0 -1
  14. package/dist/installer/install.d.ts +0 -3
  15. package/dist/installer/install.d.ts.map +0 -1
  16. package/dist/installer/install.js +0 -270
  17. package/dist/installer/install.js.map +0 -1
  18. package/dist/installer/manifest/manifest.d.ts +0 -41
  19. package/dist/installer/manifest/manifest.d.ts.map +0 -1
  20. package/dist/installer/manifest/manifest.js +0 -97
  21. package/dist/installer/manifest/manifest.js.map +0 -1
  22. package/dist/installer/prompts/prompts.d.ts +0 -33
  23. package/dist/installer/prompts/prompts.d.ts.map +0 -1
  24. package/dist/installer/prompts/prompts.js +0 -55
  25. package/dist/installer/prompts/prompts.js.map +0 -1
  26. package/dist/installer/role-filter/role-filter.d.ts +0 -15
  27. package/dist/installer/role-filter/role-filter.d.ts.map +0 -1
  28. package/dist/installer/role-filter/role-filter.js +0 -48
  29. package/dist/installer/role-filter/role-filter.js.map +0 -1
  30. package/dist/installer/ui/ui.d.ts +0 -9
  31. package/dist/installer/ui/ui.d.ts.map +0 -1
  32. package/dist/installer/ui/ui.js +0 -94
  33. package/dist/installer/ui/ui.js.map +0 -1
  34. package/dist/scripts/shared/env-parser/env-parser.d.ts +0 -30
  35. package/dist/scripts/shared/env-parser/env-parser.d.ts.map +0 -1
  36. package/dist/scripts/shared/env-parser/env-parser.js +0 -64
  37. package/dist/scripts/shared/env-parser/env-parser.js.map +0 -1
  38. package/dist/utils/ansi/ansi.d.ts +0 -55
  39. package/dist/utils/ansi/ansi.d.ts.map +0 -1
  40. package/dist/utils/ansi/ansi.js +0 -55
  41. package/dist/utils/ansi/ansi.js.map +0 -1
  42. package/hooks/clancy-branch-guard.js +0 -128
  43. package/hooks/clancy-check-update.js +0 -114
  44. package/hooks/clancy-context-monitor.js +0 -189
  45. package/hooks/clancy-credential-guard.js +0 -120
  46. package/hooks/clancy-drift-detector.js +0 -96
  47. package/hooks/clancy-notification.js +0 -105
  48. package/hooks/clancy-post-compact.js +0 -53
  49. package/hooks/clancy-statusline.js +0 -82
  50. package/hooks/package.json +0 -3
  51. package/registry/boards.json +0 -44
  52. package/src/agents/arch-agent.md +0 -72
  53. package/src/agents/concerns-agent.md +0 -89
  54. package/src/agents/design-agent.md +0 -130
  55. package/src/agents/devils-advocate.md +0 -53
  56. package/src/agents/quality-agent.md +0 -161
  57. package/src/agents/tech-agent.md +0 -92
  58. package/src/agents/verification-gate.md +0 -128
  59. package/src/roles/implementer/commands/dry-run.md +0 -14
  60. package/src/roles/implementer/commands/once.md +0 -17
  61. package/src/roles/implementer/commands/run.md +0 -11
  62. package/src/roles/implementer/workflows/once.md +0 -146
  63. package/src/roles/implementer/workflows/run.md +0 -127
  64. package/src/roles/planner/commands/approve-plan.md +0 -10
  65. package/src/roles/planner/commands/plan.md +0 -20
  66. package/src/roles/planner/workflows/approve-plan.md +0 -535
  67. package/src/roles/planner/workflows/plan.md +0 -536
  68. package/src/roles/reviewer/commands/logs.md +0 -7
  69. package/src/roles/reviewer/commands/review.md +0 -9
  70. package/src/roles/reviewer/commands/status.md +0 -9
  71. package/src/roles/reviewer/workflows/logs.md +0 -104
  72. package/src/roles/reviewer/workflows/review.md +0 -186
  73. package/src/roles/reviewer/workflows/status.md +0 -134
  74. package/src/roles/setup/commands/doctor.md +0 -7
  75. package/src/roles/setup/commands/help.md +0 -80
  76. package/src/roles/setup/commands/init.md +0 -7
  77. package/src/roles/setup/commands/map-codebase.md +0 -16
  78. package/src/roles/setup/commands/settings.md +0 -7
  79. package/src/roles/setup/commands/uninstall.md +0 -5
  80. package/src/roles/setup/commands/update-docs.md +0 -9
  81. package/src/roles/setup/commands/update.md +0 -12
  82. package/src/roles/setup/workflows/doctor.md +0 -124
  83. package/src/roles/setup/workflows/init.md +0 -1073
  84. package/src/roles/setup/workflows/map-codebase.md +0 -125
  85. package/src/roles/setup/workflows/scaffold.md +0 -845
  86. package/src/roles/setup/workflows/settings.md +0 -944
  87. package/src/roles/setup/workflows/uninstall.md +0 -161
  88. package/src/roles/setup/workflows/update-docs.md +0 -92
  89. package/src/roles/setup/workflows/update.md +0 -277
  90. package/src/roles/strategist/commands/approve-brief.md +0 -21
  91. package/src/roles/strategist/commands/brief.md +0 -27
  92. package/src/roles/strategist/workflows/approve-brief.md +0 -834
  93. package/src/roles/strategist/workflows/brief.md +0 -890
  94. package/src/templates/CLAUDE.md +0 -87
@@ -1,890 +0,0 @@
1
- # Clancy Brief Workflow
2
-
3
- ## Overview
4
-
5
- Research an idea, interrogate it thoroughly, and generate a structured strategic brief with vertical-slice ticket decomposition. Briefs are saved locally and optionally posted as comments on the source ticket. Does not create tickets — that is `/clancy:approve-brief`.
6
-
7
- ---
8
-
9
- ## Step 1 — Preflight checks
10
-
11
- 1. Check `.clancy/` exists and `.clancy/.env` is present. If not:
12
- ```
13
- .clancy/ not found. Run /clancy:init to set up Clancy first.
14
- ```
15
- Stop.
16
-
17
- 2. Source `.clancy/.env` and check board credentials are present.
18
-
19
- 3. Check `CLANCY_ROLES` includes `strategist` (or env var is unset, which indicates a global install where all roles are available). If `CLANCY_ROLES` is set but does not include `strategist`:
20
- ```
21
- The Strategist role is not enabled. Add "strategist" to CLANCY_ROLES in .clancy/.env or run /clancy:settings.
22
- ```
23
- Stop.
24
-
25
- 4. Branch freshness check — run `git fetch origin` and compare the current HEAD with `origin/$CLANCY_BASE_BRANCH` (defaults to `main`). If the local branch is behind:
26
-
27
- **AFK mode** (`--afk` flag or `CLANCY_MODE=afk`): auto-pull without prompting. Run `git pull origin $CLANCY_BASE_BRANCH` and continue.
28
-
29
- **Interactive mode:**
30
- ```
31
- ⚠️ Your local branch is behind origin/{CLANCY_BASE_BRANCH} by {N} commit(s).
32
-
33
- [1] Pull latest
34
- [2] Continue anyway
35
- [3] Abort
36
- ```
37
- - [1] runs `git pull origin $CLANCY_BASE_BRANCH` and continues
38
- - [2] continues without pulling
39
- - [3] stops
40
-
41
- ---
42
-
43
- ## Step 2 — Parse arguments
44
-
45
- Parse the arguments passed to the command. Arguments can appear in any order.
46
-
47
- ### Flags
48
-
49
- - **`--list`** — show brief inventory and stop (no brief generated)
50
- - **`--fresh`** — discard any existing brief and start over from scratch
51
- - **`--research`** — force web research agent (adds 1 web agent to the research phase)
52
- - **`--afk`** — use AI-grill instead of human grill (no interactive questions)
53
- - **`--epic {KEY}`** — hint for `/clancy:approve-brief` later. Stored in the brief's metadata. Ignored if the input is a board ticket (the source ticket is the parent).
54
-
55
- ### Input modes
56
-
57
- - **No input (no flags that consume arguments):** Interactive mode — but first check for `--afk`:
58
- - If running in AFK mode (`--afk` flag OR `CLANCY_MODE=afk`): there is no human to answer. Display: `✗ Cannot run /clancy:brief in AFK mode without a ticket or idea. Use: /clancy:brief --afk #42 (GitHub) or PROJ-123 (Jira) or ENG-42 (Linear), or /clancy:brief --afk "Add dark mode", or /clancy:brief 3 (batch mode — implies --afk).` Stop.
59
- - Otherwise: prompt `What's the idea?` and parse the response. If the response looks like a ticket reference (`#42`, `PROJ-123`, `ENG-42`), switch to board ticket mode. Otherwise treat as inline text.
60
- - **Ticket key** (`PROJ-123`, `#42`, `ENG-42`): Board ticket mode — fetch the ticket from the board API. Validate format per platform:
61
- - `#N` — valid for GitHub only. If board is Jira or Linear: `The #N format is for GitHub Issues. Use a ticket key like PROJ-123.` Stop.
62
- - `PROJ-123` / `ENG-42` (letters-dash-number) — valid for Jira and Linear. If board is GitHub: `Use #N format for GitHub Issues (e.g. #42).` Stop.
63
- - **Quoted string or unquoted non-matching text** (e.g. `"Add dark mode"`): Inline text mode — use the text directly as the idea.
64
- - **`--from {path}`** — From file mode. Cannot be combined with a ticket reference (error if both present: `Cannot use both a ticket reference and --from. Use one or the other.`). Validate:
65
- - File does not exist: `File not found: {path}` Stop.
66
- - File is empty: `File is empty: {path}` Stop.
67
- - File > 50KB: Warn `Large file ({size}KB). Clancy will use the first ~50KB for context.` Truncate internally, continue.
68
- - **Bare positive integer** (e.g. `/clancy:brief 3`): Batch mode or ambiguous.
69
- - Board is GitHub and value could be an issue: Ambiguous — ask: `Did you mean issue #3 or batch 3 tickets? [1] Brief issue #3 [2] Brief 3 tickets from queue`
70
- - Board is Jira or Linear: Batch mode (N tickets from queue). Implies `--afk` (AI-grill for all).
71
-
72
- If N > 10: `Maximum batch size is 10. Briefing 10 tickets.`
73
-
74
- ### --list flag handling
75
-
76
- If `--list` is present (with or without other arguments), jump to Step 11 (Brief Inventory) and stop.
77
-
78
- ---
79
-
80
- ## Step 3 — Gather idea (mode-specific)
81
-
82
- ### Board ticket mode
83
-
84
- Fetch the source ticket from the board API.
85
-
86
- #### GitHub — Fetch specific issue
87
-
88
- ```bash
89
- RESPONSE=$(curl -s \
90
- -H "Authorization: Bearer $GITHUB_TOKEN" \
91
- -H "X-GitHub-Api-Version: 2022-11-28" \
92
- "https://api.github.com/repos/$GITHUB_REPO/issues/$ISSUE_NUMBER")
93
- ```
94
-
95
- Validate the response:
96
- - If `pull_request` field is present and non-null: `#N is a pull request, not an issue.` Stop.
97
- - If `state` is `closed`: warn `#N is closed. Brief it anyway? [y/N]`
98
- - If `body` is null/empty: warn `No issue description — briefing from title only.`
99
- - Extract: `title`, `body`, `labels`, `milestone`.
100
-
101
- Fetch comments for existing brief detection:
102
- ```bash
103
- COMMENTS=$(curl -s \
104
- -H "Authorization: Bearer $GITHUB_TOKEN" \
105
- -H "X-GitHub-Api-Version: 2022-11-28" \
106
- "https://api.github.com/repos/$GITHUB_REPO/issues/$ISSUE_NUMBER/comments?per_page=100")
107
- ```
108
-
109
- #### Jira — Fetch specific ticket
110
-
111
- ```bash
112
- RESPONSE=$(curl -s \
113
- -u "$JIRA_USER:$JIRA_API_TOKEN" \
114
- -H "Accept: application/json" \
115
- "$JIRA_BASE_URL/rest/api/3/issue/$TICKET_KEY?fields=summary,description,status,issuetype,parent,customfield_10014,components,priority,comment,project")
116
- ```
117
-
118
- Validate the response:
119
- - If `fields.status.statusCategory.key` is `done`: warn `{KEY} is Done. Brief it anyway? [y/N]`
120
- - If `fields.status.statusCategory.key` is `indeterminate`: warn `{KEY} is In Progress — briefing anyway.`
121
- - If `fields.issuetype.name` is `Epic`: note `{KEY} is an Epic — child tickets will be created under it.`
122
- - Extract: `summary`, `description` (ADF → plain text via `extractAdfText()`), status, existing comments from `comment.comments[]`.
123
-
124
- #### Linear — Fetch specific issue
125
-
126
- ```graphql
127
- query {
128
- issues(filter: { identifier: { eq: "$IDENTIFIER" } }) {
129
- nodes {
130
- id identifier title description
131
- state { id name type }
132
- parent { id identifier title }
133
- children { nodes { id identifier title state { type } } }
134
- team { id key name }
135
- labels { nodes { id name } }
136
- priority estimate
137
- }
138
- }
139
- }
140
- ```
141
-
142
- Validate the response:
143
- - If `nodes` is empty: `Issue {KEY} not found on Linear.` Stop.
144
- - If `state.type` is `completed` or `canceled`: warn `{KEY} is {state.name}. Brief it anyway? [y/N]`
145
- - If `state.type` is `started`: warn `{KEY} is In Progress — briefing anyway.`
146
- - If `parent` is present: warn `{KEY} is a sub-issue of {parent.identifier}. Creating children will produce a 3-level hierarchy. Continue? [Y/n]`
147
- - If `team.id` differs from `LINEAR_TEAM_ID`: warn `{KEY} belongs to team "{team.name}", but LINEAR_TEAM_ID is different. Continue? [Y/n]`
148
-
149
- #### All platforms — error handling
150
-
151
- If the API call fails:
152
- - 404: `{KEY} not found — check the ticket key.` Stop.
153
- - 401: `Auth failed — check credentials in .clancy/.env` Stop.
154
- - 403: `Permission denied — check token scopes.` Stop.
155
- - 5xx / timeout: `Server error. Try again in a few minutes.` Stop.
156
- - Network error: `Could not reach {platform} — check network connection.` Stop.
157
-
158
- ### Inline text mode
159
-
160
- Use the provided text directly. No API call.
161
-
162
- ### From file mode
163
-
164
- Read the file content. Slug derived from filename (strip extension, strip date prefix if present).
165
-
166
- ### Batch mode
167
-
168
- Fetch N issues from the planning queue (same labels/statuses as `/clancy:plan`):
169
-
170
- #### GitHub batch fetch
171
- ```bash
172
- GITHUB_USERNAME=$(curl -s -H "Authorization: Bearer $GITHUB_TOKEN" https://api.github.com/user | jq -r '.login')
173
-
174
- RESPONSE=$(curl -s \
175
- -H "Authorization: Bearer $GITHUB_TOKEN" \
176
- -H "X-GitHub-Api-Version: 2022-11-28" \
177
- "https://api.github.com/repos/$GITHUB_REPO/issues?state=open&assignee=$GITHUB_USERNAME&labels=$CLANCY_PLAN_LABEL&per_page=$N")
178
- ```
179
-
180
- Filter out PRs (entries with `pull_request` key).
181
-
182
- #### Jira batch fetch
183
- ```bash
184
- RESPONSE=$(curl -s \
185
- -u "$JIRA_USER:$JIRA_API_TOKEN" \
186
- -X POST \
187
- -H "Content-Type: application/json" \
188
- -H "Accept: application/json" \
189
- "$JIRA_BASE_URL/rest/api/3/search/jql" \
190
- -d '{"jql": "project=$JIRA_PROJECT_KEY AND assignee=currentUser() AND status=\"$CLANCY_PLAN_STATUS\" ORDER BY priority ASC", "maxResults": <N>, "fields": ["summary", "description", "status", "issuetype", "parent", "comment"]}')
191
- ```
192
-
193
- `CLANCY_PLAN_STATUS` defaults to `Backlog`.
194
-
195
- #### Linear batch fetch
196
- ```graphql
197
- query {
198
- viewer {
199
- assignedIssues(
200
- filter: {
201
- state: { type: { eq: "unstarted" } }
202
- team: { id: { eq: "$LINEAR_TEAM_ID" } }
203
- }
204
- first: $N
205
- orderBy: priority
206
- ) {
207
- nodes {
208
- id identifier title description
209
- state { id name type }
210
- parent { id identifier title }
211
- children { nodes { id identifier title state { type } } }
212
- team { id key }
213
- }
214
- }
215
- }
216
- }
217
- ```
218
-
219
- If no tickets found:
220
- ```
221
- No tickets in the planning queue. Check your queue label/status configuration.
222
- ```
223
- Stop.
224
-
225
- For batch mode, process each ticket sequentially through Steps 4-10. Skip tickets that already have a brief (check `.clancy/briefs/`). Batch mode always uses AI-grill (no human interaction per ticket).
226
-
227
- ---
228
-
229
- ## Step 4 — Grill phase
230
-
231
- The grill phase is the most critical part of the brief workflow. Its purpose is to walk every branch of the design tree, resolving ambiguity upfront rather than encoding it into vague tickets.
232
-
233
- ### Mode detection
234
-
235
- ```
236
- --afk flag passed? -> AI-GRILL
237
- CLANCY_MODE=afk in env? -> AI-GRILL
238
- Batch mode (N tickets)? -> AI-GRILL
239
- Otherwise -> HUMAN GRILL
240
- ```
241
-
242
- The `--afk` flag takes precedence over `CLANCY_MODE`.
243
-
244
- ### Human grill
245
-
246
- Interview the user RELENTLESSLY about every aspect of the idea until you reach a shared understanding.
247
-
248
- **Core principle** (from Matt Pocock's "grill me" skill):
249
-
250
- > "Interview me relentlessly about every aspect of this plan until we reach a shared understanding. Walk down each branch of the design tree, resolving dependencies between decisions one by one. If a question can be answered by exploring the codebase, explore the codebase instead."
251
-
252
- **Rules:**
253
-
254
- 1. Be RELENTLESS. Do not accept vague answers. If the user says "it should be fast", ask "what's the latency budget? 100ms? 500ms? Per-request or p99?" If they say "just pick something", explain the trade-offs and make them choose.
255
-
256
- 2. For each question, **provide your recommended answer** based on codebase context, board context, or best practices. The user can agree, disagree, or ask for more detail. This speeds up the grill — the user confirms or overrides rather than researching from scratch.
257
-
258
- 3. Walk each branch of the design tree to its CONCLUSION before moving to the next. Don't jump between topics — follow each thread until it's fully resolved.
259
-
260
- 4. Explore the codebase instead of asking when the answer is in the code. Don't ask "do you have an auth module?" — check. Then ask informed follow-ups: "I see `src/auth/sso-provider.ts` uses SAML. Should the new feature use the same provider?"
261
-
262
- 5. This is a TWO-WAY conversation. The user can ask questions back at any time:
263
- - "What does the codebase currently use?" → explore and answer
264
- - "What do other projects typically do?" → web research
265
- - "Are there related tickets?" → board query
266
- - "What would you recommend?" → give an informed opinion with trade-offs, then let the user decide
267
-
268
- 6. Answers spawn follow-up questions (multi-round): "We want SSO" → "SAML or OIDC?" → "OIDC" → "Which provider? No OIDC client in codebase yet."
269
-
270
- 7. Do NOT generate the brief until the grill is complete. The goal is ZERO AMBIGUITY before a single ticket is written. Push back if the user tries to rush: "We still have open questions about X and Y. Let's resolve those first."
271
-
272
- 8. Stop when you reach a SHARED UNDERSTANDING — both sides agree they understand the full scope, constraints, and decisions. Not just "no more questions" but genuine mutual comprehension.
273
-
274
- 9. The resolved answers feed into the `## Discovery` section of the brief.
275
-
276
- **Question categories:**
277
- - **Scope:** What's in and what's out?
278
- - **Users:** Who uses this? What are the personas?
279
- - **Constraints:** Performance budget? Browser support? Auth?
280
- - **Edge cases:** What happens when X is empty / fails / times out?
281
- - **Dependencies:** Does this depend on other in-flight work?
282
- - **Existing code:** How does this interact with `{module}`?
283
- - **Data:** What's the data model? Volume? Retention?
284
- - **Security:** Who can access this? What's the auth boundary?
285
- - **Observability:** How will you know if this breaks?
286
-
287
- Typical: 5-20 clarifying questions over 2-5 rounds.
288
-
289
- ### AI-grill
290
-
291
- Same relentless energy as the human grill, but directed at the strategist itself via a devil's advocate agent.
292
-
293
- 1. Generate 10-15 clarifying questions using the same categories as the human grill (scope, users, constraints, edge cases, dependencies, existing code, data, security, observability).
294
-
295
- 2. Spawn the devil's advocate agent via the Agent tool, passing:
296
- - The idea text (ticket title + description, or inline text, or file content)
297
- - The 10-15 generated questions
298
- - The path to the agent prompt: `src/agents/devils-advocate.md`
299
-
300
- 3. The devil's advocate agent answers each question by INTERROGATING ITS SOURCES:
301
- - **Codebase:** explore affected areas, read `.clancy/docs/`, check existing patterns. Don't assume — look.
302
- - **Board:** parent ticket, related tickets, existing children. Check for conflicting requirements.
303
- - **Web:** when the question involves external technology, patterns, or third-party integrations. Same trigger as Step 6: `--research` flag forces it, otherwise judgement-based.
304
-
305
- 4. The agent CHALLENGES ITS OWN ANSWERS. If the codebase says one thing but the ticket description says another, flag the conflict. If a question can be partially answered, answer the part it can and flag the rest. Do NOT accept vague self-answers — if the codebase doesn't clearly support a decision, don't guess.
306
-
307
- 5. Answers may spawn SELF-FOLLOW-UPS within the same pass: "Should this support SSO?" → checks codebase → finds `src/auth/sso-provider.ts` → "SSO exists, but it's SAML. Should the new feature use SAML or add OIDC?" → checks ticket description → no mention → checks web → "OIDC is the modern standard" → resolves as OIDC with caveat. All resolved in one pass.
308
-
309
- 6. Single pass — no multi-round loop with the human. But the agent must be thorough enough in one pass that a second would add nothing.
310
-
311
- 7. The agent NEVER asks the human questions (that defeats `--afk` mode). Unresolvable questions go to `## Open Questions` for the PO to address during brief review.
312
-
313
- 8. Classify each question:
314
- - **Answerable** (>80% confidence, or technical decision with clear codebase precedent) → `## Discovery` with source tag
315
- - **Conflicting evidence** (codebase says X, ticket says Y) → `## Open Questions` with conflict noted
316
- - **Not answerable** (business decision, ambiguous requirements, no codebase precedent, involves money/legal/compliance/security policy) → `## Open Questions` for PO
317
-
318
- Typical: 10-15 questions, 8-12 resolved, 2-4 open.
319
-
320
- ### Output from both modes
321
-
322
- Both grill modes produce a `## Discovery` section and an `## Open Questions` section. Each Q&A in Discovery includes a source tag:
323
-
324
- ```
325
- ## Discovery
326
-
327
- Q: Should we support system preference detection?
328
- A: Yes — the codebase already uses `prefers-color-scheme` in
329
- `src/styles/media.ts`. (Source: codebase)
330
-
331
- Q: Should dark mode persist across sessions?
332
- A: Yes, store in localStorage. User confirmed. (Source: human)
333
-
334
- Q: What's the industry standard for dark mode colour contrast?
335
- A: WCAG AA requires 4.5:1 ratio for normal text. (Source: web)
336
-
337
- ## Open Questions
338
- - [ ] Should dark mode apply to emails/PDFs or just the web UI?
339
- - [ ] Should portal users see all org data or only their team's?
340
- (No RBAC policy found in codebase or ticket — needs PO input)
341
- ```
342
-
343
- Source tags: `(Source: human)`, `(Source: codebase)`, `(Source: board)`, `(Source: web)`
344
-
345
- ---
346
-
347
- ## Step 5 — Auto-detect existing brief
348
-
349
- Scan `.clancy/briefs/` for an existing brief matching this idea:
350
- - **Board ticket:** match by ticket key in the `**Source:**` line
351
- - **Inline text / file:** match by slug in the filename
352
-
353
- | Condition | Behaviour |
354
- |---|---|
355
- | No existing brief | Continue to Step 6 (fresh brief) |
356
- | Existing brief + `--fresh` flag | Delete old file, continue to Step 6 |
357
- | Existing brief + feedback found | Revise: read existing brief + all feedback, generate revised brief with `### Changes From Previous Brief` section |
358
- | Existing brief + no feedback + no `--fresh` | Stop: `Already briefed. Add feedback to revise, or use --fresh to start over.` |
359
-
360
- ### Feedback detection (3 sources, checked in order)
361
-
362
- 1. **Local brief file** — check for `## Feedback` section appended to `.clancy/briefs/{date}-{slug}.md`
363
- 2. **Companion file** — check for `.clancy/briefs/{date}-{slug}.feedback.md`
364
- 3. **Board comments** (board-sourced only) — fetch ALL comments on the source ticket. Scan each comment body for the text `Clancy Strategic Brief` (case-insensitive, match anywhere in the body — it may appear as `# Clancy Strategic Brief`, `## Clancy Strategic Brief`, or just the text). The most recent matching comment is the brief. Collect all comments posted AFTER it as feedback.
365
-
366
- Board comment feedback filtering per platform:
367
- - **GitHub:** comments where `created_at` > brief comment's `created_at` AND `user.login` != resolved username (via `GET /user`)
368
- - **Jira:** comments where created timestamp > brief comment timestamp AND `author.accountId` != brief comment's `author.accountId`
369
- - **Linear:** all comments posted after the brief comment are treated as feedback (Linear personal keys don't easily expose viewer ID)
370
-
371
- Merge order: local `## Feedback` section first, then `.feedback.md` file, then board comments (chronological). All passed to generation step as additional context.
372
-
373
- ### Edge cases
374
-
375
- - **Board comment exists but local file is missing:** Re-download the brief from the board comment into `.clancy/briefs/`. Then check for feedback normally.
376
- - **Local file exists but board comment was deleted:** Use local feedback only. No board feedback to read.
377
- - **Multiple brief comments on same ticket:** Use the MOST RECENT (latest timestamp) as the reference point for feedback detection.
378
-
379
- ---
380
-
381
- ## Step 6 — Relevance check
382
-
383
- Read `.clancy/docs/STACK.md` and `ARCHITECTURE.md` (if they exist). Compare the idea's domain against the codebase technology stack.
384
-
385
- If the idea is clearly irrelevant (targets a platform or technology completely outside the codebase):
386
- ```
387
- Skipping — this idea targets {platform}, but this codebase is {stack}.
388
- ```
389
- Log: `YYYY-MM-DD HH:MM | BRIEF | {slug} | SKIPPED — not relevant ({reason})`
390
- Stop.
391
-
392
- If the idea mentions a technology not listed in STACK.md, flag it as a concern but do NOT skip — include a note in the brief's Technical Considerations section.
393
-
394
- ---
395
-
396
- ## Step 7 — Research (adaptive agents)
397
-
398
- Assess complexity from the idea title + description:
399
-
400
- | Complexity | Agents | Trigger |
401
- |---|---|---|
402
- | Narrow (single feature, few files) | 1 codebase agent | Simple scope |
403
- | Moderate (multi-component, clear boundary) | 2 codebase agents | Medium scope |
404
- | Broad (cross-cutting, multiple subsystems) | 3 codebase agents | Large scope |
405
-
406
- Web research agent (adds 1 to the count above, max 4 total):
407
- - `--research` flag → always add web agent
408
- - Idea involves new/external technology → add web agent (judgement-based)
409
- - Internal refactor → no web agent
410
-
411
- ### What agents explore
412
-
413
- - `.clancy/docs/` — STACK.md, ARCHITECTURE.md, CONVENTIONS.md, TESTING.md, DESIGN-SYSTEM.md
414
- - Affected code areas via Glob + Read
415
- - Board for duplicates/related tickets (text-match against title):
416
- - **GitHub:** `GET /repos/$GITHUB_REPO/issues?state=open&per_page=30` and text-match
417
- - **Jira:** `POST /rest/api/3/search/jql` with `summary ~ "keywords"`
418
- - **Linear:** `issues(filter: ...)` by text search
419
- - Existing children of the source ticket (board-sourced only):
420
- - **GitHub:** scan open issues for `Epic: #{parent}` in body
421
- - **Jira:** `POST /rest/api/3/search/jql` with `parent = {KEY}`
422
- - **Linear:** already included in the fetch response (`children.nodes`)
423
- - Web research (if triggered)
424
-
425
- Display per-agent progress:
426
- ```
427
- Researching...
428
- Agent 1: Codebase structure ✅
429
- Agent 2: Testing patterns ✅
430
- Agent 3: Web research ✅ (3 sources)
431
- ```
432
-
433
- ---
434
-
435
- ## Step 8 — Generate brief
436
-
437
- Using all gathered context (idea, grill output, research findings), generate the brief in this exact template:
438
-
439
- ```markdown
440
- # Clancy Strategic Brief
441
-
442
- **Source:** {source — see below}
443
- **Date:** {YYYY-MM-DD}
444
- **Status:** Draft
445
-
446
- ---
447
-
448
- ## Problem Statement
449
- {2-4 sentences: what problem does this solve and why does it matter?}
450
-
451
- ## Goals
452
- - {Specific, measurable goal}
453
- - {Specific, measurable goal}
454
-
455
- ## Non-Goals
456
- - {What is explicitly out of scope}
457
- - {What is explicitly out of scope}
458
-
459
- ## Discovery
460
- {Q&A pairs from the grill phase, each with source tag — see Step 4 output format}
461
-
462
- ## Background Research
463
- {Findings from codebase exploration and web research. Include file paths, patterns found, and external references.}
464
-
465
- ## Related Existing Work
466
- {Existing tickets, PRs, or code that overlaps with this idea. If the source ticket has children, list them here. "None found" if clean.}
467
-
468
- ## User Stories
469
- - As a {persona}, I want to {action} so that {outcome}.
470
- - As a {persona}, I want to {action} so that {outcome}.
471
- - As a {persona}, I want to {action} so that {outcome}.
472
-
473
- ## Technical Considerations
474
- - {Architectural decisions, patterns to follow, constraints}
475
- - {Integration points, migration needs, backwards compatibility}
476
- - {Performance, security, accessibility considerations}
477
-
478
- ## Ticket Decomposition
479
-
480
- | # | Title | Description | Size | Deps | Mode |
481
- |---|-------|-------------|------|------|------|
482
- | 1 | {Vertical slice title} | {1-2 sentences} | S | — | AFK |
483
- | 2 | {Vertical slice title} | {1-2 sentences} | M | #1 | AFK |
484
- | 3 | {Vertical slice title} | {1-2 sentences} | M | #1 | HITL |
485
-
486
- ## Open Questions
487
- - [ ] {Unresolved question from grill phase — with reason}
488
- - [ ] {Unresolved question — needs PO input}
489
-
490
- ## Success Criteria
491
- - [ ] {Specific, testable criterion for the entire initiative}
492
- - [ ] {Specific, testable criterion}
493
-
494
- ## Risks
495
- - {Specific risk and mitigation strategy}
496
- - {Specific risk and mitigation strategy}
497
-
498
- ---
499
- *Generated by [Clancy](https://github.com/Pushedskydiver/clancy). To answer open questions or request changes: comment on the source ticket or add a ## Feedback section to the brief file, then re-run `/clancy:brief` to revise. To approve: `/clancy:approve-brief`. To start over: `/clancy:brief --fresh`.*
500
- ```
501
-
502
- ### Source field format
503
-
504
- - **Board ticket:** `[{KEY}] {Title}` (e.g. `[#50] Redesign settings page`, `[PROJ-200] Add customer portal`, `[ENG-42] Add real-time notifications`)
505
- - **Inline text:** `"{text}"` (e.g. `"Add dark mode support"`)
506
- - **From file:** `{path}` (e.g. `docs/rfcs/auth-rework.md`)
507
-
508
- ### Ticket Decomposition rules
509
-
510
- 1. **Max 10 tickets.** If the idea needs more, note "Consider splitting this initiative into multiple briefs."
511
- 2. **Vertical slices only.** Each ticket must cut through all layers needed to deliver one thin, working piece of functionality end-to-end. If a ticket title mentions only one layer (e.g. "Set up database schema", "Create React components"), restructure it into a slice that delivers observable behaviour.
512
- 3. **Dependencies** reference other tickets in the table by `#N` (e.g. `#1`, `#1, #3`). Use `—` for no dependencies.
513
- 4. **Size:** S (< 1 hour, few files), M (1-4 hours, moderate), L (4+ hours, significant).
514
- 5. **Mode:**
515
- - `AFK` — ticket can be implemented autonomously by `/clancy:once` or `/clancy:run`
516
- - `HITL` — ticket requires human judgement, approval, or input (design decisions, credentials, external service setup, UX review, ambiguous requirements)
517
- 6. Every ticket must trace to at least one user story.
518
-
519
- ### User Story rules
520
-
521
- - Write 3-8 user stories per brief (more = scope too large)
522
- - Each story must be testable (implies acceptance criteria)
523
- - Use the format: `As a {persona}, I want to {action} so that {outcome}.`
524
-
525
- ### Re-brief revision
526
-
527
- If revising from feedback (Step 5):
528
-
529
- 1. **Cross-reference feedback against Open Questions.** For each Open Question in the existing brief, check if the feedback contains an answer (exact or paraphrased — match by intent, not syntax). Resolved questions move to `## Discovery` with `(Source: human)` tag. Unresolved questions stay in `## Open Questions`.
530
-
531
- 2. **Apply all other feedback** — changes to scope, goals, decomposition, user stories, etc.
532
-
533
- 3. **Prepend a section** before Problem Statement:
534
-
535
- ```markdown
536
- ### Changes From Previous Brief
537
- {What feedback was addressed and how the brief changed.
538
- List resolved open questions explicitly.}
539
- ```
540
-
541
- ---
542
-
543
- ## Step 9 — Save locally
544
-
545
- Write to `.clancy/briefs/{YYYY-MM-DD}-{slug}.md`.
546
-
547
- **Slug generation:**
548
- - **Board ticket:** derive from title — lowercase, replace non-alphanumeric with hyphens, trim, truncate to 50 chars. E.g. `add-customer-portal`.
549
- - **Inline text:** derive from the text — same rules.
550
- - **From file:** derive from filename — strip extension, strip date prefix if present.
551
-
552
- **Slug collision:** If file already exists, append `-2`, `-3`, etc.
553
-
554
- **Create `.clancy/briefs/` directory** if it does not exist.
555
-
556
- ---
557
-
558
- ## Step 10 — Post to board
559
-
560
- Only for board-sourced briefs (ticket key was provided). Inline text and file briefs are local only.
561
-
562
- ### GitHub — POST comment
563
-
564
- ```bash
565
- curl -s \
566
- -H "Authorization: Bearer $GITHUB_TOKEN" \
567
- -H "X-GitHub-Api-Version: 2022-11-28" \
568
- -X POST \
569
- "https://api.github.com/repos/$GITHUB_REPO/issues/$ISSUE_NUMBER/comments" \
570
- -d '{"body": "<full brief markdown>"}'
571
- ```
572
-
573
- GitHub accepts Markdown directly.
574
-
575
- ### Jira — POST comment
576
-
577
- ```bash
578
- curl -s \
579
- -u "$JIRA_USER:$JIRA_API_TOKEN" \
580
- -X POST \
581
- -H "Content-Type: application/json" \
582
- -H "Accept: application/json" \
583
- "$JIRA_BASE_URL/rest/api/3/issue/$TICKET_KEY/comment" \
584
- -d '<ADF JSON body>'
585
- ```
586
-
587
- Construct ADF (Atlassian Document Format) JSON for the comment body:
588
- - `## Heading` → `heading` node (level 2)
589
- - `### Heading` → `heading` node (level 3)
590
- - `- bullet` → `bulletList > listItem > paragraph`
591
- - `| table |` → `table > tableRow > tableCell`
592
- - `**bold**` → marks: `[{ "type": "strong" }]`
593
- - `` `code` `` → marks: `[{ "type": "code" }]`
594
-
595
- If ADF construction is too complex for a particular element, fall back to wrapping that section in a `codeBlock` node.
596
-
597
- Comment marker heading: `## Clancy Strategic Brief` (H2 ADF heading node).
598
-
599
- ### Linear — commentCreate mutation
600
-
601
- ```bash
602
- curl -s \
603
- -X POST \
604
- -H "Content-Type: application/json" \
605
- -H "Authorization: $LINEAR_API_KEY" \
606
- "https://api.linear.app/graphql" \
607
- -d '{"query": "mutation { commentCreate(input: { issueId: \"$ISSUE_ID\", body: \"<full brief markdown>\" }) { success } }"}'
608
- ```
609
-
610
- Linear accepts Markdown directly. Comment marker heading: `# Clancy Strategic Brief`.
611
-
612
- Note: Linear personal API keys do NOT use `Bearer` prefix.
613
-
614
- ### On failure (any platform)
615
-
616
- ```
617
- ⚠️ Failed to post brief comment on {KEY}. Brief saved locally at .clancy/briefs/{file}. Paste it manually.
618
- ```
619
-
620
- Continue — do not stop. The local file is the source of truth.
621
-
622
- ---
623
-
624
- ## Step 10a — Apply pipeline label (board-sourced only)
625
-
626
- Only for board-sourced briefs (ticket key was provided). Inline text and file briefs skip this step.
627
-
628
- **This step is mandatory for board-sourced briefs — always apply the label.** Use `CLANCY_LABEL_BRIEF` from `.clancy/.env` if set. If not set, use `clancy:brief` as the default. Ensure the label exists on the board (create it if missing), then add it to the ticket. Also read `CLANCY_LABEL_PLAN` (default: `clancy:plan`) and `CLANCY_LABEL_BUILD` (default: `clancy:build`) for cleanup during re-briefs.
629
-
630
- ### Re-brief cleanup (`--fresh` flag)
631
-
632
- If this is a re-brief (`--fresh`), the ticket may already have `clancy:plan` or `clancy:build` from a prior approval. Remove them first (best-effort — ignore failures):
633
-
634
- #### GitHub
635
-
636
- ```bash
637
- # Remove plan label (ignore 404)
638
- curl -s \
639
- -H "Authorization: Bearer $GITHUB_TOKEN" \
640
- -H "Accept: application/vnd.github+json" \
641
- -H "X-GitHub-Api-Version: 2022-11-28" \
642
- -X DELETE \
643
- "https://api.github.com/repos/$GITHUB_REPO/issues/$ISSUE_NUMBER/labels/$(echo $CLANCY_LABEL_PLAN | jq -Rr @uri)"
644
-
645
- # Remove build label (ignore 404)
646
- curl -s \
647
- -H "Authorization: Bearer $GITHUB_TOKEN" \
648
- -H "Accept: application/vnd.github+json" \
649
- -H "X-GitHub-Api-Version: 2022-11-28" \
650
- -X DELETE \
651
- "https://api.github.com/repos/$GITHUB_REPO/issues/$ISSUE_NUMBER/labels/$(echo $CLANCY_LABEL_BUILD | jq -Rr @uri)"
652
- ```
653
-
654
- #### Jira
655
-
656
- ```bash
657
- # Fetch current labels, remove plan + build labels, PUT updated list
658
- CURRENT_LABELS=$(curl -s \
659
- -u "$JIRA_USER:$JIRA_API_TOKEN" \
660
- -H "Accept: application/json" \
661
- "$JIRA_BASE_URL/rest/api/3/issue/$TICKET_KEY?fields=labels" | jq -r '.fields.labels')
662
-
663
- UPDATED_LABELS=$(echo "$CURRENT_LABELS" | jq --arg plan "$CLANCY_LABEL_PLAN" --arg build "$CLANCY_LABEL_BUILD" '[.[] | select(. != $plan and . != $build)]')
664
-
665
- curl -s \
666
- -u "$JIRA_USER:$JIRA_API_TOKEN" \
667
- -X PUT \
668
- -H "Content-Type: application/json" \
669
- "$JIRA_BASE_URL/rest/api/3/issue/$TICKET_KEY" \
670
- -d "{\"fields\": {\"labels\": $UPDATED_LABELS}}"
671
- ```
672
-
673
- #### Linear
674
-
675
- ```bash
676
- # Fetch current label IDs, remove plan + build label IDs, update issue
677
- # Query current labels on the issue
678
- ISSUE_DATA=$(curl -s \
679
- -X POST \
680
- -H "Content-Type: application/json" \
681
- -H "Authorization: $LINEAR_API_KEY" \
682
- "https://api.linear.app/graphql" \
683
- -d '{"query": "query { issues(filter: { identifier: { eq: \"$IDENTIFIER\" } }) { nodes { id labels { nodes { id name } } } } }"}')
684
-
685
- # Filter out plan + build label IDs, then issueUpdate with remaining labelIds
686
- ```
687
-
688
- ### Add brief label
689
-
690
- Ensure the label exists and add it to the ticket. Best-effort — warn on failure, never stop.
691
-
692
- #### GitHub
693
-
694
- ```bash
695
- # Ensure label exists (ignore 422 = already exists)
696
- curl -s \
697
- -H "Authorization: Bearer $GITHUB_TOKEN" \
698
- -H "Accept: application/vnd.github+json" \
699
- -H "X-GitHub-Api-Version: 2022-11-28" \
700
- -H "Content-Type: application/json" \
701
- -X POST \
702
- "https://api.github.com/repos/$GITHUB_REPO/labels" \
703
- -d '{"name": "$CLANCY_LABEL_BRIEF", "color": "0075ca"}'
704
-
705
- # Add label to issue
706
- curl -s \
707
- -H "Authorization: Bearer $GITHUB_TOKEN" \
708
- -H "Accept: application/vnd.github+json" \
709
- -H "X-GitHub-Api-Version: 2022-11-28" \
710
- -H "Content-Type: application/json" \
711
- -X POST \
712
- "https://api.github.com/repos/$GITHUB_REPO/issues/$ISSUE_NUMBER/labels" \
713
- -d '{"labels": ["$CLANCY_LABEL_BRIEF"]}'
714
- ```
715
-
716
- #### Jira
717
-
718
- ```bash
719
- # Jira auto-creates labels — just add to the issue's label array
720
- CURRENT_LABELS=$(curl -s \
721
- -u "$JIRA_USER:$JIRA_API_TOKEN" \
722
- -H "Accept: application/json" \
723
- "$JIRA_BASE_URL/rest/api/3/issue/$TICKET_KEY?fields=labels" | jq -r '.fields.labels')
724
-
725
- UPDATED_LABELS=$(echo "$CURRENT_LABELS" | jq --arg brief "$CLANCY_LABEL_BRIEF" '. + [$brief] | unique')
726
-
727
- curl -s \
728
- -u "$JIRA_USER:$JIRA_API_TOKEN" \
729
- -X PUT \
730
- -H "Content-Type: application/json" \
731
- "$JIRA_BASE_URL/rest/api/3/issue/$TICKET_KEY" \
732
- -d "{\"fields\": {\"labels\": $UPDATED_LABELS}}"
733
- ```
734
-
735
- #### Linear
736
-
737
- ```bash
738
- # Ensure label exists (check team labels, workspace labels, create if missing)
739
- # Then add to issue via issueUpdate with updated labelIds array
740
- curl -s \
741
- -X POST \
742
- -H "Content-Type: application/json" \
743
- -H "Authorization: $LINEAR_API_KEY" \
744
- "https://api.linear.app/graphql" \
745
- -d '{"query": "mutation { issueLabelCreate(input: { teamId: \"$LINEAR_TEAM_ID\", name: \"$CLANCY_LABEL_BRIEF\", color: \"#0075ca\" }) { success issueLabel { id } } }"}'
746
-
747
- # Add label to issue (fetch current labelIds, append new, issueUpdate)
748
- ```
749
-
750
- #### On failure (any platform)
751
-
752
- ```
753
- ⚠️ Could not add pipeline label to {KEY}. The brief was saved and posted successfully — label it manually if needed.
754
- ```
755
-
756
- Continue — do not stop.
757
-
758
- ---
759
-
760
- ## Step 11 — Brief inventory (`--list`)
761
-
762
- If `--list` flag is present, display an inventory of all briefs and stop.
763
-
764
- Scan `.clancy/briefs/` for all `.md` files. For each file:
765
- - Parse date from filename prefix (`YYYY-MM-DD-slug.md`)
766
- - Parse `**Source:**` line
767
- - Parse Status (check for `.approved` marker file)
768
- - Parse ticket count from decomposition table (`?` if unparseable)
769
- - Calculate age (today - date)
770
- - Check stale: unapproved + age > 7 days
771
-
772
- Sort by date (newest first). Display:
773
-
774
- ```
775
- Clancy — Briefs
776
- ================================================================
777
-
778
- [1] dark-mode-support 2026-03-14 Draft 3 tickets Source: #50
779
- [2] customer-portal 2026-03-13 Approved 8 tickets Source: PROJ-200 ✅
780
- [3] real-time-notifications 2026-03-12 Draft 4 tickets Source: ENG-42
781
- [4] auth-rework 2026-03-05 Draft 6 tickets Source: file STALE (9 days)
782
-
783
- 3 unapproved drafts. 1 stale (>7 days).
784
-
785
- To approve: /clancy:approve-brief <slug or index>
786
- To review stale briefs: open the file and add ## Feedback, or delete it.
787
- ```
788
-
789
- If `.clancy/briefs/` does not exist or is empty:
790
- ```
791
- No briefs found. Run /clancy:brief to create one.
792
- ```
793
-
794
- Stop.
795
-
796
- ---
797
-
798
- ## Step 12 — Display
799
-
800
- Print the full brief to stdout, followed by the sign-off:
801
-
802
- ```
803
- "I'm going to need to ask you some questions, and I want them answered immediately."
804
- ```
805
-
806
- ### Next steps (board-sourced)
807
-
808
- ```
809
- ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
810
- Next Steps
811
- ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
812
-
813
- Answer open questions or request changes:
814
- • Comment on {KEY} on your board
815
- • Or add a ## Feedback section to the brief file
816
- Then re-run: /clancy:brief {KEY}
817
-
818
- Approve: /clancy:approve-brief {KEY}
819
- Start over: /clancy:brief --fresh {KEY}
820
- ```
821
-
822
- ### Next steps (inline text / from file)
823
-
824
- ```
825
- ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
826
- Next Steps
827
- ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
828
-
829
- Answer open questions or request changes:
830
- • Add a ## Feedback section to:
831
- .clancy/briefs/{date}-{slug}.md
832
- • Or create a companion file:
833
- .clancy/briefs/{date}-{slug}.feedback.md
834
- Then re-run: /clancy:brief
835
-
836
- Approve: /clancy:approve-brief {slug}
837
- With parent: /clancy:approve-brief {slug} --epic {KEY}
838
- Start over: /clancy:brief --fresh
839
- ```
840
-
841
- ---
842
-
843
- ## Step 13 — Log
844
-
845
- Append to `.clancy/progress.txt`:
846
-
847
- | Outcome | Log entry |
848
- |---|---|
849
- | Brief generated | `YYYY-MM-DD HH:MM \| BRIEF \| {slug} \| {N} proposed tickets` |
850
- | Brief revised (from feedback) | `YYYY-MM-DD HH:MM \| BRIEF \| {slug} \| REVISED - {N} proposed tickets` |
851
- | Brief skipped (not relevant) | `YYYY-MM-DD HH:MM \| BRIEF \| {slug} \| SKIPPED - not relevant ({reason})` |
852
- | Brief skipped (ticket Done) | `YYYY-MM-DD HH:MM \| BRIEF \| {slug} \| SKIPPED - ticket is Done` |
853
- | Brief skipped (not found) | `YYYY-MM-DD HH:MM \| BRIEF \| {slug} \| SKIPPED - ticket not found` |
854
- | Already briefed (no feedback) | (nothing logged) |
855
- | `--list` display | (nothing logged) |
856
- | Auth/network failure | (nothing logged) |
857
-
858
- ---
859
-
860
- ## Step 14 — Batch summary
861
-
862
- After all tickets in a batch are processed, display:
863
-
864
- ```
865
- Briefed {M} of {N} tickets. {K} skipped.
866
-
867
- ✅ [{KEY1}] {Title} — 4 tickets proposed
868
- ✅ [{KEY2}] {Title} — 6 tickets proposed
869
- ⏭️ [{KEY3}] {Title} — already briefed
870
- ⏭️ [{KEY4}] {Title} — not relevant
871
-
872
- Briefs saved to .clancy/briefs/. Run /clancy:approve-brief to create tickets.
873
- ```
874
-
875
- ---
876
-
877
- ## Notes
878
-
879
- - This command does NOT create tickets — it generates briefs only. Ticket creation is `/clancy:approve-brief`.
880
- - Briefs are saved locally in `.clancy/briefs/` and optionally posted as comments on the source ticket.
881
- - The grill phase is the most important part — do not skip or rush it. Zero ambiguity is the goal.
882
- - Re-running without `--fresh` auto-detects feedback: if feedback exists, revises; if no feedback, stops with guidance.
883
- - The `--fresh` flag discards the existing brief entirely and generates a new one from scratch.
884
- - The `--list` flag is an inventory display only — no brief generated, no API calls beyond the local filesystem.
885
- - Batch mode (`/clancy:brief 3`) implies AI-grill — each ticket is briefed autonomously.
886
- - All board API calls are best-effort — if a comment fails to post, print the brief and warn. The local file is the source of truth.
887
- - The `Clancy Strategic Brief` text in comments is the marker used by both `/clancy:brief` (to detect existing briefs and feedback) and `/clancy:approve-brief` (to find the brief). Search case-insensitively and match regardless of heading level (`#`, `##`, or plain text).
888
- - Jira uses ADF for comments (with `codeBlock` fallback). GitHub and Linear accept Markdown directly.
889
- - Linear personal API keys do NOT use `Bearer` prefix.
890
- - Jira uses the new `POST /rest/api/3/search/jql` endpoint (old GET `/search` removed Aug 2025).