mcpField
D
deps-runner

deps-runner

github.com/fellowship-dev开发3221 次安装2 周前更新
代码仓库

关于 deps-runner

deps-runner 是用于核验目标仓库依赖 PR 的分阶段技能,涵盖基线检查、合并决策和报告。流程按六个阶段顺序执行,风险评估独立运行,并可从已保存的交接记录恢复。

主要功能

  1. 01六个顺序核验阶段
  2. 02仓库 devbox 预检与工作器管理
  3. 03基线构建和测试检查
  4. 04一次性评估所有依赖风险
  5. 05逐个 PR 决策并生成报告

适用场景

  1. 01对照 main 基线检查依赖 PR
  2. 02在隔离 devbox 中构建和测试
  3. 03将高风险依赖更新标记为待审

安装

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

$npx skills add https://github.com/fellowship-dev/dogfooded-skills --skill deps-runner

安装后在 Claude Code 中输入/deps-runner确认已加载。

包含的文件

除 SKILL.md 外,安装时一起下载的参考资料和脚本。

CONTEXT.md
evals/
worker_lifecycle_harness.py
worker-lifecycle-001.json
shared/
report-template.md
risk-matrix.md
stages/01-scan-context/
CONTEXT.md
stages/02-preflight-baseline/
CONTEXT.md
stages/03-risk-eval/
CONTEXT.md
stages/04-build-test/
CONTEXT.md
stages/05-merge-decision/
CONTEXT.md
stages/06-report/
CONTEXT.md

详细介绍

用途

依赖项 PR 验证与合并流水线,划分为 6 个按顺序执行的 ICM 阶段: 扫描/上下文 → 预检基线 → 风险评估(单个完整阶段,涵盖所有分组) → 构建测试 → 合并决策 → 报告。每个阶段都在隔离的上下文中运行;关键 判断(风险评估)拥有独立的干净上下文阶段。行为上等同于单体 deps-runner 技能,只是按阶段划分。

此技能在 OPERATOR 会话中运行,并负责管理其工作器生命周期。阶段 01 预检目标仓库的 devbox 镜像,并启动工作器;阶段 02-05 通过网关工作器 API 驱动该工作器(参见 pylot-cli 技能的 § Workers);阶段 06 停止该工作器。仅需 gh CLI 的阶段(扫描/上下文、合并决策的标签/合并步骤、报告)在 operator 会话中直接运行,不会触及工作器。

**此流程按顺序执行。不得分派扇出任务,也不得并行启动 Task。**风险 评估作为一个阶段运行,涵盖所有依赖项分组——绝不会为每个分组启动一个子 Agent。ICM 在此处的优势是判断步骤的干净上下文隔离,以及从阶段恢复,而非并行处理。

工作器生命周期

工作器是运行目标仓库的 Fargate devbox(参见 pylot-cli § Workers)。阶段 01 预检仓库并启动工作器;阶段 02-05 驱动该工作器;阶段 06 停止该工作器。工作器的身份标识(worker_id)在阶段 01 的交接记录中确立,之后会在每个下游阶段自己的交接记录中原样传递——这样,阶段 04 中的干净上下文子 Agent 才能知道阶段 02 已经预热了哪个工作器,而无需看到编排器的 shell 状态(Task 子 Agent 不会继承编排器的 bash 变量)。

所需环境与工作器轮次规则

工作器流程需要全部三个环境变量:PYLOT_API(网关基 URL)、 PYLOT_JOB_ID(传递给每条工作器命令的任务),以及 PYLOT_OPERATOR_TOKEN (网关的 operator 身份验证令牌)。执行任何工作器操作前,请确认这些变量均可用。 pylot workers output 仅返回最新一轮的结果;发送下一条 pylot workers prompt 前,请读取并记录所有关键结果,因为后续提示词会替换可读取的输出。

# Stage 01 — preflight (no task_def => no built image => cannot spawn)
pylot devboxes project "$REPO"

# Stage 01 — spawn (only if devboxes project reported a task_def)
SPAWN=$(pylot workers spawn --mission "$PYLOT_JOB_ID" repo="$REPO" \
  name="deps-runner-$(echo "$REPO" | tr '/' '-')")
printf '%s' "$SPAWN" > .procedure-output/deps-runner/01-scan-context/.spawn-raw.json  # recovery record before parsing
WID=$(printf '%s' "$SPAWN" | python3 -c 'import sys,json
try:
    print(json.load(sys.stdin).get("worker_id",""))
except Exception:
    print("")')

# Stages 02-05 — drive (each stage reads worker_id from the prior stage's handoff)
pylot workers prompt "$WID" --mission "$PYLOT_JOB_ID" --wait --timeout 600 "<instruction>"
pylot workers output "$WID" --mission "$PYLOT_JOB_ID"

# Stage 06 — stop, FIRST action, before writing the report, then confirm terminal state
pylot workers stop "$WID" --mission "$PYLOT_JOB_ID" --force
# poll `pylot workers list --mission "$PYLOT_JOB_ID"` for this worker's confirmed-stop shape —
# ecs_status == STOPPED, or (ecs_status null/absent and status == stopped with a non-empty
# stopped_at) — on a bounded budget before recording stopped: yes — see stage 06's CONTEXT.md

如果 pylot devboxes project "$REPO" 报告没有 task_def,则该仓库没有构建好的工作器镜像。构建镜像(pylot deploy build-worker <org/repo> --wait)需要管理员凭据——operator 会收到 403——因此此流程无法自行修复。请在阶段 01 的交接记录中记录 devbox_ready: false,并直接跳到阶段 06:没有 devbox 就无法构建或测试,而阶段 06 仍会生成一份受阻报告。

如果恢复运行时记录的 worker_id 已不再处于运行状态 (pylot workers view "$WID" --mission "$PYLOT_JOB_ID" 显示 stopped/reaped),则为同一仓库启动替代工作器,在该阶段的交接记录中记录新的 worker_id,然后继续——新 devbox 会从干净的检出状态启动,因此流水线的其余部分不受影响。

参数

参数必填默认值说明
repo是—目标 org/repo(位置参数 $0)
resume_from否(从头开始)恢复执行的阶段,例如 04-build-test。复用已完成阶段的磁盘交接记录,并跳过这些阶段。

从 $ARGUMENTS 解析。接受以下形式:

  • org/repo → 从头运行
  • org/repo resume_from=04-build-test → 恢复运行

功能说明

6 阶段顺序 ICM 流程:

阶段模式说明
01-scan-contextinline获取候选依赖 PR,读取仓库和团队的 CLAUDE.md,预检仓库 devbox 并启动 worker,分组 PR
02-preflight-baselinesubagent在 worker 上验证主分支可编译且测试通过;记录基线;执行 booster 远程同步
03-risk-evalsubagent单一阶段:对每个依赖组进行分类(差异、依赖类型、直接使用情况、风险)
04-build-testsubagent对每个 PR:检出并合并主分支、安装并构建、如果是运行时则重启,针对基线运行测试
05-merge-decisionsubagent对每个 PR 应用合并矩阵:自动合并/添加标签、编写有针对性的测试,或标记给 Max 处理
06-reportinline停止 worker;写入本地报告文件;输出结果标记

各阶段不会分叉。阶段 03 会在一次连贯的处理过程中评估所有依赖组——不要为每个组启动一个子 Agent。

交接文件位置

所有交接文件都存放在仓库工作目录中:

.procedure-output/deps-runner/{stage}/handoff.md

阶段 01 会写入根上下文。每个子 Agent 阶段只会收到其 CONTEXT.md 中列出的输入交接文件——绝不会收到完整的编排器上下文。

执行

阶段 01(inline)

在编排器上下文中自行运行阶段 01。读取 CONTEXT.md:

.claude/skills/deps-runner/stages/01-scan-context/CONTEXT.md

将交接文件写入 .procedure-output/deps-runner/01-scan-context/handoff.md。

如果阶段 01 记录了 devbox_ready: false,则完全跳过阶段 02–05,直接进入阶段 06——因为没有可操作的 worker。

阶段 02 → 05(顺序运行子 Agent——一次运行一个)

按顺序对每个阶段恰好启动一个 Task。等待其完成后再启动下一个。绝不要在同一响应中启动两个阶段。绝不要将一个阶段拆分给多个并发子 Agent。

每个 Task 提示词必须自包含:

  • 仅包含该阶段的输入交接文件路径(列于该阶段的 CONTEXT.md 中)
  • 包含该阶段的 CONTEXT.md 路径
  • 不要传入编排器历史记录或之前的推理内容

Task 提示词模板:

You are running stage {NN}-{name} of the deps-runner procedure.

Read your stage instructions:
  .claude/skills/deps-runner/stages/{NN}-{name}/CONTEXT.md

Your inputs:
  {input handoff path(s) from that stage's CONTEXT.md}

Write your output to:
  .procedure-output/deps-runner/{NN}-{name}/handoff.md

Execute all steps in CONTEXT.md. Write handoff.md before exiting.

如果某阶段的交接文件报告了硬阻塞(预检失败、过时 PR 上的合并冲突、所有 PR 均构建/测试失败),则按照该阶段的失败规则继续——通常会记录并标记阻塞问题,但流程仍会继续到 06-report,以确保始终生成报告。

如果 Task 调用本身失败——子 Agent 出错、超时,或以其他方式退出且从未写入 handoff.md——这不属于可正常处理的阶段失败,上述规则均不适用(因为没有交接文件可供读取失败规则)。应将其直接视为硬阻塞:不要重试该阶段,不要尝试继续下一阶段,也不要让本次运行处于未结束状态。直接进入阶段 06,从最近一份包含 worker_id 的交接文件中读取该值(崩溃阶段自身的交接文件不存在,因此应使用前一阶段的交接文件)。阶段 06 仍须首先停止该 worker,然后写入阻塞报告——子 Agent 崩溃后绝不能让 worker 继续运行。

阶段 06(inline)

在编排器上下文中自行运行阶段 06。读取 CONTEXT.md:

.claude/skills/deps-runner/stages/06-report/CONTEXT.md

先停止 worker(第一项操作),然后写入本地报告文件。由编排器(而非子 Agent)输出 [pylot] outcome=... 标记。不要执行 Quest POST——仅写入本地报告文件。

Resume-from-stage

设置 resume_from={NN-name} 时:

  1. 确认 resume_from 之前所有阶段的交接文件都已存在于磁盘上:
    ls .procedure-output/deps-runner/*/handoff.md
    
  2. 不要重新运行已完成的阶段——后续阶段将原样复用这些阶段的交接文件作为输入。
  3. 从指定阶段开始执行,并按顺序继续到 06-report。
  4. 如果缺少必需的上游交接文件,立即停止并报告缺少的文件——恢复点无效;运行必须从更早的阶段开始。
  5. 如果从驱动 worker 的阶段(02-05)恢复,继续之前确认记录的 worker_id 仍在运行(pylot workers view "$WID" --mission "$PYLOT_JOB_ID")——如果显示 stopped/reaped,则重新生成 worker,并在该阶段的交接文件中记录新的 id。

resume_from 的阶段名称:02-preflight-baseline、03-risk-eval、04-build-test、05-merge-decision、06-report。(01-scan-context = 全新运行,无需恢复。)

阶段交接链

01-scan-context (inline, preflights + spawns worker)
      │
      ▼
02-preflight-baseline ──► 03-risk-eval ──► 04-build-test ──► 05-merge-decision ──► 06-report (inline)
   (subagent, drives        (subagent,         (subagent,        (subagent,            stops worker,
    worker)                ALL groups,          drives            drives                reads all
                          single pass)          worker)           worker)               handoffs,
                                                                                         writes report)

worker_id 会在 01 到 06 的每个阶段自身的交接文件中原样传递。

退出路径

  • 成功:阶段 06 输出 [pylot:$PYLOT_OUTCOME_NONCE] outcome="deps-runner complete: {merged}/{total} merged, {flagged} flagged" status=success
  • 失败:失败阶段的阻塞原因 → 编排器输出 [pylot:$PYLOT_OUTCOME_NONCE] outcome="deps-runner failed at stage NN: {reason}" status=failed
  • 受阻:预检失败(主程序无法编译),或目标仓库没有 devbox 镜像 → [pylot:$PYLOT_OUTCOME_NONCE] outcome="deps-runner blocked: {reason}" status=blocked

无论哪种情况,阶段 06 都会先写入本地报告文件,再输出标记。

硬性规则

  1. 仅按顺序执行——每次响应执行一个 Task,每个阶段完成后才能开始下一个阶段。任何地方都不得并行启动 Task。
  2. 禁止分支展开——阶段 03 必须在一次连贯的流程中评估所有依赖组;不得为每个组/PR/维度启动一个子 Agent。必须整体分析 PR。
  3. 阶段 01 内联运行——在此处建立上下文(PR 列表、CLAUDE.md、devbox 预检和 worker 生成)。
  4. 阶段 06 内联运行——[pylot] outcome=... 标记必须由编排器输出。
  5. 禁止 QUEST——不得 POST 到 Quest DB,不得使用 127.0.0.1:4242、quest.fellowship.dev 或 QUEST_TOKEN。报告仅写入本地报告文件。
  6. 不得将完整的编排器上下文传递到子 Agent Task 提示词中——仅提供输入。
  7. 每个阶段都必须先写入 handoff.md,下一个阶段才能读取;并且原样传递 worker_id,确保其在整个链路中持续有效。
  8. 不得跳过阶段——即使阶段的操作是“无事可做”,也必须执行每个阶段(例如,即使候选 PR 数为零,仍需运行预检并生成报告),除非阶段 01 记录了 devbox_ready: false;在这种情况下,完全跳过 02-05(没有 worker 就无法构建或测试),直接进入 06。
  9. resume_from 复用磁盘上的交接文件——已完成的阶段不再运行;缺少上游交接文件意味着恢复点无效,必须停止并报告。在再次驱动 worker 之前,确认沿用的 worker_id 仍在运行。
  10. 绝不自动合并高风险项目。 始终标记并交由 Max 处理。所有合并都必须包含 [skip ci]。
  11. 生成 worker 之前先预检仓库的 devbox(pylot devboxes project)。没有已构建镜像的仓库无法生成 worker——记录 devbox_ready: false,并直接进入阶段 06,不要生成 worker。
  12. 始终在阶段 06 的第一步停止 worker,然后再写入报告。 泄漏的 worker 会持续消耗 Fargate 计算资源,直到被手动停止或回收。
  13. 阶段级异常属于硬性阻塞,不能重试。 如果阶段 02-05 的 Task 子 Agent 报错、超时或退出时未写入 handoff.md,不得重试,也不得进入下一阶段——直接转到阶段 06,并使用最近一个包含 worker_id 的交接文件中的 worker_id,以便即使某个阶段直接崩溃、未能妥善失败,也能停止 worker。

参考文件

  • CONTEXT.md — 架构概览
  • stages/NN-name/CONTEXT.md — 各阶段的输入、任务和输出约定
  • shared/report-template.md — 本地报告文件模板(阶段 06)
  • shared/risk-matrix.md — 风险分类矩阵 + 合并决策矩阵(阶段 03/05)

评论

支持 Markdown