@rse/ase 1.0.6 → 2.0.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 (279) hide show
  1. package/dst/ase-agent-definition-api.d.ts +184 -0
  2. package/dst/ase-agent-definition-api.js +6 -0
  3. package/dst/ase-agent-definition-builtin/condenser.js +42 -0
  4. package/dst/ase-agent-definition-builtin/editor.js +45 -0
  5. package/dst/ase-agent-definition-builtin/estimator.js +98 -0
  6. package/dst/ase-agent-definition-builtin/implementer.js +121 -0
  7. package/dst/ase-agent-definition-builtin/integrator.js +56 -0
  8. package/dst/ase-agent-definition-builtin/qualifier.js +61 -0
  9. package/dst/ase-agent-definition-builtin/rebooter.js +41 -0
  10. package/dst/ase-agent-definition-builtin/researcher.js +77 -0
  11. package/dst/ase-agent-definition-core.js +827 -0
  12. package/dst/ase-agent-fleet.js +772 -0
  13. package/dst/ase-agent-process.js +232 -0
  14. package/dst/ase-agent-relay-client.js +509 -0
  15. package/dst/ase-agent-relay-core.js +213 -0
  16. package/dst/ase-agent-relay-server-bind.js +242 -0
  17. package/dst/ase-agent-relay-server-cli.js +50 -0
  18. package/dst/ase-agent-runtime-claim.js +189 -0
  19. package/dst/ase-agent-runtime-engine.js +1100 -0
  20. package/dst/ase-agent-runtime-exec.js +275 -0
  21. package/dst/ase-agent-runtime-phase.js +581 -0
  22. package/dst/ase-agent-runtime-request.js +272 -0
  23. package/dst/ase-agent-runtime-tool.js +207 -0
  24. package/dst/ase-agent-runtime.js +1316 -0
  25. package/dst/ase-agent.js +65 -0
  26. package/dst/ase-artifact.js +6 -5
  27. package/dst/ase-config-core.js +465 -0
  28. package/dst/ase-config-schema.js +351 -0
  29. package/dst/ase-config-scope.js +172 -0
  30. package/dst/ase-config.js +25 -585
  31. package/dst/ase-hook.js +230 -116
  32. package/dst/ase-lib-daemon-cli.js +130 -0
  33. package/dst/ase-lib-hash.js +20 -0
  34. package/dst/{ase-log.js → ase-lib-log.js} +40 -7
  35. package/dst/ase-lib-server-bind.js +115 -0
  36. package/dst/ase-lib-server-cli.js +474 -0
  37. package/dst/{ase-table.js → ase-lib-table.js} +1 -1
  38. package/dst/{ase-version.js → ase-lib-version.js} +3 -0
  39. package/dst/ase-man.js +96 -0
  40. package/dst/ase-mcp.js +166 -13
  41. package/dst/{ase-getopt.js → ase-service-getopt.js} +82 -80
  42. package/dst/{ase-markdown.js → ase-service-markdown.js} +18 -11
  43. package/dst/ase-service-otel.js +1246 -0
  44. package/dst/{ase-skills.js → ase-service-skills.js} +29 -64
  45. package/dst/ase-service-state.js +101 -0
  46. package/dst/ase-service.js +251 -76
  47. package/dst/ase-setup-common.js +141 -0
  48. package/dst/ase-setup-mcp.js +359 -0
  49. package/dst/ase-setup-settings.js +837 -0
  50. package/dst/ase-setup.js +113 -869
  51. package/dst/ase-spec.js +31 -19
  52. package/dst/ase-statusline.js +108 -43
  53. package/dst/ase-task-board-core.js +739 -0
  54. package/dst/ase-task-board-filter.js +127 -0
  55. package/dst/ase-task-board-flow.js +237 -0
  56. package/dst/ase-task-board-graph.js +497 -0
  57. package/dst/ase-task-board-stats.js +263 -0
  58. package/dst/ase-task-board-tui-control.js +775 -0
  59. package/dst/ase-task-board-tui-model.js +1008 -0
  60. package/dst/ase-task-board-tui-popup.js +626 -0
  61. package/dst/ase-task-board-tui-style.js +106 -0
  62. package/dst/ase-task-board-tui-view.js +847 -0
  63. package/dst/ase-task-board-tui.js +189 -0
  64. package/dst/ase-task-board-web-client.css +1 -0
  65. package/dst/ase-task-board-web-client.html +20 -0
  66. package/dst/ase-task-board-web-client.js +81 -0
  67. package/dst/ase-task-board-web-server.js +823 -0
  68. package/dst/ase-task-board.js +134 -0
  69. package/dst/ase-task-format.js +757 -0
  70. package/dst/ase-task-request.js +208 -0
  71. package/dst/ase-task-store-client.js +495 -0
  72. package/dst/ase-task-store-core.js +804 -0
  73. package/dst/ase-task-store-issues.js +237 -0
  74. package/dst/ase-task-store-plugin-api.js +6 -0
  75. package/dst/ase-task-store-plugin-ase.js +484 -0
  76. package/dst/ase-task-store-plugin-delegate.js +137 -0
  77. package/dst/ase-task-store-plugin-gitea.js +666 -0
  78. package/dst/ase-task-store-plugin-github.js +696 -0
  79. package/dst/ase-task-store-plugin-gitlab.js +668 -0
  80. package/dst/ase-task-store-server-bind.js +538 -0
  81. package/dst/ase-task-store-server-cli.js +154 -0
  82. package/dst/ase-task.js +1335 -357
  83. package/dst/{ase-compat.js → ase-util-compat.js} +2 -2
  84. package/dst/{ase-diagram.js → ase-util-diagram.js} +107 -32
  85. package/dst/{ase-meta.js → ase-util-meta.js} +2 -2
  86. package/dst/{ase-metric.js → ase-util-metric.js} +2 -2
  87. package/dst/{ase-mint.js → ase-util-mint.js} +19 -12
  88. package/dst/{ase-worktree.js → ase-util-worktree.js} +30 -19
  89. package/dst/ase-util.js +20 -0
  90. package/dst/ase.js +108 -32
  91. package/dst/man/ase-agent-adhoc.1 +515 -0
  92. package/dst/man/ase-agent-condenser.1 +193 -0
  93. package/dst/man/ase-agent-editor.1 +212 -0
  94. package/dst/man/ase-agent-estimator.1 +214 -0
  95. package/dst/man/ase-agent-fleet.1 +185 -0
  96. package/dst/man/ase-agent-implementer.1 +233 -0
  97. package/dst/man/ase-agent-integrator.1 +213 -0
  98. package/dst/man/ase-agent-qualifier.1 +214 -0
  99. package/dst/man/ase-agent-rebooter.1 +193 -0
  100. package/dst/man/ase-agent-relay.1 +128 -0
  101. package/dst/man/ase-agent-researcher.1 +217 -0
  102. package/dst/man/ase-agent.1 +264 -0
  103. package/dst/man/ase-artifact-list.1 +38 -0
  104. package/dst/man/ase-artifact-name.1 +39 -0
  105. package/dst/man/ase-artifact.1 +56 -0
  106. package/dst/man/ase-config-delete.1 +45 -0
  107. package/dst/man/ase-config-edit.1 +48 -0
  108. package/dst/man/ase-config-get.1 +46 -0
  109. package/dst/man/ase-config-init.1 +60 -0
  110. package/dst/man/ase-config-list.1 +42 -0
  111. package/dst/man/ase-config-set.1 +52 -0
  112. package/dst/man/ase-config.1 +225 -0
  113. package/dst/man/ase-hook-permission-request.1 +36 -0
  114. package/dst/man/ase-hook-pre-tool-use.1 +59 -0
  115. package/dst/man/ase-hook-session-end.1 +47 -0
  116. package/dst/man/ase-hook-session-persona.1 +37 -0
  117. package/dst/man/ase-hook-session-start.1 +81 -0
  118. package/dst/man/ase-hook-stop.1 +34 -0
  119. package/dst/man/ase-hook-user-prompt-submit.1 +34 -0
  120. package/dst/man/ase-hook.1 +51 -0
  121. package/dst/man/ase-man.1 +67 -0
  122. package/dst/man/ase-mcp.1 +61 -0
  123. package/dst/man/ase-service-log.1 +43 -0
  124. package/dst/man/ase-service-send.1 +47 -0
  125. package/dst/man/ase-service-start.1 +54 -0
  126. package/dst/man/ase-service-status.1 +46 -0
  127. package/dst/man/ase-service-stop.1 +37 -0
  128. package/dst/man/ase-service.1 +85 -0
  129. package/dst/man/ase-setup-disable.1 +44 -0
  130. package/dst/man/ase-setup-enable.1 +45 -0
  131. package/dst/man/ase-setup-install.1 +73 -0
  132. package/dst/man/ase-setup-mcp.1 +124 -0
  133. package/dst/man/ase-setup-status.1 +60 -0
  134. package/dst/man/ase-setup-statusline.1 +92 -0
  135. package/dst/man/ase-setup-telemetry.1 +92 -0
  136. package/dst/man/ase-setup-uninstall.1 +59 -0
  137. package/dst/man/ase-setup-update.1 +64 -0
  138. package/dst/man/ase-setup.1 +93 -0
  139. package/dst/man/ase-spec-export.1 +62 -0
  140. package/dst/man/ase-spec-lint.1 +40 -0
  141. package/dst/man/ase-spec-preview.1 +40 -0
  142. package/dst/man/ase-spec.1 +46 -0
  143. package/dst/man/ase-statusline.1 +189 -0
  144. package/dst/man/ase-task-assign.1 +71 -0
  145. package/dst/man/ase-task-board.1 +384 -0
  146. package/dst/man/ase-task-delete.1 +35 -0
  147. package/dst/man/ase-task-edit.1 +46 -0
  148. package/dst/man/ase-task-idscheme.1 +65 -0
  149. package/dst/man/ase-task-lifecycle.1 +57 -0
  150. package/dst/man/ase-task-list.1 +47 -0
  151. package/dst/man/ase-task-load.1 +36 -0
  152. package/dst/man/ase-task-newid.1 +61 -0
  153. package/dst/man/ase-task-purge.1 +37 -0
  154. package/dst/man/ase-task-rename.1 +44 -0
  155. package/dst/man/ase-task-request.1 +61 -0
  156. package/dst/man/ase-task-save.1 +48 -0
  157. package/dst/man/ase-task-status.1 +55 -0
  158. package/dst/man/ase-task-store.1 +194 -0
  159. package/dst/man/ase-task-view.1 +40 -0
  160. package/dst/man/ase-task.1 +160 -0
  161. package/dst/man/ase-util-compat.1 +25 -0
  162. package/dst/man/ase-util-diagram.1 +76 -0
  163. package/dst/man/ase-util-meta.1 +45 -0
  164. package/dst/man/ase-util-metric.1 +54 -0
  165. package/dst/man/ase-util-mint.1 +59 -0
  166. package/dst/man/ase-util-worktree.1 +72 -0
  167. package/dst/man/ase-util.1 +50 -0
  168. package/dst/man/ase.1 +124 -0
  169. package/package.json +79 -21
  170. package/plugin/.claude-plugin/plugin.json +1 -1
  171. package/plugin/.codex-plugin/plugin.json +1 -1
  172. package/plugin/.github/plugin/plugin.json +1 -1
  173. package/plugin/agents/ase-meta-diagram.md +12 -8
  174. package/plugin/agents/ase-repo-review.md +322 -0
  175. package/plugin/hooks/hooks-codex.json +5 -0
  176. package/plugin/hooks/hooks-copilot.json +5 -0
  177. package/plugin/hooks/hooks.json +8 -0
  178. package/plugin/meta/ase-common-approach.md +117 -0
  179. package/plugin/meta/ase-common-changeset.md +256 -0
  180. package/plugin/meta/ase-common-code.md +10 -173
  181. package/plugin/meta/ase-common-grill.md +317 -0
  182. package/plugin/meta/ase-common-resolve.md +305 -0
  183. package/plugin/meta/ase-common-task.md +83 -4
  184. package/plugin/meta/ase-constitution.md +0 -2
  185. package/plugin/meta/ase-format-specbook.md +208 -25
  186. package/plugin/meta/ase-format-specbook.yaml +242 -851
  187. package/plugin/meta/ase-format-task.md +669 -125
  188. package/plugin/meta/ase-persona.md +3 -4
  189. package/plugin/meta/ase-skill.md +9 -0
  190. package/plugin/mods/ase-mods.ts +409 -0
  191. package/plugin/mods/claude-code.d.ts +13417 -0
  192. package/plugin/skills/ase-arch-analyze/SKILL.md +1 -1
  193. package/plugin/skills/ase-arch-analyze/help.md +2 -2
  194. package/plugin/skills/ase-code-analyze/SKILL.md +59 -8
  195. package/plugin/skills/ase-code-analyze/help.md +29 -4
  196. package/plugin/skills/ase-code-edit/SKILL.md +107 -181
  197. package/plugin/skills/ase-code-edit/help.md +118 -31
  198. package/plugin/skills/ase-code-lint/SKILL.md +64 -13
  199. package/plugin/skills/ase-code-lint/help.md +32 -2
  200. package/plugin/skills/ase-docs-proofread/SKILL.md +4 -4
  201. package/plugin/skills/ase-docs-proofread/help.md +1 -1
  202. package/plugin/skills/ase-docs-refine/SKILL.md +4 -4
  203. package/plugin/skills/ase-docs-shorten/SKILL.md +4 -4
  204. package/plugin/skills/ase-help-intent/data.md +2164 -1087
  205. package/plugin/skills/ase-help-intent/help.md +1 -1
  206. package/plugin/skills/ase-help-skill/catalog.md +12 -9
  207. package/plugin/skills/ase-meta-brainstorm/SKILL.md +1 -1
  208. package/plugin/skills/ase-meta-config/SKILL.md +3 -4
  209. package/plugin/skills/ase-meta-config/help.md +31 -10
  210. package/plugin/skills/ase-meta-mint/SKILL.md +5 -5
  211. package/plugin/skills/ase-meta-mint/help.md +10 -5
  212. package/plugin/skills/ase-meta-why/help.md +1 -1
  213. package/plugin/skills/ase-meta-workflow/SKILL.md +7 -7
  214. package/plugin/skills/ase-meta-workflow/help.md +4 -4
  215. package/plugin/skills/ase-meta-workflow/sample.md +3 -3
  216. package/plugin/skills/ase-meta-workflow/workflow.txt +22 -18
  217. package/plugin/skills/{ase-meta-changelog → ase-repo-changelog}/SKILL.md +4 -3
  218. package/plugin/skills/{ase-meta-changelog → ase-repo-changelog}/help.md +5 -5
  219. package/plugin/skills/{ase-meta-commit → ase-repo-commit}/SKILL.md +6 -6
  220. package/plugin/skills/{ase-meta-commit → ase-repo-commit}/help.md +5 -5
  221. package/plugin/skills/{ase-meta-diff → ase-repo-diff}/SKILL.md +6 -6
  222. package/plugin/skills/{ase-meta-diff → ase-repo-diff}/help.md +8 -8
  223. package/plugin/skills/{ase-code-dissect → ase-repo-dissect}/SKILL.md +19 -19
  224. package/plugin/skills/{ase-code-dissect → ase-repo-dissect}/help.md +10 -12
  225. package/plugin/skills/ase-repo-merge/SKILL.md +346 -0
  226. package/plugin/skills/ase-repo-merge/help.md +107 -0
  227. package/plugin/skills/ase-repo-resolve/SKILL.md +158 -0
  228. package/plugin/skills/ase-repo-resolve/help.md +102 -0
  229. package/plugin/skills/ase-repo-review/SKILL.md +406 -0
  230. package/plugin/skills/ase-repo-review/help.md +181 -0
  231. package/plugin/skills/ase-spec-edit/SKILL.md +117 -183
  232. package/plugin/skills/ase-spec-edit/help.md +107 -26
  233. package/plugin/skills/ase-sync-reconcile/help.md +1 -1
  234. package/plugin/skills/ase-task-assign/SKILL.md +111 -0
  235. package/plugin/skills/ase-task-assign/help.md +119 -0
  236. package/plugin/skills/ase-task-condense/SKILL.md +21 -21
  237. package/plugin/skills/ase-task-condense/help.md +12 -10
  238. package/plugin/skills/ase-task-delete/SKILL.md +1 -1
  239. package/plugin/skills/ase-task-dissect/SKILL.md +71 -48
  240. package/plugin/skills/ase-task-dissect/help.md +10 -9
  241. package/plugin/skills/ase-task-edit/SKILL.md +379 -94
  242. package/plugin/skills/ase-task-edit/help.md +95 -22
  243. package/plugin/skills/ase-task-estimate/SKILL.md +492 -0
  244. package/plugin/skills/ase-task-estimate/help.md +158 -0
  245. package/plugin/skills/ase-task-grill/SKILL.md +246 -138
  246. package/plugin/skills/ase-task-grill/help.md +129 -26
  247. package/plugin/skills/ase-task-id/SKILL.md +8 -1
  248. package/plugin/skills/ase-task-id/help.md +6 -3
  249. package/plugin/skills/ase-task-implement/SKILL.md +535 -145
  250. package/plugin/skills/ase-task-implement/help.md +138 -47
  251. package/plugin/skills/ase-task-integrate/SKILL.md +549 -0
  252. package/plugin/skills/ase-task-integrate/help.md +187 -0
  253. package/plugin/skills/ase-task-list/SKILL.md +55 -23
  254. package/plugin/skills/ase-task-list/help.md +45 -21
  255. package/plugin/skills/ase-task-reboot/SKILL.md +84 -43
  256. package/plugin/skills/ase-task-reboot/help.md +28 -8
  257. package/plugin/skills/ase-task-rename/SKILL.md +10 -2
  258. package/plugin/skills/ase-task-research/SKILL.md +386 -0
  259. package/plugin/skills/ase-task-research/help.md +102 -0
  260. package/plugin/skills/ase-task-status/SKILL.md +137 -0
  261. package/plugin/skills/ase-task-status/help.md +80 -0
  262. package/plugin/skills/ase-task-view/SKILL.md +49 -24
  263. package/plugin/skills/ase-task-view/help.md +19 -9
  264. package/plugin/agents/ase-meta-review.md +0 -187
  265. package/plugin/skills/ase-code-craft/SKILL.md +0 -264
  266. package/plugin/skills/ase-code-craft/help.md +0 -122
  267. package/plugin/skills/ase-code-refactor/SKILL.md +0 -232
  268. package/plugin/skills/ase-code-refactor/help.md +0 -109
  269. package/plugin/skills/ase-code-resolve/SKILL.md +0 -289
  270. package/plugin/skills/ase-code-resolve/help.md +0 -116
  271. package/plugin/skills/ase-meta-review/SKILL.md +0 -210
  272. package/plugin/skills/ase-meta-review/help.md +0 -96
  273. package/plugin/skills/ase-task-preflight/SKILL.md +0 -166
  274. package/plugin/skills/ase-task-preflight/help.md +0 -82
  275. /package/dst/{ase-ignore.js → ase-lib-ignore.js} +0 -0
  276. /package/dst/{ase-stdio.js → ase-lib-stdio.js} +0 -0
  277. /package/dst/{ase-kv.js → ase-service-kv.js} +0 -0
  278. /package/dst/{ase-sleep.js → ase-service-sleep.js} +0 -0
  279. /package/dst/{ase-timestamp.js → ase-service-timestamp.js} +0 -0
@@ -1,10 +1,11 @@
1
1
  ---
2
2
  name: ase-task-implement
3
- argument-hint: "[--help|-h] [--next|-n <option>[,...]] [--worktree|-w] [<id>]"
3
+ argument-hint: "[--help|-h] [--next|-n <option>[,...]] [--worktree|-w <name>] [--source|-s <source>] [--changeset|-c <changeset>] [--draft|-d] [--stateless|-S] [<id>]"
4
4
  description: >
5
- Implement current or given task plan.
6
- Use when the user calls to "implement", "realize" or "apply" the
7
- "task", "plan", "spec", or "specification".
5
+ Implement current or given task plan, optionally as an implementation
6
+ draft attachment only. Use when the user calls to "implement", "realize",
7
+ "draft", "dry-run", or "test-drive" the "task", "plan", "spec", or
8
+ "specification".
8
9
  user-invocable: true
9
10
  disable-model-invocation: false
10
11
  effort: xhigh
@@ -21,19 +22,20 @@ Implement a Task Plan
21
22
 
22
23
  <expand name="getopt"
23
24
  arg1="ase-task-implement"
24
- arg2="--next|-n=(none|DONE|DELETE)... --worktree|-w --int-reuse-task">
25
+ arg2="--next|-n=(none|DONE|EDIT|INTEGRATE|DELETE)... --worktree|-w= --source|-s= --changeset|-c= --draft|-d --stateless|-S --int-reuse-task">
25
26
  $ARGUMENTS
26
27
  </expand>
27
28
 
28
29
  <objective>
29
- *Implement* the task plan by modifying the *artifacts*
30
- with a corresponding, complete *change set*.
30
+ *Implement* the task plan by creating a corresponding, complete
31
+ *change set* from its *source* into its *changeset* location.
31
32
  </objective>
32
33
 
33
34
  @${CLAUDE_SKILL_DIR}/../../meta/ase-format-task.md
34
35
  @${CLAUDE_SKILL_DIR}/../../meta/ase-common-task.md
35
36
  @${CLAUDE_SKILL_DIR}/../../meta/ase-tenets.md
36
37
  @${CLAUDE_SKILL_DIR}/../../meta/ase-common-code.md
38
+ @${CLAUDE_SKILL_DIR}/../../meta/ase-common-changeset.md
37
39
 
38
40
  Procedure
39
41
  ---------
@@ -50,6 +52,20 @@ Procedure
50
52
 
51
53
  <expand name="task-react-id" arg1="ase-task-implement"></expand>
52
54
 
55
+ 3. Resolve the draft shorthand: if <getopt-option-draft/> is `true`
56
+ and <getopt-option-changeset/> is not empty, only output the
57
+ following <template/> and then immediately *STOP* processing the
58
+ entire current skill:
59
+
60
+ <template>
61
+ ⧉ **ASE**: ◉ task: **<ase-task-id/>**, ▶ ERROR: options `--draft` and `--changeset` are mutually exclusive
62
+ </template>
63
+
64
+ Otherwise, if <getopt-option-draft/> is `true`, set
65
+ <getopt-option-changeset>attachment:draft</getopt-option-changeset>,
66
+ so the change set lands as the *implementation draft* in the
67
+ attachment `draft` of the plan only. Do not output anything.
68
+
53
69
  2. **Determine Operation:**
54
70
 
55
71
  1. Determine the current task plan content:
@@ -57,142 +73,368 @@ Procedure
57
73
  <expand name="task-load-content"></expand>
58
74
 
59
75
  2. If the <task-content/> is still empty, complain and tell the user to
60
- use the `ase-code-resolve`, `ase-code-refactor`, `ase-code-craft`,
61
- or `ase-task-edit` skills first to create a task plan. Then
76
+ use the `ase-task-edit` skill first to create a task plan. Then
62
77
  immediately stop processing this skill.
63
78
 
64
79
  3. Internalize the tenets stated by the plan:
65
80
 
66
81
  <expand name="code-tenets-from-plan"></expand>
67
82
 
68
- 3. **Prepare WorkTree:**
69
-
70
- <if condition="<getopt-option-worktree/> is not equal `true`">
71
- No worktree was requested, so the implementation is applied directly
72
- to the *current* working copy. Set <worktree-dir></worktree-dir>
73
- (empty) and *skip* all remaining sub-steps of this step. Do not
74
- output anything.
75
- </if>
76
-
77
- 1. Set <worktree-name><ase-task-id/></worktree-name>. The worktree
78
- is *never* named by its own option value: it always carries the
79
- unique *task id*, so the worktree directory and its branch stay
80
- unambiguously tied to the very task plan implemented in them.
81
- The task id is a plain identifier by construction, hence it is
82
- directly usable as both a directory and a branch name. Do not
83
- output anything.
84
-
85
- 2. Determine the *worktree directory* by calling the
86
- `ase_worktree_path(id: "<worktree-name/>", create: true)` tool of
87
- the `ase` MCP server and capturing its output into
88
- <worktree-dir/>.
89
-
90
- You *MUST* *NEVER* assemble this path yourself, as only this tool
91
- rejects a path leading through a symbolic link, through a
92
- non-directory, or out of the repository -- a path `git worktree
93
- add` would otherwise silently follow and thereby write outside
94
- the repository.
95
-
96
- <if condition="this tool call fails">
97
- Either the current directory is not a Git repository or the
98
- worktree directory is unsafe, so no worktree can be created. Only
99
- output the following <template/> and then immediately *STOP*
100
- processing the entire current skill, leaving the working copy
101
- *untouched*:
102
-
103
- <template>
104
- ⧉ **ASE**: ☻ skill: **ase-task-implement**, ▶ ERROR: no Git repository or unsafe worktree directory -- cannot create worktree
105
- </template>
106
- </if>
107
-
108
- 3. Determine the *existing worktrees* and *existing branches* by
109
- running the corresponding commands (taken exactly as given) and
110
- capturing their outputs:
111
-
112
- `git worktree list --porcelain`
113
-
114
- `git branch --list`
115
-
116
- <if condition="the worktree directory <worktree-dir/> or the branch <worktree-name/> already exists">
117
- Only output the following <template/> and then immediately *STOP*
118
- processing the entire current skill, leaving the existing
119
- worktree, its branch, and the working copy *untouched*:
83
+ 3. **Prepare Source and Changeset:**
84
+
85
+ The *source* (code basis) and the *changeset* (location of the
86
+ change set) are controlled by the `Source:` and `Changeset:`
87
+ frontmatter keys of the plan, which the `--source` and
88
+ `--changeset` options override *ad-hoc* without changing the plan.
89
+ The `worktree` value of the source refers to the *origin working
90
+ copy* the skill was started in, the `worktree` value of the
91
+ changeset to the *context worktree*, selected by the `--worktree`
92
+ option (both are the same without `--worktree`). A context worktree
93
+ created by `--worktree` carries its *own* branch, which starts at
94
+ the source, so the source branch itself is never checked out there
95
+ and stays available as the integration target.
96
+
97
+ 1. Set <task-source/> to <getopt-option-source/> if it is not
98
+ empty, otherwise to the value of the `Source:` frontmatter key
99
+ of <task-content/>, or to the configured default
100
+ <ase-project-task-default-source/> if the key is absent, and
101
+ parse it:
102
+
103
+ <expand name="changeset-value"
104
+ arg1="Source"
105
+ arg2="<task-source/>"
106
+ arg3="`worktree`, `branch`"
107
+ arg4="◉ task: **<ase-task-id/>**"></expand>
108
+
109
+ Set <source-type><value-type/></source-type> and
110
+ <source-name><value-name/></source-name>.
111
+
112
+ 2. Set <task-changeset/> to <getopt-option-changeset/> if it is not
113
+ empty, otherwise to the value of the `Changeset:` frontmatter key
114
+ of <task-content/>, or to the configured default
115
+ <ase-project-task-default-changeset/> if the key is absent, and
116
+ parse it:
117
+
118
+ <expand name="changeset-value"
119
+ arg1="Changeset"
120
+ arg2="<task-changeset/>"
121
+ arg3="`worktree`, `branch`, `attachment`"
122
+ arg4="◉ task: **<ase-task-id/>**"></expand>
123
+
124
+ Set <changeset-type><value-type/></changeset-type> and
125
+ <changeset-name><value-name/></changeset-name>.
126
+
127
+ <if condition="<task-changeset/> is not `attachment:draft` and the backmatter of <task-content/> contains an attachment block with the `Type` key value `text/x-diff; charset=utf-8; kind="draft"`, whose `Desc` key carries no `merged <commit/>` value">
128
+ The plan carries an undelivered *implementation draft*, which
129
+ only an `attachment:draft` changeset builds upon, so this run
130
+ *ignores* it and implements the plan from scratch into
131
+ <task-changeset/>. Only output the following <template/>,
132
+ directly followed by the hint, and then *continue* processing:
120
133
 
121
134
  <template>
122
- ⧉ **ASE**: ◉ task: **<ase-task-id/>**, ▶ ERROR: worktree or branch **<worktree-name/>** already exists
135
+ ⧉ **ASE**: ◉ task: **<ase-task-id/>**, ▶ WARNING: implementation draft attachment is **ignored** for changeset **<task-changeset/>**
123
136
  </template>
124
137
 
125
- Directly *after* this error <template/>, and *before* stopping,
126
- give the corrective hint by expanding the following (which,
127
- depending on the configured <ase-guidance-level/>, may expand
128
- into nothing and hence emit no output at all):
129
-
130
138
  <ase-tpl-hint level="minimal">
131
- Remove the existing worktree via `git worktree remove` and `git branch -d`, or rename the task via `/ase-task-rename` to implement it under a still unused worktree name.
139
+ Use `/ase-task-implement --draft` to build upon the draft, or `/ase-task-integrate --draft` to deliver it.
132
140
  </ase-tpl-hint>
133
141
  </if>
134
142
 
135
- 4. Create the worktree by running the corresponding command (taken
136
- exactly as given), which creates the directory *and* -- named
137
- after its last path component -- the branch <worktree-name/> from
138
- `HEAD`. The `.ase` directory is usually git-ignored, so the
139
- worktree itself never shows up as a change:
143
+ 3. Determine the *source commit* <source-commit/>: if
144
+ <source-type/> is `worktree`, capture the output of the command
145
+ `git rev-parse HEAD` (the skill runs inside the origin working
146
+ copy); if it is `branch`, capture the output of the command
147
+ `git rev-parse --verify --quiet "refs/heads/<source-name/>"`.
148
+ If the command fails, only output the following <template/> and
149
+ then immediately *STOP* processing the entire current skill,
150
+ leaving the working copy *untouched* (so a bad source never
151
+ leaves a context worktree behind):
140
152
 
141
- `git worktree add "<worktree-dir/>"`
153
+ <template>
154
+ ⧉ **ASE**: ◉ task: **<ase-task-id/>**, ▶ ERROR: source **<task-source/>** does not exist
155
+ </template>
142
156
 
143
- <if condition="this command fails">
144
- Only output the following <template/> and then immediately *STOP*
145
- processing the entire current skill, leaving the working copy
146
- *untouched*:
157
+ 4. <if condition="<getopt-option-worktree/> is not empty and <changeset-type/> is not `worktree`">
158
+ The context worktree serves the `worktree` changeset only, so a
159
+ `branch:` or `attachment:` changeset would leave it unused (e.g.
160
+ on a mistyped option). Only output the following <template/> and
161
+ then immediately *STOP* processing the entire current skill,
162
+ leaving the working copy *untouched*:
147
163
 
148
164
  <template>
149
- ⧉ **ASE**: ◉ task: **<ase-task-id/>**, ▶ ERROR: worktree **<worktree-name/>** failed to create
165
+ ⧉ **ASE**: ◉ task: **<ase-task-id/>**, ▶ ERROR: option `--worktree` requires a `worktree` changeset (got **<task-changeset/>**)
150
166
  </template>
151
167
  </if>
152
168
 
153
- 5. Only output the following <template/>:
169
+ Otherwise, prepare the context worktree, whose own branch -- if
170
+ created together with it -- starts at <source-commit/>:
171
+
172
+ <expand name="changeset-context"
173
+ arg1="<getopt-option-worktree/>"
174
+ arg2="◉ task: **<ase-task-id/>**"
175
+ arg3="false"
176
+ arg4="true"
177
+ arg5="<source-commit/>"></expand>
178
+
179
+ 5. Determine the *work directory* <work-dir/> -- the worktree in
180
+ which the implementation happens -- according to <changeset-type/>:
181
+
182
+ - `worktree`: The change set stays *uncommitted* in the context
183
+ worktree, so set <work-dir><context-dir/></work-dir>.
184
+
185
+ - <if condition="<context-dir/> differs from <origin-dir/>">
186
+ The context worktree carries its *own* branch: a freshly
187
+ created one already starts at <source-commit/>, while a
188
+ reused one keeps its own base, so earlier work in it is
189
+ *continued*. The source branch is *never* checked out in
190
+ the context worktree (it may be checked out in the origin
191
+ working copy, and it is the integration target of
192
+ `Target: source`), so nothing is switched. Do not output
193
+ anything.
194
+ </if>
195
+
196
+ - <elseif condition="<source-type/> is `branch` and the branch checked out in <origin-dir/> (according to the command `git branch --show-current`) differs from <source-name/>">
197
+ The origin working copy is *switched* to <source-name/>
198
+ in place: if the command `git status --porcelain` reports
199
+ any output, switching would drag the uncommitted changes
200
+ onto the other branch, so only output the following
201
+ <template/>, directly followed by the hint, and then
202
+ immediately *STOP* processing the entire current skill,
203
+ leaving the working copy *untouched*:
204
+
205
+ <template>
206
+ ⧉ **ASE**: ◉ task: **<ase-task-id/>**, ▶ ERROR: working copy has uncommitted changes -- cannot switch to branch **<source-name/>** in place
207
+ </template>
208
+
209
+ <ase-tpl-hint level="minimal">
210
+ Commit or stash the uncommitted changes first, or use `--worktree <name>` to implement inside an isolated worktree instead.
211
+ </ase-tpl-hint>
212
+
213
+ Otherwise, run the command
214
+ `git switch "<source-name/>"`, and, if it fails (e.g.
215
+ because the branch is checked out in another worktree),
216
+ only output the following <template/> and then
217
+ immediately *STOP* processing the entire current skill:
218
+
219
+ <template>
220
+ ⧉ **ASE**: ◉ task: **<ase-task-id/>**, ▶ ERROR: branch **<source-name/>** failed to switch
221
+ </template>
222
+
223
+ Otherwise, only output the following <template/>:
224
+
225
+ <template>
226
+ ⧉ **ASE**: ◉ task: **<ase-task-id/>**, ⎇ branch: **<source-name/>**, ▶ status: **branch switched**
227
+ </template>
228
+ </elseif>
229
+
230
+ - `branch`: The change set is *committed* onto the branch
231
+ <changeset-name/> inside a worktree carrying this branch.
232
+ Determine the *existing worktrees* by running the command
233
+ `git worktree list --porcelain` (taken exactly as given).
234
+
235
+ - If the branch <changeset-name/> is checked out in a
236
+ registered worktree, set <work-dir/> to its directory and
237
+ <work-label/> to its path. If the command
238
+ `git -C "<work-dir/>" status --porcelain` reports any
239
+ output, the change set could not be committed separately,
240
+ so only output the following <template/> and then
241
+ immediately *STOP* processing the entire current skill:
242
+
243
+ <template>
244
+ ⧉ **ASE**: ◉ task: **<ase-task-id/>**, ▶ ERROR: worktree **<work-label/>** of branch **<changeset-name/>** has uncommitted changes
245
+ </template>
246
+
247
+ - Otherwise, set <work-id/> to <changeset-name/> with every
248
+ character other than `A-Z`, `a-z`, `0-9`, `_`, and `-`
249
+ replaced by `-`, then every run of multiple `-` reduced
250
+ to a single `-`, and finally all leading and trailing `-`
251
+ and `_` removed (e.g., `feature-x` for `feature/-x`),
252
+ determine <work-dir/> by calling the
253
+ `ase_worktree_path(id: "<work-id/>", create: true)` tool of
254
+ the `ase` MCP server (you *MUST* *NEVER* assemble this
255
+ path yourself), and set
256
+ <work-label>.ase/worktree/<work-id/></work-label>. If
257
+ this tool call fails or the directory <work-dir/> already
258
+ exists, only output the following <template/> and then
259
+ immediately *STOP* processing the entire current skill:
260
+
261
+ <template>
262
+ ⧉ **ASE**: ◉ task: **<ase-task-id/>**, ▶ ERROR: worktree **<work-id/>** for branch **<changeset-name/>** cannot be created
263
+ </template>
264
+
265
+ If the branch <changeset-name/> exists according to
266
+ `git branch --list`, create the worktree by running the
267
+ command `git worktree add "<work-dir/>" "<changeset-name/>"`,
268
+ otherwise create the branch from the source together with
269
+ the worktree by running the command
270
+ `git worktree add -b "<changeset-name/>" "<work-dir/>" "<source-commit/>"`
271
+ (each taken exactly as given). If the command fails, only
272
+ output the same error <template/> as above and then
273
+ immediately *STOP* processing the entire current skill.
274
+ Otherwise, only output the following <template/>:
275
+
276
+ <template>
277
+ ⧉ **ASE**: ◉ task: **<ase-task-id/>**, ◉ worktree: **<work-label/>**, ⎇ branch: **<changeset-name/>**, ▶ status: **worktree created**
278
+ </template>
279
+
280
+ - `attachment`: The change set is made and verified in a
281
+ *temporary* worktree, detached at <source-commit/>, and
282
+ afterwards stored as an attachment of the plan only, leaving
283
+ all artifacts untouched.
284
+
285
+ 1. <if condition="the backmatter of <task-content/> contains an attachment block with the `Type` key value `text/x-diff; charset=utf-8; kind="<changeset-name/>"`, whose `Desc` key carries no `merged <commit/>` value, and which is *stale* according to the plan <format/> (its `Modified` key is absent or older than the `Modified` key of the frontmatter)">
286
+ The change set of a *previous* run was created for an
287
+ *earlier* version of the plan, so building on it would
288
+ silently carry over changes the plan no longer asks for,
289
+ and dropping it would leave its `[x]` and `[/]`
290
+ bullet-points unrealized. Only output the following
291
+ <template/>, directly followed by the hint, and then
292
+ immediately *STOP* processing the entire current skill,
293
+ leaving the plan and the artifacts *untouched*:
294
+
295
+ <template>
296
+ ⧉ **ASE**: ◉ task: **<ase-task-id/>**, ▶ ERROR: change set attachment **<changeset-name/>** is **stale** (older than the plan)
297
+ </template>
298
+
299
+ <ase-tpl-hint level="minimal">
300
+ Remove the attachment and reset the `[x]` and `[/]` checkboxes of the plan, then run `/ase-task-implement --changeset <task-changeset/>` again.
301
+ </ase-tpl-hint>
302
+ </if>
303
+
304
+ 2. Set <work-hash/> to the first 8 characters of the output
305
+ of the `ase_mint(type: "sha1", hint:
306
+ "<ase-task-id/>:<changeset-name/>:implement")` tool of the
307
+ `ase` MCP server, which keeps <work-id/> *unique* per task
308
+ and attachment. Set <work-id/> to <ase-task-id/> with all
309
+ characters other than `A-Z`, `a-z`, `0-9`, `_`, and `-`
310
+ stripped, followed by
311
+ `-<changeset-name/>-implement-<work-hash/>`, and
312
+ determine <work-dir/> by calling the
313
+ `ase_worktree_path(id: "<work-id/>", temp: true, create:
314
+ true)` tool of the `ase` MCP server, which places it into
315
+ the namespace of the *temporary* worktrees, disjoint from
316
+ all other worktrees. You *MUST* *NEVER* assemble this path
317
+ yourself.
318
+
319
+ 3. <if condition="<work-dir/> exists">
320
+ If <work-dir/> is a worktree registered according to
321
+ `git worktree list --porcelain` and its record carries a
322
+ `detached` line, it is the *leftover* of an earlier run
323
+ which stopped before its cleanup, and its partial state
324
+ must *not* be reused: remove it by running the commands
325
+ `git worktree remove --force "<work-dir/>"` and
326
+ `git worktree prune` (taken exactly as given), ignoring
327
+ any failure. Otherwise, it is *not* owned by this skill,
328
+ so only output the following <template/> and then
329
+ immediately *STOP* processing the entire current skill,
330
+ leaving <work-dir/> and the task plan *untouched*:
331
+
332
+ <template>
333
+ ⧉ **ASE**: ◉ task: **<ase-task-id/>**, ▶ ERROR: directory **<work-id/>** for attachment **<changeset-name/>** exists, but is no temporary worktree
334
+ </template>
335
+ </if>
336
+
337
+ 4. Create the worktree by running the command
338
+ `git worktree add --detach "<work-dir/>" "<source-commit/>"`
339
+ (taken exactly as given). As it starts at the source
340
+ commit, *uncommitted* changes of the source are *not*
341
+ carried over.
342
+
343
+ 5. <if condition="the backmatter of <task-content/> contains an attachment block with the `Type` key value `text/x-diff; charset=utf-8; kind="<changeset-name/>"`, whose `Desc` key carries no `merged <commit/>` value">
344
+ This block carries the change set of a *previous* run,
345
+ which realized the `[x]` and `[/]` bullet-points. A block
346
+ whose `Desc` key carries a `merged <commit/>` value was
347
+ already *delivered* by `ase-task-integrate`, so it is *not*
348
+ re-applied, and the change set of this run starts afresh
349
+ at the source commit and replaces it below. As its `Data`
350
+ payload is *elided* in <task-content/>, fetch it via the
351
+ `ase_task_attachment(id: "<ase-task-id/>", type: "text/x-diff;
352
+ charset=utf-8; kind=\"<changeset-name/>\"")` tool of the `ase`
353
+ MCP server, whose `text` output field is the payload
354
+ *verbatim* (without any indentation). Re-establish
355
+ it in the worktree by applying this payload *verbatim*, e.g. via
356
+ `git -C "<work-dir/>" apply --3way`, and re-apply hunks
357
+ which no longer apply to a meanwhile drifted source
358
+ manually. The change set of this run is built *on top* of
359
+ it, so the change set captured below is *cumulative*.
360
+ </if>
361
+
362
+ If any of these sub-steps fails, remove the worktree as above
363
+ (if created by sub-step 4), only output the following
364
+ <template/>, and then immediately *STOP* processing the
365
+ entire current skill, leaving the task plan *untouched*:
154
366
 
155
- <template>
156
- ⧉ **ASE**: ◉ task: **<ase-task-id/>**, ◉ worktree: **.ase/worktree/<worktree-name/>**, ▶ status: **worktree created**
157
- </template>
367
+ <template>
368
+ ⧉ **ASE**: ◉ task: **<ase-task-id/>**, ▶ ERROR: temporary worktree for attachment **<changeset-name/>** cannot be prepared
369
+ </template>
158
370
 
159
371
  4. **Create Implementation:**
160
372
 
161
- 1. Perform a *final implementation* of the task plan
162
- by modifying the *artifacts* with a corresponding, complete
163
- *change set*.
164
-
165
- <if condition="<task-content/> contains an `## IMPLEMENTATION DRAFT` section (from skill `ase-task-preflight`)">
166
- Take over the implementation draft of this section *1:1* as
167
- the change set: the draft is assumed to have been *reviewed*
168
- by the user, so you *MUST* *NOT* create a fresh implementation
169
- from scratch. Apply the draft *verbatim* and *adjust* only
170
- those parts which actually *fail* -- because a hunk no longer
171
- applies to meanwhile drifted artifacts, or because the
172
- verification phase rejects the result. For such adjusted parts,
173
- and for aspects the draft does not cover at all, follow the
174
- task plan in <task-content/>.
373
+ 1. <if condition="<getopt-option-stateless/> is not equal `true` and <ase-project-task-lifecycle/> is `team` or `enterprise`">
374
+ Mark the plan as being implemented: set the `Status:` key of
375
+ <task-content/> to `IMPLEMENTING` (*creating* the key at its
376
+ position in the key order of the plan <format/> if absent), but
377
+ *only* if `IMPLEMENTING` is reachable from the current state
378
+ along the transitions of the task lifecycle model (for the
379
+ `team` model from `PLANNING` or `STALLED`, for the `enterprise`
380
+ model from `DRAFTED` via `PLANNING` and `PLANNED`, or from
381
+ `PLANNED` or `STALLED`), and persist this frontmatter-only change
382
+ -- without refreshing the `Modified:` key -- by taking over the
383
+ stored `Effort:` key and calling the `ase_task_save` tool of the
384
+ `ase` MCP server *exactly* as described for the final save in
385
+ sub-step 5 below. Do not output anything.
175
386
  </if>
176
387
 
177
- <if condition="<task-content/> contains NO `## IMPLEMENTATION DRAFT` section">
178
- Follow and honor the task plan in <task-content/>.
388
+ 2. Perform a *final implementation* of the task plan inside
389
+ <work-dir/> by modifying the *artifacts* with a corresponding,
390
+ complete *change set*, following and honoring the task plan in
391
+ <task-content/>:
392
+
393
+ <expand name="changeset-land" arg1="<work-dir/>"></expand>
394
+
395
+ <if condition="<task-kind/> is `SPECIFYING`, or the task plan otherwise creates, revises, or removes statements of `SPEC` artifacts">
396
+ <expand name="task-spec-format"/>
397
+
398
+ Keep every changed `SPEC` artifact conformant to the `SPEC`
399
+ format (structure, object kinds, properties, ids, `[[xxx]]`
400
+ references, and the `Modified:` timestamp rule). Read the
401
+ **SpecBook SCHEMA Model** of the project (resolved as described in
402
+ `ase-format-spec.md`) to learn the allowed object kinds,
403
+ properties, nestings, and value constraints, and resolve the
404
+ `SPEC` artifacts by running the command
405
+ `ase artifact list --kind spec` *once* with <work-dir/> as its
406
+ working directory and parsing its `- <file/>` output lines into
407
+ the file list -- the `ase_artifact_list` tool always resolves
408
+ against the *project* working copy and hence *MUST* *NOT* be used
409
+ here. Do not output anything.
179
410
  </if>
180
411
 
181
- <if condition="<worktree-dir/> is not empty">
182
- The change set *MUST* land *exclusively inside* the worktree
183
- <worktree-dir/>: resolve *every* file path of the task plan
184
- relative to <worktree-dir/> instead of the original working copy,
185
- and run *every* verification command (build, tests, linter,
186
- type-checker, program execution) with <worktree-dir/> as its
187
- working directory. You *MUST* *NEVER* modify, stage, stash,
188
- revert, or commit anything *outside* of this worktree. Leave the
189
- worktree *uncommitted*: do *not* run `git add` and do *not* run
190
- `git commit`, so the user keeps full control over the final
191
- commit.
192
- </if>
193
-
194
- <if condition="<task-content/> does NOT contain a `## VERIFICATION` section heading">
195
- The task plan deliberately *omits* the `## VERIFICATION`
412
+ You *MUST* *skip* every bullet-point of <task-content/> in
413
+ checkbox state `[-]` (cancelled) or `[>]` (deferred): neither
414
+ realize its <text/> in the change set nor perform its check, and
415
+ do *not* count it against the completeness of the change set.
416
+ Its <text/> stays *context only*, e.g. to understand the other
417
+ bullet-points.
418
+
419
+ You *MUST* also *skip* every bullet-point of <task-content/> in
420
+ checkbox state `[x]` (done), as it was already fully resolved by
421
+ a previous run: neither realize its <text/> again nor perform its
422
+ check again, but *do* count it as *complete* for the change set.
423
+ Its <text/> stays *context only*, too.
424
+
425
+ You *MUST* treat every bullet-point of <task-content/> in
426
+ checkbox state `[?]` (question) exactly like one in state `[ ]`
427
+ (todo), i.e., as a *regular* todo, as its grilling question just
428
+ stayed unanswered: realize its <text/> or perform its check.
429
+
430
+ You *MUST* *re-examine* every bullet-point of <task-content/> in
431
+ checkbox state `[/]` (incomplete), as a previous run resolved it
432
+ only *partially*: check which parts of its <text/> are not yet
433
+ realized or verified by the artifacts, and then realize or check
434
+ *only* these remaining parts.
435
+
436
+ <if condition="<task-content/> does NOT contain a `## VERIFICATION (WHEN)` section heading">
437
+ The task plan deliberately *omits* the `## VERIFICATION (WHEN)`
196
438
  section. You *MUST* therefore *strictly skip* the entire
197
439
  verification phase after modifying the source files: do *NOT*
198
440
  run any build, do *NOT* run any tests, do *NOT* run any linter,
@@ -201,57 +443,181 @@ Procedure
201
443
  way.
202
444
  </if>
203
445
 
204
- 2. Update the frontmatter of <task-content/> as follows, *creating*
205
- each of the `Properties:`, `Status:`, and `Modified:` keys the
206
- plan does not carry yet at its position in the key order of the
207
- plan <format/>:
208
-
209
- - *Add* the value `implemented` to the `Properties:` key if it
210
- is still absent, keeping all already present values.
211
-
212
- - *Add* the value `verified` to the `Properties:` key as well,
213
- but *only* if the verification phase was actually performed
214
- and succeeded -- hence *never* for a plan whose
215
- `## VERIFICATION` section is deliberately omitted.
216
-
217
- - Set the `Status:` key to `COMPLETED`, but *only* if the
218
- change set was applied *completely* and *successfully* --
219
- this traverses the `approve`, `start`, and `complete`
220
- transitions of the state machine of the plan <format/> in one
221
- go, starting from the `DRAFTED` state which a freshly authored
222
- plan carries. Otherwise leave the `Status:` key *untouched*,
223
- as an incomplete run transitioned nowhere.
446
+ 3. Store the change set according to <changeset-type/>:
447
+
448
+ - `worktree`: Leave the change set *uncommitted* in
449
+ <work-dir/>. Do not output anything.
450
+
451
+ - `branch`: Stage the change set by running the command
452
+ `git -C "<work-dir/>" add --all`. If the command
453
+ `git -C "<work-dir/>" diff --cached --quiet` fails (i.e.
454
+ something is staged), craft a commit <message/> in the
455
+ format `<type/>: <summary/>`, where <type/> is one of
456
+ `FEATURE`, `IMPROVEMENT`, `BUGFIX`, `UPDATE`, `CLEANUP`, or
457
+ `REFACTOR` and <summary/> is a 60-80 character,
458
+ imperative-mood summary of the task plan without a trailing
459
+ period, without Markdown formatting, and without any
460
+ double-quote (`"`), backtick (`` ` ``), dollar (`$`), or
461
+ backslash (`\`) characters, and commit the change set by
462
+ running the command
463
+ `git -C "<work-dir/>" commit -m "<message/>"`. If the commit
464
+ fails, treat the change set as *not* applied successfully.
465
+ Do not output anything.
466
+
467
+ - `attachment`: Capture the *cumulative* change set into
468
+ <unified-diff/> by running the commands
469
+ `git -C "<work-dir/>" add --all` and
470
+ `git -C "<work-dir/>" diff --cached --no-color --binary HEAD`
471
+ (taken exactly as given). Then remove the temporary worktree
472
+ by running the command
473
+ `git worktree remove --force "<work-dir/>"` (taken exactly as
474
+ given). Do not output anything.
475
+
476
+ 4. Update the checkboxes of the body bullet-points of <task-content/>
477
+ as follows, changing *nothing else* of a bullet-point:
478
+
479
+ - Set the checkbox of every `DOM`, `IFC`, `ARC`, and `IMP`
480
+ bullet-point to `[x]` whose <text/> was *fully* realized by
481
+ the change set, and to `[/]` whose <text/> was realized only
482
+ *partially*. Leave the checkbox of every other bullet-point
483
+ *untouched*.
484
+
485
+ - Set the checkbox of every `REG` and `CON` bullet-point to `[x]`
486
+ whose check was actually performed *and* succeeded, and to
487
+ `[/]` whose check was performed but succeeded only *partially*.
488
+ Leave the checkbox of every other bullet-point *untouched* --
489
+ hence *all* of them for a plan whose `## VERIFICATION (WHEN)`
490
+ section is deliberately omitted.
491
+
492
+ - The rules above apply to bullet-points in the states `[ ]`,
493
+ `[?]`, and `[/]` alike, so a `[?]` bullet-point which was
494
+ not resolved at all stays `[?]`, and a re-examined `[/]`
495
+ bullet-point becomes `[x]` once its remaining parts were
496
+ resolved, or otherwise stays `[/]`.
497
+
498
+ - Leave the checkbox of every skipped `[x]` bullet-point
499
+ *untouched*, as it was already resolved by a previous run.
500
+
501
+ - Leave the checkbox of every skipped `[-]` and `[>]`
502
+ bullet-point *untouched*, as only the user resolves its
503
+ cancelled or deferred state.
504
+
505
+ 5. Update the frontmatter and backmatter of <task-content/> as
506
+ follows, *creating* each of the `Status:` and `Modified:` keys
507
+ the plan does not carry yet at its position in the key order of
508
+ the plan <format/>:
509
+
510
+ - <if condition="<getopt-option-stateless/> is not equal `true` and <ase-project-task-lifecycle/> is `team` or `enterprise` and the `Status:` key was set to `IMPLEMENTING` in step 1 above">
511
+ Set the `Status:` key to `IMPLEMENTED` if the change set was
512
+ applied *completely* and *successfully* (with the skipped
513
+ `[-]` and `[>]` bullet-points not counting, and the skipped
514
+ `[x]` bullet-points counting as complete), or to `STALLED`
515
+ otherwise.
516
+ </if>
517
+ <else>
518
+ Leave the `Status:` key *untouched* -- especially for the
519
+ `solo` model, whose task is closed by `ase-task-integrate`
520
+ only, and under `--stateless`.
521
+ </else>
224
522
 
225
523
  - Refresh the `Modified:` key with the current time in
226
524
  ISO-style format, determined by calling the
227
525
  `ase_timestamp(format: "yyyy-LL-dd HH:mm")` tool of the `ase`
228
- MCP server.
526
+ MCP server, but *only* if step 4 changed at least one
527
+ checkbox, as the key tracks "body" changes only -- a
528
+ frontmatter-only update leaves it *untouched*. Set
529
+ <timestamp-modified/> to the resulting `Modified:` key value,
530
+ or to the current time determined the same way if the key
531
+ was left untouched.
532
+
533
+ - <if condition="<changeset-type/> is `attachment`">
534
+ Append the change set <unified-diff/> as an *attachment
535
+ block* to the "backmatter" of <task-content/> with the
536
+ following <template/>, closely following the plan <format/>.
537
+ If an attachment block with the `Type` key value
538
+ `text/x-diff; charset=utf-8; kind="<changeset-name/>"`
539
+ already exists from a previous run, *replace* this entire
540
+ existing attachment block in place. Set
541
+ <timestamp-attachment-created/> to the value of the `Created`
542
+ key of the *replaced* attachment block, so the creation time
543
+ of the change set survives its replacement, or to
544
+ <timestamp-modified/> if no such block or key exists. Set
545
+ <payload/> to <unified-diff/> with *every* line -- including
546
+ empty lines -- indented by *exactly* 4 spaces, so the YAML
547
+ literal block scalar of the `Data` key carries the diff
548
+ *verbatim*. The "body" keeps its trailing empty line directly
549
+ before the `---` line of the attachment block.
229
550
 
230
- Apart from the frontmatter keys above, the plan body *MUST* stay
231
- *exactly* as loaded.
551
+ <template>
552
+ ---
553
+ Type: text/x-diff; charset=utf-8; kind="<changeset-name/>"
554
+ Desc: base <source-commit/>
555
+ Created: <timestamp-attachment-created/>
556
+ Modified: <timestamp-modified/>
557
+ Data: |4+
558
+ <payload/>
559
+ </template>
560
+ </if>
561
+
562
+ Apart from the checkboxes, the frontmatter keys, and the change
563
+ set attachment above, the plan *MUST* stay *exactly* as loaded --
564
+ in particular, the "backmatter" with its other attachment blocks
565
+ (including a *change set snapshot*, which is maintained by the
566
+ `ase agent` agents only) is passed through *verbatim*.
567
+
568
+ Right before persisting, take over a concurrently stored effort
569
+ estimation, as the `estimator` agent and the `ase-task-estimate`
570
+ skill can set the `Effort:` key while the task is implemented
571
+ (and the checkbox changes above keep it valid): call the
572
+ `ase_task_load(id: "<ase-task-id/>", tag: true)` tool of the
573
+ `ase` MCP server, set <task-tag/> to the content of the trailing
574
+ `<task-plan-tag>` delimiter line of its `text` output field, and
575
+ set the `Effort:` frontmatter key of <task-content/> to the one
576
+ of the loaded plan -- *replacing* it, *creating* it at its
577
+ position in the key order of the plan <format/>, or *removing*
578
+ it if the loaded plan carries none -- changing *nothing else* of
579
+ <task-content/>.
232
580
 
233
581
  Finally call the `ase_task_save(id: "<ase-task-id/>", text:
234
- "<task-content/>")` tool of the `ase` MCP server to persist the
235
- updated task plan. This `ase_task_save` MCP tool call is the
582
+ "<task-content/>", base: "<task-tag/>")` tool of the `ase` MCP
583
+ server to persist the updated task plan. If the save is refused
584
+ because the plan was *changed* meanwhile, repeat the take-over
585
+ above and the save, at most *three* times in total, and then
586
+ save once more *without* the `base` argument. This `ase_task_save` MCP tool call is the
236
587
  *only* permitted way to persist the plan -- *NEVER* write the
237
588
  plan file via `Write`/`Edit` or by executing a shell command.
238
589
  Do not output anything in this sub-step.
239
590
 
240
- 3. Only output the following <template/>:
591
+ 6. Only output the following <template/>:
241
592
 
242
593
  <template>
243
- ⧉ **ASE**: ◉ task: **<ase-task-id/>**, ▶ status: **plan implemented**
594
+ ⧉ **ASE**: ◉ task: **<ase-task-id/>**, ⇢ changeset: **<task-changeset/>**, ▶ status: **plan implemented**
244
595
  </template>
245
596
 
246
- 4. <if condition="<worktree-dir/> is not empty">
247
- Give the closing hint by expanding the following (which,
597
+ 7. Give the closing hint by expanding the following (which,
248
598
  depending on the configured <ase-guidance-level/>, may expand
249
599
  into nothing and hence emit no output at all):
250
600
 
601
+ <if condition="<changeset-type/> is `worktree` and <context-label/> is not `.`">
251
602
  <ase-tpl-hint level="minimal">
252
- The change set is uncommitted in `.ase/worktree/<worktree-name/>` on branch `<worktree-name/>` -- review and commit it there, then remove the worktree via `git worktree remove`.
603
+ The change set is uncommitted in `<context-label/>` -- review it there, then use `/ase-task-integrate` to deliver it.
253
604
  </ase-tpl-hint>
254
605
  </if>
606
+ <elseif condition="<changeset-type/> is `branch`">
607
+ <ase-tpl-hint level="minimal">
608
+ The change set is committed on branch `<changeset-name/>` in `<work-label/>` -- review it there, then use `/ase-task-integrate` to deliver it.
609
+ </ase-tpl-hint>
610
+ </elseif>
611
+ <elseif condition="<task-changeset/> is `attachment:draft`">
612
+ <ase-tpl-hint level="minimal">
613
+ The change set is attached to the plan as its implementation draft only -- review it via `/ase-task-view --full`, then use `/ase-task-integrate --draft` to deliver it.
614
+ </ase-tpl-hint>
615
+ </elseif>
616
+ <elseif condition="<changeset-type/> is `attachment`">
617
+ <ase-tpl-hint level="minimal">
618
+ The change set is attached to the plan only -- review it via `/ase-task-view --full`, then use `/ase-task-integrate --changeset <task-changeset/>` to deliver it.
619
+ </ase-tpl-hint>
620
+ </elseif>
255
621
 
256
622
  5. **Decide Next Step:**
257
623
 
@@ -259,9 +625,11 @@ Procedure
259
625
 
260
626
  <expand name="task-next-select"
261
627
  arg1="ase-task-implement"
262
- arg2="DONE|DELETE">
628
+ arg2="DONE|EDIT|INTEGRATE|DELETE">
263
629
  Next Step: How would you like to proceed with the plan?
264
630
  DONE: Stop processing and PRESERVE task plan.
631
+ EDIT: Hand processing off to editing.
632
+ INTEGRATE: Hand processing off to integration.
265
633
  DELETE: Stop processing and DELETE the task plan.
266
634
  </expand>
267
635
 
@@ -274,6 +642,28 @@ Procedure
274
642
  ⧉ **ASE**: ◉ task: **<ase-task-id/>**, ▶ status: **plan implemented -- done**
275
643
  </template>
276
644
 
645
+ - If <result/> is `EDIT`:
646
+ <expand name="task-next-handoff" arg1="ase-task-edit"
647
+ arg2="plan implemented -- hand-off to edit"></expand>
648
+
649
+ - If <result/> is `INTEGRATE`:
650
+ Set <handoff-args></handoff-args> (empty). If
651
+ <getopt-option-worktree/> is not empty, append
652
+ ` --worktree <getopt-option-worktree/>`; if
653
+ <getopt-option-changeset/> is not empty, append
654
+ ` --changeset <getopt-option-changeset/>`; if
655
+ <getopt-option-source/> is not empty and the `Target:`
656
+ frontmatter key of <task-content/> (or, if absent, the
657
+ configured default <ase-project-task-default-target/>) is `source`,
658
+ append ` --target <getopt-option-source/>`; and if
659
+ <getopt-option-stateless/> is `true`, append ` --stateless`
660
+ to <handoff-args/>, so the integration delivers the very
661
+ change set just created into the very source it is based on.
662
+
663
+ <expand name="task-next-handoff" arg1="ase-task-integrate"
664
+ arg2="plan implemented -- hand-off to integration"
665
+ arg3="<handoff-args/>"></expand>
666
+
277
667
  - If <result/> is `DELETE`:
278
668
  Set <args></args> (empty). Do *not* forward any remaining
279
669
  `--next` list tokens, because the `ase:ase-task-delete`