-
实现路径:task-planning 判断是否 itemized(硬规则 5 开例外让 LLM 写这 一个字段)→ org-planner 收尾把 acceptance.md 物化成子任务 → coder-validator 用新工具 task subtask-result 逐条上报,settleNode() 新增闸门强制核对 子任务全部 completed 才认这一轮 success。 - work-graph-db.js: tasks 加 acceptance_mode 列,createTask 支持 parentTaskId(复用既有列),新增 settleSubtaskResult 条件更新 - graph-engine.js: maybeMaterializeItemizedSubtasks(org-planner 结算 success 后物化子任务,agent_call/subgraph 两种形态都认,subgraph 场景 扫子 run 全节点找 acceptance.md,找不到优雅降级不阻塞主产出); coder-validator 判 success 前新增子任务完整性闸门 (ENGINE_FAIL_REASONS.SUBTASKS_INCOMPLETE) - task-planning.js / company.js: acceptance_mode 字段透传链路 - bin/lemon.js: 新增 task subtasks / task subtask-result 两个子命令 - coder-validator/agent.md、task-planning/agent.md: 对应提示词更新 真实回归验证过(新建公司走完整链路),过程中发现两个跟本次改动无关的 预存在问题:一次瞬时的 produces_missing 误判(重试即愈)、一个结构性的 writesArtifacts 产出闸门不匹配 bug(另立 44 号文档记录,未修复)。 全量单测 1120/1123 通过,3 个失败与本次改动无关(git stash 验证过)。 Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01U7xYyvv3pzuV9diMVUH5QL
-
runClaimedNode 派发真实调用之前,先查一次 agentLocator.missingBodyDefinition (systemAgentId)——此前这个判据只在招聘/建公司路径上被查过,图执行的核心路径 从没查过:本体因任何原因(装配没跑完、手工改坏、迁移遗留)仍是空骨架时,引擎 会原样把它当正常本体派发一次真实调用,静默产出一份没有角色指导支撑的结果 (真实样本见 34 号文档 §五:unit-tester 顶着 _base 骨架跑完了一整条真实任务)。 本体不完整时:新 fail_reason='body_not_ready'(与招聘路径的同名状态同义), 不扣预算(没有调用发生,"一次调用一定发生了"这条记账理由不成立)、不起边界 守卫、走正常的选边/兜底/熔断路径(不发明第二套重试语义)。 只在 agentExecutor === defaultAgentExecutor 时生效(与 boundaryGuardApplicable 同一判据)——第一版忘了这条,把全仓库几百个用假 systemAgentId + 注入假 executor 的用例全部判成 body_not_ready,跑单测直接炸穿 75 个用例;加上这条判据后收窄回来, 只在真会起 CLI 的路径上生效。 只查 agent_call 节点:subgraph 节点的 systemAgentId 不是即将被直接调用的本体, 它派发的是 workgraph-planning 去规划子图。 新增 graph-engine-body-not-ready.test.js(4 例)+ 更新 graph-engine-fail-reason.test.js 的取值域断言(五个→六个)。全量单测 1004/1004 通过。 Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
-
planner 骨架(brd→prd→sdd→goal-benchmark→validator)复现:三个 planning 节点 声明了 produces 却没真落盘,executor 没抛异常就被引擎判 success;goal-benchmark 的入边 needs:[brd,prd,sdd] 只用来拼提示词里的 ⚠️ 提示,agent 视而不见照样产出 合法 acceptance。下游 validator 永远读不到三份文档,backward 重试撞循环硬顶后 只能人工兜底。 settleNode 判 success 之前新增两道闸门(均只对 agent_call 节点生效,subgraph/org 节点的契约由子 work run 自己的节点过闸): - unsatisfiedRequiredProduces:声明的 required produces 一个候选文件都没落盘 → fail_reason=produces_missing,不再放行 - requiredInputsMissing:声明的 required needs 在 graph_files 里查不到实例 → fail_reason=missing_required_input,不采信 agent 自报的 success 两者都只判「有没有」,不判「分类对不对」——ambiguous 归类留给下游 ⚠️ 提示词处理, 避免把「写了东西但引擎猜不出对应哪个 kind」误判成没执行。 包含此前已完成但未提交的 27-P4 T3(graph_runs.max_concurrency 落库)及配套 advance-batch 测试。 Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
-
28-followups §3.1。**审计结论与那条待办原来的写法不一样,两列要分开处理。** ## source_kind:删 与 origin 一一映射(global_agent↔builtin / company_hired↔created), 实查生产库 76 行零例外。全仓唯一读侧是 migrate() 里那条 origin 回填, 而那是给「origin 列出现之前写下的行」用的一次性迁移。 顺序:**先回填、再删列**,两步都用 hasColumn 守着(幂等)。反过来做不报错 —— 库能开、测试能过,只是那几行 origin 悄悄是错的。守卫 source-kind-drop-migration.test.js 走存量库重启那条路,专门钉这个顺序, 反向验过:弄反立刻红。 写侧散在 3 处生产 INSERT + 35 个测试文件。批量改的时候正则误伤了 4 处 (吃掉了 JS 默认参数、位置占位符、ON CONFLICT 的赋值行),逐个修回并复查了 diff —— **这种跨几十个文件的机械改动,靠「全量跑一遍」兜底比靠正则写得对更可靠**。 ## legacy_path:不能删,它还没死 原待办说「所有读取点都已改成从 id 推导」——那半句对新行成立,对存量行不成立: · 新行 legacy_path 恒等于 system/agents/{id}(确实冗余); · **存量行里存着批次 4 之前的公司侧路径**,而 graph-seed-service 判「悬空行 / 孤儿行」 靠的正是这个路径指向的目录还在不在。从 id 推导出来的路径永远指向 system/agents/, 那条判据会整个失效。 实查生产库:76 行里还有 2 行是老路径(org-planner / org-coder 指着已不存在的 data/companies/mycompany/agents/)—— 正是这条判据要认出来的那种行。 退出条件写进了 graph-db.js 的建表注释(不只留在文档里): 库里不再有 legacy_path <> 'system/agents/' || id 的行。 ## 顺带记一条:getDb() 会就地迁移生产库 删列那次,生产库的列是被一条**查状态用的**一行 node -e 删掉的 —— 服务当时没重启,人也没打算迁移。结果是对的(幂等;与备份逐行核对 76 行一致、 origin 全部按映射回填正确),但「读一下状态」不该顺手改 schema 这件事值得知道。 闸门只挡测试进程,故意不挡普通脚本(挡了服务自己也起不来)。 注释里给了只读的正确姿势。 全量:140 文件 / 1299 测试全绿。 Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
-
测试 786/786 全绿(76 文件,起点 760/72),未改任何既有断言。 ## 本轮三件新东西,全部经真 CLI 验证 W12 补完 · 失败原因四环打通 - 引擎自判的失败(executor 抛异常、边界越界、子 run 无归因)现在也落 graph_run_nodes.fail_reason,不再只有 agent 归因产出的才有值 - 概览 tab 展示「[引擎判定] boundary_escape」+ 终端样式 excerpt, 取不到 fail_reason 时回落 output_excerpt,并标明来源 - 真跑实查:两行 fail_reason='boundary_escape' 都在库里, 产生→传递→落库→读回四环在真 CLI 下走通 W13 · 运行态文件根治(守卫误判的根因) - 17 个 todo.md / plan.md / scheduled_tasks.json git rm --cached + gitignore; 源码(agent.md/config.json/soul.md/tools.md)一个未碰,模板本体仍跟踪 - _registry.json 的 usedCount 挪进已忽略的 data/template-usage.json - 真跑验收:整轮(agent-creator、Master 各一次真 CLI、3 次 hire)结束时 worktree git status 与基线逐字相同,_registry.json 零 diff 单步进度感 · 真 CLI 一个节点 3-7 分钟 - 画布卡片秒表 + 详情面板常驻条「运行中 2m40s · 最近事件 …(2m40s 前)」 - 不做假进度条:引擎不知道 agent 还要多久 - 顺手修 NodeDetailPanel 不跟 SSE 走(否则秒表也不会动) W9 失败上下文进提示词、W10 跨层地址两半、W11 Hot Swap 显式告警同批完成。 ## 真跑结论:链路更长,但「work 节点 → success」仍未跑到 走到:orggraph-planning 落图自雇 → agent-creator 补定义 → workgraph-planning 真跑规划 + **先雇后提交**(W5/W6 再次成立)→ 子 run 起来 → work 节点 RUNNING → 7m19s 后 fail。两层原因叠加,都与 W1-W14 无关: 1. **新缺陷**:agent-manager.js:324 把 idleTimeoutMs 硬编码 120s, readme-writer 通读源码静默超 2 分钟被掐死(动笔前就死了)。 同进程 ClaudeCliProtocol 早把自己的 idle 上限放到 24h, stream-executor 的 JSDoc 默认值写的是 30 分钟 —— 这里把两者都压掉一个数量级; 且 ...options 透传的 idleTimeoutMs 会被下一行覆盖,调用方无法覆写。 2. **并行 agent 污染**:retrain-watchdog 每 5 分钟唤起的 Master 在同一工作树里 改了两个源文件,被守卫 git status 差集算到该节点头上 → 额外署 boundary_escape。 这是 W3「拦不住」第 5 条第一次真实发生。 顺带记一笔:这一轮任务是 **LemonBoss 自己的 Master 自主下的单**, 走的正是 POST /api/company/:id/tasks,它还自行诊断出了上面那个 idle timeout 并动手改(引用了未定义的常量,是坏的)。 ## 已知未修(下一轮) - idleTimeoutMs 硬编码 120s —— 「work 节点 → success」跑不通的唯一技术原因 - W7 在**零边最小图**上失效:判据③要求存在 active org_graph_edges, 零边图上三条判据全落空,work 层本体被写进 org_graph_nodes。 服务层那 9 例测试造的都是有边的成型图,正好绕开这个形状 - 前端 ACTIVE_RUN 含 blocked、后端 ACTIVE_ROOT_RUN_STATUS 不含: 一家公司只要失败过一次,控制台上就再也下不了第二个任务(后端其实放行) - 真跑期间工作树里不能有第二个 agent 活动,否则守卫判罚不可信 —— 应写进真跑规程 Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>