• ## 1. 子 run 转终态不回写父节点 → 任务永久卡死(界面走查发现)
    
    复现:org 节点的子 work run 第一次失败 → 父节点判 fail → 入口节点没有 fail 出边
    → blocked → 用户在中栏把子 run 修好跑到 completed → **父节点仍钉在 blocked,
    root run 也钉住,org 层永远推不下去**。唯一人工出路是对 org 节点点「重试」,
    而那会把整张子图重置到下一个 attempt,刚跑完的成果全丢。
    
    根因:propagateToParent 的幂等守卫写的是 `parentNode.status !== 'running' → return`,
    判据用错了维度——它想防「同一个结果被结算两次」,实际拦掉的是「子 run 换了个结果」。
    subgraph 节点的状态本来就是从子 run 派生的,子 run 换了终态就该重新派生。
    
    修法:新增 reviveParentFromChild,只认「转好」(fail/blocked → success),
    且要求 parentNode.child_run_id 正是这个子 run。恢复走 **blocked → ready → running
    → success 三步合法转换**,而不是给全局放宽 NODE_TRANSITIONS——转换表是给所有调用方的
    安全网,不该为一条恢复路径把 blocked → success 对外开放;三条 node.status 事件
    也让「这个节点是被救回来的」在 timeline 上看得见。
    
    补测试时才暴露的第二半:父 run 多半也钉在 blocked,而 RUN_TRANSITIONS 没有
    blocked → completed,settleRun 在转换非法时是**静默跳过**的。所以复活时要先把
    父 run 从 blocked 拉回 running(这条合法),否则节点复活了 run 还是卡着。
    
    ## 2. 边界守卫把并行 agent 的写算到当前节点头上(真 CLI 冒烟的断点)
    
    真跑实测:招聘模板库里没有的角色走 hired_from_base,自动流水线起 agent-creator,
    而它的 CLI workDir 就是 system/agents/agent-creator/——一个被 git 跟踪的目录。
    它在里面重写自己的 todo.md、删一条 scheduled_tasks,被整仓 git diff 扫到,
    归属算到当时正在跑的 work 节点,一个**真正成功**的节点被判 fail。
    只要这些运行态文件还被 git 跟踪,每次含 hired_from_base 的招聘都稳定复现。
    
    修法:splitUnattributable 把 agent 运行态文件(todo.md / plan.md / memory.md /
    _lessons.md / .claude/scheduled_tasks.json)从越界证据里摘出去,单独记一条
    unattributable,不参与判罚。摘除范围刻意窄——同目录下的 agent.md / config.json
    等源码仍然算越界。
    
    路径提取按「首个空白之前」切而不是固定偏移:diffRepoStatus 已去掉前导空格,
    porcelain 状态位长度不定(修改类 "M path" 1 字符、未跟踪类 "?? path" 2 字符),
    固定 slice(3) 恰好对**修改类**失效——而 agent-creator 改自己 todo.md 正是修改类。
    这条单独立了一个回归用例。
    
    ponytail: 这是缓解不是根治。根治要把运行态文件从 git 移出去(27-P3B W13),
    本次只保证守卫不再冤枉节点;同一次招聘里 agent 若写了运行态文件之外的源码,
    仍会算到当前节点头上。
    
    测试 760/760 全绿(72 文件,起点 753/71):新增 graph-engine-revive-parent.test.js
    4 条 + graph-boundary.test.js 3 条。
    
    Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
    yibo authored
     
    Browse File »

  • 测试 736/736 全绿(68 文件,起点 719/66,净增 17 条,未改任何既有断言)。
    
    W1 · seed 接进启动流程 + 悬空行回收
    - server/index.js 与 agent-server.js 均在 listen() 前调 runStartupSeedSafely()
      (幂等、失败降级记日志、不挡服务启动)
    - seedTemplates() 此前**没有任何运行时调用方**,只有测试与手动脚本引用,
      于是 system/templates/ 新增本体永远进不了 system_agents,而
      work_graph_nodes.system_agent_id 是指向该表的外键
    - 占位 id 回收:legacy_path 已失效的 company_hired 行改为可被 template 就地转正,
      保留行 id 以保外键。此前 seedTemplates 遇占用即 skip,导致污染不可逆:
      lookupSharedAgentMd 恒 null → hire 静默退回全量拷贝 → 模板改动对已雇公司不生效
    - 生产库实查:company_hired 0 行(原 10 条悬空全清)、template 45、
      verifyCounts().ok=true、foreign_key_check 空
    
    W2 · 项目根分配(四环闭合)
    - ensureProjectRoot 复用 path-resolver.allocateProjectRoot(sandbox 模式)
    - 分配 → 进 agent_call 与 planning 两处提示词 + callAgent metadata
      → 落 artifacts/project-root.json(wx 独占)→ readProjectRootRecord 读回
    - 子 run 经 createRun 继承 root_run_id,跨层共享同一项目根
    - 核实 data/companies/ 在 .gitignore 内,故项目根内的合法写入不会被 W3 守卫误报
    
    W3 · 产出边界守卫(部分,文档如实标注)
    - 真 CLI 是子进程直接写盘,引擎拦不住,守卫只能拒收结果、不能回滚
    - 7 条「拦不住」的情形逐条列明;文档自述「在 cwd 隔离做掉之前,
      真跑仍应在可丢弃的工作副本里做」
    
    W4 · 修验收 fail-open(性质严重)
    - benchmark-validator / testdata-validator 的 Step 表教 agent 写 verdict:"fail",
      而引擎 FAILING_VERDICTS={attributed,inconclusive} 不含它 → 契约非法的产物
      被判 success 放行。失效方向是放行不是拦截
    - org-validator 的审计字段 verdict → audit_verdict:它与 work 层判词写同一路径
      (nodes/<nodeRunId>/attempt-<n>.json),此前只靠「该节点恰好是 subgraph」
      才没被 readNodeProduct 当判词读,属隐患藏在巧合里
    - 新增防线 template-verdicts.test.js,从 graph-engine.js 源码取
      FAILING_VERDICTS / ATTRIBUTION_REASONS 扫全部模板;经三次变异验证有效
      (改回 "fail" / 改回 verdict / 造 "ok" 均变红并报精确行号)
    
    真 CLI 冒烟未执行,两条理由(终验 agent 自行判断,符合任务给的门槛):
    ① W3 按其自身文档明确「不是沙箱」且要求真跑在可丢弃副本里做,而当前是主仓库、
       持有未提交交付物、且有并行 agent 在写,W3 自述的误判项必然触发;
    ② 断点已零成本静态证明:getAgentConfig 解析裸名只查 system/agents/、
       从不查 system/templates/,resolveAgentName 不做按需 hire,实测 prd-planning /
       sdd-planning / benchmark-validator / testdata-validator / validator-triager /
       org-validator 全部 throw「Agent not found」。花 $3-8 复现已知断点无意义。
    故「做完这四件就能真跑」不成立,真跑挪到 W5/W6 之后。
    
    Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
    yibo authored
     
    Browse File »