mcpField
R
run-with-it

run-with-it

github.com/chanakya-netAgent 工作流2138 次安装4 周前更新
代码仓库

关于 run-with-it

用于执行已准备 GitHub issue 的编排技能,涵盖依赖规划、Sub-Coordinator 调度、审查和关闭。面向 Agent 开发运行,通过精简报告和持久化状态管理长时任务。

主要功能

  1. 01按依赖关系排列 issue
  2. 02滚动调度 Sub-Coordinator 池
  3. 03由每个 Sub-Coordinator 端到端处理一个 issue
  4. 04将运行状态写入持久化状态文件
  5. 05发布终结评论并关闭 GitHub issue

适用场景

  1. 01执行一组已准备且存在依赖的 GitHub issue
  2. 02在并行任务释放槽位时继续分派工作
  3. 03在上下文压缩后恢复编排
  4. 04所有 issue 结束后创建最终 pull request

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/chanakya-net/maestro-ai --skill run-with-it

安装后在 Claude Code 中输入/run-with-it确认已加载。

详细介绍

技能隔离

调用后,只有本技能是生效的权威;除非通过 Skill 工具调用按名称调用,否则不得激活其他技能。显式终止或交接之前,禁止自发调用外部技能。此隔离仅约束编排流程;下级核心行为、原生工具使用和推理仍完全可用,且不能被此技能覆盖。

关键主编排器规则(可安全应对上下文压缩——始终执行,即使在上下文压缩之后)

这些规则在本技能会话的整个生命周期内均适用。它们在此处首先列出,以便在上下文压缩后保留,绝不丢失:

  • 每次循环迭代前都要重新读取 .run-with-it/main-state.json。 上下文压缩后,你不会记得之前做过什么——该文件就是你的全部记忆。绝不能根据对话历史推断问题状态。
  • 绝不要在此会话中直接实现工作。 所有实现工作都由通过平台分发器(Bash 下的 run-with-it-dispatch.sh,原生 PowerShell 下的 run-with-it-dispatch.ps1)启动、且 role=sub-coord 的子协调器负责;分发器会将 run-agent.sh / run-agent.ps1 与 sub-coordinator-prompt.md 结合使用。在任何情况下,都不存在“在此聊天中实现”的备用选项。
  • 绝不要在此会话中运行测试、构建命令或编译项目。 子协调器及其子 Agent 负责运行验证;主协调器只读取精简报告。
  • 计划完成后,绝不要暂停并询问用户接下来怎么办。 执行计划写好后,立即进入主循环。
  • 绝不要提供执行选项菜单(例如选项 A / B / C)。
  • 只要存在远程仓库,就始终从 GitHub(gh)获取问题数据。 只有在 gh 不可用、身份验证失败、获准的权限升级尝试失败,或不存在 GitHub 远程仓库时,才回退到本地文件。
  • 清理期间绝不要删除用户修改过的文件。 删除任何工作区产物前,先检查 git status --short。
  • 绝不要将完整的子协调器日志文件载入上下文。 子协调器日志位于 .run-with-it/issues/<n>/sub-coordinator.log。不要将原始日志内容输出到 AI 上下文;只读取精简报告 JSON:.run-with-it/issues/<n>/report.json。
  • 绝不要将实时状态日志载入上下文。 实时进度写入 .run-with-it/status/current.txt 和 .run-with-it/status/events.log;Shell 监视器可以向终端输出一行有变化的内容,但主协调器不得将这些文件读入 AI 记忆。
  • 按问题划分的阶段看板。 每当运行阶段发生变化时,池运行器都会输出一行精简的 STATUS|type=run-board|board=...(例如 #618 merge-recovery(cyc2) | #631 impl(cyc1) | #633 blocked:631 | #627 done),用于查看“当前阶段,而非详情”。随时可通过 python3 "$ASSET_ROOT/run-with-it-state.py" status-board --state-file .run-with-it/main-state.json 按需输出看板(只读;添加 --oneline 可输出单行格式)。
  • 池运行存活心跳。 池运行器每隔 POOL_HEARTBEAT_SECONDS(默认值为 60)输出一条 STATUS|type=pool-heartbeat|pool_pid=<pid>|active=<n>|parallel_jobs=<n>|total=..|completed=..|in_progress=..|pending=..|blocked=..|waiting_context=..。监视输出中出现心跳,表示池运行器仍在运行,即使没有其他变化;将其中的计数作为定期进度更新告知用户。
  • 提前为所有待处理问题组装上下文文件——包括依赖项。 池运行器只能分发上下文文件已存在于磁盘上的问题;没有上下文文件的问题不会被纳入可用槽位(完整原因见步骤 B)。如果出现 STATUS|type=pool-waiting-context,立即组装缺失的上下文(步骤 C),同时让池运行器继续运行。
  • 保持会话运行,直到每个问题都进入终止状态。 主协调器会话必须持续运行监视循环,并在每个监视窗口结束后,根据最新的 run-board / pool-heartbeat 行输出一行面向用户的进度更新(例如:池仍在运行——2 个运行中、3 个待处理、4 个已完成、1 个受阻)。只要仍有任何问题处于 pending、in_progress 或 merge_recovery 状态,就绝不能结束本轮、保持沉默或宣布运行完成。若出现仍有待处理问题的 pool-empty,则返回步骤 A,而不是宣告完成。
  • GitHub 操作(关闭、评论等,例如 gh issue close)完全由主协调器控制平面负责。 子协调器不得操作 GitHub。池运行器读取到终止状态的精简报告后,会立即为相应问题添加终止评论或将其关闭。
  • 绝不要检查、推断或干预子协调器内部的路由决策。 子协调器启动后,它为子工作器选择的 Agent 和模型完全由其自行负责——主协调器无法查看这些内部选择,也无权干预。不要读取日志文件来判断正在运行的是哪个工作器 Agent 或模型。
  • 绝不要在运行过程中终止、取消或重启子协调器。 如果子协调器似乎使用了不同于预期的 Agent 或模型,这是正确行为——它正在依据复杂度进行路由。不要干预。对于正在运行的子协调器,只有以下两种有效做法:(a) 等待其完成并写入精简报告;或 (b) 超过 SUB_COORD_TIMEOUT_SECONDS 后提醒用户,并等待用户指示“继续”或“跳过”。唯一例外: 用户确认执行 discard,此操作会根据清理丢弃流程,通过平台停止辅助脚本(run-with-it-stop.sh / run-with-it-stop.ps1)终止整个运行,包括监督器、分发器和运行器。即使如此,也绝不要自行编写终止命令。
  • 绝不要向已启动的子协调器注入工作器路由覆盖项。 规范工作器覆盖项(FORCED_AGENT、FORCED_MODEL、COMPLEXITY_LEVEL、COMPLEXITY_SCORE)只能在启动前设置,作为步骤 C 中组装的上下文文件的一部分。平台分发器调用 run-agent.sh / run-agent.ps1 后,这些值即被锁定,主协调器不得尝试更改。
  • 使用平台池运行器(run-with-it-pool.sh / run-with-it-pool.ps1)作为唯一的滚动池监督器。 池运行器会启动子协调器分发进程,捕获每个分发器 PID,并在开始监控前持久化 issue、pid、started_at、context_file、log_file、done_file 和 report_file。
  • 在分发器中使用平台工作器监视器(worker-watch.sh / worker-watch.ps1)检查池监控期间子协调器的存活状态。 传入每个分发子进程 PID、done_file 和 log_file;PID 存活状态仅作为诊断信息。只有存在完成哨兵和精简报告产物,才算完成。
  • 所有关于实现质量、路由正确性和工作器行为的判断,都必须完全依据精简报告 JSON。 对于子协调器会话内部发生的情况,主协调器没有其他事实来源。
  • 完成时的 GitHub 操作必须立即按顺序执行。 即使子协调器并行运行,每个问题一旦达到终止状态,就要立即逐个处理其 GitHub 评论或关闭操作,以避免竞争条件。
  • 当 GitHub 或 git 不可用时,保留本地回退行为。
  • 变更应尽量少,并聚焦于编排和控制平面行为。

使用 Run With It

用途 / 适用时机

在完成需求梳理和问题整合后使用。run-with-it 是最终运行时路由权威——它接收已准备好的问题,并执行路由、协调、审核和关闭。

建议的上游流程:

  1. break-req 梳理需求和约束。
  2. create-git-issue 发布 PRD + 实现切片,并提供路由提示。
  3. run-with-it 制定执行计划,启动 Sub-Coordinators,并推动问题直至关闭。

架构

run-with-it 采用两层架构,以便在无限期运行期间维持有界上下文窗口:

Main Orchestrator(此技能,在主会话中运行):

  • 启动时一次性获取所有 ready-for-agent 问题
  • 从原始基础分支创建一个共享运行功能分支(Maestro/<funny-action-animal>);存在 GitHub 远程仓库时推送该分支,并将其用作最终 PR 的头部分支
  • 主要依据每个问题的 ## Blocked by 部分,通过依赖图和拓扑排序确定执行顺序;在执行前将循环依赖或未解决的外部阻塞标记为受阻
  • 通过平台调度器维护一个最多包含 PARALLEL_JOBS 个活动 Sub-Coordinators 的滚动池——任何任务完成后,空出的槽位都会立即补入新任务,无需等待整批任务完成
  • 每当 Sub-Coordinator 完成,就读取其简要报告;如果问题已有最终结果,立即发布 GitHub 终结评论并关闭/更新该问题,然后将下一个就绪问题放入空出的槽位
  • 将自身状态日志写入 .run-with-it/main/main.log
  • 只读取简要报告 JSON——绝不读取实现差异或日志文件
  • 每处理完一个问题后更新 main-state.json(其完整的外部记忆)
  • 按问题逐一立即发布 GitHub 终结评论并关闭/更新问题,而非等整个任务池完成后再处理
  • 当 Sub-Coordinator 报告 merge_failed 时,启动 Merge Recovery Coordinator;Main Orchestrator 自身绝不合并问题分支
  • 所有问题均有最终结果后,从共享运行功能分支创建一个最终 PR,并使用 run-with-it-pr-body.py 根据 .run-with-it/main-state.json 生成正文
  • 每轮循环开始时重新读取 main-state.json,以应对上下文压缩

Sub-Coordinator(通过 sub-coordinator-prompt.md 启动,在子 Agent 会话中运行):

  • 端到端处理且仅处理一个问题
  • 从共享运行功能分支创建问题分支和问题工作树
  • 执行复杂度分析、确定性路由、受门控的只读规划、实现、审核和修改循环
  • 运行子工作进程时,将 REPO_ROOT 指向问题工作树,同时将日志/报告保存在根目录的 .run-with-it/ 下
  • 当实现/修改的产物重试次数耗尽时,启动 Artifact Recovery Worker,以便在生成任何最终受阻报告之前检查、验证、提交或重新排队未提交的工作
  • 在 .run-with-it/locks/merge.lock 下尝试合并回共享功能分支
  • 完成后,在 .run-with-it/issues/<n>/ 下写入简要报告 JSON 和完整日志文件
  • 启动工作 Agent,其日志/结果/完成标记文件写入 .run-with-it/issues/<n>/workers/<role>/ 下
  • 绝不接触 GitHub;绝不更新 main-state.json 计划 Worker(通过 plan-prompt.md 启动,受门槛控制,在评估复杂度后、实施前运行):
  • 使用强模型以只读方式读取问题工作树,并将具体的方案计划写入 .run-with-it/issues/<n>/plan.md,同时在 workers/plan/ 下写入机器可读的 plan.json
  • 绝不编辑或提交——它在基准 SHA 之前运行,因此不会破坏实施者的差异
  • 根据实际代码重新评估复杂度;Sub-Coordinator 在安排实施和修改时,优先采用这一基于实际情况的等级,而非盲评分(混合式细化)
  • 由 RUN_WITH_IT_PLAN_MIN_COMPLEXITY 控制门槛(默认为 medium-hard),并由 RUN_WITH_IT_PLAN_ENABLED 控制启用状态(默认为 1);琐碎问题会跳过计划,无论如何都会转交给弱模型
  • 实施者、审查者和修改者都会通过 RUN_WITH_IT_PLAN_FILE 使用 plan.md

工件恢复 Worker(通过 artifact-recovery-prompt.md 启动,仅在实施/修改工件故障耗尽后运行):

  • 检查问题工作树,包括未提交的修改和保留的恢复补丁
  • 在工作完整时运行验证,并将挽救的工作提交到问题分支
  • 仅在有具体提交和验证证据时,才写入缺失的 impl 或 modify 结果工件
  • 向 Sub-Coordinator 返回结构化的 synthesized-result、requeue 或 blocked 决策

合并恢复协调器(通过 merge-recovery-prompt.md 启动,仅在 merge_failed 后运行):

  • 处理一次失败的问题分支合并
  • 全面读取共享功能分支,因为其中包含 Sub-Coordinator 先前完成的工作
  • 在同一个合并锁下解决冲突或由合并引起的验证失败
  • 成功后推送共享功能分支,并写入简洁的恢复报告
  • 绝不关闭问题、创建最终 PR 或更新 main-state.json

这种隔离意味着,每个问题的实施复杂度都被限制在各自独立的 Sub-Coordinator 会话中。Main Orchestrator 的上下文每完成一个问题只增加一条精简的 JSON 记录,因此即使运行数小时或数天,上下文也不会退化。

硬性边界

  • 不要综合生成 PRD。
  • 不要编写初始问题模板。
  • 不要重新定义审查者 JSON schema 的归属(由 assets/review-prompt.md 负责)。
  • 不要修改运行脚本的实现细节。
  • 不要更改 assets/agent-registry.json 中的注册表数据定义。

操作系统检测

在发现资源和选择运行脚本之前,检测当前操作系统,并将其记录在 OS_FAMILY 环境变量中:

  • Windows(原生 PowerShell)(OS_FAMILY=windows): 使用 .ps1 运行脚本(run-with-it-pool.ps1、run-with-it-dispatch.ps1、worker-watch.ps1、run-agent.ps1),并使用 $env:USERPROFILE 作为主目录。
  • macOS / Linux / Git Bash / WSL(OS_FAMILY=unix): uname -s 会返回 Darwin、Linux、MINGW*、MSYS* 或 CYGWIN*。使用 .sh 运行脚本,并使用 $HOME 作为主目录。

根据检测到的运行环境,调整此技能中的所有 shell 命令:

操作PowerShell(Windows)Bash(Mac/Linux/Git Bash)
主目录$env:USERPROFILE$HOME
创建目录New-Item -ItemType Directory -Forcemkdir -p
检查命令Get-Command X -ErrorAction SilentlyContinuecommand -v X
检查目录Test-Path[ -d ... ]
临时文件[System.IO.Path]::GetTempFileName()mktemp -t name.XXXXXX
复制文件Copy-Item -Forcecp -f
设置可执行权限(不需要)chmod +x

输入

执行前提供任务摘要。其他所有输入均为可选覆盖项。

变量默认值描述
ASSETS_DEST—资产根目录覆盖值
AGENT_REGISTRY_FILE—注册表文件覆盖值
ISSUE_LABELready-for-agentIssue 接收的标签筛选条件
ISSUE_LIMIT1000获取 Issue 的最大数量(默认获取全部)
ISSUE_STATEopenIssue 状态筛选条件
COMMITS_LIMIT5Sub-Coordinator 上下文中包含的近期提交数量
MAX_ITERATIONS20已弃用/无效 — 审查/修改循环上限在 sub-coordinator-prompt.md(附录 B)中硬编码为 8 个周期;为保持向后兼容,仍会在上下文文件中传递,但不会被读取
RUN_WITH_IT_PLAN_ENABLED1实现前计划阶段的总开关;设为 0 时禁用该阶段(每个 Issue 都会跳过规划)
RUN_WITH_IT_PLAN_MIN_COMPLEXITYmedium-hard触发计划阶段的最低盲测复杂度等级;低于此等级时跳过该阶段(简单 Issue 无论如何都会路由到弱级别)
SUB_COORD_AGENTcodex每个 Sub-Coordinator 使用的 Agent 标识
SUB_COORD_MODELgpt-5.6-sol每个 Sub-Coordinator 使用的模型(Sub-Coordinator 会独立路由自己的子级)
SUB_COORD_TIMEOUT_SECONDS3600未完成的 Sub-Coordinator 触发停滞警报前的秒数
STATUS_POLL_SECONDS10状态行输出的 Shell 轮询间隔
POOL_WATCH_SECONDS240Step D 中每次有界 run-with-it-watch.sh/.ps1 调用的监视窗口时长
LOG_TAIL_POLL_SECONDS120子协调器日志尾部的 Shell 轮询间隔
RUN_WITH_IT_STATUS_FILE.run-with-it/status/current.txt单行状态总线(每次更新时覆盖)
RUN_WITH_IT_EVENTS_LOG.run-with-it/status/events.log仅追加的事件日志 — 仅供终端检查;切勿加载到 AI 上下文中
RUN_WITH_IT_ISSUE_DIR.run-with-it/issues/<n>由 Sub-Coordinator/池创建的 Issue 专属产物文件夹
RUN_WITH_IT_LOG_FILErole-specificSub-Coordinator:.run-with-it/issues/<n>/sub-coordinator.log;工作器:.run-with-it/issues/<n>/workers/<role>/cycle-<cycle>.log
RUN_WITH_IT_DONE_FILErole-specific工作器:.run-with-it/issues/<n>/workers/<role>/cycle-<cycle>.done
RUN_WITH_IT_RESULT_FILErole-specific工作器:.run-with-it/issues/<n>/workers/<role>/cycle-<cycle>-result.json
RUN_WITH_IT_STATE_FILErole-specific工作器:.run-with-it/issues/<n>/workers/<role>/cycle-<cycle>.state.json;由调度器维护的看门狗状态
FORCED_AGENT—传递给 Sub-Coordinator 的规范显式子工作器 Agent 覆盖值
FORCED_MODEL—传递给 Sub-Coordinator 的规范显式子工作器模型覆盖值
AGENT—已弃用的顶层别名;只有明确由用户提供的值才会规范化为 FORCED_AGENT;忽略环境中的 AGENT 运行器遥测数据
MODEL—已弃用的顶层别名;只有明确由用户提供的值才会规范化为 FORCED_MODEL;忽略环境中的 MODEL 运行器遥测数据
COMPLEXITY_LEVEL—传递给 Sub-Coordinator 的路由覆盖值
COMPLEXITY_SCORE—传递给 Sub-Coordinator 的路由覆盖值
AGENT_ALLOWLIST—逗号分隔;传递给 Sub-Coordinator
AGENT_DENYLIST—逗号分隔;传递给 Sub-Coordinator
MAX_AGENT_FALLBACKS2Agent 回退尝试的最大次数;向下传递
DELEGATED_REVIEWtrue启用 Sub-Coordinator 委派审查;向下传递
MAX_AGENT_DEPTH1始终注入;防止 Sub-Coordinator 子级生成子 Agent
PARALLEL_JOBS4滚动池大小。释放的槽位会立即补满。设为 1 时按顺序执行。
POOL_HEARTBEAT_SECONDS60池运行器输出 `STATUS
MAX_SPAWN_BOOTSTRAP_ATTEMPTS3池运行器将 Issue 作为终止状态完成处理而非重试前,连续生成失败的最大次数
RUN_WITH_IT_WORKER_STALE_SECONDS600工作器状态文件超过此时长未更新时,将视为孤立快照,而非运行中的工作器。活动调度器每次轮询(约 20 秒)都会重写该文件,因此静默这么久意味着调度器已停止运行。最小值为 60。
MAX_WORKER_WAIT_SECONDS3600Sub-Coordinator 退出后,等待单个运行中工作器的最长时间,即使该工作器看起来仍在运行。设为 0 时禁用此上限 — 此时仅以过期时限作为最后保障。
MAX_SUB_COORD_COMPACTION_HANDOFFS6每个 Issue 允许的上下文预算交接次数。该预算与 MAX_SUB_COORD_RECOVERY_ATTEMPTS 分开计算,因为上下文压缩停止属于约定的交接,而非失败。
WAIT_STATUS_INTERVAL_SECONDS300重复输出内容未变的 sub-coord-recovery-wait 行的最小间隔。工作器/角色/原因发生变化时始终会输出。

自动 Worker 模型矩阵

计算有效路由档位后,每个非复杂度自动路由都使用以下确切模型集:

有效档位自动模型
quite-easy / easyGPT-5.4、Codex Spark、GPT-5.6 Luna、Claude Sonnet 5、Claude Haiku 4.5、Agy 提供的符合条件的 Gemini 模型
mediumGPT-5.6 Terra、Codex Spark、Claude Sonnet 5
medium-hardGPT-5.5、GPT-5.6 Sol、Claude Opus 5
complexGPT-5.6 Sol、Claude Opus 5
holy-fuckGPT-5.6 Sol、GPT-6 Astra、Claude Opus 5、Claude Fable 5.1

复杂度评分不受此自动矩阵限制,仍采用独立的权重路由。Review 会按现有规则提升一个档位;Planning 会按现有规则提升两个档位,然后再应用此矩阵。显式设置的 FORCED_MODEL 值不受自动模型集限制,但仍必须通过兼容性和可用性检查。

按有效档位设置的 effort:

  • Sol:medium-hard 时为 high,complex 和 holy-fuck 时为 xhigh。
  • Sonnet 5:从 quite-easy 到 medium 依次为 low、medium、medium。
  • Opus 5:medium-hard 时为 high,complex 时为 xhigh,holy-fuck 时为 max。
  • Astra:holy-fuck 时为 max。
  • Fable 5.1:holy-fuck 时为 max。

通用路由 effort 会作为 Codex 的 model_reasoning_effort 或 Claude Code 的 --effort 传递;Agy 不会收到 effort 标志。

资源发现(必需)

按以下顺序解析资源:

  1. 若 $ASSETS_DEST 已设置且内容完整,则使用它。
  2. $HOME/.ai-skill-collections/assets。
  3. ./assets。

共享必需文件:

  • prompt.md
  • agent-registry.json
  • review-prompt.md
  • modifier-prompt.md
  • complexity-prompt.md
  • plan-prompt.md
  • coordinator-rules.md
  • sub-coordinator-prompt.md
  • main-orchestrator-rules.md
  • artifact-recovery-prompt.md
  • merge-recovery-prompt.md
  • run-with-it-state.py
  • run-with-it-github-update.py
  • run-with-it-pr-body.py
  • run-with-it-router.py
  • run-with-it-artifacts.py

Bash 必需辅助文件:

  • run-agent.sh
  • run-with-it-dispatch.sh
  • run-with-it-pool.sh
  • run-with-it-watch.sh
  • run-with-it-stop.sh
  • worker-watch.sh

PowerShell 必需辅助文件:

  • run-agent.ps1
  • run-with-it-dispatch.ps1
  • run-with-it-pool.ps1
  • run-with-it-watch.ps1
  • run-with-it-stop.ps1
  • worker-watch.ps1

选择规则:

  • 使用首个包含所有共享文件和检测到的平台所需辅助文件的路径。
  • Bash/macOS/Linux/Git Bash/WSL 运行不得要求提供 .ps1 辅助文件。
  • 原生 PowerShell 运行不得要求提供 .sh 辅助文件。
  • 两种平台的 pool runner 都需要 python3(或指向 Python 3 解释器的 PYTHON_BIN)来运行共享状态、GitHub 更新和路由辅助脚本。
  • 如果没有完整路径,则停止并报告缺失文件。
  • 解析资源时不得要求 git。
  • 已解析的资源根目录是本次运行唯一的资源来源。
全新/无 Git 项目说明
  • 没有 git 时,此技能仅支持资源发现和本地 issue 接收;issue 分支、工作树、合并、合并恢复和最终 PR 都需要 git 仓库。
  • 资源发现基于文件系统,而非 git 根目录。
  • 如果缺少资源,请报告适用于当前平台的一条命令修复方法:

PowerShell(Windows):

New-Item -ItemType Directory -Force "$env:USERPROFILE\.ai-skill-collections\assets"; Copy-Item -Force .\assets\prompt.md, .\assets\run-agent.ps1, .\assets\run-with-it-dispatch.ps1, .\assets\run-with-it-pool.ps1, .\assets\run-with-it-watch.ps1, .\assets\run-with-it-stop.ps1, .\assets\worker-watch.ps1, .\assets\run-with-it-state.py, .\assets\run-with-it-github-update.py, .\assets\run-with-it-pr-body.py, .\assets\run-with-it-router.py, .\assets\run-with-it-artifacts.py, .\assets\agent-registry.json, .\assets\review-prompt.md, .\assets\modifier-prompt.md, .\assets\artifact-recovery-prompt.md, .\assets\complexity-prompt.md, .\assets\plan-prompt.md, .\assets\coordinator-rules.md, .\assets\sub-coordinator-prompt.md, .\assets\main-orchestrator-rules.md, .\assets\merge-recovery-prompt.md "$env:USERPROFILE\.ai-skill-collections\assets\"

Bash(macOS / Linux / Git Bash):

mkdir -p "$HOME/.ai-skill-collections/assets" && cp -f ./assets/prompt.md ./assets/run-agent.sh ./assets/run-with-it-dispatch.sh ./assets/run-with-it-pool.sh ./assets/run-with-it-watch.sh ./assets/run-with-it-stop.sh ./assets/worker-watch.sh ./assets/run-with-it-state.py ./assets/run-with-it-github-update.py ./assets/run-with-it-pr-body.py ./assets/run-with-it-router.py ./assets/run-with-it-artifacts.py ./assets/agent-registry.json ./assets/review-prompt.md ./assets/modifier-prompt.md ./assets/artifact-recovery-prompt.md ./assets/complexity-prompt.md ./assets/plan-prompt.md ./assets/coordinator-rules.md ./assets/sub-coordinator-prompt.md ./assets/main-orchestrator-rules.md ./assets/merge-recovery-prompt.md "$HOME/.ai-skill-collections/assets/" && chmod +x "$HOME/.ai-skill-collections/assets/run-agent.sh" "$HOME/.ai-skill-collections/assets/run-with-it-dispatch.sh" "$HOME/.ai-skill-collections/assets/run-with-it-pool.sh" "$HOME/.ai-skill-collections/assets/run-with-it-watch.sh" "$HOME/.ai-skill-collections/assets/run-with-it-stop.sh" "$HOME/.ai-skill-collections/assets/worker-watch.sh" "$HOME/.ai-skill-collections/assets/run-with-it-state.py" "$HOME/.ai-skill-collections/assets/run-with-it-github-update.py" "$HOME/.ai-skill-collections/assets/run-with-it-pr-body.py" "$HOME/.ai-skill-collections/assets/run-with-it-router.py" "$HOME/.ai-skill-collections/assets/run-with-it-artifacts.py"

Main Orchestrator 规则文件

执行开始时(预检之前),将 $ASSET_ROOT/main-orchestrator-rules.md 复制到 .run-with-it/main-orchestrator-rules.md:

mkdir -p .run-with-it
cp "$ASSET_ROOT/main-orchestrator-rules.md" .run-with-it/main-orchestrator-rules.md

每次 Main Loop 迭代(步骤 A)开始时、任何上下文压缩之后以及任何 GitHub 操作之前,都要重新读取 .run-with-it/main-orchestrator-rules.md。

.run-with-it/main-orchestrator-rules.md(工作副本)会在正常清理过程中删除。

预检

执行前请验证:

  1. 已解析的资源根目录存在,且包含资源发现中列出的所有必需文件。在 Bash 上,运行器(run-agent.sh、run-with-it-dispatch.sh、run-with-it-pool.sh、run-with-it-watch.sh、run-with-it-stop.sh、worker-watch.sh)和 Python 辅助脚本(run-with-it-state.py、run-with-it-github-update.py、run-with-it-pr-body.py、run-with-it-router.py、run-with-it-artifacts.py)均可执行。在原生 PowerShell 上,请确认 .ps1 运行器存在;不要求可执行权限。

  2. 可使用 python3,或者 PYTHON_BIN 指向 Python 3 解释器,以供共享池辅助脚本使用。

  3. 需要从 GitHub 获取任务时,确认 gh 已通过身份验证。

  4. 已安装(检测到)SUB_COORD_AGENT:在 Bash 上运行 "$ASSET_ROOT/run-agent.sh" --list-agents --detected-only;在原生 PowerShell 上运行 & (Join-Path $ASSET_ROOT "run-agent.ps1") --list-agents --detected-only。确认列表中包含 SUB_COORD_AGENT。

  5. SUB_COORD_MODEL 已列在 agent-registry.json 中 SUB_COORD_AGENT 的 known_models 内。

  6. 检测现有状态(恢复或放弃提示):在获取任何 issue 或选择新任务之前,检查当前工作目录中是否存在 .run-with-it/main-state.json。

    • 如果文件存在,请暂停,并向用户原样显示以下提示:

      Existing run state found at .run-with-it/main-state.json.
      Type "resume" to continue the previous run, or "discard" to delete it and start fresh.
      
    • resume:不要删除文件。转到“恢复流程”部分。

    • discard:应用清理中的 Discard 策略,然后按照正常预检流程获取新 issue,如同之前不存在状态文件一样。

    • 在用户回复之前,不要启动任何新任务、获取任何 issue,也不要启动任何 Sub-Coordinator。

如果资源发现中要求的任何文件在已解析的资源根目录中缺失,请立即失败,并显示资源发现中相应平台所用的同一条单行修复提示。

初始批量获取 Issue

如果上下文中没有 issue 数据,请在启动时仅获取带有已配置获取标签(默认为 ready-for-agent)且处于 open 状态的 issue。

使用 ISSUE_LIMIT(默认为 1000)作为 --limit 参数——默认情况下,这会获取所有匹配的 issue。除非用户明确将 ISSUE_LIMIT 设为更小的值,否则不要限制结果数量。

gh issue list --state "${ISSUE_STATE:-open}" --label "${ISSUE_LABEL:-ready-for-agent}" --limit "${ISSUE_LIMIT:-1000}" --json number,title,labels,body,url

回退策略:

  • 首选:通过 gh 获取 GitHub issue。如果仓库有 GitHub 远程仓库,始终使用 GitHub。GitHub 可能可访问时,绝不要在不告知的情况下回退到本地文件。
  • 如果 gh 因当前工具处于沙盒环境而失败(权限错误、命名管道或套接字问题),在考虑回退之前,请在可用时使用该工具明确批准的权限提升流程。如果无法提升权限或请求被拒绝,则输出 STATUS|type=intake-fallback|reason=gh-permission-blocked;仅在下方允许时使用本地回退。
  • 回退:本地 issues.md(支持 LOCAL_ISSUES_FILE 覆盖)——仅当 gh 不可用、身份验证失败、经批准的权限提升尝试失败,或不存在 GitHub 远程仓库时,才允许回退。使用本地文件前,输出 STATUS|type=intake-fallback|reason=<no-gh-auth|no-remote|gh-permission-blocked|gh-failed-after-escalation>。
  • 如果 Git 元数据不可用,则继续执行,提交上下文留空。

开始获取任务之前,创建共享运行功能分支:

  1. 记录原始基准分支和 SHA。
  2. 将分支命名为便于人类识别的 Maestro/<funny-action-animal>,而不是 UUID 分支。
    • 使用小写、以连字符分隔的 slug,前缀后恰好包含两个单词:<action-or-trait>-<animal>。
    • 优先选择有趣但适合工作场合的名称,例如 cunning-fox、unfaithful-lion、scheming-otter、dramatic-llama、sneaky-raven、tapdancing-badger、plotting-penguin 或 chaotic-hamster。
    • 分支名称中不要使用原始 UUID。
    • 如果生成的分支在本地或远程已存在,请生成不同的 slug;只有在多次尝试后仍发生冲突时,才追加简短的数字后缀。
  3. 从该基准分支创建 Maestro/<funny-action-animal>。
  4. 如果存在 GitHub 远程仓库,则推送该分支。
  5. 记录 run_branch.base_branch、run_branch.base_sha、run_branch.feature_branch、run_branch.feature_branch_start_sha、run_branch.remote 和 run_branch.pushed。

获取所有议题后:

  1. 在规划前筛选已获取的问题:每个可执行问题都必须带有配置的接收标签(默认为 ready-for-agent)。不要将未加标签的问题、PRD/父问题、needs-triage 问题,或仅通过交叉引用发现的问题添加到 main-state.json。
  2. 仅根据每个可执行问题的 ## Blocked by 部分构建依赖图。将 #123、完整的 GitHub 问题 URL 和纯问题编号规范化。将 None - can start immediately 视为无依赖项。
  3. 将 PRD/父问题引用视为上下文,而非依赖项。计算 deps 时,忽略来自 ## Parent 的问题引用、PRD: ... 这类标题、needs-triage 这类标签,以及正文其他位置偶然出现的问题链接。
  4. 只有当依赖项指向同一接收集合中另一个已获取的可执行问题时,该依赖项才可执行。如果 ## Blocked by 提及 PRD/父问题或接收集合之外的问题,则忽略该引用,并在 dependency_proof 中将其记录为非阻塞上下文,而不要将该问题标记为阻塞。
  5. 仅检测可执行问题之间的循环和未解决依赖项;将受影响的问题标记为 blocked,并填写 dependency_proof 和 blocking_reasons。
  6. 确定执行顺序:按拓扑排序,并遵循依赖关系。同一依赖层级内的优先顺序为:关键修复 → 开发基础设施 → tracer-bullet 功能切片 → 润色和快速优化 → 重构。当 PARALLEL_JOBS > 1 时,问题进入滚动任务池(同时最多运行 PARALLEL_JOBS 个);释放的槽位应立即补入新问题,而不是等到整批任务完成。
  7. 如果可执行依赖项处于 open/unresolved 状态、merge_recovery、failed-merge 或 blocked 状态,则相关问题尚未就绪,必须等到依赖项变为 completed。任务池运行器会在依赖项就绪前,为处于 merge_recovery 状态的问题执行合并恢复。
  8. 在开始任何工作之前,将完整执行计划写入 .run-with-it/main-state.json。记录 parallel_jobs、execution_mode(PARALLEL_JOBS=1 时为 sequential,否则为 rolling-pool)、topo_order、dependency_tiers,以及每个问题的 dependency_proof、parallel_safe 和规范化的 ownership_scope。按以下方式推导并发元数据:
    • ownership_scope:问题正文、标题和验收标准中提及的顶层目录(或问题描述明确时的更深层路径)列表。使用不含 glob 字符的仓库相对目录路径;带 glob 的范围仅按其字面目录前缀进行比较;绝对路径、盘符路径、UNC 路径和会逃出仓库的 .. 路径均视为格式错误(此时该问题独占执行)。
    • parallel_safe:除非问题属于全仓库重构、迁移、格式整理,或会触及无法归入有界范围的文件,否则设为 true;符合上述任一情况时,设 parallel_safe: false,以强制独占执行。
    • concurrency_policy:新编写的计划必须设置 execution_plan.concurrency_policy: "strict",并为每个问题推导上述元数据。在 strict 模式下,缺少并发元数据的问题将独占执行——工作树只能隔离文件系统冲突,不能隔离语义冲突、迁移、生成文件或共享外部资源。
    • 缺少 concurrency_policy 的旧状态按 permissive 模式运行:缺少元数据时允许并行,依赖工作树隔离和合并恢复。这种默认放行行为仅用于向后兼容在该标志出现前写入的状态;不要在新计划中省略该标志。
    • 明确设置 parallel_safe: false、元数据为根目录或格式错误,或已确认 ownership_scope 重叠时,无论采用何种策略都必须延后该问题。任务池运行器会以 STATUS|type=pool-admission-deferred|count=<n>|deferrals=<issue:reason,...> 报告延后情况。
  9. 输出:STATUS|type=plan|total_issues=<n>|mode=<sequential|rolling-pool>|parallel_jobs=<PARALLEL_JOBS>|pending=<n>|blocked=<n>
  10. 输出:STATUS|type=memory-refresh|state_file=.run-with-it/main-state.json|tasks_loaded=<n>|completed=0|pending=<n>

主协调器循环

写完计划后立即无条件执行。 绝不暂停,绝不提供执行选项,写完计划后绝不询问用户希望如何继续。立即进入循环。

MAIN ORCHESTRATOR LOOP
Repeat until all issues in main-state.json have a terminal status
(completed / failed-review / failed-merge / blocked):

══ STEP A: MEMORY REFRESH ══════════════════════════════════════════════════════
Re-read .run-with-it/main-orchestrator-rules.md from disk.
Re-read .run-with-it/main-state.json from disk.
This is mandatory at the TOP of every iteration, no exceptions.
After context compression, these files are the sole source of truth.

Emit: STATUS|type=memory-refresh|state_file=.run-with-it/main-state.json
      |tasks_loaded=<total>|completed=<n>|pending=<n>|failed=<n>
Emit: STATUS|type=main-loop|iteration=<n>|pending=<count>|completed=<count>
      |failed=<count>

══ STEP B: SUPPLY CONTEXTS FOR THE ROLLING POOL ════════════════════════════════
Compute ACTIVE_POOL = all issues in issue_registry with status="in_progress"
(cross-check against active_pool_issues in state for consistency).

Collect NEWLY_QUEUED = ALL issues with status="pending" that do not yet have a
context file on disk (issue_registry[<n>].context_file unset, or the recorded
path no longer exists) — INCLUDING issues whose dependencies are not yet
completed. Order by priority:
  critical fixes → dev infra → tracer-bullet slices → polish → refactors.

Rationale (do not "optimize" this back to a slot-sized batch): the pool runner
is the only dispatcher, and it can only dispatch issues whose context files
already exist — issues without contexts are invisible to slot filling. Writing
every context up front is what lets the pool fill freed slots immediately and
auto-dispatch dependents the moment their dependencies complete, without
waiting on this session. Context staleness is acceptable: the Sub-Coordinator
re-fetches the issue body when it starts.

For each issue <n> in NEWLY_QUEUED:
  Leave issue status="pending" until the platform pool runner spawns it.
  Record its context file path in main-state.json during Step C.
  The pool runner marks status="in_progress" and appends <n> to
  active_pool_issues when it captures the dispatcher PID.
Emit: STATUS|type=pool-fill|active=<len(ACTIVE_POOL)>
      |newly_queued=<len(NEWLY_QUEUED)>|pending_remaining=<pending_after>
      |parallel_jobs=<PARALLEL_JOBS>

If ACTIVE_POOL is empty and NEWLY_QUEUED is empty:
  Check if any issues remain with status="pending" — if all have unmet deps
  whose blockers are terminal-but-not-completed, re-evaluate them; if still
  unresolvable, mark them "blocked".
  If ALL issues are terminal (completed / failed-review / failed-merge / blocked):
    EXIT LOOP → proceed to Final Ledger and Cleanup.

══ STEP C: ASSEMBLE SUB-COORDINATOR CONTEXT FILES ══════════════════════════════
Repeat for EACH issue <n> in NEWLY_QUEUED:

Build $SUB_COORD_CONTEXT_FILE_<n> (a separate temp file per issue) containing, in order:
  1. Full issue body: re-fetch using:
       gh issue view <n> --json number,title,body,labels,url,comments
     (re-fetch even if pre-fetched at startup — ensures freshest data)
     If gh fails because the current tool is sandboxed, use that tool's explicit approved permission-escalation flow when available. If the approved retry fails and local file exists,
     use cached issue body with a note.
  2. Last COMMITS_LIMIT (default 5) recent commits:
       git log --oneline -<COMMITS_LIMIT>
  3. If .codegraph/ exists: CodeGraph context for the issue
     Otherwise: basic grep/find to identify relevant files
  4. Environment configuration block (append at end of context file):
     SUB_COORD_ISSUE_NUMBER=<n>
     OS_FAMILY=<unix|windows>
     RUN_WITH_IT_ISSUE_DIR=<abs-path-to-.run-with-it/issues/<n>>
     SUB_COORD_REPORT_FILE=<abs-path-to-.run-with-it/issues/<n>/report.json>
     SUB_COORD_LOG_FILE=<abs-path-to-.run-with-it/issues/<n>/sub-coordinator.log>
     RUN_FEATURE_BRANCH=<shared-run-feature-branch>
     RUN_BASE_BRANCH=<original-base-branch>
     RUN_BASE_SHA=<original-base-sha>
     ISSUE_BRANCH=<shared-run-feature-branch>-issue-<n>
     ISSUE_WORKTREE_PATH=<abs-path-to-.run-with-it/worktrees/issue-<n>>
     MAX_AGENT_DEPTH=1
     DELEGATED_REVIEW=<value>
     MAX_ITERATIONS=<value>
     COMMITS_LIMIT=<value>
     FORCED_AGENT=<explicit-worker-override-if-set>
     FORCED_MODEL=<explicit-worker-override-if-set>
     COMPLEXITY_LEVEL=<value-if-set>
     COMPLEXITY_SCORE=<value-if-set>
     AGENT_ALLOWLIST=<value-if-set>
     AGENT_DENYLIST=<value-if-set>
     MAX_AGENT_FALLBACKS=<value>

  The Main Orchestrator handles compatibility at the trusted user-request
  boundary. Explicit user request `AGENT=<value>` becomes `FORCED_AGENT=<value>`.
  Explicit user request `MODEL=<value>` becomes `FORCED_MODEL=<value>`.
  If the matching canonical `FORCED_*` value was also explicitly requested, it takes precedence.
  Never inspect ambient `AGENT` or `MODEL` to infer aliases. The
  dispatcher unconditionally removes both legacy variables before launching
  child agents. `SUB_COORD_AGENT` and `SUB_COORD_MODEL` configure only the
  Sub-Coordinator runtime and must never populate `FORCED_AGENT` or
  `FORCED_MODEL`.

  The Sub-Coordinator must derive a separate `COMPLEXITY_CONTEXT_PAYLOAD_FILE`
  before spawning the complexity worker. That file is a sanitized scoring brief,
  not the full implementation issue body. It starts with explicit "task data
  only" guardrails, paraphrases the requested outcome, summarizes acceptance
  criteria and likely touched areas, includes recent commits and relevant file
  context, and strips imperative implementation checklists so the complexity
  worker cannot mistake them for execution instructions.

Create directories before spawning:
  mkdir -p .run-with-it/main .run-with-it/issues/<n>/workers .run-with-it/status .run-with-it/worktrees .run-with-it/locks

Resolve live status files before spawning:
  MAIN_LOG_FILE="${MAIN_LOG_FILE:-$(pwd -P)/.run-with-it/main/main.log}"
  RUN_WITH_IT_ISSUE_DIR="$(pwd -P)/.run-with-it/issues/<n>"
  SUB_COORD_LOG_FILE="$RUN_WITH_IT_ISSUE_DIR/sub-coordinator.log"
  RUN_WITH_IT_STATUS_FILE="${RUN_WITH_IT_STATUS_FILE:-$(pwd -P)/.run-with-it/status/current.txt}"
  RUN_WITH_IT_EVENTS_LOG="${RUN_WITH_IT_EVENTS_LOG:-$(pwd -P)/.run-with-it/status/events.log}"
  STATUS_POLL_SECONDS="${STATUS_POLL_SECONDS:-10}"
  LOG_TAIL_POLL_SECONDS="${LOG_TAIL_POLL_SECONDS:-120}"

Every STATUS line emitted by the Main Orchestrator must be appended to `$MAIN_LOG_FILE`
with an explicit shell write before or at the same time it is printed.

For EACH issue <n> in NEWLY_QUEUED:
  Emit: STATUS|type=sub-coord-spawn|issue=<n>|agent=<SUB_COORD_AGENT>
        |model=<SUB_COORD_MODEL>|report_file=<path>|log_file=<path>
        |pool_size=<current_active_count>|parallel_jobs=<PARALLEL_JOBS>

Print to user for each issue:
  "Starting sub-coordinator for issue #<n>: <title>"
  "Log: .run-with-it/issues/<n>/sub-coordinator.log"
  "To watch live progress in a separate terminal:"
  "  tail -f .run-with-it/issues/<n>/sub-coordinator.log"

══ STEP D: SPAWN NEWLY QUEUED + ROLLING POOL MONITOR ════════════════════════════

Execution-mode requirement (critical):
  Do not write a bespoke rolling-pool script in the Main Orchestrator session.
  Use the shared platform pool runner; it maintains the pool and calls the
  platform dispatcher with `role=sub-coord` for each active issue.

  Launch the pool runner ONCE as a detached supervisor with `--detach` /
  `-Detach`, then stay attached by running the bounded platform watch runner
  (`run-with-it-watch.sh` / `run-with-it-watch.ps1`) in a loop. Never treat
  starting the pool process as completion of Step D: Step D completes only when
  a watch call prints `WATCH|result=pool-empty`.

  Do not run the pool runner as a blocking foreground call — execution tools
  bound foreground calls (often to ~10 minutes) and killing the supervisor
  mid-run orphans the pool. Do not hand-roll `nohup`, a trailing Bash `&`, or
  `Start-Process` backgrounding either; the runner's detach mode creates its own
  process session and records `pool_pid` in `.run-with-it/main/pool.state.json`
  for the watch runner.

  Required handoff before Step D:
  - Each ready issue in `main-state.json` must have `issue_registry[<n>].context_file`
    (or `sub_coord_context_file`) pointing at the context file assembled in Step C.

  Bash (macOS / Linux / Git Bash) — launch once:

    "$ASSET_ROOT/run-with-it-pool.sh" \
      --asset-root "$ASSET_ROOT" \
      --state-file "$(pwd -P)/.run-with-it/main-state.json" \
      --parallel-jobs "$PARALLEL_JOBS" \
      --agent "$SUB_COORD_AGENT" \
      --model "$SUB_COORD_MODEL" \
      --status-file "$RUN_WITH_IT_STATUS_FILE" \
      --events-log "$RUN_WITH_IT_EVENTS_LOG" \
      --main-log "$MAIN_LOG_FILE" \
      --poll-seconds "$STATUS_POLL_SECONDS" \
      --timeout-seconds "$SUB_COORD_TIMEOUT_SECONDS" \
      --pool-state-file "$(pwd -P)/.run-with-it/main/pool.state.json" \
      --detach

  Then watch in a loop, one bounded foreground call at a time:

    "$ASSET_ROOT/run-with-it-watch.sh" \
      --events-log "$RUN_WITH_IT_EVENTS_LOG" \
      --pool-state-file "$(pwd -P)/.run-with-it/main/pool.state.json" \
      --wait-seconds "${POOL_WATCH_SECONDS:-240}" \
      --poll-seconds "$STATUS_POLL_SECONDS"

  PowerShell (Windows) — launch once:

    & powershell -NoProfile -File (Join-Path $ASSET_ROOT "run-with-it-pool.ps1") `
      -AssetRoot $ASSET_ROOT `
      -StateFile (Join-Path (Join-Path (Get-Location).Path ".run-with-it") "main-state.json") `
      -ParallelJobs $env:PARALLEL_JOBS `
      -Agent $env:SUB_COORD_AGENT `
      -Model $env:SUB_COORD_MODEL `
      -StatusFile $env:RUN_WITH_IT_STATUS_FILE `
      -EventsLog $env:RUN_WITH_IT_EVENTS_LOG `
      -MainLog $MAIN_LOG_FILE `
      -PollSeconds $env:STATUS_POLL_SECONDS `
      -TimeoutSeconds $env:SUB_COORD_TIMEOUT_SECONDS `
      -Detach

  Then watch in a loop:

    & powershell -NoProfile -File (Join-Path $ASSET_ROOT "run-with-it-watch.ps1") `
      -EventsLog $env:RUN_WITH_IT_EVENTS_LOG `
      -PoolStateFile (Join-Path (Join-Path (Join-Path (Get-Location).Path ".run-with-it") "main") "pool.state.json") `
      -PollSeconds $env:STATUS_POLL_SECONDS

  Each watch call prints every STATUS line appended to the events log since the
  previous call and exits within its watch window, well inside any tool-call
  timeout. After EVERY call — even when nothing changed — print a one-line
  user-facing progress update built from the newest `run-board` and
  `pool-heartbeat` lines, e.g.:

    "Pool alive (pid 12345) — 2 running, 3 pending, 4 completed, 1 blocked.
     Board: #42 impl(cyc1) | #43 review(cyc2) | #44 done"

  The pool emits `pool-heartbeat` every POOL_HEARTBEAT_SECONDS (default 60), so
  the user is never left guessing whether the run is alive. Then react to the
  drained lines:
  - `STATUS|type=pool-waiting-context` or `STATUS|type=sub-coord-dispatch-
    bootstrap-failed|...|reason=missing-context-file`: contexts are missing —
    assemble them NOW (run Step C for those issues) while the pool keeps
    running; it picks the new contexts up on its next tick without a relaunch.
  Then branch on the final `WATCH|result=...` marker:
  - `running` (exit 0): the pool is alive; immediately run the watch again.
  - `pool-dead` (exit 3): the pool supervisor died without `pool-empty`; relaunch
    the pool runner with the same `--detach` command — it re-attaches to live
    Sub-Coordinators and dead ones flow through exit analysis — then keep watching.
  - `pool-empty` (exit 0): Step D is complete. This is NOT the end of the run:
    GOTO Step A, which decides between another pool pass (issues still pending)
    and Final Ledger (all terminal).

  Do not end the Main Coordinator turn between watch calls, and do not start an
  unrelated shell to monitor the pool. The Main Orchestrator stays attached and
  looping until every issue is terminal (completed / failed-review / failed-merge / blocked).
  Per-issue dispatcher PIDs are persisted by the platform pool runner.
  The pool runner must also perform each terminal per-issue GitHub update immediately after finalizing that issue's compact report: post the terminal comment populated from the report, close the issue when `outcome=completed`, leave `blocked` and `failed-review` issues open after commenting, and emit `STATUS|type=github-update|issue=<n>|outcome=<outcome>|action=<commented|skipped|failed>|closed=<true|false>`.

══ GOTO STEP A ═════════════════════════════════════════════════════════════════

平台调度器 — 共享角色启动器

run-with-it-dispatch.sh 和 run-with-it-dispatch.ps1 是共享的 run-with-it 编排基础组件。主协调器使用它们并设置 role=sub-coord;子协调器使用它们并设置 role=complexity、plan、impl、review 或 modify。它们包装 run-agent.sh / run-agent.ps1,传递特定角色的 RUN_WITH_IT_* 环境变量,写入调度状态行,将 stdout/stderr 捕获到角色日志中,通过 worker-watch.sh / worker-watch.ps1 监视完成/结果产物,并写入由调度器管理的看门狗状态文件。模型发出的心跳仅供参考;由 runner 管理的 wrapper-heartbeat 和调度器状态是存活状态的判定依据,独立于模型 stdout。

当子协调器从短生命周期的 shell/工具调用中启动 worker 调度器时,在 Bash 中使用 --detach,或在原生 PowerShell 中使用 -Detach,然后从由调度器管理的状态文件读取调度器 PID。不要依赖原始 shell 后台任务和 WORKER_PID=$! 来启动 worker 调度。

Bash 的 --detach 会在返回前创建新的进程会话/进程组。这是必要的,因为普通的 nohup ... & 可能仍附属于工具调用的进程组,并在记录 worker runner PID 前被终止。

如果分离运行的 worker 调度器退出,或在状态文件记录 runner_pid 前发出 STATUS|type=dispatch-bootstrap-failed,应将其视为启动引导丢失,而不是 worker/模型结果。使用相同的日志、完成、结果、状态、仓库根目录、问题目录、状态和事件路径,在前台监控模式下重试同一个 worker 一次,以便调度器捕获 dispatch-pid 或具体的产物故障。

Worker 结果文件绝不能是 $SUB_COORD_REPORT_FILE 或 .run-with-it/issues/<n>/report.json — 有关完整的路径约定,请参阅 coordinator-rules.md(Worker-Agent 调度规则)。

run-with-it-dispatch.sh \
  --role <sub-coord|complexity|impl|review|modify|merge-recovery> \
  --issue <n> \
  --cycle <n> \
  --agent <agent> \
  --model <model> \
  --context-file <file> \
  --prompt-file <file> \
  --log-file <file> \
  --done-file <file> \
  --result-file <file> \
  --state-file <file> \
  --repo-root <worktree-or-repo-path> \
  --status-file <file> \
  --events-log <file> \
  --quiet-seconds <seconds> \
  --stall-seconds <seconds> \
  --detach

PowerShell 使用相同的字段名和 PowerShell 风格的参数,例如 -Role impl -Issue 123 -LogFile <file> -DoneFile <file> -ResultFile <file> -StateFile <file> -Detach。

使用 --dry-run / -DryRun 打印包装后的 runner 调用;使用 --validate-only / -ValidateOnly 验证输入,并在不启动进程的情况下发出 STATUS|type=dispatch-ready。

Worker 看门狗文件采用按问题划分的布局 cycle-<cycle>.state.json。state="quiet" 和 state="stalled" 描述模型输出健康状况,而由 runner 管理的 wrapper 心跳用于跟踪进程存活状态。state="artifact-recovery-required" 表示已保留 Git 进度,但没有机器可读的通过验证结果,因此必须进入产物恢复流程。完成仍要求存在完成标记、有效的角色专属结果产物,以及通过的实现/修改验证。

RUN_WITH_IT_AUTO_FAIL_STALLED_ROLES(Bash 默认值:complexity,impl,modify,plan)是为缺少 wrapper 心跳的旧版 runner 提供的兼容性回退机制。当前 runner 不会仅因 stdout 安静而被终止;RUN_WITH_IT_WORKER_HARD_LIMIT_SECONDS 会限制执行时长,并在终止前保留 Git 进度以供恢复。

创建最终 PR

所有问题都已进入终态后、执行 gh pr create 之前,根据持久化的运行状态生成 PR 正文:

"$ASSET_ROOT/run-with-it-pr-body.py" render --state-file .run-with-it/main-state.json > .run-with-it/final-pr-body.md
gh pr create --body-file .run-with-it/final-pr-body.md

生成的正文必须将已完成/已关闭的问题列为普通问题链接,例如 #123。最终 PR 正文不得使用自动关闭关键词,因为这些问题已通过逐问题的 GitHub 更新流程关闭。禁止在问题引用附近使用不区分大小写的自动关闭关键词变体:close、closes、closed、fix、fixes、fixed、resolve、resolves、resolved。

run-agent.sh — 完整语法参考

run-agent.sh --agent <agent> [--model <model>] --context-file <file> [--prompt-file <file>]
             [--permission-mode <mode>] [--extra-arg <arg>] [--unattended] [--dry-run]
run-agent.sh --list-agents [--detected-only]
run-agent.sh --list-models <agent>
标志对应环境变量必填描述
--agent <agent>AGENT是已启用的 Agent 标识(例如 codex、claude、agy;在 Copilot 方案额度用尽期间,github-copilot/copilot 已在注册表中禁用)
--model <model>MODEL是(始终显式传入)要使用的模型 ID
--context-file <file>CONTEXT_PAYLOAD_FILE是组装后的上下文载荷文件路径
--prompt-file <file>PROMPT_FILE否(默认值为 <script-dir>/prompt.md)提示词文件路径
--repo-root <path>REPO_ROOT否传递给 Agent 的工作目录;子协调器使用 issue 工作树
--permission-mode <mode>AGENT_PERMISSION_MODE否覆盖 Agent 权限模式
--extra-arg <arg>AGENT_EXTRA_ARGS否可重复指定;附加到 Agent 调用参数中
--unattendedUNATTENDED=1是 — 在 run-with-it 分派中始终传入设置权限模式时必需
--dry-run—否打印解析后的命令,但不执行
--list-agents——列出所有 Agent 及检测状态;添加 --detected-only 可筛选
--list-models <agent>——列出某个 Agent 已知的模型

其他环境变量(无对应标志):

环境变量默认值描述
AGENT_REGISTRY_FILE<script-dir>/agent-registry.jsonAgent 注册表路径
GUI_MODEautoauto 检测 GUI 环境变量;1 强制使用 GUI 安全的非交互模式;0 强制使用 CLI/CI 模式
REPO_ROOT$(pwd)传递给 Agent 的工作目录
PRINT_PROMPT0设为 1 可打印组装后的提示词,但不运行

GUI_MODE 行为:

  • auto — 检测 VSCODE_PID、TERM_PROGRAM=vscode、ELECTRON_RUN_AS_NODE、ANTIGRAVITY_APP、CURSOR_TRACE_ID、CLAUDE_CODE_ENTRYPOINT;任一项匹配时设为 GUI_MODE=1。
  • 1 — 强制设为 UNATTENDED=1,并将危险的完全绕过权限标志降级为更安全的、对应各 Agent 的选项。
  • 0 — 保持 CLI/CI 行为,不降级权限。

清理

仅在成功完成、运行失败、运行中断或执行显式 discard 命令后进行清理。恢复运行(resume)时不得触发清理。

成功完成运行

成功完成运行后:

  • 删除所有 $SUB_COORD_CONTEXT_FILE 临时文件(这些文件应已在每个 issue 处理后删除,但需清理任何残留文件)。
  • 删除 .run-with-it/main-state.json、.run-with-it/main-orchestrator-rules.md、.run-with-it/coordinator-rules.md。
  • 删除已跟踪文件、工作树或 .run-with-it/ 之外的任何文件前,先打印计划清理的目标并请求用户确认。确认后,删除 .run-with-it/issues/、.run-with-it/main/、.run-with-it/status/、.run-with-it/worktrees/ 和 .run-with-it/locks/ 下生成的文件。
  • 尽可能使用 git worktree remove 移除 issue 工作树。创建最终 PR 后保留共享运行功能分支。
  • 如果 .run-with-it/ 目录为空,则将其删除。
  • 对工作区根目录中存在的 technical_requirements.md、prd.md 和 issues.md,分别运行 git status --short <file>。仅当文件未跟踪(??)或干净(未列出)时才删除。如果文件有用户修改(任何其他状态),则跳过删除并输出 STATUS|type=cleanup|action=skipped-dirty-file|file=<file> — 切勿删除用户修改过的工作区文件。
  • 使用幂等追加,确保 .gitignore 中包含 .run-with-it/、technical_requirements.md、prd.md 和 issues.md 条目。
  • 如果存在 .git/,则仅暂存已删除的文件和 .gitignore;提交消息为 chore: remove skill-generated artifacts post-run。
  • 输出 STATUS|type=cleanup|action=completed|files_removed=<n>。
运行失败或中断

运行失败或中断时:

  • 保留所有 .run-with-it/ 文件,包括保留的工作树和锁,以供检查。
  • 打印保留文件的路径(状态、报告、日志、审查)。
  • 提供 discard 命令以强制删除并重新开始。
丢弃

执行 discard 时,必须先终止所有脱离运行的进程,再删除任何内容。supervisor、dispatchers 和 runners 都是脱离运行的:它们会继续运行,向已删除或新建的路径写入内容,并且仍可能执行 GitHub 更新。仅终止 dispatcher PID 不够——runners 会单独启动(nohup / Start-Process),并且其生命周期会超过 dispatcher。

  1. 运行平台停止辅助程序——它会终止并验证运行状态中记录的每个 PID(pool_pid、每个 dispatcher_pid 和 runner_pid,包括嵌套的 worker 和 recovery dispatcher)对应的完整 Unix 进程组 / Windows 进程树;在发送信号前会检查每个 PID 的命令行身份,确保绝不会向属于无关进程的复用 PID 发送信号:

    Bash: "$ASSET_ROOT/run-with-it-stop.sh" --run-root "$(pwd -P)" PowerShell: & powershell -NoProfile -File (Join-Path $ASSET_ROOT "run-with-it-stop.ps1") -RunRoot (Get-Location).Path

    辅助程序会为每个 PID 打印一行 STOP|type=target|...,并打印一行最终结果 STOP|result=<clean|survivors>|terminated=<n>|already_dead=<n>|skipped_not_ours=<n>。

  2. 如果无法确认进程已终止,则拒绝丢弃。 如果升级处理后仍有目标进程存活,停止辅助程序会以状态码 3 退出,并在 STOP|result=survivors|...|survivors=<pids> 中报告这些进程。向用户报告存活的 PID 并停止操作;不要在进程仍运行时删除其状态数据。

  3. 打印计划丢弃的目标,并在删除前请求用户确认。确认后,删除保留的生成文件,包括 .run-with-it/main-state.json、.run-with-it/main/pool.state.json、报告、日志、审查、工作树、锁、technical_requirements.md、prd.md 和 issues.md。

  4. 更新 .gitignore,并使用提交消息 chore: remove skill-generated artifacts (discarded run) 提交。

  5. 输出 STATUS|type=cleanup|action=discarded|files_removed=<n>。

  6. 作为全新运行继续执行。

附录 A:主状态架构

主编排器将 .run-with-it/main-state.json(schema_version 4)持久化保存。这是主编排器的全部持久化记忆。

{
  "schema_version": 4,
  "run_id": "<funny-action-animal slug generated at run start>",
  "started_at": "<iso8601>",
  "run_branch": {
    "base_branch": "main",
    "base_sha": "abc123",
    "feature_branch": "Maestro/cunning-fox",
    "feature_branch_start_sha": "abc123",
    "remote": "origin",
    "pushed": true,
    "pr_url": null
  },
  "execution_plan": {
    "execution_mode": "sequential | rolling-pool",
    "concurrency_policy": "strict",
    "parallel_jobs": 4,
    "topo_order": [36, 37],
    "dependency_tiers": [[36], [37]],
    "pool_config": {
      "max_concurrent": 4,
      "fill_strategy": "rolling"
    }
  },
  "issue_registry": {
    "36": {
      "status": "completed | in_progress | pending | merge_recovery | failed-review | failed-merge | blocked",
      "title": "issue title",
      "deps": [],
      "dependency_proof": "Blocked by: None",
      "parallel_safe": true,
      "ownership_scope": ["src/orders"],
      "issue_dir": ".run-with-it/issues/36",
      "report_file": ".run-with-it/issues/36/report.json",
      "merge_recovery_report_file": ".run-with-it/issues/36/merge-recovery-report.json",
      "log_file": ".run-with-it/issues/36/sub-coordinator.log",
      "issue_branch": "Maestro/cunning-fox-issue-36",
      "worktree_path": ".run-with-it/worktrees/issue-36",
      "issue_base_sha": "abc1234",
      "issue_base_source": "remote-tracking | local-fallback",
      "commit_sha": "abc1234"
    }
  },
  "active_pool_issues": [37, 38],
  "completed_summaries": [
    {
      "issue": 36,
      "outcome": "completed",
      "summary": "One paragraph compact report summary.",
      "files_modified_count": 3,
      "lines_added": 42,
      "lines_deleted": 7,
      "review_cycles": 1,
      "commit_sha": "abc1234",
      "verification": {
        "passed": true,
        "evidence": "15 tests passed, 0 failed"
      },
      "model_usage": [
        {
          "role": "impl",
          "cycle": 1,
          "agent": "codex",
          "model": "gpt-5.3-codex",
          "selection_reason": "under-target"
        }
      ],
      "report_file": ".run-with-it/issues/36/report.json"
    }
  ],
  "ledger_rows": [
    "STATUS|type=ledger|task=36|... (verbatim line as emitted)"
  ]
}

关键不变量:

  • issue_registry 中每个 issue 都有一个条目
  • run_branch 记录用于最终 PR 的共享功能分支
  • topo_order 和 dependency_tiers 根据 issue 依赖关系的拓扑排序生成
  • completed_summaries 会为每个已完成的 issue 累积一条精简记录,其中包含精简的 summary、verification、model_usage 和 report_file 字段——主编排器压缩后会读取这些记录
  • merge_recovery 不是终止状态;只有状态为 completed 时,依赖才算满足
  • ledger_rows 保存原样的 STATUS 行,用于最终输出账本
  • active_pool_issues 列出拥有活动 Sub-Coordinator 的 issue;恢复运行时,请遵循附录 C 中的恢复流程——验证 supervisor 租约并保留活动状态,因为脱离运行的 dispatcher 可能仍在运行
  • 当 PARALLEL_JOBS=1 时,active_pool_issues 始终至多包含一个条目
.run-with-it/ 的 .gitignore 自动追加(必需)

首次写入 .run-with-it/ 下的任何文件时:

  • 如果当前工作目录中存在 .git/,确保 .gitignore 中包含 .run-with-it/:
    • 如果 .gitignore 不存在,则创建它
    • 仅当尚未包含 .run-with-it/ 时,才将其追加为单独一行(幂等)
    • 保持现有 .gitignore 内容不变
  • 如果不存在 .git/,则静默跳过创建 .gitignore。

附录 B:状态与账本约定

状态消息

输出可解析的单行状态消息:

  • plan: STATUS|type=plan|total_issues=<n>|mode=<sequential|rolling-pool>|parallel_jobs=<PARALLEL_JOBS>|pending=<n>|blocked=<n>
  • pool fill: STATUS|type=pool-fill|active=<count>|newly_queued=<count>|pending_remaining=<count>|parallel_jobs=<PARALLEL_JOBS>
  • pool slot filled: STATUS|type=pool-slot-filled|issue=<n>|freed_by=<m>|pool_size=<count>
  • pool detached: STATUS|type=pool-detached|pid=<pid>|pool_state_file=<path>
  • pool already running (duplicate launch refused, exit 2): STATUS|type=pool-already-running|pid=<pid>|pool_state_file=<path>
  • pool reattached: STATUS|type=pool-reattached|count=<n>|state_file=<path>
  • sub-coordinator reattach: STATUS|type=sub-coord-reattach|issue=<n>|pid=<pid>|identity=<live|stale|dead>|report_file=<path> — stale 表示记录的 PID 仍处于活动状态,但其命令行已不再匹配调度器(PID 已被复用);绝不会接管该进程,并会进入退出分析
  • pool admission deferred: STATUS|type=pool-admission-deferred|count=<n>|deferrals=<issue:reason,...>
  • pool unreachable: STATUS|type=pool-unreachable|count=<n>|unreachable=<issue:root,root;...> — 因依赖项以终止但未完成的状态结束,永远无法就绪的问题。root 表示应归责的终止问题,并追溯传递归因。池耗尽时会重复输出,并附带 |final=1,因此提前结束的运行总会说明哪些失败导致了哪些问题受阻。
  • sub-coordinator recovery wait: STATUS|type=sub-coord-recovery-wait|issue=<n>|role=<role>|worker_state=<state>|state_file=<path>|reason=in-flight-worker-running|waited_seconds=<n>|worker_age_seconds=<n>|max_wait_seconds=<n> — 按 WAIT_STATUS_INTERVAL_SECONDS 限频;worker_age_seconds 表示该 worker 的任意产物上次变动至今的时长
  • pool empty: STATUS|type=pool-empty|pending_remaining=<n>
  • merge recovery queued: STATUS|type=merge-recovery|issue=<n>|report_file=<path>|state=<started|completed|failed-merge|blocked>
  • memory refresh: STATUS|type=memory-refresh|state_file=.run-with-it/main-state.json|tasks_loaded=<n>|completed=<n>|pending=<n>|failed=<n>
  • main loop: STATUS|type=main-loop|iteration=<n>|pending=<count>|completed=<count>|failed=<count>
  • sub-coordinator spawn: STATUS|type=sub-coord-spawn|issue=<n>|agent=<name>|model=<model>|report_file=<path>|log_file=<path>|pool_size=<n>|parallel_jobs=<PARALLEL_JOBS>
  • sub-coordinator pid-tracked: STATUS|type=sub-coord-pid|issue=<n>|pid=<pid>|done_file=<path>|report_file=<path>
  • live agent start: STATUS|type=agent-start|issue=<n>|role=<sub-coord|complexity|impl|review|modify>|agent=<name>|model=<model>
  • live agent complete: STATUS|type=agent-complete|issue=<n>|role=<sub-coord|complexity|impl|review|modify>|agent=<name>|model=<model>|status=<success|failed>
  • worker done: STATUS|type=worker-done|issue=<n>|role=<complexity|plan|impl|review|modify>|phase=<phase>|source=<agent|runner-exit>
  • sub-coordinator complete: STATUS|type=sub-coord-complete|issue=<n>|outcome=<completed|failed-review|merge_failed|blocked>|report_file=<path>|commit_sha=<sha-or-none>
  • merge start: STATUS|type=merge-start|issue=<n>|branch=<issue_branch>|target=<feature_branch>
  • merge complete: STATUS|type=merge-complete|issue=<n>|merge_sha=<sha>|pushed=<true|false>
  • merge failed: STATUS|type=merge-failed|issue=<n>|reason=<conflict|verification|push|unknown>
  • stall: STATUS|type=stall|issue=<n>|idle_for=<seconds>|action=alert-user
  • intake fallback: STATUS|type=intake-fallback|reason=<no-gh-auth|no-remote|gh-permission-blocked|gh-failed-after-escalation>
  • runner sandbox retry: STATUS|type=runner-sandbox-retry|agent=<agent>|model=<model>|reason=<error-summary>
  • runner sandbox retry result: STATUS|type=runner-sandbox-retry-result|outcome=<success|failed>
  • cleanup completed: STATUS|type=cleanup|action=completed|files_removed=<n>
  • discard shutdown (from the stop helper): STOP|type=target|source=<pool|dispatcher|runner>|pid=<pid>|action=<term-group|term-pid|stop-tree|already-dead|skip-not-ours>,随后是 STOP|result=<clean|survivors>|terminated=<n>|already_dead=<n>|skipped_not_ours=<n>
  • cleanup discarded: STATUS|type=cleanup|action=discarded|files_removed=<n>
  • final ledger row: STATUS|type=ledger|task=<task-id>|role=impl|cycle=0|agent=<agent-name>|model=<model-id>|added=<n>|deleted=<n>|total=<n>|reason=sub-coordinator|input_tokens=<n-or-unknown>|output_tokens=<n-or-unknown>|cache_hit_tokens=<n-or-unknown>|telemetry_source=sub-coordinator-report
最终台账

循环退出后、清理之前,读取 main-state.json 中的 ledger_rows,打印汇总后的最终台账。这意味着即使上下文被压缩,台账也能保留下来,并记录所有问题,包括在上下文压缩前已完成的问题。

另外,打印所有 completed_summaries 条目的最终摘要,显示:

  • 处理的问题总数
  • 已完成/评审失败/合并失败/受阻的数量
  • 所有问题的新增/删除总行数
  • 每个问题的 model_usage 中任务级模型用量(role、cycle、agent、model、selection_reason)
  • 汇总 Token 用量(对已完成问题的所有报告 JSON 中的 token_usage 字段求和)

附录 C:恢复与状态约定

恢复流程

启动时,如果 .run-with-it/main-state.json 存在,则提示用户(根据预检第 6 项,即检测现有状态)。用户选择 resume 时:

  1. 重新读取 .run-with-it/main-state.json。
  2. 先验证主管租约。 池主管和分发器以分离模式运行,因此中断的会话中的进程可能仍在运行。读取 .run-with-it/main/pool.state.json 并检查 pool_pid:
    • 主管仍在运行(PID 存在,且其命令行指向池运行器,例如 ps -p <pid> -o command= 包含 run-with-it-pool):不要重置任何内容,也不要重新启动。重新进入针对现有主管的步骤 D 监视循环,并持续执行,直到 WATCH|result=pool-empty。
    • 主管已停止(状态文件缺失、PID 对应的进程已停止,或 PID 已被无关进程占用):重新启动分离的池运行器。它会重新接入 active_pool_issues——仍在运行的分发器会在新主管下继续运行;已停止的分发器则会进入结构化退出分析。
  3. 绝不要批量重置 in_progress 问题或清空 active_pool_issues。 重置仍有分离分发器在运行的问题,会导致该问题被再次分发,造成重复工作、合并、状态写入、Token 开销和 GitHub 评论。只有在结构化证据证明某个问题的分发器已停止——问题的分发器状态文件中记录的分发器 PID 已停止——且没有该问题专属的 sub-state.json 可用于恢复时,才通过 run-with-it-state.py requeue 将单个问题重新排入 pending 队列。池运行器的重新接入路径已会执行此分析;优先重新启动池,而不是手动重新排队。
  4. 找出所有 status="pending" 的问题——这些问题尚未开始。
  5. 找出所有 status="completed"、"failed-review"、"failed-merge" 或 "blocked" 的问题——完全跳过这些问题。
  6. 在主循环中重新进入步骤 A。
  7. 输出:STATUS|type=resume|tasks_restored=<n>|completed=<n>|supervisor=<alive|relaunched>|re_queued_in_progress=<m>|parallel_jobs=<PARALLEL_JOBS>

如果用户输入 resume 时 .run-with-it/main-state.json 缺失或无法解析,则输出:

STATUS|type=resume-error|reason=<missing|parse-error>|action=user-required

然后停止,并询问用户是否要作为全新运行继续。

压缩后的恢复

上下文压缩后(对话历史已清除),将当前情况视为恢复:根据步骤 A 重新读取 .run-with-it/main-state.json,然后遵循上述恢复流程——验证主管租约并保留活动状态。池主管和分发器以分离模式运行,不受压缩影响;它们几乎肯定仍在运行,因此应重新进入监视循环,而不是改动问题状态。completed 问题绝不重新运行。状态文件始终是唯一权威来源——绝不要根据对话历史推断问题状态。

附录 D:终态问题评论约定

终端问题评论

对于终端结果,立即发布问题评论:completed、blocked、failed-review 或 failed-merge(合并恢复失败后设置)。 每条终端评论都必须在读取该问题的精简报告后发布,且不得等待无关问题或整个任务池完成。 从子协调器的精简报告 JSON 中填入所有字段。

所有终端结果都使用相同的 Markdown 模板,并按以下固定顺序排列各部分:

  1. ## Status
  2. ## Summary
  3. ## Verification
  4. ## Token Usage
  5. ## Notes
  6. ## Blocking Reasons(仅当 report.blocking_reasons 非空时)

终端评论模板:

## Status
<completed|blocked|failed-review|failed-merge>

## Summary
<task outcome summary — from report.summary>

## Verification
<task-specific verification results — from report.verification.evidence>

## Token Usage
- Input tokens: <n|unknown>
- Output tokens: <n|unknown>
- Cache hit tokens: <n|unknown>

## Notes
Review: <approve|revise (N cycles)>, final verdict: <approve|reject>, reviewer model: <model-id>
<follow-ups, blockers, or additional reviewer notes — omit line if none>

## Blocking Reasons
<omit this section entirely when verdict is not reject; when verdict=reject, list each entry from report.blocking_reasons as a separate bullet>

评论要求:

  • Token Usage 只能报告任务专属的遥测数据(来自 report.token_usage)。
  • 如果任何 token 值不可用,应将该值明确显示为 unknown。
  • Verification 必须概述运行的检查,以及检查通过、失败还是受阻(来自 report.verification)。
  • 当 DELEGATED_REVIEW=true 且已运行评审时,Notes 必须恰好包含一行评审摘要。格式:Review: <verdict-path>, final verdict: <approve|reject>, reviewer model: <model-id>。对于直接批准,写入 approve (1 cycle);对于修改后批准,写入 revise (N cycles)。当 report.review_skipped 为 true 时,改为写入 Review: skipped (trivial-change)。
  • 仅当 report.blocking_reasons 非空时,才必须包含 Blocking Reasons 部分。将每条内容分别显示为 Markdown 项目符号。否则完全省略该部分。

评论

支持 Markdown