1---2name: ase-task-grill3description: Interview the user relentlessly about the task plan until reaching a shared understanding, resolving each branch of the question decision tree. Use when the user wants to stress-test a plan, get grilled on their plan, or mentions "grill me" or "grill plan".4---5
6@${CLAUDE_SKILL_DIR}/../../meta/ase-control.md
7@${CLAUDE_SKILL_DIR}/../../meta/ase-skill.md
8@${CLAUDE_SKILL_DIR}/../../meta/ase-dialog.md
9@${CLAUDE_SKILL_DIR}/../../meta/ase-getopt.md
10
11<skill name="ase-task-grill">
12Iteratively Grill a Task Plan
13</skill>
14
15<expand name="getopt"
16 arg1="ase-task-grill"
17 arg2="--next|-n=(none|DONE|EDIT|IMPLEMENT|PREFLIGHT)... --int-reuse-task">
18 $ARGUMENTS
19</expand>
20
21<objective>
22Interview the user relentlessly about every essential aspect of the
23task plan until reaching a shared understanding.
24</objective>
25
26@${CLAUDE_SKILL_DIR}/../../meta/ase-format-task.md
27
28Procedure
29---------
30
311. **Determine Task:**
32
33 1. Set <id><getopt-arguments/></id> initially.
34 Inherit the always existing <ase-task-id/> from the current context.
35 Inherit the always existing <ase-session-id/> from the current context.
36 Do not output anything.
37
38 2. React on task id:
39
40 1. <if condition="
41 <id/> matches the regexp `^[a-zA-Z][a-zA-Z0-9_-]*$`
42 ">
43 Set <ase-task-id><id/></ase-task-id> (set task id) and
44 call the `ase_task_id(id: "<ase-task-id/>", session:
45 "<ase-session-id/>")` tool from the `ase` MCP server
46 to switch the task, and then only output the following
47 <template/>:
48
49 <template>
50 ⧉ **ASE**: ◉ task: **<ase-task-id/>**, ▶ status: **task given**
51 </template>
52 </if>
53
54 2. <elseif condition="<id/> is NOT empty">
55 The argument is neither empty nor a valid task id. As this
56 skill only accepts an optional `[<id>]` argument and *never*
57 a free-text instruction, only output the following <template/>
58 and then immediately *STOP* processing the entire current skill:
59
60 <template>
61 ⧉ **ASE**: ☻ skill: **ase-task-grill**, ▶ ERROR: expected single `[<id>]` argument
62 </template>
63 </elseif>
64
652. **Determine Task Plan:**
66
67 1. Determine the current task plan content:
68
69 <if condition="
70 <getopt-option-int-reuse-task/> is equal `true`
71 *and* a `ase_task_save(id: '<ase-task-id/>', ...)` tool call
72 exists earlier in the current session
73 ">
74 Set <text/> to the `text` argument of the most recent
75 `ase_task_save(id: '<ase-task-id/>', ...)` tool call,
76 *without* calling `ase_task_load` again. Set <status>plan
77 reused</status>. Do not output anything.
78 </if>
79 <else>
80 Call the `ase_task_load(id: "<ase-task-id/>")` tool of the
81 `ase` MCP server to load the current task plan content and
82 set <text/> to the `text` output field of this `ase_task_load`
83 tool call. Do not output anything related to this MCP tool
84 call. Set <status>plan loaded</status>.
85 </else>
86
87 - If <text/> starts with `ERROR:` or `WARNING:`:
88 Output the following <template/> and then immediately *STOP*
89 processing the entire current skill:
90
91 <template>
92 ⧉ **ASE**: ☻ skill: **ase-task-grill**, ▶ **<text/>**
93 </template>
94
95 - If <text/> starts NOT with `ERROR:` and NOT with `WARNING:`:
96 Set <plan><text/></plan> (set plan to text).
97 Calculate the number of words <words/> of <plan/>.
98 Then output the following <template/>:
99
100 <template>
101 ⧉ **ASE**: ◉ task: **<ase-task-id/>**, ✪ plan: **<words/>** words, ▶ status: **<status/>**
102 </template>
103
104 2. <if condition="<plan/> is empty">
105 Complain and tell the user to use the `ase-code-resolve`,
106 `ase-code-refactor`, `ase-code-craft`, or `ase-task-edit` skills
107 first to create a task plan. Then immediately stop processing
108 this skill.
109 </if>
110
1113. **Iterate Over Task Plan Aspects:**
112
113 Interactively interview the user *relentlessly* about every
114 *essential aspect* of the task plan in <plan/> *until* reaching a
115 shared understanding and no decisions/questions are left open.
116
117 This especially means, you *MUST* clarify as many aspects as
118 necessary to ensure that for at least the most important decisions,
119 during a subsequent implementation, no essential freedom of choices
120 exist any longer.
121
122 For this process, determine the <n/> essential aspects <aspect-N/>
123 (a one or two word long short identifier like `Foo` or `Bar-Baz`)
124 and the corresponding decision/question <question-N/> where a shared
125 understanding is required.
126
127 Honor also the following checks for identifying the problematic
128 aspects:
129
130 - **Fuzzy Language**:
131 When the user uses vague or overloaded terms instead of a precise
132 or canonical term.
133
134 - **Conflicting Terminology**:
135 When the user uses a term that conflicts with the existing
136 terminology in the code base.
137
138 - **Conflicting Code**:
139 When the user states how something works, check whether the
140 current code state really agrees.
141
142 - **Non-Concrete Scenarios**:
143 When domain relationships are being discussed, stress-test them
144 with specific scenarios. Invent scenarios that probe edge cases
145 and force the user to be precise about the boundaries between
146 concepts.
147
148 Then create a decisions/questions tree for them. Walk down each
149 branch of this decision tree, resolving dependencies between
150 decisions one-by-one. Ask the questions <question-N/> and determine
151 corresponding answer <answer-N/>, one at a time.
152
153 1. For each question <question-N/> in the iteration cycle <N/>:
154
155 1. Output the following <template/>:
156
157 <template>
158 <ase-tpl-bullet-signal/> ASPECT <N/>/<n/>: **<aspect-N/>**, QUESTION: **<question-N/>**
159 </template>
160
161 2. Determine the answer alternatives:
162
163 1. Check the <plan/> for the answer <answer-N-1/>.
164
165 2. Check the code base and your world knowledge and
166 use this information to find *up to three* grounded
167 alternative answers <answer-N-K/> (K={2,3,4}), so there
168 are between two and four answer options in total.
169
170 3. In the following, you *MUST* *NOT* use your built-in
171 <user-dialog-tool/> tool! Instead, you *MUST* just show a
172 custom dialog according to the expanded `custom-dialog`
173 definition. You *MUST* closely follow this definition.
174
175 Let the user select the <answer-N/> out of the answer
176 alternatives <answer-N-K/> by raising a question with the
177 following custom dialog, where per alternative <answer-N-K/>
178 you determine a brief label <answer-N-K-label/> and a
179 description <answer-N-K-description/>, and you mark the
180 <answer-N-1/> by prefixing its description with
181 `⚝ **CURRENT PLAN** ⚝ `. Emit only the answer lines for the
182 alternatives <answer-N-K/> you actually determined in the
183 previous step (between two and four lines in total):
184
185 <expand name="custom-dialog" arg1="--other">
186 <aspect-N/>: <question-N/>
187 <answer-N-1-label/>: ⚝ **CURRENT PLAN** ⚝ - <answer-N-1-description/>
188 <answer-N-K-label/>: <answer-N-K-description/>
189 [...]
190 </expand>
191
192 Set <answer-N/> to the selected <result/>.
193
194 4. Output the following <template/>:
195
196 <template>
197 <ase-tpl-bullet-normal/> ASPECT <N/>/<n/>: **<aspect-N/>**, ANSWER: **<answer-N/>**
198 </template>
199
200 2. Finally, update the plan in <plan/> based on all answers <answer-N/>.
201
202 3. <if condition="<plan/> contains '⎈ Created: <text/>'">
203 Set <timestamp-created><text/></timestamp-created> (set
204 timestamp-created to extracted text)
205 </if>
206
207 4. Call the `ase_timestamp(format: "yyyy-LL-dd HH:mm")` tool of the
208 `ase` MCP server and use the `text` field of its response for
209 <timestamp-modified/> information. If <timestamp-created/> is
210 still unset (because the previous <plan/> had no `Created:`
211 line), set <timestamp-created><timestamp-modified/></timestamp-created>
212 (fall back to the modified timestamp). Then insert the current
213 <ase-task-id/>, previous <timestamp-created/>, and refreshed
214 <timestamp-modified/> information and calculate the number of
215 words <words/> of <plan/>.
216
217 5. Call the `ase_task_save(id: "<ase-task-id/>",
218 text: "<plan/>")` of the `ase` MCP server to save the updated
219 task plan content. Do not output anything related to this MCP
220 call.
221
222 6. Only output the following <template/> and continue processing:
223
224 <template>
225 ⧉ **ASE**: ◉ task: **<ase-task-id/>**, ✪ plan: **<words/>** words, ▶ status: **plan updated**
226 </template>
227
2284. **Decide Next Step:**
229
230 1. *Determine next step*:
231
232 - If <getopt-option-next/> is not equal to `none`:
233 Treat <getopt-option-next/> as a comma-separated chronological
234 list of pre-selected next-step tokens. *Split* it on `,`,
235 take the *first* token as <head/>, and store the remaining
236 tokens (joined back with `,`, or `none` if empty) into
237 <getopt-option-next/> so downstream skills can consume the tail.
238
239 - If <head/> matches the regex `^(DONE|EDIT|IMPLEMENT|PREFLIGHT)$`:
240 Honor the pre-selected token.
241 Set <result><head/></result>.
242
243 - else:
244 Only output the following <template/> and then immediately
245 *STOP* processing the entire current skill:
246
247 <template>
248 ⧉ **ASE**: ☻ skill: **ase-task-grill**, ▶ ERROR: invalid `--next` token: **<head/>**
249 </template>
250
251 - If <getopt-option-next/> is equal to `none`:
252
253 In the following, you *MUST* *NOT* use your built-in
254 <user-dialog-tool/> tool! Instead, you *MUST* just show a
255 custom dialog according to the expanded `custom-dialog`
256 definition. You *MUST* closely follow this definition:
257
258 <expand name="custom-dialog" arg1="--no-other">
259 Next Step: How would you like to proceed with the plan?
260 DONE: Stop processing.
261 EDIT: Hand off plan to editing.
262 PREFLIGHT: Hand off plan to pre-flighting.
263 IMPLEMENT: Hand off plan to implementation.
264 </expand>
265
266 2. Check the tool <result/> and dispatch accordingly:
267
268 - If <result/> is `DONE` or `CANCEL`:
269 Only output the following <template/> and then *STOP*,
270 without output of any further information.
271
272 <template>
273 ⧉ **ASE**: ◉ task: **<ase-task-id/>**, ✪ plan: **<words/>** words, ▶ status: **plan updated -- done**
274 </template>
275
276 - If <result/> is `EDIT`:
277 Set <args>--int-reuse-task</args>.
278 <if condition="<getopt-option-next/> is not equal `none`">
279 Set <args><args/> --next <getopt-option-next/></args>
280 </if>
281 Only output the following <template/> and then call the
282 tool `Skill(skill: "ase:ase-task-edit", args: "<args/>")`
283 to invoke the `ase:ase-task-edit` skill in order to *edit*
284 the updated plan. Immediately stop processing the current
285 skill once the `Skill` tool was used.
286
287 <template>
288 ⧉ **ASE**: ◉ task: **<ase-task-id/>**, ✪ plan: **<words/>** words, ▶ status: **plan updated -- hand-off to edit**
289 </template>
290
291 - If <result/> is `PREFLIGHT`:
292 Set <args>--int-reuse-task</args>.
293 <if condition="<getopt-option-next/> is not equal `none`">
294 Set <args><args/> --next <getopt-option-next/></args>
295 </if>
296 Only output the following <template/> and then call the
297 `Skill(skill: "ase:ase-task-preflight", args: "<args/>")` tool
298 to *apply* the plan.
299
300 <template>
301 ⧉ **ASE**: ◉ task: **<ase-task-id/>**, ✪ plan: **<words/>** words, ▶ status: **plan updated -- hand-off to pre-flight**
302 </template>
303
304 - If <result/> is `IMPLEMENT`:
305 Set <args>--int-reuse-task</args>.
306 <if condition="<getopt-option-next/> is not equal `none`">
307 Set <args><args/> --next <getopt-option-next/></args>
308 </if>
309 Only output the following <template/> and then call the
310 `Skill(skill: "ase:ase-task-implement", args: "<args/>")` tool
311 to *apply* the plan.
312
313 <template>
314 ⧉ **ASE**: ◉ task: **<ase-task-id/>**, ✪ plan: **<words/>** words, ▶ status: **plan updated -- hand-off to implementation**
315 </template>