git:20261013.cc922f0 to git:20261016.8cf48d3

5 added, 54 removed. Audit A to A.

---
name: ase-task-implement
argument-hint: "[--help|-h] [--next|-n <option>[,...]] [--worktree|-w <name>] [--source|-s <source>] [--changeset|-c <changeset>] [--draft|-d] [--stateless|-S] [<id>]"
description: >
Implement current or given task plan, optionally as an implementation
draft attachment only. Use when the user calls to "implement", "realize",
"draft", "dry-run", or "test-drive" the "task", "plan", "spec", or
"specification".
user-invocable: true
disable-model-invocation: false
effort: xhigh
---
@${CLAUDE_SKILL_DIR}/../../meta/ase-control.md
@${CLAUDE_SKILL_DIR}/../../meta/ase-skill.md
@${CLAUDE_SKILL_DIR}/../../meta/ase-dialog.md
@${CLAUDE_SKILL_DIR}/../../meta/ase-getopt.md
<purpose name="ase-task-implement">
Implement a Task Plan
</purpose>
<expand name="getopt"
arg1="ase-task-implement"
arg2="--next|-n=(none|DONE|EDIT|INTEGRATE|DELETE)... --worktree|-w= --source|-s= --changeset|-c= --draft|-d --stateless|-S --int-reuse-task">
$ARGUMENTS
</expand>
<objective>
*Implement* the task plan by creating a corresponding, complete
*change set* from its *source* into its *changeset* location.
</objective>
@${CLAUDE_SKILL_DIR}/../../meta/ase-format-task.md
@${CLAUDE_SKILL_DIR}/../../meta/ase-common-task.md
@${CLAUDE_SKILL_DIR}/../../meta/ase-tenets.md
@${CLAUDE_SKILL_DIR}/../../meta/ase-common-code.md
@${CLAUDE_SKILL_DIR}/../../meta/ase-common-changeset.md
Procedure
---------
1. **Determine Task:**
1. Set <instruction><getopt-arguments/></instruction> initially, with any
leading and trailing whitespace stripped.
Inherit the always existing <ase-task-id/> from the current context.
Inherit the always existing <ase-session-id/> from the current context.
Do not output anything.
2. React on task id:
<expand name="task-react-id" arg1="ase-task-implement"></expand>
3. Resolve the draft shorthand: if <getopt-option-draft/> is `true`
and <getopt-option-changeset/> is not empty, only output the
following <template/> and then immediately *STOP* processing the
entire current skill:
<template>
⧉ **ASE**: ◉ task: **<ase-task-id/>**, ▶ ERROR: options `--draft` and `--changeset` are mutually exclusive
</template>
Otherwise, if <getopt-option-draft/> is `true`, set
<getopt-option-changeset>attachment:draft</getopt-option-changeset>,
so the change set lands as the *implementation draft* in the
attachment `draft` of the plan only. Do not output anything.
2. **Determine Operation:**
1. Determine the current task plan content:
<expand name="task-load-content"></expand>
2. If the <task-content/> is still empty, complain and tell the user to
use the `ase-code-resolve`, `ase-code-refactor`, `ase-code-craft`,
or `ase-task-edit` skills first to create a task plan. Then
immediately stop processing this skill.
3. Internalize the tenets stated by the plan:
<expand name="code-tenets-from-plan"></expand>
3. **Prepare Source and Changeset:**
The *source* (code basis) and the *changeset* (location of the
change set) are controlled by the `Source:` and `Changeset:`
frontmatter keys of the plan, which the `--source` and
`--changeset` options override *ad-hoc* without changing the plan.
The `worktree` value of the source refers to the *origin working
copy* the skill was started in, the `worktree` value of the
changeset to the *context worktree*, selected by the `--worktree`
option (both are the same without `--worktree`). A context worktree
created by `--worktree` carries its *own* branch, which starts at
the source, so the source branch itself is never checked out there
and stays available as the integration target.
1. Set <task-source/> to <getopt-option-source/> if it is not
empty, otherwise to the value of the `Source:` frontmatter key
of <task-content/>, or to the configured default
<ase-project-task-default-source/> if the key is absent, and
parse it:
<expand name="changeset-value"
arg1="Source"
arg2="<task-source/>"
arg3="`worktree`, `branch`"
arg4="◉ task: **<ase-task-id/>**"></expand>
Set <source-type><value-type/></source-type> and
<source-name><value-name/></source-name>.
2. Set <task-changeset/> to <getopt-option-changeset/> if it is not
empty, otherwise to the value of the `Changeset:` frontmatter key
of <task-content/>, or to the configured default
<ase-project-task-default-changeset/> if the key is absent, and
parse it:
<expand name="changeset-value"
arg1="Changeset"
arg2="<task-changeset/>"
arg3="`worktree`, `branch`, `attachment`"
arg4="◉ task: **<ase-task-id/>**"></expand>
Set <changeset-type><value-type/></changeset-type> and
<changeset-name><value-name/></changeset-name>.
<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">
The plan carries an undelivered *implementation draft*, which
only an `attachment:draft` changeset builds upon, so this run
*ignores* it and implements the plan from scratch into
<task-changeset/>. Only output the following <template/>,
directly followed by the hint, and then *continue* processing:
<template>
⧉ **ASE**: ◉ task: **<ase-task-id/>**, ▶ WARNING: implementation draft attachment is **ignored** for changeset **<task-changeset/>**
</template>
<ase-tpl-hint level="minimal">
Use `/ase-task-implement --draft` to build upon the draft, or `/ase-task-integrate --draft` to deliver it.
</ase-tpl-hint>
</if>
3. Determine the *source commit* <source-commit/>: if
<source-type/> is `worktree`, capture the output of the command
`git rev-parse HEAD` (the skill runs inside the origin working
copy); if it is `branch`, capture the output of the command
`git rev-parse --verify --quiet "refs/heads/<source-name/>"`.
If the command fails, only output the following <template/> and
then immediately *STOP* processing the entire current skill,
leaving the working copy *untouched* (so a bad source never
leaves a context worktree behind):
<template>
⧉ **ASE**: ◉ task: **<ase-task-id/>**, ▶ ERROR: source **<task-source/>** does not exist
</template>
4. <if condition="<getopt-option-worktree/> is not empty and <changeset-type/> is not `worktree`">
The context worktree serves the `worktree` changeset only, so a
`branch:` or `attachment:` changeset would leave it unused (e.g.
on a mistyped option). Only output the following <template/> and
then immediately *STOP* processing the entire current skill,
leaving the working copy *untouched*:
<template>
⧉ **ASE**: ◉ task: **<ase-task-id/>**, ▶ ERROR: option `--worktree` requires a `worktree` changeset (got **<task-changeset/>**)
</template>
</if>
Otherwise, prepare the context worktree, whose own branch -- if
created together with it -- starts at <source-commit/>:
<expand name="changeset-context"
arg1="<getopt-option-worktree/>"
arg2="◉ task: **<ase-task-id/>**"
arg3="false"
arg4="true"
arg5="<source-commit/>"></expand>
5. Determine the *work directory* <work-dir/> -- the worktree in
which the implementation happens -- according to <changeset-type/>:
- `worktree`: The change set stays *uncommitted* in the context
worktree, so set <work-dir><context-dir/></work-dir>.
- <if condition="<context-dir/> differs from <origin-dir/>">
The context worktree carries its *own* branch: a freshly
created one already starts at <source-commit/>, while a
reused one keeps its own base, so earlier work in it is
*continued*. The source branch is *never* checked out in
the context worktree (it may be checked out in the origin
working copy, and it is the integration target of
`Target: source`), so nothing is switched. Do not output
anything.
</if>
- <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/>">
The origin working copy is *switched* to <source-name/>
in place: if the command `git status --porcelain` reports
any output, switching would drag the uncommitted changes
onto the other branch, so only output the following
<template/>, directly followed by the hint, and then
immediately *STOP* processing the entire current skill,
leaving the working copy *untouched*:
<template>
⧉ **ASE**: ◉ task: **<ase-task-id/>**, ▶ ERROR: working copy has uncommitted changes -- cannot switch to branch **<source-name/>** in place
</template>
<ase-tpl-hint level="minimal">
Commit or stash the uncommitted changes first, or use `--worktree <name>` to implement inside an isolated worktree instead.
</ase-tpl-hint>
Otherwise, run the command
`git switch "<source-name/>"`, and, if it fails (e.g.
because the branch is checked out in another worktree),
only output the following <template/> and then
immediately *STOP* processing the entire current skill:
<template>
⧉ **ASE**: ◉ task: **<ase-task-id/>**, ▶ ERROR: branch **<source-name/>** failed to switch
</template>
Otherwise, only output the following <template/>:
<template>
⧉ **ASE**: ◉ task: **<ase-task-id/>**, ⎇ branch: **<source-name/>**, ▶ status: **branch switched**
</template>
</elseif>
- `branch`: The change set is *committed* onto the branch
<changeset-name/> inside a worktree carrying this branch.
Determine the *existing worktrees* by running the command
`git worktree list --porcelain` (taken exactly as given).
- If the branch <changeset-name/> is checked out in a
registered worktree, set <work-dir/> to its directory and
<work-label/> to its path. If the command
`git -C "<work-dir/>" status --porcelain` reports any
output, the change set could not be committed separately,
so only output the following <template/> and then
immediately *STOP* processing the entire current skill:
<template>
⧉ **ASE**: ◉ task: **<ase-task-id/>**, ▶ ERROR: worktree **<work-label/>** of branch **<changeset-name/>** has uncommitted changes
</template>
- Otherwise, set <work-id/> to <changeset-name/> with every
character other than `A-Z`, `a-z`, `0-9`, `_`, and `-`
replaced by `-`, determine <work-dir/> by calling the
`ase_worktree_path(id: "<work-id/>", create: true)` tool of
the `ase` MCP server (you *MUST* *NEVER* assemble this
path yourself), and set
<work-label>.ase/worktree/<work-id/></work-label>. If
this tool call fails or the directory <work-dir/> already
exists, only output the following <template/> and then
immediately *STOP* processing the entire current skill:
<template>
⧉ **ASE**: ◉ task: **<ase-task-id/>**, ▶ ERROR: worktree **<work-id/>** for branch **<changeset-name/>** cannot be created
</template>
If the branch <changeset-name/> exists according to
`git branch --list`, create the worktree by running the
command `git worktree add "<work-dir/>" "<changeset-name/>"`,
otherwise create the branch from the source together with
the worktree by running the command
`git worktree add -b "<changeset-name/>" "<work-dir/>" "<source-commit/>"`
(each taken exactly as given). If the command fails, only
output the same error <template/> as above and then
immediately *STOP* processing the entire current skill.
Otherwise, only output the following <template/>:
<template>
⧉ **ASE**: ◉ task: **<ase-task-id/>**, ◉ worktree: **<work-label/>**, ⎇ branch: **<changeset-name/>**, ▶ status: **worktree created**
</template>
- `attachment`: The change set is made and verified in a
*temporary* worktree, detached at <source-commit/>, and
afterwards stored as an attachment of the plan only, leaving
all artifacts untouched.
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)">
The change set of a *previous* run was created for an
*earlier* version of the plan, so building on it would
silently carry over changes the plan no longer asks for,
and dropping it would leave its `[x]` and `[/]`
bullet-points unrealized. Only output the following
<template/>, directly followed by the hint, and then
immediately *STOP* processing the entire current skill,
leaving the plan and the artifacts *untouched*:
<template>
⧉ **ASE**: ◉ task: **<ase-task-id/>**, ▶ ERROR: change set attachment **<changeset-name/>** is **stale** (older than the plan)
</template>
<ase-tpl-hint level="minimal">
Remove the attachment and reset the `[x]` and `[/]` checkboxes of the plan, then run `/ase-task-implement --changeset <task-changeset/>` again.
</ase-tpl-hint>
</if>
2. Set <work-hash/> to the first 8 characters of the output
of the `ase_mint(type: "sha1", hint:
"<ase-task-id/>:<changeset-name/>:implement")` tool of the
`ase` MCP server, which keeps <work-id/> *unique* per task
and attachment. Set <work-id/> to <ase-task-id/> with all
characters other than `A-Z`, `a-z`, `0-9`, `_`, and `-`
stripped, followed by
`-<changeset-name/>-implement-<work-hash/>`, and
determine <work-dir/> by calling the
`ase_worktree_path(id: "<work-id/>", temp: true, create:
true)` tool of the `ase` MCP server, which places it into
the namespace of the *temporary* worktrees, disjoint from
all other worktrees. You *MUST* *NEVER* assemble this path
yourself.
3. <if condition="<work-dir/> exists">
If <work-dir/> is a worktree registered according to
`git worktree list --porcelain` and its record carries a
`detached` line, it is the *leftover* of an earlier run
which stopped before its cleanup, and its partial state
must *not* be reused: remove it by running the commands
`git worktree remove --force "<work-dir/>"` and
`git worktree prune` (taken exactly as given), ignoring
any failure. Otherwise, it is *not* owned by this skill,
so only output the following <template/> and then
immediately *STOP* processing the entire current skill,
leaving <work-dir/> and the task plan *untouched*:
<template>
⧉ **ASE**: ◉ task: **<ase-task-id/>**, ▶ ERROR: directory **<work-id/>** for attachment **<changeset-name/>** exists, but is no temporary worktree
</template>
</if>
4. Create the worktree by running the command
`git worktree add --detach "<work-dir/>" "<source-commit/>"`
(taken exactly as given). As it starts at the source
commit, *uncommitted* changes of the source are *not*
carried over.
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">
This block carries the change set of a *previous* run,
which realized the `[x]` and `[/]` bullet-points. A block
whose `Desc` key carries a `merged <commit/>` value was
already *delivered* by `ase-task-integrate`, so it is *not*
re-applied, and the change set of this run starts afresh
at the source commit and replaces it below. As its `Data`
payload is *elided* in <task-content/>, fetch it via the
`ase_task_attachment(id: "<ase-task-id/>", type: "text/x-diff;
charset=utf-8; kind=\"<changeset-name/>\"")` tool of the `ase`
MCP server, whose `text` output field is the payload
*verbatim* (without any indentation). Re-establish
it in the worktree by applying this payload *verbatim*, e.g. via
`git -C "<work-dir/>" apply --3way`, and re-apply hunks
which no longer apply to a meanwhile drifted source
manually. The change set of this run is built *on top* of
it, so the change set captured below is *cumulative*.
</if>
If any of these sub-steps fails, remove the worktree as above
(if created by sub-step 4), only output the following
<template/>, and then immediately *STOP* processing the
entire current skill, leaving the task plan *untouched*:
<template>
⧉ **ASE**: ◉ task: **<ase-task-id/>**, ▶ ERROR: temporary worktree for attachment **<changeset-name/>** cannot be prepared
</template>
- 6. <if condition="<changeset-type/> is `worktree` and <work-dir/> is equal to <origin-dir/>">
- The change set stays uncommitted in the *origin working copy*,
- which may already carry *foreign* uncommitted changes (e.g.
- other work in progress), which do not belong to the change set
- and hence *MUST* *NOT* show up in its snapshot. So, capture the
- baseline of the working tree before the implementation:
-
- <expand name="changeset-baseline" arg1="<work-dir/>"></expand>
- </if>
- <else>
- A context worktree, a branch, or a temporary worktree carries
- nothing but the change set (of this and earlier runs), so set
- <changeset-baseline></changeset-baseline> (empty).
- </else>
-
4. **Create Implementation:**
1. <if condition="<getopt-option-stateless/> is not equal `true` and <ase-project-task-lifecycle/> is `team` or `enterprise`">
Mark the plan as being implemented: set the `Status:` key of
<task-content/> to `IMPLEMENTING` (*creating* the key at its
position in the key order of the plan <format/> if absent), but
*only* if `IMPLEMENTING` is reachable from the current state
along the transitions of the task lifecycle model (for the
`team` model from `PLANNING` or `STALLED`, for the `enterprise`
model from `DRAFTED` via `PLANNING` and `PLANNED`, or from
`PLANNED` or `STALLED`), and persist this frontmatter-only change
-- without refreshing the `Modified:` key -- by calling the
`ase_task_save(id: "<ase-task-id/>", text: "<task-content/>")`
tool of the `ase` MCP server. Do not output anything.
</if>
2. Perform a *final implementation* of the task plan inside
<work-dir/> by modifying the *artifacts* with a corresponding,
complete *change set*, following and honoring the task plan in
<task-content/>:
<expand name="changeset-land" arg1="<work-dir/>"></expand>
You *MUST* *skip* every bullet-point of <task-content/> in
checkbox state `[-]` (cancelled) or `[>]` (deferred): neither
realize its <text/> in the change set nor perform its check, and
do *not* count it against the completeness of the change set.
Its <text/> stays *context only*, e.g. to understand the other
bullet-points.
You *MUST* also *skip* every bullet-point of <task-content/> in
checkbox state `[x]` (done), as it was already fully resolved by
a previous run: neither realize its <text/> again nor perform its
check again, but *do* count it as *complete* for the change set.
Its <text/> stays *context only*, too.
You *MUST* treat every bullet-point of <task-content/> in
checkbox state `[?]` (question) exactly like one in state `[ ]`
(todo), i.e., as a *regular* todo, as its grilling question just
stayed unanswered: realize its <text/> or perform its check.
You *MUST* *re-examine* every bullet-point of <task-content/> in
checkbox state `[/]` (incomplete), as a previous run resolved it
only *partially*: check which parts of its <text/> are not yet
realized or verified by the artifacts, and then realize or check
*only* these remaining parts.
<if condition="<task-content/> does NOT contain a `## VERIFICATION (WHEN)` section heading">
The task plan deliberately *omits* the `## VERIFICATION (WHEN)`
section. You *MUST* therefore *strictly skip* the entire
verification phase after modifying the source files: do *NOT*
run any build, do *NOT* run any tests, do *NOT* run any linter,
do *NOT* run any type-checker, do *NOT* execute the modified
program, and do *NOT* otherwise verify the change set in any
way.
</if>
3. Store the change set according to <changeset-type/>:
- `worktree`: Leave the change set *uncommitted* in
<work-dir/>. Do not output anything.
- `branch`: Stage the change set by running the command
`git -C "<work-dir/>" add --all`. If the command
`git -C "<work-dir/>" diff --cached --quiet` fails (i.e.
something is staged), craft a commit <message/> in the
format `<type/>: <summary/>`, where <type/> is one of
`FEATURE`, `IMPROVEMENT`, `BUGFIX`, `UPDATE`, `CLEANUP`, or
`REFACTOR` and <summary/> is a 60-80 character,
imperative-mood summary of the task plan without a trailing
period, without Markdown formatting, and without any
double-quote (`"`), backtick (`` ` ``), dollar (`$`), or
backslash (`\`) characters, and commit the change set by
running the command
`git -C "<work-dir/>" commit -m "<message/>"`. If the commit
fails, treat the change set as *not* applied successfully.
Do not output anything.
- `attachment`: Capture the *cumulative* change set into
<unified-diff/> by running the commands
`git -C "<work-dir/>" add --all` and
`git -C "<work-dir/>" diff --cached --no-color --binary HEAD`
(taken exactly as given). Then remove the temporary worktree
by running the command
`git worktree remove --force "<work-dir/>"` (taken exactly as
given). Do not output anything.
4. Update the checkboxes of the body bullet-points of <task-content/>
as follows, changing *nothing else* of a bullet-point:
- Set the checkbox of every `DOM`, `IFC`, `ARC`, and `IMP`
bullet-point to `[x]` whose <text/> was *fully* realized by
the change set, and to `[/]` whose <text/> was realized only
*partially*. Leave the checkbox of every other bullet-point
*untouched*.
- Set the checkbox of every `REG` and `CON` bullet-point to `[x]`
whose check was actually performed *and* succeeded, and to
`[/]` whose check was performed but succeeded only *partially*.
Leave the checkbox of every other bullet-point *untouched* --
hence *all* of them for a plan whose `## VERIFICATION (WHEN)`
section is deliberately omitted.
- The rules above apply to bullet-points in the states `[ ]`,
`[?]`, and `[/]` alike, so a `[?]` bullet-point which was
not resolved at all stays `[?]`, and a re-examined `[/]`
bullet-point becomes `[x]` once its remaining parts were
resolved, or otherwise stays `[/]`.
- Leave the checkbox of every skipped `[x]` bullet-point
*untouched*, as it was already resolved by a previous run.
- Leave the checkbox of every skipped `[-]` and `[>]`
bullet-point *untouched*, as only the user resolves its
cancelled or deferred state.
5. Update the frontmatter and backmatter of <task-content/> as
follows, *creating* each of the `Status:` and `Modified:` keys
the plan does not carry yet at its position in the key order of
the plan <format/>:
- <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">
Set the `Status:` key to `IMPLEMENTED` if the change set was
applied *completely* and *successfully* (with the skipped
`[-]` and `[>]` bullet-points not counting, and the skipped
`[x]` bullet-points counting as complete), or to `STALLED`
otherwise.
</if>
<else>
Leave the `Status:` key *untouched* -- especially for the
`solo` model, whose task is closed by `ase-task-integrate`
only, and under `--stateless`.
</else>
- Refresh the `Modified:` key with the current time in
ISO-style format, determined by calling the
`ase_timestamp(format: "yyyy-LL-dd HH:mm")` tool of the `ase`
MCP server, but *only* if step 4 changed at least one
checkbox, as the key tracks "body" changes only -- a
frontmatter-only update leaves it *untouched*. Set
<timestamp-modified/> to the resulting `Modified:` key value,
or to the current time determined the same way if the key
was left untouched.
- <if condition="<changeset-type/> is `attachment`">
Append the change set <unified-diff/> as an *attachment
block* to the "backmatter" of <task-content/> with the
following <template/>, closely following the plan <format/>.
If an attachment block with the `Type` key value
`text/x-diff; charset=utf-8; kind="<changeset-name/>"`
already exists from a previous run, *replace* this entire
existing attachment block in place. Set
<timestamp-attachment-created/> to the value of the `Created`
key of the *replaced* attachment block, so the creation time
of the change set survives its replacement, or to
<timestamp-modified/> if no such block or key exists. Set
<payload/> to <unified-diff/> with *every* line -- including
empty lines -- indented by *exactly* 4 spaces, so the YAML
literal block scalar of the `Data` key carries the diff
*verbatim*. The "body" keeps its trailing empty line directly
before the `---` line of the attachment block.
<template>
---
Type: text/x-diff; charset=utf-8; kind="<changeset-name/>"
Desc: base <source-commit/>
Created: <timestamp-attachment-created/>
Modified: <timestamp-modified/>
Data: |4+
<payload/>
</template>
</if>
- - <if condition="<changeset-type/> is `worktree` or `branch`">
- Attach the *change set snapshot*, which makes the change set
- viewable wherever the task is visible (e.g. on the task boards
- during its approval). Set <snapshot-suffix/> to `, partial` if
- the change set was *not* applied completely and successfully
- (the same criterion as for the `STALLED` state above), or to
- empty otherwise. For <changeset-type/> `worktree`, expand the
- following:
-
- <expand name="changeset-snapshot"
- arg1="<work-dir/>"
- arg2="<source-commit/>"
- arg3=""
- arg4="<snapshot-suffix/>"
- arg5="<timestamp-modified/>"
- arg6="<changeset-baseline/>"></expand>
-
- For <changeset-type/> `branch`, expand the following instead:
-
- <expand name="changeset-snapshot"
- arg1="<work-dir/>"
- arg2="<source-commit/>"
- arg3="<changeset-name/>"
- arg4="<snapshot-suffix/>"
- arg5="<timestamp-modified/>"
- arg6=""></expand>
- </if>
- <elseif condition="<changeset-name/> is not `changeset`">
- The change set is an attachment itself, so it needs no
- snapshot, and a snapshot of an earlier run would show an
- *outdated* change set: *remove* an attachment block with the
- `Type` key value `text/x-diff; charset=utf-8; kind="changeset"`
- from the "backmatter" of <task-content/>, if existing.
- </elseif>
-
- Apart from the checkboxes, the frontmatter keys, the change set
- attachment, and the change set snapshot above, the plan *MUST*
- stay *exactly* as loaded -- in particular, the "backmatter" with
- its other attachment blocks is passed through *verbatim*.
+ Apart from the checkboxes, the frontmatter keys, and the change
+ set attachment above, the plan *MUST* stay *exactly* as loaded --
+ in particular, the "backmatter" with its other attachment blocks
+ (including a *change set snapshot*, which is maintained by the
+ `ase agent` agents only) is passed through *verbatim*.
Finally call the `ase_task_save(id: "<ase-task-id/>", text:
"<task-content/>")` tool of the `ase` MCP server to persist the
updated task plan. This `ase_task_save` MCP tool call is the
*only* permitted way to persist the plan -- *NEVER* write the
plan file via `Write`/`Edit` or by executing a shell command.
Do not output anything in this sub-step.
6. Only output the following <template/>:
<template>
⧉ **ASE**: ◉ task: **<ase-task-id/>**, ⇢ changeset: **<task-changeset/>**, ▶ status: **plan implemented**
</template>
7. Give the closing hint by expanding the following (which,
depending on the configured <ase-guidance-level/>, may expand
into nothing and hence emit no output at all):
<if condition="<changeset-type/> is `worktree` and <context-label/> is not `.`">
<ase-tpl-hint level="minimal">
The change set is uncommitted in `<context-label/>` -- review it there, then use `/ase-task-integrate` to deliver it.
</ase-tpl-hint>
</if>
<elseif condition="<changeset-type/> is `branch`">
<ase-tpl-hint level="minimal">
The change set is committed on branch `<changeset-name/>` in `<work-label/>` -- review it there, then use `/ase-task-integrate` to deliver it.
</ase-tpl-hint>
</elseif>
<elseif condition="<task-changeset/> is `attachment:draft`">
<ase-tpl-hint level="minimal">
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.
</ase-tpl-hint>
</elseif>
<elseif condition="<changeset-type/> is `attachment`">
<ase-tpl-hint level="minimal">
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.
</ase-tpl-hint>
</elseif>
5. **Decide Next Step:**
1. *Determine next step*:
<expand name="task-next-select"
arg1="ase-task-implement"
arg2="DONE|EDIT|INTEGRATE|DELETE">
Next Step: How would you like to proceed with the plan?
DONE: Stop processing and PRESERVE task plan.
EDIT: Hand processing off to editing.
INTEGRATE: Hand processing off to integration.
DELETE: Stop processing and DELETE the task plan.
</expand>
2. Check the tool <result/> and dispatch accordingly:
- If <result/> is `DONE` or `CANCEL`:
Only output the following <template/> and then *STOP*.
<template>
⧉ **ASE**: ◉ task: **<ase-task-id/>**, ▶ status: **plan implemented -- done**
</template>
- If <result/> is `EDIT`:
<expand name="task-next-handoff" arg1="ase-task-edit"
arg2="plan implemented -- hand-off to edit"></expand>
- If <result/> is `INTEGRATE`:
Set <handoff-args></handoff-args> (empty). If
<getopt-option-worktree/> is not empty, append
` --worktree <getopt-option-worktree/>`; if
<getopt-option-changeset/> is not empty, append
` --changeset <getopt-option-changeset/>`; if
<getopt-option-source/> is not empty and the `Target:`
frontmatter key of <task-content/> (or, if absent, the
configured default <ase-project-task-default-target/>) is `source`,
append ` --target <getopt-option-source/>`; and if
<getopt-option-stateless/> is `true`, append ` --stateless`
to <handoff-args/>, so the integration delivers the very
change set just created into the very source it is based on.
<expand name="task-next-handoff" arg1="ase-task-integrate"
arg2="plan implemented -- hand-off to integration"
arg3="<handoff-args/>"></expand>
- If <result/> is `DELETE`:
Set <args></args> (empty). Do *not* forward any remaining
`--next` list tokens, because the `ase:ase-task-delete`
skill accepts only an optional `[<id>]` argument and no
`--next` option; remaining tokens are intentionally discarded.
Only output the following <template/> and then call the
tool `Skill(skill: "ase:ase-task-delete", args: "<args/>")`
to invoke the `ase:ase-task-delete` skill in order to
*delete* the updated plan. Immediately stop processing the
current skill once the `Skill` tool was used.
<template>
⧉ **ASE**: ◉ task: **<ase-task-id/>**, ▶ status: **plan implemented -- hand-off to delete task**
</template>