关于 implement-feature
implement-feature 用于在已审阅的功能工作流中执行获准的子任务。它通过 Beads 选择和跟踪工作,遵循已审阅的设计约束,并将实现限制在明确的任务范围内。
主要功能
- 01通过 Beads 选择并认领功能子任务
- 02依据已审阅设计检查任务范围
- 03实现限定范围内的更改和文档
- 04运行任务指定的验证与专项评审
- 05在共享锁下完成交互证据记录
适用场景
- 01实现已审阅功能中的下一个就绪任务
- 02在功能工作树中执行用户指定的子任务
- 03验证限定范围的更改而不运行完整仓库套件
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ robertderose/ dstack --skill implement-feature安装后在 Claude Code 中输入/implement-feature确认已加载。
详细介绍
目的
在 /start-feature 关闭 spec-reconcile 后使用此技能。接受与 /start-feature 相同的人工功能选择器。Beads 负责选择可执行工作;design.md 提供预期行为和设计约束。将 <core-dir> 解析为已安装的 ../dstack-core 技能目录。如果提供的选择器解析为独立的 task、bug、chore、spike 或 feature,而非经过审查的 workflow:feature epic 的子项,请在认领前停止,并建议使用 /implement-task <human task selector>。
调用授权进行有界的本地实现提交;必要时,为选定根节点提交一次启动交互证据;并在每个子项和实现协调器完成后提交一次仅包含交互内容的审计。此调用不授权推送、拉取请求、合并或移除工作树,也不授权远程交付。
共享的原生 Beads 权限
修改功能前,请阅读 ../dstack-core/references/INTERACTION-BOUNDARY.md。原生关联工作树的 Beads 权限是共享的;bd -C 不是隔离边界。每个认领/关闭/证据/最终化阶段都必须在 beads-workflow-lock.py 下运行;如果租约繁忙、存在其他交互记录或发生快照竞争,请停止。绝不使用原始 bd 写入绕过租约,也绝不复制其他功能的审计证据。
启动版本证据
认领子项或修改功能前,请按照 ../dstack-core/references/SKILL-VERSION.md 中针对 implement-feature 的说明操作。只读解析功能并激活工作树后,首先捕获第 1 节所述的干净功能工作树基线。然后捕获准确的单行输出,将其追加到所选根节点的 Beads 备注中,并在认领子项前完成该启动交互边界。stale 结果会提示运行 npx skills update;unavailable 记录未作出新鲜度声明,不会阻止离线工作。
执行
1. 加载最少上下文
从调用目录解析仓库根目录,然后在该仓库中运行 bd prime。以只读方式解析提供的功能选择器。获取根节点 ID 后、进行任何认领、备注或其他修改之前,立即运行 <core-dir>/scripts/migrate-review-topology.py guard --root-id <feature-root> --controller-topology-version 3。遇到更新的标记或尚未迁移的旧审查类型时,必须安全失败;只有规范主工作树迁移器可以修改拓扑。如果未提供选择器,请按以下确定性优先级处理:
- 当前分支与
feat/<slug>匹配时,使用当前分支; - 使用上次成功运行
/start-feature时记录的仓库本地功能; - 否则停止并要求提供选择器,不要改选无关的就绪工作。
repository_root=$(git rev-parse --show-toplevel)
bd -C "$repository_root" prime
branch=$(git -C "$repository_root" branch --show-current)
if [[ "$branch" == feat/* ]]; then
feature_selector=${branch#feat/}
else
feature_selector=$(git -C "$repository_root" config --get dstack.activeFeature || true)
fi
test -n "$feature_selector"
uv run <core-dir>/scripts/resolve-feature.py "$feature_selector" --root "$repository_root" --json
bd -C "$repository_root" show <resolved-root-id> --json
此处绝不使用自动选择下一个功能。必须像验证用户提供的选择器一样,通过解析器验证存储值;状态过期或存在歧义时必须停止,不得改选其他功能。
返回的根节点 ID 仅用于 Beads 操作;返回的 <slug> 引用用于工作树、报告和后续命令。根据根节点元数据 implementation_id 解析实现协调器。仅将查询功能子项用作一次性元数据修复路径。这样,常规上下文加载不受功能总规模影响,并且同时适用于 molecules 和迁移后的父子生命周期。功能工作树必须已由 /start-feature 激活;不要在此处切换或创建工作树。
根据分支而非进程 CWD 解析权威工作树。这也使得从基础工作树调用时安全:
feature_branch=feat/<slug>
task_worktree=
worktree_path=
while IFS= read -r line; do
case "$line" in
"worktree "*) worktree_path=${line#worktree } ;;
"branch refs/heads/$feature_branch") task_worktree=$worktree_path ;;
esac
done < <(git -C "$repository_root" worktree list --porcelain)
test -n "$task_worktree"
test "$(git -C "$task_worktree" branch --show-current)" = "$feature_branch"
test "$(git -C "$task_worktree" rev-parse --show-toplevel)" = "$task_worktree"
之后所有功能 Git 命令都使用 git -C "$task_worktree",所有功能 Beads 命令都使用 bd -C "$task_worktree"。如果无法准确解析分支或工作树,请在进行任何修改前停止。
如果用户指定了一个已就绪的子任务,优先选择它;否则使用 Beads 的原子化“下一个就绪”选择机制。在启动交互边界完成最终确认并捕获下方所述的子任务基线之前,不要认领子任务。已认领的子任务是下一个工作单元,而非本次调用的终点;每个子任务关闭并完成最终确认后,立即返回此选择步骤,捕获新的干净基线,并继续处理此功能。
在加载更多文件之前,先读取结构化元数据、范围、验收标准、阻塞项、设计参考、文档归属和验证信息。除非需要更广泛的上下文,否则只阅读相关的设计章节和面向读者的页面。
旧版 tasks.md 文件仅用作迁移输入。Beads 导入后,绝不要将其用作实时任务状态。
在写入启动版本说明或进行任何其他功能变更之前,要求功能工作树干净,并从已解析的功能工作树中捕获不可变的基线提交:
test -z "$(git -C "$task_worktree" status --porcelain)"
startup_base_commit=$(git -C "$task_worktree" rev-parse HEAD)
workflow_run_id=<stable workflow run id>
以下所有连续的 Beads 变更命令——包括启动说明、认领、审查/证据更新、关闭和交互最终确认——都必须在使用规范仓库根目录的共享 beads-workflow-lock.py 租约内运行。bd -C "$task_worktree" 用于选择功能上下文,但不会创建隔离锁或数据库。租约繁忙或交互快照已更改都属于阻塞情况;绝不要绕过它直接写入 bd。
uv run <core-dir>/scripts/beads-workflow-lock.py exec \
--repository-root "$repository_root" --run-id "$workflow_run_id" --timeout 0 \
-- bash -eu -c '<contiguous Beads mutation and interaction finalization commands>'
对启动根任务、每个已关闭的子任务以及已关闭的实现协调任务,均使用此失败即关闭流程。verify-feature 模式会复用独立的干净基线和暂存索引检查。关闭子任务和协调任务时,必须有与所选工作单元对应的交互;如果启动说明未产生任何行,启动检查可传入 --allow-clean。该流程只允许所选功能链路中的行,并会拒绝任何其他脏路径或不安全的交互状态:
set -euo pipefail
finalize_feature_interactions() {
work_unit_id=$1
baseline_commit=$2
allow_clean=${3:-false}
verify_args=(
--worktree "$task_worktree" --root-id <root-id>
--issue-id "$work_unit_id" --baseline-commit "$baseline_commit"
)
if test "$allow_clean" = true; then
verify_args+=(--allow-clean)
fi
worktree_result=$(uv run <core-dir>/scripts/reconcile-beads-interactions.py verify-feature \
"${verify_args[@]}")
worktree_dirty=$(printf '%s\n' "$worktree_result" | python3 -c \
'import json, sys; print(str(json.load(sys.stdin)["dirty"]).lower())')
if test "$worktree_dirty" = true; then
snapshot_sha256=$(printf '%s\n' "$worktree_result" | python3 -c \
'import json, sys; print(json.load(sys.stdin)["snapshot_sha256"])')
snapshot_mode=$(printf '%s\n' "$worktree_result" | python3 -c \
'import json, sys; print(json.load(sys.stdin)["snapshot_mode"])')
snapshot_blob=$(git -C "$task_worktree" hash-object -- .beads/interactions.jsonl)
precommit_head=$(git -C "$task_worktree" rev-parse HEAD)
cat > /tmp/dstack-feature-interactions-message <<EOF
chore: Record feature work evidence
Beads: ${work_unit_id}
EOF
git -C "$task_worktree" add -- .beads/interactions.jsonl
test "$(git -C "$task_worktree" diff --cached --name-only)" = ".beads/interactions.jsonl"
uv run <core-dir>/scripts/reconcile-beads-interactions.py verify-feature \
"${verify_args[@]}" \
--expected-content-sha256 "$snapshot_sha256" --expected-mode "$snapshot_mode" --staged
precommit_index_tree=$(git -C "$task_worktree" write-tree)
test "$(git -C "$task_worktree" rev-parse HEAD)" = "$precommit_head"
test "$(git -C "$task_worktree" write-tree)" = "$precommit_index_tree"
git -C "$task_worktree" commit -F /tmp/dstack-feature-interactions-message
interaction_commit_sha=$(git -C "$task_worktree" rev-parse HEAD)
test "$(git -C "$task_worktree" rev-parse "$interaction_commit_sha^")" = "$precommit_head"
test "$(git -C "$task_worktree" show -s --format=%T "$interaction_commit_sha")" = "$precommit_index_tree"
audit_paths=$(git -C "$task_worktree" diff-tree --no-commit-id --name-only -r "$interaction_commit_sha")
test "$audit_paths" = ".beads/interactions.jsonl"
test "$(git -C "$task_worktree" rev-parse "$interaction_commit_sha:.beads/interactions.jsonl")" = "$snapshot_blob"
audit_mode=$(git -C "$task_worktree" ls-tree "$interaction_commit_sha" -- .beads/interactions.jsonl | awk '{print $1}')
test "$audit_mode" = "$snapshot_mode"
elif test "$worktree_dirty" = false; then
uv run <core-dir>/scripts/reconcile-beads-interactions.py verify-feature \
"${verify_args[@]}" >/dev/null
interaction_commit_sha="not required — no tracked interaction append"
else
printf 'ERROR: verify-feature returned an invalid dirty state\n' >&2
return 1
fi
test -z "$(git -C "$task_worktree" status --porcelain)"
}
运行启动版本诊断,将其原样输出的行追加到 <root-id>,并调用 finalize_feature_interactions <root-id> "$startup_base_commit" true;可选的 true 允许在说明未产生任何交互行时,启动期间跟踪文件保持干净。只有当该根任务边界干净后,才能认领子任务:
skill_version_evidence=$(python3 <core-dir>/scripts/check-skill-version.py \
--skill-name implement-feature --format line)
bd -C "$task_worktree" update <root-id> --append-notes "$skill_version_evidence"
finalize_feature_interactions <root-id> "$startup_base_commit" true
在执行用户指定的认领或自动选择之前,立即捕获子任务边界:
test -z "$(git -C "$task_worktree" status --porcelain)"
task_base_commit=$(git -C "$task_worktree" rev-parse HEAD)
bd -C "$task_worktree" ready --parent <implementation-id> --claim --json
bd -C "$task_worktree" show <task-id> --json
如果用户指定了特定子任务,在执行 bd -C "$task_worktree" update <task-id> --claim 和 bd -C "$task_worktree" show <task-id> --json 之前,应用相同的干净基线规则。保留 task_base_commit,直到该子任务关闭且其交互完成最终确认。验证拒绝此边界时,绝不要暂存、还原或提交任何内容。获准执行功能 Beads 变更后,在任何常规暂停或返回之前,都要针对所选工作单元 ID 完成当前交互区间的最终确认;如果代码或无关状态仍处于脏状态,则停止并保留原样。
2. 实现边界明确的成果
修改代码前,针对选定的子任务和已评审的设计,执行语义层面的边界检查。子任务必须明确一项可独立评审的行为、一位主要负责人,以及一个切实可行的提交边界。字符数仅作警示信号,不作为正确性限制。如果子任务合并了彼此独立的成果、责任边界、文档集或提交边界,请勿编写代码:记录规划缺陷,重新开启 spec-reconcile,并将任务退回规格协调阶段,而不是在实现期间自行拆分。
在任何时候发现实质性的规划变更,都必须停止实现。行为、责任、兼容性或验收方面的实质性变更必须停止实现,并使已评审的源边界失效:重新开启 spec-reconcile 和受影响的评审 beads,将过时的评审证据标记为无效,协调设计与任务验收,提交并评审新的规格边界,只有在相关关卡全部通过后才能重新领取实现任务。不得在原地协调实质性意图,也不得继续沿用旧的评审证据。只有在不改变已评审意图、责任、兼容性、验收或评审边界的前提下,才允许原地进行编辑性澄清;记录该澄清后继续。
实现满足选定任务的最小完整变更。遵循已评审的设计和既定的仓库模式。将代码、测试、配置、迁移、可观测性、故障行为和恢复控制在任务边界内。
更新任务指定的确切读者页面。只有在交付的行为产生持久的读者需求时,才添加其他页面。将每个新页面与同一工作单元一起登记到 docs/src/SUMMARY.md 中。功能设计应继续作为已发布的审计记录,但产品文档必须能够独立使用,无需依赖这些设计。
3. 验证与审查
迭代期间,运行覆盖变更行为的最小范围检查。运行 Beads 中记录的精确任务专用验证命令;如果更改了文档,还要运行 uv run --no-project python scripts/check-docs.py。
验证和这位专注审查者的工作范围严格限定于精确的任务验收标准、声明的变更路径和受影响的检查。不要自动运行整个仓库测试套件。仅在用户明确要求,或独立于此生命周期的仓库交付政策要求时,才运行整个测试套件。修复后,仅重新运行输入有变更的检查;不要重新运行已成功且无关的检查。
可选的 Pi 适配器定义于
../dstack-core/references/PI-REVIEWER-ROSTER.md;它将逻辑上的 task 角色映射到 dstack-task-reviewer。无需单独的上下文构建器:控制器会根据所选 Beads issue、设计/文档、受影响的检查和不可变的 Git 源边界,派生一个临时任务分配。它会确保每个所选子任务恰好对应一位全新的审查者,并且绝不创建第二份持久任务分配清单。如果不存在指定的 Agent,请提供 PI-REVIEWER-ROSTER.md 中记录的显式项目本地同步方式;如果用户拒绝同步或同步失败,则明确报错。如果指定的 Agent 不可用,则明确报错,不得静默替换角色或改变审查人数。Pi 的发现、恢复、替换和 Beads 证据归属均遵循共享参考文档。
恰好启动一位初始审查者,并设置 context: fresh,重点审查正确性、安全性、可维护性、测试是否充分,以及是否符合所选任务和设计。启动前,遵循 ../dstack-core/references/REVIEW-STATE.md 和 ../dstack-core/references/REVIEW-FINDINGS.md,持久记录负责的审查 issue、审查者会话、不可变的 Git 源边界、声明的任务分配范围、当前处理状态和当前未解决的问题。除非存在明确未覆盖的风险或用户明确要求,否则不要增加用于提高信心的审查者。
解决可操作的问题。恢复同一位审查者并使用相同的运行 ID 验证修复。只有在无法恢复原审查者时,才使用新的替代审查者;如果修复实质性地改变了审查范围,则停止并遵循上述规划缺陷处理路径,而不要要求替代审查者批准不同的边界。向替代审查者提供相同的源边界、问题记录、解决情况和审查后的差异。将无法使用/替代的原因以及当前的 Review state: 记录与命令、结果、限制、问题和修复一并记录:
bd -C "$task_worktree" update <task-id> --append-notes "Validation and review evidence: ..."
4. 提交并关闭
运行 git -C "$task_worktree" status --short;识别已有变更或超出范围的变更,并将其排除在任务边界之外。
当任务会更改仓库时:
- 提交完整且范围明确的成果;
- 在提交消息中包含 Beads 任务 ID;
- 使用
git -C "$task_worktree" rev-parse HEAD获取准确的提交 SHA; - 在关闭任务前,将该 SHA 记录在任务备注中。
commit_sha=$(git -C "$task_worktree" rev-parse HEAD)
bd -C "$task_worktree" update <task-id> --append-notes "Commit evidence: ${commit_sha}"
bd -C "$task_worktree" close <task-id> --reason "Acceptance criteria satisfied; commit ${commit_sha}"
当任务确实不需要更改仓库时,验证没有预期的任务变更尚未提交,并在关闭前记录准确的理由:
bd -C "$task_worktree" update <task-id> --append-notes "Commit evidence: no commit required — <specific reason>"
bd -C "$task_worktree" close <task-id> --reason "Acceptance criteria satisfied; no commit required — <specific reason>"
关闭任务时,不得使用占位 SHA、遗漏提交字段,或使用未作解释的短语 no commit required。每个已关闭的实现任务都必须有真实的提交 SHA,或具体的不提交理由。子任务的关闭是对 Beads 的最后一次变更:之后不要再添加子任务备注。关闭后立即调用
finalize_feature_interactions <task-id> "$task_base_commit"。这会在存在跟踪行时,为每个子任务记录一条仅包含交互内容的审计提交,并证明在凝聚检查点或下一次选择之前,功能工作树保持干净。保留并报告 interaction_commit_sha;不要将其写回已关闭的子任务。
发现超出范围的工作时,应在最终子任务证据和关闭操作之前,连同来源信息一起记录,使其所选谱系交互行保留在该子任务已验证的边界内:
bd -C "$task_worktree" create "<discovered work>" \
--type <bug|spike|chore|task> \
--deps discovered-from:<task-id> \
--json
缺陷使用 bug,带退出条件的有限范围事实调查使用 spike,维护工作使用 chore,其他情况使用 task。不要创建实现类 decision 来推迟尚未解决的产品策略;应将该问题交回规格协调流程。只有当发现的问题确实是安全完成任务的前置条件时,才添加阻塞边。
5. 持续推进,直到功能全部完成
任务边界或提交边界都不是停止点。每个子任务成功提交并关闭后,在认领下一个子任务之前,必须根据实现、评审和验证的新证据进行一次内聚性检查。重点检查是否出现了新的权责边界、迁移、外部依赖或高风险副作用类别。如果没有发现独立价值或评审边界,就继续处理同一功能。仅有偶然出现的复杂性,不构成拆分依据。
如果证据表明剩余成果具有独立价值且可单独评审,则捕获干净的交互基线,暂停实现协调器,并在该协调器上记录内聚性缺陷及其来源。返回前,完成该协调器的交互周期。不要在实现循环中创建替代子任务或新的 Epic,也不要继续在内聚性不足的协调器下认领剩余工作。通过常规功能规划权限返回,定义存在依赖关系的功能 Epic,保留用户权限和现有 Beads 依赖语义,并在恢复实现前通过必需的设计/评审关卡。保留已完成的工作,仅在确属前置条件时添加 blocks 边。
内聚性检查通过时:
- 确保功能工作树干净,并在认领任何任务前捕获新的
task_base_commit=$(git -C "$task_worktree" rev-parse HEAD); - 在同一实现协调器下查询并以原子方式认领下一个就绪子任务;
- 实现、验证、评审、提交、关闭该子任务,并完成其交互边界;
- 只要仍有未关闭的实现子任务,就重复上述过程。
没有就绪子任务时,检查所有未关闭的子任务及其阻塞边。解决非决策类阻塞、过时的依赖状态或图结构缺陷,然后继续。对于正在外部运行的前置任务,应协调并等待,而不是重复执行或放弃;对于暂时性的外部故障,应重试,同时完成该功能中其他就绪的工作。只有在需要豁免时,无法进行必需验证才需要交由用户决策。不要因为一项任务受阻,就停止处理另一项已就绪的任务。
只有当所有剩余的未关闭子任务都因缺少用户决策而受阻时,才暂停并询问用户;每次只询问一个决策问题,并在收到每个答复后立即继续。此状态仅适用于迁移后的工作:原生 /plan-features 输出必须已经包含所有实现决策。
如果实现过程中发现涉及行为、权责、兼容性、验收或新的独立边界的重大规划缺陷,应停止并遵循第 2 节中的规划缺陷失效处理流程。不要沿用旧规格或评审证据继续推进。如果发现的内容仅是编辑性澄清,且不改变已评审的意图,则记录后继续。原生 /plan-features 输出应能避免这两种情况,但该关卡用于防止实现过程中发现的偏差。
6. 完成实施协调器
所有必需的子项都已关闭或明确延期后,要求功能工作树保持干净,记录协调器边界,将已交付行为与 design.md 进行比较,运行实施级验收检查,记录证据,并关闭实施协调器:
test -z "$(git -C "$task_worktree" status --porcelain)"
coordinator_base_commit=$(git -C "$task_worktree" rev-parse HEAD)
bd -C "$task_worktree" update <implementation-id> --append-notes "Implementation acceptance evidence: ..."
bd -C "$task_worktree" close <implementation-id> --reason "Required implementation work complete; acceptance verified"
finalize_feature_interactions <implementation-id> "$coordinator_base_commit"
协调器关闭是该边界内最后一次 Beads 变更;之后不要再追加协调器备注。关闭前必须提交仅包含交互内容的提交,并确保最终状态干净。这些功能分支审计提交会为 /close-feature 保留历史记录;它们不能取代后续的 prepare、finalize,以及对关闭或交付期间生成的行进行的合并后溯源验证。
协调器关闭后清除过时的默认选择,但仅当它仍指向此功能时:
test "$(git -C "$task_worktree" config --get dstack.activeFeature || true)" != "<slug>" || \
git -C "$task_worktree" config --unset-all dstack.activeFeature
只有在实施协调器关闭后,或所有剩余子项都同时受阻于明确的用户决策时,才能返回。报告规范功能引用和人类可读名称、所有已完成的任务 ID 和提交、工作树、变更、文档、验证、审查、发现的工作、实施与交互审计提交、协调器状态,以及下一个生命周期事项。始终包含一行 Recommended next step:
- 实施协调器成功关闭时,建议运行
/close-feature <slug>; - 因等待决策而暂停时,说明实施受阻,指出阻塞类别,并且只提出下一个决策问题;
- 因验证、审查、环境、依赖项或仓库状态问题而受阻时,说明
/implement-feature <slug>恢复前所需的确切建议或批准。
不要只以状态摘要结束。建议必须明确说明该功能是否已准备好进入收尾,或是否需要先征求用户意见。