• ## 验收 4:从「静态成立」变成真的跑过一次
    
    原状态是 🟡「静态成立,未真跑」—— 人读代码把
    fixture verdict → FAILING_VERDICTS → readNodeProduct → callAgentNode 判 fail
    这条链读通了,但没有任何一次真跑或真链路证据。
    
    现在 graph-real-chain-smoke ⑥ 走完整条:fixture 产出 verdict="attributed"
    → 节点 fail、fail_reason=input_underspecified、沿 fail 边点亮下游、
    判词落在**下游节点**行上(判词的载体是「点亮它的那次状态转换」,不是失败节点自己)。
    反向验过:verdict 改成 passed 立刻红。
    
    写 fixture 时踩到一条值得记的:fail_reason 是封闭域 ATTRIBUTION_REASONS,
    第一版编了个 contract_invalid,被**按设计降级成 null** 并留一条 timeline ——
    引擎不认识的归因一律不信。判据没错,是 fixture 错。
    
    ## 验收 2 / 8:由 2026-08-20 那次真跑验掉(§六ter)
    
    · 2 —— 19 次真 agent 调用之后 `git status --porcelain` 完全为空,交付物都在项目根内。
      这正是 §六bis「后半被并行 agent 打破」那条的干净环境重验。
    · 8 —— 判据取「它引用了只可能来自提示词的内部 id」:triager 判词原文写着
      「org-coder-impl 私有目录 rn_96a8cd696dcc 下只有 _research.md」,
      rn_96a8cd696dcc 是 graph_run_nodes.id,agent 没有别的途径知道它。
    
    ## 验收 9:产出端通了,消费端没等到那个形状
    
    真跑里 triager **确实产出了两半地址**(orgNode + workNode)——
    这一条本身有分量:27-P3/P4 §八.22 第 13 处记的正是「引擎四环全通,
    但产出方 agent.md 里根本没有这个键」,那半条现在通了。
    
    紧接着「忽略跨层地址」那条**不是缺陷,是判据在正常工作**:这次回退发生在
    work 层内部,edge.to 本身就是 agent_call 节点,已是最细粒度,没有跨层可言。
    缺的是**那个形状**:一次 org 层回退边、且目标是 subgraph 节点。
    
    别把「机制没验」和「机制没有」混为一谈 —— 定点重置的逻辑侧有
    graph-cross-layer-address.test.js 三例注入式覆盖,缺的只是真跑里发生过一次。
    
    ## 顺带
    
    · template-verdicts 的样本非空那条补 ENOENT 容忍。它扫**活目录**,
      而 graph-real-chain-smoke 会在 system/agents/{aid}/{cid}/ 下建了又清运行态 ——
      文件在「列出名字」和「读它」之间消失是正常的。walk() 与 violations() 早就容忍了,
      只有这一处漏了,实测偶发红过一次。**扫活目录的守卫,每一处读都要容忍 ENOENT。**
    · 真跑 timeline 里发现一条未修的:每个节点的产物索引写入都撞
      UNIQUE idx_graph_files_path 失败并被降级成日志(重试时同路径再写一次)。
      后果是 files.json 产物索引在有重试的 run 上静默不全 —— 归 P4 一起处理,记在 §六ter。
    
    全量:139 文件 / 1297 测试全绿。
    
    Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
    yibo authored
     
    Browse File »
  • agent_call 与 subgraph 是**两段不同的默认实现**(defaultAgentExecutor /
    defaultPlanWorkGraph),各有各的 onAcpEvent 累加、各有各的守卫开关分支。
    上一轮只覆盖了前者,「规划子图」那半条链仍然是零真实覆盖。
    
    现在走完:defaultPlanWorkGraph → AgentManager → ClaudeCliProtocol(mock)
    → extractPlannedGraph 解析回复 → createWorkGraphSafely → 建子 run。
    
    断言两处假 planner 天然绕开的接线:
    · 子 run 的定义确实来自 fixture 那张图(节点名 / systemAgentId 逐个对)
    · 规划那一轮烧的 token 也进了预算 —— 走的是 defaultPlanWorkGraph 自己那条
      onAcpEvent,与 agent_call 那条不是同一段代码
    ③ 的守卫断言补上 subgraph 分支的正反对照。
    
    新增 fixture workgraph-planning.json:图 JSON 同时放进 chunks 与 result
    (mock 下 output 取哪一半由 AgentManager 决定,不该由 fixture 来赌)。
    
    反向验过:抽掉 fixture 里的图 JSON、或把它的 usage 归零,对应用例分别变红。
    
    **覆盖边界写在用例注释里**:跳过 resolvePlanningAgentName 里的按需 hire
    (预塞一行 company_agents)—— hire 要一条真实公司记录,那条路径另有
    company-hire-org-layer.test.js 盯着;这条 smoke 验的是规划链路,不是招聘。
    
    全量:139 文件 / 1296 测试全绿。
    
    Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
    yibo authored
     
    Browse File »
  • ## 一、W7「零边图」不是待办 —— 它早修了,是注释在骗人
    
    `company-service.js` 的判据注释仍写着「判据用**有没有边**」,并留着一段
    「已知残留:单 org node 的最小图没有边,判据③不生效……真跑到那一步再看」。
    
    **那个残留在 `58a2865`(08-17)就修掉了**:`orgGraphMembership` 现在的主判据是
    `authored_by='planner'` 的节点存在(「orggraph-planning 提交过一张图」的直接证据,
    零边也认),边数降为存量行的回落判据;守卫 `company-hire-org-layer.test.js` 的
    `CO_ZEROEDGE` + `W7-fix` 两条盯着。
    
    注释没跟着改,于是它把读的人**引向一个已经修好的缺陷**去重修一遍 —— 我就是这么被
    带偏的:读到那段注释就没再往 `orgGraphMembership` 里跟,还据此往待办清单里写了一条。
    这是「指路牌失效」那一族,和 CLAUDE.md 死链同型,只是方向相反(那边指向不存在的东西,
    这边描述已不存在的洞)。
    
    判据的措辞也改了:**「成型」的判据在 graph-service.orgGraphMembership(),不在这里**,
    免得下一个人照注释理解。P3B 文档与 docs/README.md 的对应条目一并更正。
    
    ## 二、还上「真实路径 smoke 进 CI」那笔欠账的一半(27-P3/P4 §十 硬规矩 2)
    
    原话是「凡是靠注入点验的能力,都要有一条真实路径的 smoke 进 CI 才算验收完成 ——
    这条欠账仍未还」。此前唯一走真实路径的 `scripts/real-pm-smoke.js` 要真 API 额度、
    人工跑、而且验的是 DevLoop 不是图执行。
    
    做法是把「真 LLM」和「真代码路径」拆开:**只把最外层的 CLI 子进程换成 fixture 回放**,
    setAgentExecutor / setPlanWorkGraph 一个都不调。链路完整走
    advanceOne → defaultAgentExecutor → AgentManager → ClaudeCliProtocol
    → onAcpEvent → 落盘 → readNodeProduct → settleNode → spendBudget → 边界守卫。
    
    三条断言各盯一处**假 executor 天然绕开**的接线:
    · ① mock/files 真的落到节点产物目录(假 executor 直接 return,这一环整个不存在)
    · ② token 用量真的从 session/result.usage 数进预算 —— **就是 §六 验收 10 卡了两轮的那一维**
    · ③ boundaryGuardApplicable 在这条路径上为真(注入假 executor 时它恒为假,
         那条唯一有实际后果的分支实际零覆盖);带反向对照,注入后必须变假
    
    反向验过:断掉①的落盘、断掉②的累加,对应用例分别变红。
    
    为此改了一处 mock:session/result 的 usage 原来硬编码 {input:0,output:0},
    现在 fixture 可指定(缺省仍是 0,既有 fixture 行为一个字不变)。
    **不改这一处,token 那一维在 CI 里永远产不出数** —— 验收 10 当初就是卡在这儿。
    
    **没还清的部分写在文档里,别当成还清了**:真 LLM 仍进不了 CI;
    subgraph 那一支(defaultPlanWorkGraph)仍只有注入式覆盖;
    多节点 / 回退边 / 熔断没进这条 smoke,它只推一个节点。
    
    afterAll 清掉真实链路建出的公司态目录(gitignore 挡着不进库,但留着会让别的
    用例遍历 system/agents/ 时多扫一份)。
    
    全量:139 文件 / 1295 测试全绿。
    
    Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
    yibo authored
     
    Browse File »
  • ## 移进 done/
    
    · 27-p3c-goal-task-model.md —— 五批实施完毕,§15.5 / §16.8 的后续项也全部收掉。
      新增 **§十七**:欠账清单对账、边界守卫从「乱扣帽子」改成「留证据不判罚」、
      测试污染生产图库(第四次踩同一族,但换了个方向进来)、那条卡了两天的 run,
      以及 **§17.5 真跑验收** —— org-planner-sdd/benchmark/validator 全 success、
      work run completed、父节点自动拉回、org-coder 起实现层子图、
      org-coder-validator 判 fail 走回退边打回 impl(loopCount 1)。
      **返工闭环第一次由真 agent(不是注入的假 executor)走通。**
    
    · 27-p3c-batch3-handover.md —— 四条复核结论全修完、§五 那条 run 已解开,
      §七 待办全部打勾。从待办转为**事故记录归档**:§六 那几条多会话协作规则是真踩出来的。
    
    两份的相对链接都已重指(done/ ↔ todo/ 跨目录),no-dead-path-references 守卫通过。
    
    ## 留在 todo/ 的,状态说清楚
    
    · 27-graph-agent-architecture.md —— 状态行校准。那一行是别人判断「能不能搬 done」的依据。
    · 27-p3b-real-run-runway.md —— 加状态行:验收 7 ⛔ 真跑不成立(readme-writer 混进
      org graph,**未修**)、2/4/8/9 未在干净环境验。缺陷② 的**根因**今天修了,
      但特意写明「**根因修了不等于验收点验了**」—— 不然下一个人会照着状态行当成验过。
    · 27-p3-p4-work-graph-console.md —— 在索引里写明留 todo 的原因:
      §十 那笔「真实路径 smoke 进 CI」的欠账未还。
    · 28-followups.md —— §3.3 标已修(含「GET /info 的 404 闸门仍没修,别当成修过」);
      §五 守卫表加两行(graph-db-prod-guard / heartbeat-company-scoped),
      并补第七条的来历。
    
    ## docs/README.md
    
    索引补上新增的 done 条目与 P3B / 28-followups 行,主线说明改成
    「当前未完成的是哪几件」——原来只说完成了什么,读的人得自己推。
    
    全量:138 文件 / 1292 测试全绿。
    
    Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
    yibo authored
     
    Browse File »

  • 起因是「全量测试偶发挂一条」。查下来既不是回归、也不是那 45 个孤儿进程(它们 CPU 早归零、
    不再写任何东西),而是**还活着的心跳在测试扫描 system/agents/ 的同时往里建目录**:
    
        locator.taskDir() 的落点是 system/agents/<agent>/<companyId>/<taskId>,
        运行态目录落在本体目录里属既定设计;但心跳每 5 分钟建一个新的
        (cto/_global/ 已 263 个子项且在涨),于是扫描 system/agents/ 的守卫测试
        (no-dead-path-references 那一类)会撞上瞬时竞态:列到了目录名,进去时那一层还没写完。
    
    症状是偶发假失败、重跑就好 —— 这类最费人,因为第一反应总是去怀疑自己刚改的代码。
    
    改法:server/index.js 启动的那个 setTimeout 块里,恰好装着全部「会自己起 agent 的东西」
    (两处中断恢复 + 任务队列扫描 + 两路心跳),所以一条早退就够,不必在五个地方各加一个判断。
    
        DISABLE_BACKGROUND_AGENTS=1 bash start.sh
    
    实测:127 文件 / 1226 用例全绿,跑前跑后 cto/_global 子项数都是 263。
    
    **验证它生效不能只看日志里的 ⏸** —— 那只证明代码走到了早退。硬判据是目录数前后相等,
    也就是真的没有东西在写。文档 §七 把这条写成了可粘的三行。
    
    排掉的两个坑,都记在文档和 .env.example 里:
    
    1. `.env` 里不能给这个键赋空值。start.sh 是 `set -a; source .env` 加载的,.env 里只要
       存在同名键(哪怕空的)就会盖掉命令行传进来的 =1,而且不报错。所以 .env.example 里
       它只以注释形式出现 —— 一个「示例文件顺手写全」的习惯会直接让开关失效。
    
    2. 开关生效后 `[TaskQueue] 🚀 已启动` 仍会打印,那是另一个模块:services/task-queue.js
       (ArenaSK 时代 /api/claude-chat 的队列,routes/claude-chat.js 模块加载时起),
       和批 3 的 services/task-scheduler.js 同名不同物。它的心跳只扫内存里的 this.tasks,
       不碰 system/agents/,不是干扰源。名字撞车,容易误判成开关没生效。
    
    文档同步:
      - docs/done/claude-cli-session-leak.md §七 重写(原文写的是「得让测试隔离,或跑前停心跳」,
        现在后者已实现,改成开关的用法 + 硬判据 + 上面两个坑);原第 2 条降为 §七之二
      - CLAUDE.md 测试命令块加一行(这是找「怎么跑测试」的人真正会看的地方)
      - docs/README.md 索引行补上开关
    
    Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
    yibo authored
     
    Browse File »
  • 泄漏被修过一次(310a2b2 / 3e718aa),修完照样漏。第二次排查发现原因不是修错了,而是:
    
        系统里有两个互相独立的会话池,上一次只修了其中一个;而被修的那个,还漏了一条分支。
    
        池 A  routes/agent-chat.js 的 sessions       ← /api/agent/:id/chat,含两路心跳
        池 B  src/core/session-pool.js 的 SessionPool ← AgentManager.callAgent,图执行 / DevLoop
    
    两者没有任何共享代码,回收逻辑各写各的。这个结构性事实此前没有任何一处记着,
    所以第二个人查到同一个症状时会重走一遍全程 —— 这份文档就是为了让第三个人不必再走。
    
    正文八节,除了两个洞各自的成因与修法(b0b2b62 / 2092a2e),有三处是排查方法而非结论:
    
    §三 按 cwd 第三层判断孤儿归属的对照表。两个池子都把 cwd 下沉到运行态目录,
         `_global` / `_no-task` 是 agent-locator 的保留缺省值、两边都会出现,不能靠它区分。
    
    §四 为什么上一版守卫是瞎的。dropSession 和 closeSession 都会让会话从池子里消失,
         黑盒探针两种情况都返回 false —— 差别只在子进程死没死,而那是探针看不见的维度。
         选探针要问的不是「能不能测出正确行为」,而是「能不能区分正确行为和这个具体的错误行为」。
    
    §八 三步定位脚本,外加一条:先确认跑着的服务器进程是什么时候启动的,再去看代码。
         本次排查中,正在跑的实例比修复 commit 早 18 秒启动,代码里有的修复它并没有。
    
    线上验证(PID 63099,13 分钟窗口两轮心跳):触发 5 / 完成 5 / 回收 5,峰值子进程 3、稳态 0。
    17:13:32 那个 3 正是泄漏时代的签名(cto+coo+qa-judge 同秒触发),清理前那批孤儿一个都不回收,
    现在 30 秒内全部释放。窗口内没有失败心跳,所以 2092a2e 那条 catch 路径是靠单测的变异检验
    保证的、不是靠线上观察 —— 文档 §六 里写明了,没算成已验证。
    
    docs/README.md 同步加索引条目(no-dead-path-references 守卫 4 条全绿)。
    
    Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
    yibo authored
     
    Browse File »

  • 用户授权清理 system/templates/ 的过期引用。全仓库核了 34 处,
    结论与预期相反:没有该删的死代码,但有两处正在静默失效。
    
    真正坏掉的(demo-harness-company.js):
      path.join(ROOT, 'system/templates/base/agent.md')   → system/agents/_base/
      path.join(ROOT, 'system/templates/base/config.json') → system/agents/_base/
    两处都包在 fs.existsSync() 里,所以目录消失后**不报错**,只是
    静默跳过 base 本体的挂载 —— demo 跑出来的 agent 没有四段式骨架,
    但脚本照常打印成功。又一个静默降级。
    
    顺带:real-pm-smoke.js 的提示文案、migrate-agent-naming.js 里
    已失效的遍历项、docs/README.md 的 qa-judge 落点。
    
    CLAUDE.md 目录速查表原来只有 `system/templates/devloop-*/` 一行,
    连 system/agents/ 都没列。换成两行并写清三个容易踩的点:目录才是
    数据源头(seedAgents 直接扫目录)、_registry.json 只补
    benchmark_score、_ 前缀是保留 id 会被跳过。
    
    **刻意不动的**:server/tests/ 下 30 处引用。它们分两类,都得留 ——
    ① 记录迁移过程的注释;② 断言目录已不存在的守卫
    (`expect(git(['ls-files','--','system/templates'])).toBe('')`、
    `expect(fs.existsSync(...)).toBe(false)`)。删掉后者等于删掉
    「迁移已完成」的证明。legacy_path 那几个测试夹具同理,是历史数据形态。
    
    验证:三个脚本 node --check 通过;改后的四个路径实测存在。
    
    Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
    yibo authored
     
    Browse File »

  • 按 docs/README.md 既有约定(done/ 放「已实现/当前有效」),把两份已落地的
    阶段设计文档移入 done/system-design/:
    
    - 27-p1-virtual-reference.md  P1 虚拟引用寻址,commit 226489d
    - 27-p2-org-graph.md          P2 Org Graph,70a4727 + f20d0d8,真实建公司端到端验证过
    
    用 git mv 保留历史(R098 / R087)。移动断掉的 33 处相对链接已全部修复:
    moved 文件内的出向链接改 ../../todo/system-design/,todo/ 下 6 个文件的入向链接
    改 ../../done/system-design/。全 docs/ 扫描无断链。
    
    README 此前严重过时——只列了 2 份 27 文档,实际已有 11 份。本次补全 todo/ 表格,
    每份标注状态与作用(总纲 / 需求源头 / 命名规范 / 端到端 / 参考场景 /
    P3+P4 已实现 / 验收契约 / P4 设计中),并在 done/ 表格补上 P1、P2 两行。
    
    ■ 刻意没有移动 27-p3-p4-work-graph-console.md
    它虽然已实现(c3abf4a),但文档正被另一进程持续修改(工作区 M 状态)。
    移动会打断它的编辑路径,等它收尾后再归档。
    
    ■ 三份文件的链接修复留在工作区未提交
    27-naming-conventions.md / 27-p3-p4-work-graph-console.md / 27-requirement.md
    里,我的链接修复与另一进程的在途编辑混在同一文件中,单独拆分风险大于收益。
    工作区内容是正确的(链接已指向新路径),会随它下次提交一并带上。
    
    Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
    yibo authored
     
    Browse File »

  • - New docs/README.md indexes the tree: done/ (shipped features + reference manuals),
      todo/ (current focus — Graph Agent architecture), todo/future/ (deprioritized
      roadmaps: FDE pipeline todo list, stale v1.1 milestones, harness engineering
      proposal — orthogonal to the Graph Agent work, not blocking it)
    - Move completed/reference docs into docs/done/ (LEMONBOSS-SYSTEM-DESIGN, architecture-v5,
      claude-code-cron, open-api-manual, qa_judge_req, task_timeline_design, user-guides/,
      system-design/01-26 minus the three moved to todo/future/) — verified against actual
      code (qa-judge template, Task Timeline route/service/view) before filing as done
    - Fix the two TOC links in LEMONBOSS-SYSTEM-DESIGN.md that would otherwise point at the
      old paths after the move
    - docs/todo/system-design/27-graph-agent-architecture.md: add the P2 Org Graph doc link
      in the roadmap table and 关联文档 section
    - Add docs/todo/system-design/27-p2-org-graph.md (P2 requirements & design, drafted in
      parallel while P0/P1 landed)
    
    Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
    yibo authored
     
    Browse File »