【免费下载链接】firstmateTalk to one agent. Ship with a crew.项目地址https://gitcode.com/gh_mirrors/fi/firstmate点击查看免费下载导读本文讲解 Firstmate 在 Grok 主表面primary surface上的监督协议当 Grok 会话拥有监督权owns supervision且离开模式away mode未激活时如何通过一次**跟踪后台任务tracked background task**完成 watcher 的挂载arm、等待与再挂载从而让 Grok 在待机期间持续守护工作队列。读完本文你将掌握bin/fm-wake-drain.sh的排水与--ack-through确认语义、run_terminal_command后台挂载的精确命令形态、watcher: started / attached / FAILED状态行解读、background-task-completed提醒的处理流程以及 Grok Stop hook 后备backstop的能力选择机制——并能对照源码与测试理解每一环节的底层实现。一、为什么 Grok 需要一套独立的监督协议Firstmate 的“Talk to one agent. Ship with a crew”理念要求主会话结束一轮后后台仍有一个 watcher 持续观察任务队列、分支结果、检查项与 Relay 轮询并在出现可操作事件时唤醒主会话。不同 harness 的唤醒机制不同Harness监督/唤醒模型文档ClaudeStop钩子 asyncRewake自动挂载turnend-guard.mdCodex前台有界 checkpoint 轮询codex.mdCursorstop钩子 park挂起等待 watcherturnend-guard.mdPi / omp / OpenCode扩展/插件在子进程关闭后自动再挂载watcher-continuity.mdGrok跟踪后台任务 后台任务完成通知本文Grok 没有asyncRewake其 TUI 会话在 turn 结束后无法由 Stop 钩子前台挂起一个长生命周期 watcher但它支持“跟踪后台任务”并能在后台任务完成时注入一条synthetic_reason: task_completed的合成用户消息。因此 docs/supervision-protocols/grok.md 定义了“background-notify supervision”后台通知监督模式监督本身作为 Grok 的一个后台任务运行任务完成通知就是唤醒信号。与之对照Codex 选择前台有界 checkpointbin/fm-watch-checkpoint.sh因为 Codex 在工具调用运行期间无法推理必须有界地交还控制权而 Grok 可以直接消费后台任务的完成通知见 codex.md。二、核心协议Grok background-notify 监督10 条规则当本会话拥有监督权、且离开模式未激活时协议由以下步骤与硬性约束组成完整契约见 docs/supervision-protocols/grok.md1. 先排水bin/fm-wake-drain.sh任何挂载之前先运行bin/fm-wake-drain.sh处理完所有发出的 wake、并核对OPEN DECISIONS开放决策与UNREAD STATUS未读状态行之后必须原样执行 drain 打印的WAKE_ACK_REQUIRED那一行所给出的--ack-through命令。在确认之前这些工作保持“可持久、可幂等重放”durable for idempotent re-handling after interruption——即使会话中途被打断排水与确认都是可重复执行的。从实现看bin/fm-wake-drain.sh的确认语义是“按 actor 消费队列而非按全局截止点消费”--ack-through SEQ只删除调用方已认领claimed的、序号不高于截止值的行只有--recovery-generation绑定恢复期recovery episode的退役。序号更高、随后追加的 wake 会继续留在队列中待呈现watcher-continuity.md。2. Relay 激活时先 source 环境若 Relay中继轮询处于激活状态先执行source __FM_X_MODE_ENV__其中__FM_X_MODE_ENV__是协议模板中的占位符。协议文本由bin/fm-supervision-instructions.sh生成脚本在输出前会把__FM_GROK_ARM__等占位符替换为当前 home 解析出的真实 arm 命令见 bin/fm-supervision-instructions.sh 的line${line//__FM_GROK_ARM__/$grok_arm}。也就是说你在会话启动块里看到的实际命令已经是替换好的可执行形态。3. 首次周期用跟踪后台工具挂载第一次挂载必须作为 Grok 自己的独立调用使用run_terminal_command并携带background: truerun_terminal_command with background: true on: [ -f __FM_X_MODE_ENV_SH__ ] . __FM_X_MODE_ENV_SH__; exec __FM_GROK_ARM__这条命令的含义是若 X-mode 环境脚本__FM_X_MODE_ENV_SH__存在则先 source 之然后用exec替换进程执行 arm__FM_GROK_ARM__即解析后的bin/fm-watch-arm.sh调用。用exec是为了让后台任务进程本身就是 watcher arm而不是 arm 的父 shell——这样任务完成通知直接对应 arm 的生命周期。4. 只信任 arm 的一行状态输出挂载后arm 只输出一行状态Grok 必须只依据这一行判断watcher: started ...—— 一个新的 watcher 周期已启动存在 live 周期watcher: attached ...—— 已附着到既有健康周期附着后后台任务会跟随经过身份校验的继任者verified identity-matched successors而不是在第一个周期结束时退出watcher: FAILED ...—— 监督已宕down只有在失败或无周期时才需要修复并重新挂载。这是“arm 层周期契约”的一部分bin/fm-watch-arm.sh永不返回干净的空成功。子进程返回可操作输出时arm 正常返回该 reason返回零/空输出时arm 重查 home 锁与 beacon附着到已验证的健康继任者或对照 watcher 的有界终结投递账本state/.watch-deliveries.log解决关闭watcher-continuity.md。5–10. 挂载后的行为约束成功 start/attach 后结束本轮后台 arm 保持为 live 等待直到它返回可操作的 wake 或失败等待是静默的不要在等待期间主动输出或轮询绝不使用 shell做 firstmate 监督绝不把 arm 捆绑到其他命令上shell、截断管道truncating pipe或捆绑调用会被 PreToolUse seatbelt 自动拒绝——当本项目的 Grok 钩子被信任时bin/fm-arm-pretool-check.sh负责这条安全带bin/fm-arm-pretool-check.sh。为什么禁止与捆绑Firstmate 的连续性架构刻意把“必须持续存在的监督”放在进程边界之上Pi/omp/OpenCode 由适配器在子进程关闭后自动再挂载Claude 由 Stop 钩子再挂载而 Grok 依赖跟踪后台任务的生命周期。fire-and-forget 的无法被 Grok 跟踪也无法在完成时触发task_completed通知所以是被拒绝的反模式watcher-continuity.md。三、background-task-completed提醒的处理流程Grok 在后台 arm 完成时会注入一条携带synthetic_reason: task_completed的合成用户消息。当你看到针对该 arm 的“后台任务完成”系统提醒时按以下顺序处理先运行bin/fm-wake-drain.sh与挂载前相同处理并确认队列可选用get_command_or_subagent_output(task_id)获取 arm 输出读取 reason 行若 reason 是signal、stale、check或heartbeat按AGENTS.md中定义的 harness 无关契约harness-neutral contract处理普通 wake若 home 仍需要监督用与首次相同的后台__FM_GROK_ARM__调用重新挂载下一周期——正如bin/fm-supervision-lib.sh所定义的那样不要仅凭一行 attach 状态凭空发明一个 wake先排水只对真实 wake 记录、drain 的OPEN DECISIONS/UNREAD STATUS条目或真实 watcher reason 行采取行动。重新挂载时若已存在健康周期就附着它并跟随其已验证的继任链。关于“仅凭 attach 状态不要发明 wake”的底层原因arm 层周期契约保证——若 attach 状态行对应的是可操作 reason该 reason 在打印前已被 watcher 连同 PID 与进程身份写入state/.watch-deliveries.log只有 PID 与身份都匹配附着 arm 才能在 wake 已被处理并确认后报告投递结果并退出零。没有匹配投递记录的周期才会输出watcher: FAILED - cycle ended without an actionable reason并以非零退出。所以 attach 状态本身不是 wake 证据watcher-continuity.md。等待语义与“One-shot”设计watcher 刻意保持 one-shot一个可操作 reason 关闭一个 watcher 周期。连续性continuity现在构建在这个进程边界之上而不是依赖模型记住“再挂载一步”。这正是 Grok 协议中“普通 wake 后重新挂载下一周期”成为强制步骤的原因——重挂载不是可选优化而是连续性的必须环节watcher-continuity.md。四、监督主机Supervision Host在场时若 home 运行监督主机config/supervision-host-off可关闭设计文档见 supervision-host.mdGrok 的跟踪后台 arm 会在普通 arm 的位置运行监督主机bin/fm-supervision-host.sh park其余一切照旧但有如下补充supervision-host.md 的{grok}分支Attended无 away 记录每条 wake 都会原样到达你因为该 harness 尚无已验证的对话镜像可供监督会话消费Away存在 away 记录且无 daemon主机把每条 wake 交给 headless away 会话按 away 记录运行监督分支契约你被 park只有主机交还的 wake 才会到达你——表现为 arm 的background-task-completed通知其输出携带关闭信息加一行supervision-host: whysupervision-host: cycle boundary ...主机在其 park 边界结束本轮你需要运行bin/fm-wake-drain.sh处理其呈现的内容运行其打印的确认命令空队列会打印--ack-through 0然后用同一条后台主机调用重新挂载第 7 条红线预工具 seatbelt 不会对主机命令分类所以必须保持它恰为上面那一条后台调用——绝不 shell、绝不接管道、绝不捆绑其他命令/afk只写记录本 home 上bin/fm-afk-launch.sh start-native会拒绝 away daemon/quiet遵循 quiet 技能。主机把 wake 交还给你时该 wake 是自动监督而非队长的回归按 away 姿势排水并处理绝不从它运行回归流程。回归后若出现命名“队长回归”的supervision-host:行说明该轮有可见结果未包含在回归简报中需要把每条supervision-host: outcome ...转达给队长这些行也保留在bin/fm-branch-outcome.sh list中再排水处理任何排队 wake 后确认。五、Stop 钩子后备bin/fm-turnend-guard-grok.sh的能力选择主项目 Stop 钩子运行bin/fm-turnend-guard-grok.sh作为后备backstop而非正常 wake 路径。它解决的是“turn 结束时没有 live watcher”的盲区bin/fm-guard.sh是拉取式警告只在其他监督命令调用它时运行而 turn-end 守卫在主会话自己的边界上堵住剩余缺口turnend-guard.md。能力选择逻辑源码级bin/fm-turnend-guard-grok.sh从每一条正在运行的 Stop payload中做恰好一个类型化能力决策bin/fm-turnend-guard-grok.sh读取 payloadcatpayload 为空或jq缺失 →exit 0用jq --stream校验 payload 中sessionId、stopHookActive、stop_hook_active各恰好出现一次否则exit 0能力判定优先级布尔字段stopHookActivecamelCase出现 →nativecamelCase 有类型化优先级两种拼写同时出现时以它为准否则布尔字段stop_hook_activesnake_case出现 →native兼容旧拼写两者皆缺 →legacy保留一个 pre-native 的grok --resume兜底字段类型非布尔、payload 畸形、jq缺失等 → 不启动任何延续路径直接放行。native 路径把 payload 直接管道给bin/fm-turnend-guard.sh将其退出码 0 或 2 原样返回给同一 Grok 进程——绝不启动grok --resumelegacy 路径仅真正 pre-native payload 可达若GROK_TURNEND_GUARD_ACTIVE已设置则放行提取字符串sessionId、确认grok可执行运行共享守卫并捕获 stderr当守卫返回 2 时用fm_operational_input_encode turn-end-guard ...编码一条“TURN WOULD END BLIND”操作提示然后执行GROK_TURNEND_GUARD_ACTIVE1 \ GROK_HOME${GROK_HOME:-$HOME/.grok} \ grok --resume $SESSION_ID \ --cwd $ROOT \ --output-format plain \ -p $PROMPT注意 legacy 兜底有意省略--permission-mode且受GROK_TURNEND_GUARD_ACTIVE保护保证一个 turn 只触发一次延续turnend-guard.md。为什么要有这个后备守卫在 turn 边界上当“工作/进程事件源/注册检查/Relay 轮询需要监督”且“没有身份匹配且 beacon 新鲜的 watcher”同时成立时动作。Grok 的 native 路径可以像 Claude/Codex 一样用 exit 2 阻塞legacy 路径则以有界的一次grok --resume延续兜底 pre-native 构建。任何强制延续之后都需要按上面的后台协议重新挂载 watcher。该后备还解释了 turnend-guard.md 中的一个关键历史教训Grok 的 Claude 兼容 settings 加载在GROK_AGENT或GROK_HOOK_EVENT存在时被判定为惰性inert——两个标记都必须存在因为 Grok 不会向每种进程注入相同的变量。若只按GROK_AGENT判定grok 1.0.0 的钩子进程携带的是GROK_HOOK_EVENT/GROK_HOOK_NAME/GROK_SESSION_ID/GROK_WORKSPACE_ROOT而没有GROK_AGENT守卫会停止触发导致 Claude 专属的asyncRewake在 Grok 下同步运行、foreground 等待声明为 28800 秒的超时Grok turn 永不结束。同时绝不能把守卫扩大到GROK_SESSION_ID——Grok 会把它注入每个子进程它会存活进 Grok 启动的 Claude 会话静默禁用 Claude 自己的连续性turnend-guard.md。钩子注册与信任Grok 注册Stop钩子于.grok/hooks/fm-primary-turnend-guard.json。项目钩子要求 checkout 以/hooks-trust或启动时--trust被信任真正的 pre-native 构建可以从隔离的全局钩子目录运行同一跟踪钩子。对 grokfm-spawn.sh还会在$GROK_HOME/hooks/GROK_HOME未设置时为~/.grok/hooks/安装一个 firstmate 拥有的全局 turn-end 钩子并在 worktree 中放置每个任务的.fm-grok-turnend指针令牌teardown 时移除任务令牌与指针docs/configuration.md。六、支持的表面与明确边界交互式 TUI 会话是 Grok 主表面的受支持形态headlessgrok -p可能等待后台进程退出但不会可靠地完整呈现自动唤醒的模型输出——不要将 firstmate 主会话作为一次性 headless 进程运行docs/supervision-protocols/grok.md这一限制与其他 harness 同类OpenCode 的目标是持久 TUI 会话而非 headlessopencode runCursor 的stop步骤在 headlesscursor-agent -p下不触发turnend-guard.md守卫在无监督需求时静默退出默认跨 harness 模式secondmate home、child crewmate/scout worktree 的适用范围由bin/fm-primary-scope-lib.sh判定没有任何 harness 适配器用 shell 与号来制造监督。七、回归测试与验证Grok 监督路径由以下测试钉住pintests/fm-turnend-guard.test.sh覆盖 Grok native 与 legacy 能力选择、类型化字段优先级、畸形输入、恰好一条路径的安全性以及全部五种主 harness 注册tests/fm-grok-harness.test.shGrok harness 适配器测试被 bin/fm-test-isolation-proof.sh 列入隔离证明清单tests/fm-watch-arm.test.sharm 层周期契约——持久队列重放、世代绑定确认、持久 live 继任者、可处置 checkout 拒绝等tests/fm-wake-queue.test.sh按 actor 的混合队列消费、陈旧确认补救、呈现截止点、分支持有行的守卫计数可选 live 测试tests/fm-grok-continuity-live-e2e.test.sh 与 tests/fm-grok-stop-live-e2e.test.sh见 bin/fm-test-run.sh 的 opt-in 列表在真实 Grok 安装上验证后台任务通知协议与 Stop 钩子后备。跨 harness 的实证证据与精确的 opt-in 命令记录在 docs/verification/supervision.md。八、快速上手Grok 会话的监督操作清单挂载前bin/fm-wake-drain.sh处理OPEN DECISIONS/UNREAD STATUS执行打印的--ack-through确认命令Relay 激活时source__FM_X_MODE_ENV__首次周期run_terminal_commandbackground: true执行[ -f __FM_X_MODE_ENV_SH__ ] . __FM_X_MODE_ENV_SH__; exec __FM_GROK_ARM__只看一行状态watcher: started/watcher: attached即视为 livewatcher: FAILED才修复并重挂结束本轮静默等待绝不使用 shell绝不捆绑其他命令seatbelt 会自动拒绝收到task_completed提醒先 drain可选抓取 arm 输出读 reason按signal/stale/check/heartbeat或普通 wake 分别处理然后重新挂载下一周期监督主机在场arm 位置运行bin/fm-supervision-host.sh parkcycle boundary时 drain 确认 用同一条后台调用重挂turn 结束被 Stop 钩子拦下按 nativeexit 2或 legacygrok --resume有界延续路径强制延续后回到步骤 3 重挂 watcher。这条协议把 Grok 的原生“跟踪后台任务 合成完成通知”能力与 Firstmate 的持久、幂等 wake 队列结合起来让 Grok 主会话在待机期间获得与 Claude、Codex、Cursor 等 harness 同等强度的监督连续性同时保持“只信任一行状态、绝不 shell、绝不捆绑”的硬性纪律。赞分享【免费下载链接】firstmateTalk to one agent. Ship with a crew.项目地址https://gitcode.com/gh_mirrors/fi/firstmate点击查看免费下载相关推荐Firstmate OpenCode TUI 插件监督唤醒协议session.idle 驱动的后台 Watcher 连续再武装Firstmate OpenCode TUI 插件监督唤醒协议session.idle 驱动的后台 Watcher 连续再武装 本指南以 firstmateFirstmate Pi 扩展后台唤醒与监督分支协议从接管舰队锁到事件驱动的零 Token 监督Firstmate Pi 扩展后台唤醒与监督分支协议从接管舰队锁到事件驱动的零 Token 监督 本文基于 docs/supervision protocolStarlette后台任务与生命周期管理Starlette后台任务与生命周期管理 本文深入解析了Starlette框架的后台任务 BackgroundTask 机制和生命周期 Lifespan 管理功后端Web框架上一篇GraphQL APIs项目结构分析如何高效组织和管理API资源下一篇Logseq双向链接笔记把想法拆成可互相引用的块创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
阅读完成 · 觉得有帮助?