【免费下载链接】firstmate
Talk to one agent. Ship with a crew.
导读:本指南围绕 firstmate 仓库中scout-completion技能(.agents/skills/scout-completion/SKILL.md)展开,讲解侦察型(scout)任务完成后的一整套收尾与晋升(promotion)机制:如何以自包含报告为唯一交付物安全回收临时工作树、如何通过 captain-hold 共享完成门控放行清理、视觉类成果如何遵循 crew 托管的 Lavish 看板契约,以及在实施被单独授权时如何用bin/fm-promote.sh原地晋升而非重复派单。读完本文,你将掌握 firstmate 中 scout→ship 全生命周期中每一个判定点、命令行参数与底层守卫的完整用法。
一、背景:scout 任务在 firstmate 中的定位
firstmate 是"Talk to one agent. Ship with a crew."的 Agent 发行版:你只与 firstmate 对话,由它调度整个 crew(README.md)。在任务形态上,firstmate 明确区分两种任务(README.md):
- Ship(交付型):交付经授权的代码变更,产物是 PR、本地合并或按项目模式落地的变更;
- Scout(侦察型):交付的是知识,而不是代码变更。
按 AGENTS.md 的正式定义,scout 任务的产物是data/<id>/report.md(独立调查报告),绝不产出 PR。它适用于以下场景:船长明确要求独立的"知识型/设计型"交付物,或存在会实质影响"做什么、是否做"的不确定性——即调查、诊断、规划、复现、审计类工作。
scout 任务在底层由bin/fm-spawn.sh --scout创建,并在任务元数据中记录kind=scout(bin/fm-spawn.sh)。与 ship 任务的关键差异在于:scout 不记录任何交付姿态(mode / yolo / ship branch),它的工作树被声明为**临时(scratch)**性质,唯一的工作产品是报告文件。
二、完成即报告:自包含报告是丢弃工作树的唯一前提
scout-completion技能的第一条硬性约束是:
A completed scout must leave a self-contained report before its scratch worktree can be discarded.
也就是说,scout 的临时工作树只有在报告已存在的情况下才允许被丢弃。这一约束在清理脚本中有对应的实现证据:bin/fm-teardown.sh 的头部注释明确写道:
Scout tasks (kind=scout in meta) carve out of that check: their worktree is declared scratch and the report at
data/<task-id>/report.mdis the work product. Teardown proceeds only once the report exists and the shared unresolved-decision completion gate verifies its captain-held inventory.
对应地,teardown 在关闭任务时以--report "$data_relative/$ID/report.md"将报告写入积压任务的完成字段(bin/fm-teardown.sh),data/<id>/report.md就是 scout 的"完成链接"。
"自包含"(self-contained)的实操含义:报告必须承载调查的全部结论、证据与后续建议,因为工作树随即被回收,一切留在工作树里而未写进报告的信息都会永久丢失。firstmate 对信息边界的规范也与此一致——任务级备注属于积压条目,而调查发现必须进入 scout 报告(AGENTS.md)。
三、收尾三动作:读取转达、记录 Done artifact、重新评估队列
技能规定 scout 完成后 firstmate 需要依次执行三个动作:
- 读取并转达(read and relay):完整读取
data/<id>/report.md,将调查发现转达给相关方。注意角色约束——ship 与 scout worker 从不直接与船长对话,所有通信都经 firstmate 中转(AGENTS.md)。 - 将报告记录为 Done artifact:报告本身即为该任务的完成产物(见上文 teardown 的
--report写入路径)。 - 重新评估队列(re-evaluate the queue):调查往往会改变后续待办——某个问题被排除了、某个方案被证实不可行、或产生新的实施建议,因此 scout 收尾后应结合报告重新审视 backlog 队列。
四、报告只能建议实施,绝不授权实施
技能中有一条容易被忽略、但极其关键的权力边界:
A report may recommend implementation but does not authorize it.
scout 报告的定位是"知识交付物",它可以建议实施某项修复、可以描述复现步骤与根因,但它本身不构成实施授权。实施是一项独立的授权决策,必须由船长(或按项目既定授权流程)另行批准。这条边界的意义在于防止"调查结论被自动当作开工令"——在 firstmate 的项目边界设计中,crew 对项目的一切代码变更都必须位于配置好的合并授权(merge authority)之后。
五、共享完成门控:先加载 captain-hold-lifecycle
技能要求:在把调查或任何视觉评审视为"完成"之前,必须加载captain-hold-lifecycle;teardown 会强制执行这一共享完成门(shared completion gate)。
这条要求的实质是:scout 的调查结论可能触发或关联"船长决策"(captain call)。在 firstmate 中,决策不是独立实体,而是被船长持有的普通积压任务(docs/captain-hold-lifecycle.md)。因此,scout 的清理流程必须经过bin/fm-captain-hold.sh的verify子命令——它是专为 scout teardown 设计的只读检查(docs/captain-hold-lifecycle.md),在移除任何源码状态之前、检查报告之后运行,校验三件事:
- 记录的 attestation(已验证清单)存在;
- 清单中每个条目的 captain-held 任务仍然"持久":要么仍处于活动 hold 状态,要么已带有记录的 answer;
- 自上次
complete之后没有新开启的 keyed 状态决策。
其中第三项一旦失败,verify即拒绝放行,修复方式是重新运行complete;--force则是船长明确批准的丢弃逃生通道,但它不会解除推迟(deferral),也不会代替船长回答——它授权丢弃未落地的工作,绝不授权丢弃船长的提问(docs/captain-hold-lifecycle.md)。
从源码结构看,这一门控被设计为"共享":verify是只读的通用检查,任何一处会销毁 scout 源码状态的清理路径都必须经过它,从而保证"船长决策未被回答/复核时,调查源码绝不会被静默抹除"。该机制的完整回归套件位于 tests/fm-captain-hold-lifecycle.test.sh,其中明确覆盖了"仅报告、未解决船长决策的 scout 拒绝--none完成"与"非强制的 scout teardown 始终要求持久清单校验"两类场景(docs/captain-hold-lifecycle.md)。
六、视觉成果:遵循 crew 托管的 Lavish 看板契约
当 scout 的交付物是一个供船长迭代的视觉 artifact(如 HTML 报告、看板卡片)时,技能要求:
keep it alive and follow the crew-hosted Lavish board contract in
docs/configuration.mdrather than arming or polling the board from firstmate.
其核心原则是所有权归属:托管 Lavish 看板的活跃任务(worker)拥有该看板的 listener,firstmate 作为调度方绝不亲自 arm 或轮询看板。具体契约记载于 docs/configuration.md,要点如下:
| 环节 | 操作 | 说明 |
|---|---|---|
| 打开 artifact | lavish-axi打开artifact.html | 保存会话以识别看板所在服务器,轮询前必须存在有效会话证据 |
| 武装(arm) | bin/fm-procevent-lavish.sh arm <artifact.html> --for <task-id> | 仅 worker 执行;arm在 process-event 所有者确认 listener 已运行后才打印armed;任务无有效端点元数据时拒绝武装 |
| 确认一轮(re-arm) | 同一 owner 再次arm | 即对该轮捕获的确认;可携带--agent-reply-file <path>暂存 agent 回复 |
| 结束终轮(conclude) | bin/fm-procevent.sh handled <source-id> <sequence> | 终态结果(含session_ended、空 End)送达 owner 并附带停止指令,handled是唯一收尾与退役方式 |
要点提醒:
- 武装时若同看板的旧 listener 在确认窗口内仍持有看板,
arm以still-listening而非armed退出,新注册需等源退役后重新武装才生效; - 捕获结果以不可变的 task-owner 路由证据直接投递到该任务的 steering inbox,不需要 firstmate 的
check唤醒; - 只要存在未确认的捕获轮,一切退役路径(含 runner 的终态退役与显式
retire)都会拒绝,并点名需要先确认的轮次; - 若托管 worker 无法恢复,先重启 worker 重新托管,firstmate 的守卫式接管仅作为最后手段,且必须先证明旧声明已死亡。
这一契约的意图很明确:看板的"反馈回路"归 worker 所有,firstmate 只负责在结果产生后读取与决策,从而避免调度方与执行方对同一设备的并发争用。
七、晋升路径:用 fm-promote.sh 原地晋升,绝不重复派单
当实施被单独授权后,技能给出的路径是:
promote the existing scout through
bin/fm-promote.shrather than creating a duplicate task.
晋升(promotion)的核心理念是原地换约(in-place contract flip):worker 的窗口、工作树、已加载上下文全部保留,只有契约发生变化。bin/fm-promote.sh头部注释对此有精确描述(bin/fm-promote.sh)。
7.1 命令用法
fm-promote.sh <task-id> --mode <no-mistakes|direct-PR|local-only> --yolo <on|off> [--branch-prefix <prefix>]三个关键参数的含义与取值规则:
| 参数 | 取值 | 说明 |
|---|---|---|
--mode | no-mistakes/direct-PR/local-only | 该任务的交付模式。scout 不记录交付姿态,因此晋升是决定交付契约的时点,必须在晋升时显式决定,脚本拒绝猜测 |
--yolo | on/off | 该任务的合并自主权,同样是任务级决策而非项目查询 |
--branch-prefix | 任意合法 git 分支前缀(默认fm/) | 与任务 id 拼成 ship 分支名fm/<task-id>,必须通过git check-ref-format校验 |
值得注意的边界规则(均有源码级守卫):
no-mistakes-prod-only是注册表(registry)策略而非任务模式,晋升时拒绝,须将任务表面分类解析为no-mistakes或direct-PR;- 没有
--forge参数:forge 绑定来自注册表(bin/fm-project-mode.sh --forge <project>),属于项目事实而非逐任务决策;对未绑定项目的任务,forge 为none; - Gerrit forge 下
--yolo on被拒绝:Code-Review+2是"具名人类批准"的正面声明,firstmate 不得伪造(船长 2026-09-15 决策,见 bin/fm-promote.sh); - 晋升参与生命周期串行化:先取 control 锁再取 meta 锁,任何其他生命周期动作进行中时晋升会被拒绝(bin/fm-promote.sh);
- 晋升前提是任务元数据中存在
kind=scout,否则拒绝。
7.2 晋升前的 brief 守卫
晋升会读取 scout 的 brief(data/<id>/brief.md)并做多项内容校验(bin/fm-promote.sh):
- 拒绝残留的
{TASK}/{FIRSTMATE_SPEC}占位符——船长的原始诉求必须保存在## Captain's intent中; ## Captain's intent与## Firstmate spec必须非空;## Captain's intent不得含有以 Captain 标签或地址开头的行(标题已记录出处,正文不得重复身份标注);- 未采用小节化结构的旧式 scout brief,只把显式标记为船长话语的 Task 行计入 intent,且读取范围排除围栏代码块与缩进示例,防止被引用的
Captain:样例冒充船长指令通过出处门(bin/fm-dod-lib.sh)。
7.3 晋升写入了什么
晋升在元数据与文档两个层面完成契约翻转:
元数据翻转(bin/fm-promote.sh):以原子方式把kind=scout替换为kind=ship,并写入mode=、yolo=、branch=三行——这正是 scout 缺失、由晋升时点决定的交付契约。同时通过fm_backlog_atomic_transition发布,保证记录发布是原子、可重放的。
Ship 指令生成:晋升生成data/<task-id>/ship-instructions.md,结构为(bin/fm-promote.sh):
# Task→## Captain's intent:完整保留 scout brief 中的船长原话;## Firstmate spec:晋升期的 ship 指令(即下文第七节 7 步义务);# Current delivery mode contract:mode=+ forge、ship 安全规则(fm_ship_rule_one)、no-mistakes 模式下的 ask-user 升级块、以及由单一所有者bin/fm-dod-lib.sh渲染的模式专属 Definition of done(fm_dod_block)。
关键设计:被晋升的 worker 收到的交付契约与普通 ship brief 完全一致,包括 no-mistakes 模式的 ask-user 升级规则与--yes禁令——脚本注释明确指出,"被晋升的 no-mistakes worker 从未收到 ask-user 升级规则与--yes禁令"正是旧实现遗留的交付漏洞(bin/fm-promote.sh)。
Brief 追加:同一份"当前 ship 契约"也被追加进brief.md,确保未来任何 relaunch 都以新契约为准,无法复活旧的 scout 交付规则(bin/fm-promote.sh)。
交付指令:脚本末尾打印FM_HOME=... bin/fm-send.sh fm-<id> "$(cat <ship-instructions>)",即把 ship 指令投递给当前 worker 的确切命令(bin/fm-promote.sh)。对 secondmate 场景,还会打印 public-followup 的 rechain 提示。
八、被晋升 worker 的七步交付义务
技能规定,被晋升的 worker 必须完成以下义务链:
- 先验证隔离(Verify isolation before anything else):运行
pwd -P与git rev-parse --show-toplevel,两者必须解析到启动时所在的临时任务工作树(如 treehouse 池路径或 Orca 管理的工作树),而非 firstmate 操作的主检出;任一项不符即停止并升级给 firstmate。 - 盘点临时状态(Inventory this worktree's scratch state):改动任何东西之前,先用
git status和git log清点工作树的临时改动。 - 回到干净的默认分支基线,再创建分支:
git checkout -b <branch> --(branch 即晋升时写入的 ship 分支)。 - 只携带预期的修复变更:把临时提交(scratch commits)、调试编辑、实验文件全部留在身后。
- 复现的 bug 转成回归测试:若 scout 复现了 bug,该复现必须变成回归测试随修复交付。
- scout 期 spec 降级为调查上下文:scout 期的
## Firstmate spec与任何未标记的旧式# Task文本,只作为调查上下文,不再是船长意图或当前 ship 指令。 - 其余原指令原样生效:状态协议、指令收件箱及确认、升级规则(含 ask-user)及所有安全规则继续适用,除非当前交付契约明确替换了 scout 专属交付规则。
这套义务在 bin/fm-promote.sh 中被完整渲染进PROMOTION_SHIP_SPEC,并在 relaunch 时同样生效:测试 tests/fm-control-relaunch.test.sh 覆盖了"被晋升 scout 的 relaunch 使用记录的自定义分支"与"被晋升 scout 的 relaunch 收到当前交付契约而非陈旧 scout 交付文本"两类场景。
九、验证与测试证据
该机制的关键行为均有自动化回归覆盖:
| 行为 | 测试位置 |
|---|---|
| scout 报告存在 + 共享完成门通过后,teardown 才移除工作树 | tests/fm-backend-orca.test.sh(如test_scout_teardown_removes_orca_worktree_via_helper) |
| 船长决策完成门(verify / complete / answer 路径) | tests/fm-captain-hold-lifecycle.test.sh |
| 晋升的锁串行化、promoted scout 的 relaunch 契约继承 | tests/fm-control-relaunch.test.sh |
| 晋升对 brief 占位符与 Captain 出处门的校验 | tests/fm-dod-lib.test.sh |
从源码结构看,这些测试共同钉住了一条核心不变量:"没有报告、没有通过船长决策门,任何 scout 源码状态都不得被销毁;有了授权,晋升必须原地完成且新 worker 拿到的契约与普通 ship 完全一致。"
十、常见误区与最佳实践小结
- 报告 ≠ 开工令:scout 报告可以建议实施,但实施必须单独授权;未经授权就把调查结论当成实施任务,会绕过 firstmate 的合并授权边界。
- 先完成门控再谈清理:任何"调查已完成"的判断,都必须先加载
captain-hold-lifecycle并满足verify校验;--force不能替代船长回答。 - 看板归 worker,不归 firstmate:视觉 artifact 场景下,firstmate 只消费结果,绝不 arm/poll 看板;武装、确认、收尾都按 docs/configuration.md 的 crew 托管契约执行。
- 晋升不重复派单:实施获授权时用
bin/fm-promote.sh <task-id> --mode ... --yolo ...原地晋升,并显式给出--mode与--yolo——脚本拒绝猜测。 - 临时状态必须隔离在 ship 分支之外:被晋升 worker 先盘点、回默认分支基线、再建
fm/<task-id>分支,只携带预期修复,把复现转成回归测试。
通过以上机制,firstmate 在"调查"与"实施"之间划出了清晰且可验证的边界:知识由报告沉淀,授权由契约翻转承载,源码安全由共享完成门兜底——这正是 scout→ship 全生命周期可审计、可恢复、不丢工作的底层原因。深入源码可从 bin/fm-promote.sh、bin/fm-teardown.sh、docs/captain-hold-lifecycle.md 三个入口继续研读。
【免费下载链接】firstmate
Talk to one agent. Ship with a crew.
相关推荐
opencodex 稳定版发布:从 preview 到 latest 的晋升(promotion)实战指南
opencodex 稳定版发布:从 preview 到 latest 的晋升(promotion)实战指南 本文以 opencodex 仓库发布流程档案 040
零成本晋升监控专家:NewRelic/Datadog认证实战指南
零成本晋升监控专家:NewRelic/Datadog认证实战指南 想要在云原生监控领域快速提升竞争力?通过New Relic和Datadog的免费认证,你完全可
文档教程教育微调评估工程师(Fine-Tuning Eval Engineer):构建评估基准与检查点晋升门禁的完整实战指南
微调评估工程师(Fine Tuning Eval Engineer):构建评估基准与检查点晋升门禁的完整实战指南 在 LLM 微调生命周期中,"评估"往往被当成
AI 插件AI 技能开发工具
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考