-
前一提交(c03ae10b)的 git add 因命令里混了一个已失效的 pathspec 而整体失败, 只有此前单独 git mv 出去的改名部分被记录下来,实际的引用修正全部漏提交。 补上:docs/README.md 索引(todo 表挪到 done 表 + 顶部状态行)、其余 27 系列 文档里指向该文档的相对链接(todo/ 与 done/ 下深度不同,分别处理)、 system/agents/*/agent.md 与 tools.md 里 cwd 深度 3 的 ../../../../../ 相对引用 (agent-md-refs.test.js 会校验这些链接真实可解析到文件)、_registry.json 的 description 字段、work-graph-templates/README.md、server/ 源码里的设计文档路径注释。 Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01JnCKUFSGvdz4SY7BvYWdMU
-
代码修复: - SessionPool 的 scope 参数从未真正从 graph-engine 传到 AgentManager,导致 fan-out 场景下同一 agent 的并发调用会撞会话键;补上生产接线(graph-engine.js/agent-manager.js) - advanceTree 改成 Promise.allSettled 并发推进兄弟子 run(原来只推最深的一个) - graph-real-chain-smoke.test.js 补齐多节点/回退边/双层熔断的真实链路覆盖 真实验证: - 27-P3B 最后一条验收(org 层回退边指向 subgraph 节点)用隔离 worktree 真实 Claude CLI 跑通并记录证据(§六quater) - 27-P3B 正文里 W5/W6/W7/W9 的"仍未验"备注核实后发现均已被此前的真跑验过,只是没回填; W8(重新规划组织按钮)此前确实没验过,本轮用隔离 worktree + 真实浏览器点击补验 文档收口: - 27-P3B、27-P4 两份文档功能与验收均已完整,移入 docs/done/,更新全部交叉引用 - T5(账户欠费门真实计费接口)按用户决定移入 docs/todo/future/,不阻塞收口 - 订正两处过期判断:graph_edge_contracts.role 列早已落库、CONVENTIONS.md 非 spec:extract 生成物 Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01JnCKUFSGvdz4SY7BvYWdMU
-
T-mtratkfb(源自 T-mtraluo2 系统性缺陷评估的缺口一):unsatisfiedRequiredProduces 在 contract.json 缺失时退化成「私有目录里随便有个非元数据文件就算数」(hasCandidates), 而 _base/agent.md 四段式生命周期(RESEARCH→PLAN→EXECUTE→VERIFY,全仓库几十个角色共用) 第一阶段就会落 `_research.md`,比真正的交付物早得多——org-coder 只做到 RESEARCH 就能 用这份笔记骗过闸门被判 success(复现:run_fe5a50b4e836,项目根空目录、节点私有目录 只有 _research.md,却被判 success)。 修复:candidates 过滤掉 `_` 前缀文件(全仓库通用的阶段性私有笔记命名约定,真交付物 从不用这个前缀,不会误杀合法产出)。 回归测试:graph-files-index.test.js 新增④c,按 run_fe5a50b4e836 的真实文件状态复现 (只写 _research.md),先反向验证过——去掉过滤条件时该用例确实 FAIL(status 变 success),加回后 PASS(status 变 blocked / produces_missing)。 缺口二(impl↔validate 图缺 fail/backward 边)已在 8b1e7fb6 一并修复 (createDecomposedWorkGraph 补了 validate --fail--> impl 退回边,task-decomposition- phase4.test.js 三条新测试覆盖边形状/真实退回重试/硬顶熔断),本次未重复改动,仅确认 其单测仍全绿。 全量单测 1636/1638 通过(2 个失败 env-example-secrets / test-id-stability 与本次 改动无关,revert 后依旧失败,确认是改动前既有缺陷)。 复现样本 run_fe5a50b4e836 的图定义创建于两处修复落地之前(13:39 vs 8b1e7fb6 的 17:09),结构上永久缺 backward 边,无法靠新代码自愈;建议由 COO 走正常回收流程 (取消该 blocked 子任务,让父任务 T-mtradxxu-b112 重新派发一次子任务,新图会走 已修复的 createDecomposedWorkGraph)而不是热改这一条历史数据。 Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
-
46 号文档 Phase 4:decomposed_work 子任务的父子生命周期管理。 - 父任务被 subtask-planning 成功拆分后让位给子任务(新状态 decomposed), 取消自己排队中的完整 org graph run - 父任务预算按拆出的步数均分给每条子任务 - 父子终态汇总(settleParentTaskIfAllChildrenDone),子任务全部完成后 自动结算父任务并联动 goal 收敛 - 同父子任务独立并发坑位(上限 3),判据钉在 updateRunStatus 的唯一准入 事务里,不占用公司级 max_parallel_tasks 槽位 - 前端(Phase 5):decomposed 状态样式 + 子任务进度展示,复用已有的 parentTaskId 通用树形逻辑,未改后端接口 真实回归当场撞出一个几乎必现的真缺陷:markTaskDecomposed 原本只认父任务 还是 queued,但 task-scheduler 抢坑是毫秒级、subtask-planning 是数十秒的 真实 LLM 调用,等它拆完时父任务几乎必然已经 running,接管必然失败,而 stopRun 依然会把真实在跑的 org graph 取消掉。已修复(接管条件放宽 + 调整先接管再取消的顺序)并用真实公司数据验证;同父并发坑位也用真实数据 确认生效(两条子任务真实同时 running 20+ 分钟)。 回归过程中牵出一个独立缺陷:org-validator 对同一种 benchmark 契约判断 不稳定(5 次里 1 次误把源码路径当 --target 判 target_not_json,反手把 责任推给 subtask-planning)。根因是 decomposed_work 轻量图当时只有一条 前进边、没有失败边,validator 判 fail 后无路可退。已补 validate --fail--> impl 退回边(复用引擎已验证过的 backward_count 双层硬顶 + remediation_note 反思闭环),新增 3 条单测覆盖边形状、真实退回重试、硬顶熔断三个场景。 全量单测 1229/1231 通过(2 个失败改动前即存在、与本次无关)。 Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01H9Mq8rViHp8xuj6zTy76hh
-
subtask-planning 每个 step 新增 acceptance 字段(benchmark 段格式),createTask 强制 decomposed_work 子任务必须带验收契约并用 goal-contract.validateContract 校验, enqueueTaskRun 起轻量图前把契约落进新 run 的 artifacts/acceptance.json——解决 46号文档 Phase 3 v2 真实回归撞见的 org-validator 死锁(轻量图没有 org-planner 产出契约,退无可退)。 真实起 subtask-planning agent 验证时发现设计稿的字段形状假设有误(真实产出是 benchmark 段本身,不是三段式 wrapper),已按真实产出修正代码与文档,并用那次 真实调用的原始输出跑通完整链路验证。 Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01H85SS5hVC4u1PbVhjmrhH8
-
验证 46 号文档 Phase 3 v2(CEO 心跳发现并派发子任务)时,触发 CEO 心跳 直接撞上 401——company-heartbeat-service.js 的 _sendAgentChat 和 heartbeat-service.js 的 _triggerHeartbeat 都在自环调用 POST /api/agent/:agentId/chat(agent-chat.js 挂了 requireAuthOrInternal), 但两处都没有带 INTERNAL_TOKEN_HEADER——company.js/task-settle.js 的同类 自环调用早就在带,这两处漏了。 失败只落一行 console.warn,界面上什么都看不出来,影响的不只是 CEO 心跳: 两套心跳系统(per-agent 的 heartbeat-service 和公司级的 company-heartbeat-service,含它驱动的 pipeline/schedule 触发)都受影响。 按现成模式补上内部令牌头。全量单测 1189 passed(唯二失败与本次改动 无关),修完真实验证 CEO 心跳能正常跑完整段推理会话。 Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01H85SS5hVC4u1PbVhjmrhH8
-
真实回归暴露"认领后没有触发源"的真问题,讨论后发现"认领"(pull,CAS 抢占)要解决的"多方竞争同一条任务"场景根本不存在——只有 CEO 一个人拍板 要不要派、派给谁。CEO 心跳统一发现+直接派发(push)成本更低,还能顺带 控制派发节奏,不需要认领。 删除:claimSubtask/unclaimSubtask(work-graph-db.js)、POST /claim、 POST /unclaim(company.js)、CLAIMABLE_WORK_ROLES 白名单、 claimable/claimed 两个 status 值、claimed_at 列。 改名:subtask_kind 的 'claimable_work' → 'decomposed_work' (materializeClaimableSubtasks → materializeDecomposedSubtasks), "认领"这个词不再准确,物化出的行现在就是普通 draft task。 新增: - triggerSubtaskPlanning 加递归防护(task.parent_task_id 非空直接跳过) ——设计 v2 时发现的真实漏洞:CEO 对子任务调 /enqueue 会默认 withSubtaskPlanning=true,不挡会对已经是"第几步"粒度的子任务再拆一层。 - createDecomposedWorkGraph:现造一张两节点轻量 work graph (impl=org-coder、validate=org-validator,agent_call 不是 subgraph), 跳过公司完整 org graph 的 brd/prd/sdd 规划仪式——subtask-planning 已经 把"怎么做"拆到这个粒度了,再走一遍纯属重复劳动。含一条没有真实验证过 的假设(org-coder/org-validator 裸调用会不会读不到预期上下文),如实 写在代码注释和文档里。 - enqueueTaskRun 按 subtask_kind 选图:decomposed_work 走轻量图, 普通 task 行为不变(回归测试覆盖)。 - ceo/heartbeat.md、tools.md 补了巡检 decomposed_work 草稿 + 判断节奏 + 调用现成 /enqueue 的指令。 测试:删除 task-pool-claim.test.js(随 v1 代码作废),新增 task-decomposition-dispatch.test.js(12 条),更新 task-decomposition-validator-gate.test.js 措辞。全量单测 1191 条, 1189 passed(唯二失败与本次改动无关),零残留 CLI 子进程。 Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01H85SS5hVC4u1PbVhjmrhH8
-
tasks 表新增 subtask_kind('acceptance_item'|'claimable_work',区分 43 号 文档的验收条目物化和 Phase 3 的可认领工作项物化,共用一张表不新开)+ claimed_at 列(批 6 迁移,ALTER ADD COLUMN,纯增量向后兼容)。 - work-graph-db.js:createTask 新增 subtaskKind/status 参数 + 校验; claimSubtask/unclaimSubtask 是全仓库第一个真正的"认领(pull)"CAS 写入 (之前 assignee_agent_id 全部写入点都是"派发 push",没有先例可抄,照抄 claimQueuedTask 的 changes 判据);materializeClaimableSubtasks 把 subtask-planning 的 steps[] 物化成可认领子任务,两阶段建法处理 depends_on_hint 的前向引用,幂等,与 acceptance_item 物化互不干扰。 - graph-engine.js:settleNode 的 SUBTASKS_INCOMPLETE 硬闸门收窄成只查 subtask_kind='acceptance_item'——这是必须同步改的一步,不收窄的话新物化 的 claimable_work 行会让所有开了 subtask-planning 的 task 验收判定失控 (已用回归测试固定住这个场景)。maybeMaterializeItemizedSubtasks 的 createTask 调用同步打上 subtask_kind='acceptance_item'。 - subtask-planning.js:triggerSubtaskPlanning 写完 artifact 后立刻物化 claimable_work 子任务,不等 org-planner 跑完。 - company.js:taskView 补 subtaskKind/claimedAt;GET /tasks 加 subtaskKind 过滤(?subtaskKind=claimable_work&status=claimable 就是可认领池查询); 新增 POST .../claim、POST .../unclaim 两个端点,角色白名单先写死 ['org-coder'](不做能力匹配,系统里没有结构化角色能力字段)。认领成功 同时把 executor 改成 'agent',复用既有的 executor='agent' 派单闭环 (/task/report 上报生命周期),不需要碰 graph-engine 的调度模型。 新增 task-pool-claim.test.js(23 条:DB 层校验/CAS/物化 + 路由层白名单/ 并发/放弃);task-decomposition-validator-gate.test.js 补一条回归测试 (claimable_work 子任务不影响 acceptance_item 的验收判定)+ 更新既有用例 显式打 subtaskKind;task-decomposition-materialize.test.js 补 subtask_kind 落库断言。全量单测 1202 条,1200 passed(唯二失败与本次改动 无关、改动前即存在)。 本轮明确不做:依赖顺序强制、能力匹配、graph-engine 调度模型改动、 Phase 4 的独立开发验证循环、Phase 5 看板 UI。 Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01H85SS5hVC4u1PbVhjmrhH8
-
46 号文档 Phase 2 真实端到端回归(真实公司 p2verify0902 + 真实 goal/task/ Claude CLI)第一次跑就复现一个真缺陷:原始打分用「交集计数、>0 就算命中」, 一条长任务描述几乎必然跟经验库里的高频工程词汇偶然重合几个 bigram,导致 一个贪吃蛇任务被"验证修复要重新触发流程"这类无关的工程经验污染成 reasoning_source=memory,压过了本该触发的 deep research 分支。 改成 containment ratio(命中词数 / 经验块自身词数,对经验块归一化而不是 对查询归一化),阈值用真实噪音案例(~3%-4%)和合成相关案例(~16%-32%) 校准。补回归测试固定复现这次真事故场景。修完重启服务用第二条真实任务 (Markdown 转 HTML 工具)重新验证:reasoning_source 正确变成 deep_research,两轮调用(subtask-planning → org-hunt → subtask-planning) 真实跑通,全程零残留 CLI 子进程。46 号文档补了真实回归记录,包括一个 如实记录的局限:org-hunt 那次调用没有工具调用痕迹,更接近"多问一个角色 的第二意见"而非真的做了外部检索。 Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01H85SS5hVC4u1PbVhjmrhH8
-
subtask-planning 改成两段式:先查 experience-lookup(扫已雇 agent 的 dream 沉淀经验,关键词打分)拼进提示词,agent 自评 confidence;经验为空或 confidence low 时触发 deep-research(图外直接调用 org-hunt 轻量提示词, 不套用其训练场景三件套契约,默认关闭,需 ENABLE_DEEP_RESEARCH=1)。 reasoning_source/experience_refs/research_used 增补进 subtask-plan.json, 向后兼容旧注入桩。 范围收窄:不做"历史同类 goal 检索"(需要语义检索基础设施);Phase 3-5 (任务池认领/子任务预算/看板 UI)涉及核心调度引擎范式级改动,另起设计。 Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01H85SS5hVC4u1PbVhjmrhH8
-
reopenRunForRetry 与 _reapStaleRunningNodes(开机孤儿清扫 + 45号文档持续性存活 扫描共用)把 run 从 blocked/ready 拉回 running 走的是裸 admitOrRequeue,不是 startRun,只改了状态从没重新挂上 runAuto 自驱动循环——手动/自动重试推一步后没人 接着推,agentRunId 仍是 null,backward 重试每次都在这里再卡一次。两处都补上 startRun 收尾那段逻辑:真的推成 running 且 execution_mode==='auto' 才挂 driver。 Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
-
47号:itemized 子任务物化在当前 workgraph-planning 常见子图形状下因 acceptance.md 永远产不出来而形同虚设;maybeMaterializeItemizedSubtasks 新增兜底,缺失时改读 已被 44 号文档证实稳定产出的 goal-benchmark.json 的 dimensions[]。 46号 Phase 1:新 agent subtask-planning,钩在 enqueueTaskRun(显式 opt-in,只在 goal 批量下达/单条 task 下达两处触发,保住 quick task 零 LLM 调用的既有保证); 产物写共享 artifacts/subtask-plan.json,复用 R-19.3 任务级共享索引对接下游。 Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
-
真实事故:h3video 公司 h3-story-draft 节点卡在 status=running,背后 CLI 会话已死但服务器 进程没重启,开机一次性孤儿扫描/goal-task 巡检/wallclock 看门狗均看不到,ceo 被转发问题后 绕过引擎自己拉会话,陷入死循环。 - sweepStaleRunningAgentCalls + startStaleAgentCallWatchdog:运行时长超阈值(默认 25 分钟) 的 agent_call 节点判 infra_flake 原地重跑,5 分钟一次巡检,挂进 server/index.js - ceo/tools.md 补 force-fail 端点(已有,未改代码)的使用文档 + 禁止自拉会话的规则 - ceo/heartbeat.md 同步更新"不用管的"一节 Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01WjFL1nfPDqZnJeuskYHwvs
-
Snapshot-then-stop race in stopRun() left child runs created after the snapshot outside the stop scope; add auto-mode guard rejecting manual /next on execution_mode='auto' runs (source of the concurrent-advance race). Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
-
44 号:writesArtifacts 节点产出闸门永远打不过 - goal-benchmark 按设计把产物写进 root run 共享 artifacts/ 目录(三个节点合成同一份 acceptance.json,天然不可能落在某节点私有目录),但 unsatisfiedRequiredProduces 的 R-19 逃生口 readDeclaredProduces 的 allowedRoots 只认节点私有目录 + 项目根,够不到 共享区——这条契约在当前实现下无论 agent 表现多好都无法通过。 - 修法(44 号文档方案 1,改动面最小):allowedRoots 加入 runRootDir(run)/artifacts/; goal-benchmark 的 agent.md/tools.md 补上"写完共享产物后在自己节点私有目录声明一份 contract.json"这一步。 - 回归:graph-files-index.test.js 新增用例 ⑭。 41 号:routeFailure 的 infra_flake 分支完全无视 target_node - 30 号文档记录过一次真实死循环:节点自称 infra_flake 并点名 target_node,引擎原来 一律原地重跑该节点自己,从不看 target_node。 - 修法(最保守方案,用户确认):新增 infraFlakeTargetEdge——target_node 只有在图上 真有一条从本节点出发的 backward fail 边指向那个节点时才生效,命中就改走正常的 backward 边路由(计入 backward_count/双层熔断),不再享受"原地重跑、只受 infra_flake_count 约束"的免账本待遇;没命中维持原有行为。 - 重要澄清:这条修复堵不住 30 号文档那次真实事故——事故里点名的目标是下游节点, 而 org-graph-service.js 规则 4(backward-labeled)从图结构上就不允许 backward 边 指向非祖先,那次事故本来就不是"有边不认",是"诊断内容在打图结构不允许表达的 主意",已经靠 INFRA_FLAKE_HARD_CAP 熔断收敛,不在这条修复范围内。 - 回归:graph-engine.test.js 的 infra_flake describe 块新增两条用例。 44 号文档移入 done/,41 号清单项相应更新,43 号文档的交叉引用一并修正。 Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01CwGcvMfUcgCcweN5vjhTkn
-
实现路径: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
-
test/integration 类节点从不产出一个能被 indexNodeOutputs() 认作 kind='log' 的文件(落盘的都是 coder.log/test.log,归入 kind='artifact'), required 的 log 契约永远无法满足,把节点卡进 missing_required_input 死循环。33 号文档修过一次模板文件,但 workgraph-planning agent 实际 照抄的是 tools.md 里一份没同步更新的旧范例,同一个坑复现(snakegame-co T-mtfh2kuf-7c31)。这次把底线收到 declareEdgeContract 唯一落库口, 不再依赖每个模板/每次 LLM 规划都记得写对;顺带同步 tools.md 范例。 Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01U7xYyvv3pzuV9diMVUH5QL
-
39 号文档 P5 落地的是"配了 company.json.target_dir 就生效"这一半, "人怎么把这两个字段填进去"此前只能手工编辑 company.json。 复用已存在的 PUT /api/company/:companyId(companyService.update()), 没有新建端点。新增 target_dir/target_mode 分支,校验直接调 path-resolver.validateLinkedTarget(39 号文档 P5 抽出来的共享函数, 和 graph-engine.js 运行时校验同一份判据):合法路径写入成功、敏感 路径黑名单拒绝、linked-new 非空目录拒绝、linked-existing 不存在拒绝, 校验失败路由层转 400;传空字符串清空配置;不传 target_mode 默认 linked-existing,与 graph-engine.js 的 readCompanyTargetConfig 同口径。 前端:CompanyDashboard.vue 概览 tab 加一张配置卡片,本地表单状态 不直接双向绑定 selectedCompany,保存失败不会冲掉用户刚打的字。 新增测试 8 例,npm run web:build 编译通过。**未做真实浏览器点击 验证**——服务器上有其它并行会话真实在跑的 agent 进程,这次没有重启 服务器(42 号文档 §二记过一次"重启杀掉别人真实进程"的教训),文档 里标记了这个已知缺口。 Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BwG4b7Nq1NLR9eeE3M9Us9
-
之前几轮全量跑一直有 3 个失败,当时判断是环境耦合/pre-existing、跟本次改动无关就没细查, 这次逐个真查了一遍,三个都是真 bug: - system/agents/sdd-planning/SKILL.md:Evolve 训练产出从 train/evolve/SKILL.md 提升到 生产位置时,"训练依据"引用的相对路径没跟着调整(少了 train/ 前缀),指向了不存在的 system/agents/hunt/、system/agents/digest/;真实文件其实在同一个 agent 自己的 train/hunt/、train/digest/ 下,补前缀即可。 - graduation-criteria-reality.test.js:断言死等 code-planner 的状态回到 'active',但 该本体的 config.json 早已从曾经踩坑的 "training" 改成了真正毕业态的 "enabled"—— seedAgents() 把 DB 同步成 'enabled' 是设计如此(同为毕业态,不是降级),不该被判失败。 改成用 isUngraduatedStatus() 判断"没被打回未毕业域",不再钉死具体状态值;顺手把 graph-seed-service.js 里那句会随源码变化过期的注释也改成不点名具体值。 - graph-engine-extend-budget.test.js:一颗时间炸弹——用硬编码绝对时间戳 '2026-08-23T05:23:52.886Z' 模拟"卡住很久了",但被测代码真的调 Date.now() 算经过时长, 写这条用例时"经过时长"确实超过 2h 上限、又低于追加后的 6h 上限;现在真实时间已经过去 178 小时,连追加后的上限都超了,测试注定要红,跟被测代码毫无关系。改成 Date.now() - 3小时 相对计算,不再随时间推移漂移。 全量 vitest 131/131 文件、1089/1089 用例通过。 Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
-
冲突在 docs/README.md:并行会话在真实端到端测试里发现 boss agent(39 号文档)还有 三个单测没覆盖的真问题,把 39 号重新留在 todo/ 并拆出 42 号跟进文档;与我这边把 39 号挪进 done/ 的判断冲突——采纳对方判断(39 号文档物理路径挪回 todo/system-design/, докс/README.md 用对方更新的行 + 补 42 号一行),因为他们是基于更新的真实测试结果。 顺带把 29-dream-design.md 这次会话移到 done/ 后遗漏的引用修掉: system/agents/{dream-distiller,dream-screener}/agent.md、 server/{routes/dream.js,services/dream-service.js}、 server/tests/unit/dream-routes.test.js 六处 docs/todo/system-design/29-dream-design.md 路径改成 docs/done/system-design/29-dream-design.md(no-dead-path-references.test.js / agent-md-refs.test.js 两条守卫测试之前没扫到这几处,这次真跑测试才暴露)。 Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> -
服务器重启会杀死正在跑的 graph 节点背后的真实进程,但 graph_run_nodes. status 永远停在 running(ceo 的两条唤醒路径都只认 blocked,对这个状态 完全不可见)——39 号文档真跑复盘撞出来的坑,这次补上。 1a:graph-engine.js 新增 sweepOrphanedRunningNodes(cutoffIso),复用 routeFailure 的 infra_flake 分支(不发明新状态),server/index.js 在 本次进程启动时刻挂一次开机扫描,排在其余「补一次全量扫描」钩子之前。 1b:新增 forceFailNode() + POST /:id/nodes/:nodeId/force-fail,补上 retry 端点管不到 running 节点这个缺口——人工/ceo 判定"这个真的救不 回来了"时的手动出口,转 fail 后交给既有失败路由处理,不发明新路径。 新增测试 12 例(graph-engine-orphan-sweep.test.js 4 例、 graph-run-force-fail.test.js 8 例),全量测试 1483/1487,零回归。 Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BwG4b7Nq1NLR9eeE3M9Us9
-
核心修复:indexNodeOutputs() 此前只扫节点私有目录,不扫项目根——但引擎自己的写入边界 明确允许交付物写项目根,导致内容型交付物节点(产出写进项目根时)永远进不了 R-19 产物 索引,下游 needs 声明永远查不到实例。新增 readDeclaredProduces():agent 可在 contract.json 里显式声明 produces:{kind: 绝对路径},校验(绝对路径/落在项目根或私有目录内/ 文件真实存在)通过才登记,不满足就整个 kind 判「没产出」,不静默放过。全局提示词 (describeArtifactContract)同步更新,所有 org/work 节点自动学到这个新字段。 新增 org-hunt / org-digest / org-evolve 三个 graph 原生 agent(方法论抄 innovator-hunt/digest/evolver,协议原生兼容 graph 引擎),配套新增 work-graph-templates 的 deliverable.json(内容型交付物骨架,不引入验证 agent)。11 轮真实试跑挖出并修复 5 个 独立缺陷(详见 41 号文档问题 7):建公司自动规划与手写图的竞态、work-graph 模板库缺内容型 交付物骨架、验收节点任务描述范围溢出、两个规划 agent(orggraph-planning/workgraph-planning) 的路径口径写错、以及上述 R-19 索引缺口。最终产出与原生 FDE 对比:内容骨架可迁移、质量不 打折,但可靠性差距悬殊。 补充说明:system/agents/{ceo,innovator-evolver,master,org-innovator}/{agent,soul}.md 是 本会话开始前已存在的 dream 自编辑改动,随本次提交一并收进去,不属于本次改动范围。 Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> -
company.json 新增 target_dir/target_mode,graph-engine 的项目根分配 读到配置后不再逐 run 分配新 sandbox,同公司所有 run 解析到同一个固定 路径(复用 path-resolver 的 linked-new/linked-existing 校验逻辑, 抽出 validateLinkedTarget/resolveFixedTarget 共享);未配置时零回归。 配了 target_dir 的公司 max_parallel_tasks 强制钉 1,避免多任务并发 写同一个仓库。按 39 号设计文档 §二 P5 落地。 Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BwG4b7Nq1NLR9eeE3M9Us9
-
按 39 号设计文档落地 ceo 常驻监督:company.js 的 goals/tasks 端点 放行内部令牌自环调用,POST /tasks 支持 draft 模式(agent 自主提任务 不再立刻烧预算),ceo 补雇进公司创建流程;task-settle 新增事件驱动 唤醒 + 30 分钟兜底轮询;graph-engine 的回退熔断收敛时顺手回写一条 draft task,形成"卡住 → 自动/ceo 判断 → 重新规划"闭环。 Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BwG4b7Nq1NLR9eeE3M9Us9
-
2026-08-28 把本地 mycompany/innovator-fde-trial 同步到生产时手搓合并脚本踩过两个坑: 本地库和生产库同名字段的物理列序可能不同(SELECT * 位置对齐会静默写错列),以及 graph_runs/graph_run_nodes 循环外键的回填 UPDATE 必须给关联子查询加表别名。 把手搓版本整理成 scripts/sync-company-to-graph-db.js(按列名对齐 + 支持 --dry-run), 并在 graph-db.js migrate() 和 production-deploy.md 里记下这两个坑,供下次同步复用。 Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01UpkWPa2CmuWJFJZksqvxWB
-
company-service.js:company.json 加 ownerId(无 SQL 表,纯 JSON 字段);create() 接收 ownerId;list({ user }) 按传入用户过滤,不传就不过滤(company-heartbeat-service.js 等 系统内部巡检要看全部公司);新增 canAccessCompany(company, user) 作为全仓库唯一一份 归属判据(admin 不过滤,判负一律 404 不是 403,不暴露"这个 id 存在只是不是你的")。 company.js 用 router.param('companyId', ...) 统一收口(约 50 条路由,含 okrPath() 系列 动态路由)。graph-run.js 的两个挂载点参数形状不一样,设计阶段的描述不准确,实现时才 发现:companyRouter 唯一路由是 /:companyId/graph-runs 直接查;主 router 全部路由是 /:id/...,:id 指的是 run 不是公司,改成先查 run 的 company_id 再判断,run 不存在或 公司不是你的统一回"run 不存在"。devloop.js 用 :pid 反查 company_id;POST /projects 单独校验 body 里的 company_id(放在基本字段校验之后,避免归属检查打乱输入校验的错误 优先级);GET /projects 按归属过滤列表。 okr.js 最终没有按原计划接入 companyId 归属校验——实现前查证发现 OkrDashboard.vue 挂载的 /okr 页面全站没有任何导航入口指向它,是个孤儿页面,给访问不到的页面建"选公司" 前端交互不划算,改成 requireAdmin(跟 dream.js 同款),先堵住直接拼 URL 看到跨公司 聚合数据的口子。真正在用的公司级 OKR(company.js 的 /:id/okr)已随 company.js 一起隔离。 存量数据迁移:scripts/backfill-company-owner.js(npm run backfill:company-owner), 两家存量公司已划给种子账号,幂等验证过。 8 个既有测试文件用的公司 id 都是从没真正建过的字符串标签,挂锁后集体 404——新增共享 helper server/tests/helpers/ensure-test-company.js 修复;两处原有的"跳过已有 company.json 的目录,那是真公司"防御逻辑,判据从"有没有 company.json"改成"ownerId 是不是 -1 这个测试专用标记",否则新出现的测试夹具会被误判成真公司永远不清理。 验证:真实 curl 走过(admin 看到全部存量公司、新用户看到空列表、新用户拼 URL 访问 别人的公司 404、新建公司 ownerId 精确落在创建者、admin 和创建者都看得到其他人看不到); 全量 vitest 1427 passed,3 个无关既有失败不受影响。 Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> -
给此前完全零防护的 company.js/okr.js/tasks.js/devloop.js/graph-run.js(两个挂载点)/ arena.js/config.js/evolution.js/whatsapp-auth.js 挂 requireAuth;dream.js 挂 requireAdmin (系统级经验汇流视图,只有 admin 能看)。open-api.js(自己一套 OPEN_API_KEYS)/auth.js 自身/health 端点按计划排除。这一步只挡"没登录",公司归属过滤留到 Phase 2。 agent-chat.js 不能直接挂 requireAuth:company.js(自动建公司/招聘后自动训练)、 task-settle.js(goal 汇报回调)三处服务端自环调用会 fetch 自己的 /api/agent/* 端点, 拿不到任何用户 cookie,直接挂锁会打断这几条核心自动化链路。新增 requireAuthOrInternal + jwt-auth.js 的进程内 INTERNAL_TOKEN(启动时随机生成,只活在内存里):自环调用带上 x-internal-token 头放行,其余情况仍要求真实登录;三处调用点同步改造。 17 个既有测试文件、67+ 处用例直接拿 supertest 打这些路由,从没设过登录 cookie(测的是 业务逻辑不是鉴权)。没有逐个补登录态,改为 requireAuth/requireAdmin 在 NODE_ENV=test 时默认放行,除非显式 FORCE_REAL_AUTH=1;新增 route-auth-gate.test.js 在放行关闭状态下 做结构检查(router.stack 里中间件是否真的排在所有路由前面),确保"锁真的挂上了"这件事 有测试兜底,不被业务测试的默认放行悄悄掩盖。 验证:真实 curl 走过全部路由(无 cookie 401、admin 登录全通、非 admin 能看公司但 dream.js 403);手工删过一行 requireAuth 确认守卫测试真的会红;全量 vitest 1427 passed, 另 3 个失败与本次改动无关(stash 验证过改前改后一致,系仓库并发工作遗留)。 Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
-
sweepStuckActiveGoals 候选查询多加了 archived_at IS NULL,把「goal 被归档但 status 从未跟着收口成终态」这类形状(G-mt1qwgt5-6b77:唯一 task cancelled+archived 时 goal 的 archived_at 被打上同一时刻,status 却留在 active)永久排除在扫描之外。去掉该过滤: settleGoalIfAllTasksDone 对空 task 列表/存在非终态 task 都是 no-op,不会误收口合法归档 但确实没收敛的 goal。同时手动收口了 e2e-demo 库里唯一命中该形态的 G-mt1qwgt5-6b77。 Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
-
settleGoalIfAllTasksDone 用 listGoalTasks 默认口径(includeArchived: false)取 task 列表,task 若同时被 cancelled+archived 会被过滤掉, tasks.length 提前归零直接 return null,goal 永远收不了口——僵尸扫描等 于没扫到。实证:G-mt0a6upq-a98e / G-mt0a6upq-52ee 两条 goal 卡在 active 超 17 小时未被收口,两条 task 均已 cancelled+archived。 改成 includeArchived: true 取全量后再按语义过滤:draft 任务归档(人删 掉的需求)继续不参与判定,但 cancelled/completed/failed 之后再归档 (结果已发生只是从界面收起)必须照样计入,否则会反过来破坏"归档掉的 草稿不参与判定"这条既有行为(拆分产出可删的验收用例钉住的就是这个)。 Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
-
resumePendingGoalValidations 只补「收敛钩子跑过、卡在验收/汇报半路」的情形; 若钩子压根没被触发过(进程重启/异常吞掉/事件丢失),task 早到终态但 goal 永远停在 active,只能靠人工 OKR 巡检发现(e2e-demo 公司 G-mt2r62ia-73af 卡 了 48 小时)。新增 sweepStuckActiveGoals 开机全量扫描一次,并启动 5 分钟 周期性 startZombieGoalSweeper 兜底,把发现窗口从「天」压到「分钟」。 Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
-
两个独立的小修复,都是这次 e2e 回归 + 用户讨论"workgraph-planning 该怎么训练"时发现的: 1. workgraph-plan-<taskId>.md 撞名:一个任务里 org-planner/org-coder/org-validator 各自调 workgraph-planning 一次、各自的规划记录却共用同一个文件名,落在同一个项目根下, 后写的原样覆盖先写的——真实撞见过(org-planner 当时的规划记录被 org-validator 覆盖, 事后一个字都找不回来)。改成 workgraph-plan-<taskId>-<宿主orgNode节点名>.md。 2. subgraph 节点结算 → workgraph-planning 自己的 memory.md 桥接:阶段一的 recordNodeOutcomeMemory 明确排除了 subgraph 节点(那是给 agent_call 记的),导致 workgraph-planning 每次规划出的图最终跑得好不好,完全没有可积累的历史——这正是它 "允许裁剪却没有具体判据"这个问题一直无法通过真实反馈自我改进的原因之一。新增 recordWorkgraphPlanningMemory,在 subgraph 节点结算时把结果记进 workgraph-planning (全局唯一规划本体,不是宿主 org node 自己的身份)的 memory.md,只在真实规划 (planWorkGraph===defaultPlanWorkGraph)时记,避免测试夹具污染真实目录。 新增 3 条回归测试,graph-engine 相关测试文件全绿。 Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
-
run_b962ea87f58f 卡在 wallclock_ms 耗尽的锚点未结清问题上,需要人工追加预算 才能继续。extendBudget 只增不减、只加到已配额的维度上,追加时顺带结清卡死的 墙钟锚点(否则 startRunSync 一启动就把挂起时长记进新预算里)。 Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
-
30 号文档记录的真实事故:org-coder-test 被上游 missing_required_input 打回后, 产出的是「建议重跑 org-coder-validator」的诊断文件而不是正常测试结果,引擎把诊断文件里 的 infra_flake 标记当成了这个节点自己的执行结果——infra_flake 原地重跑故意不烧 attempt/backward_count("这不是节点的错,不该烧它的重试额度"),代价是它是唯一没有 熔断线的失败路径,真撞上了一次每轮产出雷同、永不停止的死循环,眼看着把任务预算耗光。 新增 graph_run_nodes.infra_flake_count 列,只在 infra_flake 原地重跑时累加,真正发起 新一轮真实派发(bumpNodeAttempt)时清零;连续判 infra_flake 超过硬顶(3,与 LOOP_HARD_CAP_EDGE 同量级)就不再原地重跑,改判 blocked 交给人工——不猜该走哪条 fail 边(infra_flake 这个取值域通常没人给它连边)。新增回归测试锁死"永不恢复的 infra_flake 在硬顶后停止重跑"这条行为,graph-engine 相关 10 个测试文件 94/94 通过。 Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
-
POST /:cid/tasks -> enqueueTaskRun 入队时从未写过 assignee_agent_id, COO 心跳巡检靠 tasks.assignee_agent_id(the "to" field) 判断任务有没有 人接手,读到永远的 NULL 就把正常跑图的任务误报成孤儿任务 (本周已发生两次:T-mt25asz4、T-mt5d3mi9-57cf)。 - enqueueTaskRun 入队时补写占位哨兵 'org-graph'(GRAPH_TAKEOVER_ASSIGNEE) - settleTaskFromRun 收敛时用 COALESCE 兜底,只在仍为空时补,不覆盖 派单式任务(agent-chat dispatch 流程)已经写好的真实 assignee - TASK_PATCH_COLUMNS 补上 assigneeAgentId,否则 updateTask 写不进这列 T-mt5dkvjm Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
-
system/templates/ 已在 28 号文档的合并里并入 system/agents/,「模板」作为独立 数据概念已经消失;确认后手工 CRUD 页面(创建/改名/删除骨架、触发生成与训练、 传 skill 文件、provision)也已经没人用,一并下线: - 前端:删 AppNav「Templates」菜单项、/templates 路由、TemplateAgents.vue - 后端:company.js 删掉只服务于该页面的写接口(PATCH/DELETE/POST /templates、 generate/train/skills-upload/provision/files 系列),保留 GET /templates (CompanyDashboard 招聘弹窗和 CLI `company templates` 命令仍依赖它列出可招角色) - CLI:bin/lemon.js 删 `template create`/`template train`(调用的是被删接口) - 修正两处过时注释(company-service.js / graph-service.js):不再声称 buildAgentDefinitionBrief 有两个调用方,/hire 是唯一派单点 - work-layer-body-paths.test.js 同步更新断言(2 处调用方 → 1 处) Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
-
_scanConversationsDir 塞进 list 的字段是 conversationId,getTaskTimeline 过滤时却读 c.convId(始终 undefined),传进 _extractTaskId 后 convId.includes(...) 直接抛 TypeError,导致 /api/tasks/:id/timeline 每次调用都 500,前端任务详情页因此看不到任何日志。 Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
-
此前只有人类对话路径 agent-chat.js 会写 memory.md,图执行的验收反馈从不进 memory.md,Dream 天天扫全是空转。runClaimedNode 结算后新增 recordNodeOutcomeMemory 桥接点,只在真派发(isRealDispatch)且 systemAgentId 对应本体已雇佣(bodyDir 存在) 时才记一行 success/fail 摘要,避免测试夹具/假 executor 用例把假地址写进真实 system/agents/ 目录。memory-service.appendToMemoryMd 补 mkdirSync,因为这条新调用方 不像既有的 saveSessionSummary 那样先建过 memory/ 目录。 从原本混在墙钟看门狗改动里的工作区 diff 中拆出,两个特性互不相关。 Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
-
manual 模式没人点「下一步」、auto 驱动循环随进程重启丢失时,run_status='running' 的 run 再也不会触发 checkBudget,wallclock_ms 超时无人发现(实例:T-msx6toej 卡 135 小时才被人工揪出)。新增 sweepWallclockBudgets + 60s 兜底定时器 startWallclockWatchdog,复用既有 checkBudget/suspendRunTree 路径,接入点在 index.js DISABLE_BACKGROUND_AGENTS 早退之前。 Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>