Back to skills
SKILL.md
Subagent Driven Development Zh
BSecurity子代理驱动开发、每个任务派一个全新子代理实现、任务级评审加最终整分支评审、修复循环与五轮熔断、用账本文件抗上下文压缩、按任务复杂度选模型。当用户说「按这份计划派子代理执行」「每个任务开一个新 Agent 做」「实现完自动评审再进下一个」「上下文会被压缩,进度别丢」「这份 plan 你来调度执行」时使用。主循环:建隔离工作区与账本、通读计划并做冲突预扫 → 逐任务抽简报、派实现者、生成评审包、派任务评审人(spec 符合度与代码质量两个判定缺一不可)→ 有问题进修复循环,每轮一次修复加一次限定范围复审,最多五轮,到顶后逐条裁决并记账 → 全部完成后做整分支终审、一次性修复、裁决残留 → 收尾交给开发分支收尾。硬规则:不为了问一句而停下来,能裁决就裁决并记账;协调者自己不动手改代码;子代理不得再派子代理。
- 2 stars
- 0 votes
- 0 copies
- 0 views
- Added October 13, 2026
Security analysis
85/100- Performs destructive filesystem operations
Pro scans all 8 files and shows the line behind each finding
npx -y skills add po-et/workbuddy-skills --skill subagent-driven-development-zh --agent claude-codeAre you the author of Subagent Driven Development Zh?
Add the live security badge to your README. It updates with every re-scan.
[](https://www.skillsdirectory.com/skills/po-et-subagent-driven-development-zh)---
name: subagent-driven-development-zh
description: 子代理驱动开发、每个任务派一个全新子代理实现、任务级评审加最终整分支评审、修复循环与五轮熔断、用账本文件抗上下文压缩、按任务复杂度选模型。当用户说「按这份计划派子代理执行」「每个任务开一个新 Agent 做」「实现完自动评审再进下一个」「上下文会被压缩,进度别丢」「这份 plan 你来调度执行」时使用。主循环:建隔离工作区与账本、通读计划并做冲突预扫 → 逐任务抽简报、派实现者、生成评审包、派任务评审人(spec 符合度与代码质量两个判定缺一不可)→ 有问题进修复循环,每轮一次修复加一次限定范围复审,最多五轮,到顶后逐条裁决并记账 → 全部完成后做整分支终审、一次性修复、裁决残留 → 收尾交给开发分支收尾。硬规则:不为了问一句而停下来,能裁决就裁决并记账;协调者自己不动手改代码;子代理不得再派子代理。
author: Captain
version: 0.1.0
display_name: "子代理驱动开发"
display_name_en: "Subagent-Driven Development (zh)"
description_zh: "用一份实施计划驱动子代理流水线:每任务一个全新实现者、任务级双判定评审、五轮封顶的修复循环、账本抗压缩、整分支终审;协调者只调度不下场。"
description_en: "Drive a plan with a subagent pipeline: a fresh implementer per task, a two-verdict task review, a five-round fix loop, a ledger that survives compaction, and a final whole-branch review."
examples_zh:
- "按这份计划派子代理执行"
- "每个任务开一个新 Agent 做,实现完自动评审再进下一个"
- "这份 plan 你来调度执行"
examples_en:
- "Execute this plan with a fresh subagent per task"
- "Review each task before moving to the next one"
- "Keep progress in a ledger so compaction cannot lose it"
metadata:
{ "openclaw": { "requires": { "bins": ["git", "bash"] }, "os": ["darwin", "linux"], "emoji": "🤖" } }
---
# 子代理驱动开发
执行计划的方式是:**每个任务派一个全新的实现者子代理**,每个任务之后做一次任务评审(spec 符合度 + 代码质量),全部完成后再做一次覆盖整个分支的终审。
**为什么用子代理:** 你把任务派给拥有独立上下文的专职代理。通过精确构造它们的指令与上下文,你保证它们专注并把事情做成。它们**不应该**继承你这次会话的上下文与历史——你要恰好给它需要的那些。这同时保住了你自己的上下文,让它专心做协调。
**核心原则:每任务一个全新子代理 + 任务评审(spec + 质量)+ 覆盖面广的终审 = 高质量 + 快迭代。**
**旁白节制:** 工具调用之间最多讲一行,记录由账本和工具结果承担。
**连续执行:** **不要**在任务之间停下来向用户请示。把计划里的任务一口气执行完。只有下面四件事、或者全部任务完成,才停。「要继续吗?」和进度汇报是在浪费用户时间——他们让你执行计划,你就执行。
**要裁决,不要停摆。** 一个正在跑的计划不该等人。冲突、歧义、计划缺陷、你本想申请突破的上限——**自己裁决**。Spec 是有约束力的权威,计划是对 spec 的论证,两者都没答案的地方由你的判断定夺。每一个决定都记进账本,格式是 `裁决:<你决定了什么> —— <为什么> —— <如果错了代价是什么>`,然后继续。裁错了,代价是用户看得见、也能回退的返工;为了一个问题把会话停一天,代价是他们的一整天,且什么也换不来。
**只有这四件事让你停:** 不可逆或破坏性操作;涉及安全的动作;这个工作树之外、按惯例应当先问的副作用(合并、推送到共享分支、发布);计划烂到每条前进路径都是猜。遇到这四种,停下来问。
## 何时用
- 手上有一份实施计划,任务之间**大体独立**
- 想**在当前会话里**执行完,不做会话切换
- 你的平台支持派发子代理
不适用:没有计划(先去做头脑风暴与写计划);任务之间强耦合(先回去重新拆);没有子代理能力(改用「执行实施计划」技能 `executing-plans-zh`)。
## 准备
确保工作发生在隔离工作区里:用「Git 工作树隔离工作区」技能(`using-git-worktrees-zh`)新建或确认。**未经用户明确同意,绝不在 main/master 上开始实现。**
**对话记忆挺不过上下文压缩。** 真实会话里,丢了位置的协调者重新派发过整段已完成的任务序列——这是观察到的最昂贵的失败。**进度要记在账本文件里,不能只记在待办里。**
- **一份计划一个工作目录**:技能开始时执行 `{baseDir}/scripts/sdd-workspace.sh PLAN_FILE`,它会打印这份计划专属的、已被 git 忽略的目录(`<仓库根>/.sdd/<计划文件名>/`),**这份计划**的全部产物都放这儿:账本、简报、报告、评审包。别人的计划目录不归你读也不归你写。
- 检查 `<工作目录>/progress.md` 是否已存在。若它第一行指的就是你这份计划,则带 `任务 <N>:完成` 那行的任务**已经做完**——不要重派,从第一个没有该行的任务继续。若某个任务的最后一行是修复轮次,说明它在循环中途,从下一轮继续。第一行指向**另一份**计划的账本,属于别人的进度:原地留着,另起自己的。
- 建账本时第一行写明身份:`# SDD 账本 —— 计划:<计划文件路径>`。
- **账本是你的恢复地图**:它记下的提交在 git 里真实存在,哪怕你的上下文已经不记得创建过它们。压缩之后,**信账本和 `git log`,不要信自己的回忆**。
- `git clean -fdx` 会毁掉工作目录(它是被忽略的临时区);真发生了,从 `git log` 恢复。
开场三条命令:
```bash
# 1. 解析本计划专属工作目录(顺带建好自我忽略的 .gitignore)
WS=$(bash "{baseDir}/scripts/sdd-workspace.sh" docs/plans/2026-09-17-feature.md)
# 2. 断点续跑:账本第一行必须指向本计划;已带「完成」行的任务不要重派
head -1 "$WS/progress.md" 2>/dev/null
grep -n '完成' "$WS/progress.md" 2>/dev/null
# 3. 新建账本时先写身份行
[ -f "$WS/progress.md" ] || echo "# SDD 账本 —— 计划:docs/plans/2026-09-17-feature.md" > "$WS/progress.md"
```
**通读计划一次**,记下它的上下文与全局约束,为每个任务建一条待办。计划若点名了 Spec,把 spec 也读了:**spec 是计划论证所依据的权威**,计划内部的冲突以 spec 为准裁决。找不到 spec 的计划要在账本里记一笔,说明此后的裁决都是暂定的。
派发任务 1 之前,**做一次冲突预扫**,边查边把查了什么写下来:
- 互相矛盾的任务,或与计划「全局约束」矛盾的任务
- 计划明文要求、但评审标准视为缺陷的东西(不做任何断言的测试、逻辑块的逐字复制)
**预扫的产出是一张表,不是一句结论。** 每一对共享文件或接口的任务占一行:两个任务是谁、一个产出什么对上另一个消费什么、你发现了什么。每个任务再占一行:它自己的正文是否自洽——它规定的测试对上它规定的代码,它创建的文件对上它后面又去改的文件。**没有这些行的「预扫干净」不算预扫。**
把表写进账本。执行开始前把发现的每一条都裁决掉(每条都对着授权它的计划正文裁),并把裁决记进账本。预扫干净就默默继续。修复循环仍然是那些只有在实现时才浮现的冲突的兜网。
## 选模型
**用能胜任的最弱模型**,以省成本、提速度。
- **机械型实现任务**(独立函数、规格清楚、1 到 2 个文件):用便宜的快模型。计划写得好时,多数实现任务都是机械的。
- **集成与判断型任务**(多文件协调、模式匹配、调试):用标准模型。
- **架构与设计型任务**:用手上最强的模型。**整分支终审属于这一类**——用最强模型,不要用会话默认。
- **评审任务**:同样按判断力选,随 diff 的体量、复杂度与风险缩放。小的机械 diff 不需要最强模型;微妙的并发改动需要。修复后的限定范围复审用中低档。
- **修复循环升级(第 4 到 5 轮)**:用比卡住的那个实现者**高至少一档**的模型。
**派发时永远显式指定模型。** 不写模型会继承你会话的模型——往往是最强也最贵的那个,这会悄悄让本节失效。
**轮数比单价更重要。** 墙上时间与上下文成本随子代理的轮数增长,而最便宜的模型在多步工作上经常多花 2 到 3 倍的轮数,总成本反而更高。**评审人、以及要从散文描述里干活的实现者,floor 定在中档。** 当任务的计划正文里已经写着要写的完整代码时,实现就是誊写加测试,那个实现者用最便宜档。单文件机械修复也用最便宜档。
## 主循环
**同形小任务要合批。** 计划里若有若干个任务,每个都是同一种小的、独立的改动(同样的一行修复、常量替换、字段新增,散布在多个文件里),**不要一任务一个子代理**。写**一份**派发简报,列出每个文件及其改动,整批发给**一个**子代理,把它的 diff 当作一个单元评审。一任务一派发留给那些需要自己的判断、自己的测试、自己的评审面的工作。
**你粘进派发提示词的一切、以及子代理打印回来的一切,都会在本次会话余下的时间里常驻你的上下文,并在之后每一轮被重读。产物一律以文件交接。**
**等待子代理时:** 不要用短超时去轮询等待接口,也不要一头扎进一次静默的无限等待。手上还有本地活(更新账本、打包下一个评审、读报告)就继续干,子代理的结果会自己到。真正空闲时,**按有界时段等待**(平台允许的话,五到十分钟一段),每段之间发一行状态,并核对在跑的子代理:列出来,追一下那些跑完却没汇报的。有界时段几乎保住了长等待的全部效率,同时保证卡死或走丢的子代理在几分钟内被发现,而不是拖到会话末尾。
### 1. 派发实现者
派发前先记下 BASE(`git rev-parse HEAD`)——评审包和修复轮 diff 都要用。
- **任务简报:** 派发前执行 `{baseDir}/scripts/task-brief.sh PLAN_FILE N`,它把该任务的完整正文抽到一个独立命名的文件并打印路径。组织派发词时让**简报成为需求的唯一来源**。你的派发词应包含:(1) 一句话说明这个任务在项目里的位置;(2) 简报路径,并写明「先读这个——它是你的需求,里面的数值要逐字照用」;(3) 前序任务里简报无从得知的接口与决策;(4) 你对简报中任何歧义的裁决;(5) 报告文件路径与报告契约。**精确数值(数字、魔法字符串、签名、测试用例)只出现在简报里。永远不要让子代理去读整份计划文件。**
- **报告文件:** 按简报命名(简报 `…/task-N-brief.md` → 报告 `…/task-N-report.md`),写进派发词。实现者把完整报告写在那儿,回复里只给状态、提交、一行测试摘要和顾虑。
- **一条派发词只描述一个任务,不是会话史。** 不要把累积的前序摘要(「任务 1 到 3 之后的状态」)粘进后续派发——真实会话里有一条派发词达到 4 万余字符,其中 99% 是粘贴的历史。全新子代理只需要它的任务、它要碰的接口、以及全局约束,别的都不要。
- 派发词带着**不得再派子代理**的契约(模板里已有):实现者永不派发子代理——不派助手,尤其不派评审人。评审由你在它汇报之后发起。真实会话里,工作者自己生成的评审人,每一个都在重复协调者本就会派的那次任务评审——白白多出一整个评审席位。
- 若前序任务在本任务涉及的区域寄存过(parked)问题,在派发词里带上指向那条账本记录的指针。
- 记下实现者的代理身份(派发结果里),第 1 到 3 轮修复要恢复这个代理。
- **永远不要并行派发多个实现子代理**(会冲突)。
模板:`{baseDir}/references/implementer-prompt.md`
### 2. 处理报告
实现者会返回四种状态之一:
- **DONE:** 生成评审包(`{baseDir}/scripts/review-package.sh PLAN_FILE BASE HEAD`,它打印它写入的文件路径;**BASE 用你派发前记下的那个,绝不要用 `HEAD~1`**——那会悄悄丢掉多提交任务里除最后一个之外的全部提交),然后带着这个路径派任务评审人。
- **DONE_WITH_CONCERNS:** 活干完了但有疑虑。**先读疑虑再往下**。疑虑涉及正确性或范围的,先处理再评审;只是观察(「这个文件有点大了」)的,记下来继续评审。
- **NEEDS_CONTEXT:** 缺信息。补上缺的上下文,重新派发。
- **BLOCKED:** 做不下去。判断阻塞类型:上下文问题 → 补上下文、同模型重派;需要更强推理 → 换更强模型重派;任务太大 → 拆小;**计划本身错了 → 裁决更正、记账、把裁决带进重派的派发词**。
**绝不**忽略一次升级,也**绝不**在什么都没变的情况下让同一个模型重试。实现者说它卡住了,就必须有东西改变。
实现者**提问**时——不管是开始前还是做到一半——**清楚完整地回答**,需要就补上下文,不要催它赶紧开写。
### 3. 任务评审
任务评审是**任务范围内的关卡**,覆盖面广的评审只在最后做一次。**永远不要跳过任务评审**,也**绝不接受缺少任一判定的报告**——spec 符合度**和**任务质量两个判定缺一不可。实现者的自审**永远不能**替代任务评审,两者都要。
- **把 diff 以文件形式交给评审人**:执行 `{baseDir}/scripts/review-package.sh PLAN_FILE BASE HEAD`,把它打印的路径给评审人(没有 bash 时:`git log --oneline`、`git diff --stat`、`git diff -U10` 三条的输出重定向到同一个独立命名的文件)。这样评审包**不进入你自己的上下文**,而评审人一次 Read 就能看到提交列表、变更统计和带上下文的完整 diff。**绝不派一个没有 diff 文件的任务评审人。**
- **评审人的输入**:同一份简报文件、报告文件、评审包三条路径,外加约束这个任务的全局约束。
- 交给评审人的**全局约束块是它的注意力透镜**。从计划的「全局约束」一节或 spec 里**逐字照抄**有约束力的要求:精确数值、精确格式、以及组件之间被明文规定的关系(「和 X 同样的布局」「与 Y 一致」)。评审人模板里已经带了流程性规则(YAGNI、测试卫生、评审方法),约束块留给**这个项目**的 spec 要求。
- 不要在没有具体、任务相关理由的情况下加「把所有用法都查一遍」「有用的话跑一下竞态测试」这类开放式指令。
- 不要让评审人重跑实现者已经在同一份代码上跑过的测试——实现者的报告就是测试证据。
- **不要替评审人预判结论**——绝不指示评审人忽略或不要报某个问题。你认为某个发现会是误报,就让评审人提出来,在修复循环里裁决它。**如果你正在写的提示词里出现「不要报」「别把 X 当缺陷」「最多算 Minor」「这是计划选择的」——停:你在预判,通常是为了给自己省一轮循环。**
任务评审人可能报「⚠️ 无法从 diff 判定」的条目——那些要求活在未改动的代码里,或跨任务。它们不阻塞其余评审,但**你必须在标记任务完成前逐条自己解决**:你手里有评审人没有的计划与跨任务上下文。确认某条确实是缺口的,按 spec 评审失败处理,与其他发现一起进修复循环。
模板:`{baseDir}/references/task-reviewer-prompt.md`
### 4. 修复循环
评审报出 spec ❌、任何 Critical 或 Important 发现、或你确认为真实缺口的 ⚠️ 条目时,循环触发。
循环开始前,有两条路立刻出局:
- **Minor 发现**随手记进账本(`任务 <N>:minor(延后):<一句话>`),并让整分支终审去看那份清单,由它分诊哪些必须在合并前修掉。**没人读的汇总等于悄悄丢弃。** Minor 永不进循环。
- 被标为**计划授权**的发现——或任何与计划正文要求相冲突的发现——**归你裁决**:把发现与计划正文放在一起权衡,以 spec 为有约束力的权威做决定,**在行动之前把裁决记进账本**。不要因为「计划要求这么写」就驳回发现,也不要在没有记录裁决的情况下派一个违背计划的修复。
其余全部进循环。**一轮 = 一次修复派发 + 一次限定范围复审。每个任务最多五轮。**
- **第 1 到 3 轮 —— 恢复原来那个实现者。** 把待办发现**逐字**发给它。它的上下文是完整的:它知道任务、代码和自己的选择。若你的运行时没法给活着的子代理再发消息,就派一个全新实现者,带上简报路径、报告文件路径和发现——**报告文件在两种情况下都是持久记忆**。
- **第 4 到 5 轮 —— 派一个全新实现者,用更强的模型**(见选模型),带上简报路径、报告文件路径、待办发现,以及这句框定:「先前的实现者尝试过这个任务 [N] 次,现在归你。读报告文件了解已经试过什么。」熬过三次恢复的循环,通常意味着这个实现者看不见自己的问题——**换新眼睛 + 提一档能力,一步到位**。
- **每一轮,两种方式都一样:** 实现者修复、**重跑覆盖被改代码的测试**、把修复报告追加到同一个报告文件、返回简短契约。重新派评审之前,先确认修复报告里有**覆盖测试、执行的命令、以及输出**三样,齐了才派复审。在修复消息里**点名覆盖测试文件**——一行修复不需要跑整个套件。
- **复审是限定范围的。** 执行 `{baseDir}/scripts/review-package.sh PLAN_FILE FIX_BASE HEAD`(FIX_BASE 是上一次评审看到的 head),用 `{baseDir}/references/re-review-prompt.md` 派发,附上发现清单、简报、报告文件和打印出的 diff 路径。复审人对每条发现给出「已解决 / 未解决」,并**只**在修复 diff 里找新的破坏。修复 diff 里新出现的 Critical/Important 破坏并入待办发现清单。范围之外的观察进账本作为延后 minor——**它们永不延长循环**。
- **每轮之后**追加账本:`任务 <N>:修复第 <R>/5 轮(已解决 <X> 条,待办 <Y> 条 —— <发现一句话>;提交 <a7>..<b7>)`
**绝不在协调者会话里自己修发现**——你的上下文要保持干净以做协调,而且协调者的修复会跳过评审。
**熔断:** 第 5 轮的复审仍留有待办发现时,**停止派发**。你自己逐条裁决——你手里有评审人没有的计划与跨任务上下文:
- **评审人错了,或这点可争议:** 寄存它——`任务 <N>:寄存 —— <发现> —— 裁决:<为什么这段代码站得住>`。终审能看到双方说法。
- **是真的,但下游没有东西建在它上面:** 同样寄存,裁决里写明它是真的、已延后。
- **是真的且承重**——后续任务建在它上面,或它暴露了计划缺陷:裁决出**能解开下游阻塞的最小改动**,记为 `任务 <N>:裁决:<发现> —— <你决定了什么、为什么>`,并把它带进下一个任务的派发词。**悄悄寄存一个结构性失败,会让每个依赖它的任务都建在上面。** 只有当这个缺陷让每条前进路径都成了猜,才停下来。
**只在封顶时裁决。** 提前裁决来结束循环,是换了个名字的预判。**每一次裁决都是一条账本记录——禁止悄悄丢弃。**
### 5. 完成任务
评审干净时——或者封顶后每条待办发现都已寄存并带裁决——把完成行和其余记账一起追加进账本:
- `任务 <N>:完成(提交 <base7>..<head7>,评审干净)`
- `任务 <N>:完成(提交 <base7>..<head7>,寄存 <K> 条)`(熔断跳闸后)
然后标记待办完成、继续下一个。**评审仍有既没修复、也没在封顶时带裁决寄存的 Critical/Important 问题时,绝不进入下一个任务。**
## 终审
整分支终审同样要评审包:执行 `{baseDir}/scripts/review-package.sh PLAN_FILE MERGE_BASE HEAD`(MERGE_BASE 是分支的起点,例如 `git merge-base main HEAD`),把打印的路径写进终审派发词,让终审人读一个文件,而不是自己用 git 命令重新推导分支 diff。**用手上最强的模型派发**(见选模型),提示词用仓库里的代码评审技能(如 `code-review-zh` / `code-review-five-axis-zh`)。把它指向账本里的「延后 minor」和「寄存」行,让它分诊哪些必须在合并前修掉。
终审若返回发现,**派一个修复子代理,带完整发现清单**——不要一个发现一个修复者。逐发现的修复者各自重建上下文、各自重跑套件;真实会话里,终审的逐条修复浪潮比它全部任务加起来还贵。然后**只做一次**限定范围复审(对修复区间跑 `review-package.sh`,用复审模板)。残留发现按任务循环熔断的办法裁决:带裁决寄存,或裁决承重的那些并记下你的决定。**这里也只有那四类情况能让你停。没有第二轮修复浪潮**——残留的承重发现会在开发分支收尾呈现选项时浮到用户面前。
## 输出契约:收尾
删任何东西之前,把账本里含 `裁决:` 的每一行——预扫裁决、寄存发现、熔断裁决,一条不落——收集进你的最终消息,放在「**我做的裁决**」标题下,按你做出的顺序排列,每条附上「如果错了代价是什么」。**这份清单是穷尽的**:账本里有的裁决,清单里就必须有。那是你替用户做的决定唯一能传达到他们的地方——他们读完,把你搞错的地方返工掉。**一个随工作目录一起消失的裁决,是一个在暗处做的决定。**
整分支终审干净、其修复已合入之后,删掉这份计划的工作目录(`rm -rf <工作目录>`)——现在 git 历史就是记录。**兄弟目录属于别的计划,别碰。**
然后使用「开发分支收尾」技能(`finishing-a-development-branch-zh`)。
## 红线与常见借口反驳
| 借口 | 现实 |
|------|------|
| 「spec 符合度差不多就行」 | 评审人找到了 spec 缺口 = 没做完。修掉,或者走到封顶再裁决——只有这两个出口。 |
| 「我自己修算了,派发太麻烦」 | 协调者的修复污染你的上下文,还跳过评审。恢复那个实现者。 |
| 「再来一轮就收敛了」 | 过了封顶,轮次不会收敛——那个失败是结构性的。裁决并分流。 |
| 「反正评审人又会找出新东西」 | 限定范围复审只验证修复,它不能乱逛。未改动代码上的新发现进账本,不进循环。 |
| 「这条发现明显不对,我直接丢掉」 | 你只在封顶裁决,且每条裁决都是账本记录。禁止悄悄丢弃。 |
| 「修复很小,复审省了吧」 | 没评审的修复正是回归落地的方式。每轮都以一次限定范围复审结束。 |
| 「评审拖慢了循环」 | 没有评审的循环只是没验证过的空转。评审是这个循环的刹车和方向盘。 |
| 「记账本是额外开销」 | 账本是压缩之后唯一活下来的东西。没有账本的协调者重新派发过整段已完成的任务序列。 |
| 「实现者自己生了个评审人,白赚一份保障」 | 那是对同一份 diff 的重复席位,任务评审才是关卡。工作者自生的评审人是要上报的缺陷,不是严谨。 |
---
改编自 [obra/superpowers](https://github.com/obra/superpowers) 的 `subagent-driven-development`(MIT)。改动见 ATTRIBUTION.md。
Files in this skill
- ATTRIBUTION.md
- SKILL.md
- references/implementer-prompt.md
- references/re-review-prompt.md
- references/task-reviewer-prompt.md
- scripts/review-package.sh
- scripts/sdd-workspace.sh
- scripts/task-brief.sh
Attribution
Comments
Loading comments…
Newsletter
Get the weekly list of safe new skills, and the ones we pulled.