-
真在浏览器上看了才发现的:320px 减去 padding 只剩 292px 可用,而两个节点 加一条边就要 380px+ —— 实际效果是节点名被从中间切断(`org-cod…`)、必须 横向滚才看得全。而它是**全局导航**,是这个页面上最不该被压的一栏。 同一时刻中间那栏(work graph)拿着 600px 却经常是空的:选中的 task 只要 还没跑过 work graph,那栏就是一句空态提示。 改成 `280px minmax(380px, 0.9fr) minmax(0, 1.1fr) 360px`:org graph 保底 380px,两张画布按 0.9 : 1.1 分剩余空间,屏幕越宽一起长。work graph 仍拿 多数 —— 它才是下钻之后的主画布。rail 态(≤1400px 最左栏收成图标条)同步。 改后实测:org-planner → org-coder 两个节点完整显示,边上的 prd 标签与回退 边的 0/3 熔断徽标都看得见,控制条从两行挤成一行。 Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
-
## 批 4:解除「一家公司同时只有一个 active root run」 - DROP idx_graph_runs_one_active_root(建表块删掉 + 迁移块显式 DROP, CREATE ... IF NOT EXISTS 对存量库不生效) - max_parallel_tasks 从 company.json 调用时读(不是模块加载时快照, 否则改配置要重启才生效且不报错);缺省 1、非法回落 1 并留声、硬上限 20 - 准入判据「从活跃集外进入活跃集」按额度计数 **生死线用 8 个真进程并发抢坑实测**(不是纸面论证):max=1/2/3/5 四组, 每组恰好抢到 max 个、库里活跃数 = max,落选进程各吃 40 次 RunSlotBusyError, 零 other 错误。唯一索引没了之后,准入事务是真守卫。 ## 批 3 对抗复核的四条遗留 - N1 🔴 cancelQueuedRun 的前提被批 3 自己的 requeueBlockedRootRun 改没了: queued 的 run 现在可以是跑过一半的。探针实测取消后子 run 残留 paused/stop_requested=0 —— 那条 running 的子 run 继续调 agent 烧 token。 改为无条件走 engine.stopRun - L1 ⚠️ 恢复路径对 manual 只兑现一半:注释写着「T1 永远回不来这个后果因此 消失」,但调度器故意不碰 manual → 退回队列后没人接。定案:「manual 不自动 出队」约束的是首次起跑的授权,已被人亲手起过的不算新授权。 判据用 attempt>0 而不是 started_at —— 后者会被 requeue 清成 NULL, 恰好在需要它的那一刻是空的(实测踩过) - N2 🟠「退回队列」对用户完全不可见:200 + ok:true + 按钮全灰 + 图消失 + 一句「节点状态一律 pending」的假提示。加 notice 明说 - N3 🟠 isSlotRaceError 把 InvalidTransitionError 当竞态吞掉,而探针证伪了 那条注释:被推走时条件更新返回 0 不抛,真正抛它的只有「调用方声明了非法 转换」。删掉该分支,让它吵起来 四条里三条是同一个模式:注释承诺的前提被本轮自己的改动改没了,注释还留着。 文档 §十三.3 / §十四.4 已就这个模式立过两次案,这是第三、四、五次。 ## 文档 §十五 实施记录,含 §15.4 一次流程事故:87b776c 由第三方会话在对抗复核完成 前误提,提交说明的「1201 用例全绿」压在一份尚未通过复核的代码上。 全量:128 文件 / 1240 测试全绿,web:build 通过。 Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
-
队列与调度(§五.1): - 下达任务不再因「公司已有 active root run」吃 409,改为建 queued run + queued task 排队;出队走 updateRunStatus 的 CAS + BEGIN IMMEDIATE 准入事务,触发挂在 transitionRun 这个唯一漏斗上,60s sweep 兜底。 - 依赖已不可能满足的排队任务就地推导成 blocked,且每次 tick 重算不落死,上游重跑 成功后能原路解开。 恢复路径(批 3 复核 F1/F2):三条恢复转换的 from 全在活跃集之外,撞坑满时退回队列而不是 永远躺在 blocked;退不回去的裸 run 干净拒绝,不留半截状态。 控制台三处可见性修复 —— 症状全是纯视觉、不报错、git status 干净: 1. 顶栏墙钟恒 `now - started_at`,没有终点。一条昨晚就 blocked 的 run 第二天还在涨到 「16h 58min」,而那是页面上唯一的时间信号 —— 「已经停了等人处置」被显示成了 「还在跑再等等」,这两件事需要的动作相反。终点改取 run.updated_at,并标「已停」。 2. 越界日志只报「留下 N 处改动」,文件清单躺在 timeline.ndjson 里翻不到。判罚就是按 这份清单下的,而人要判断「这真是 agent 写的吗」唯一的依据就是路径(并行的开发会话 改宿主仓库会被算到当时在跑的节点头上,那是误判,看一眼就知道)。改为列出 entries。 3. run 收敛成 blocked 时只把 task 写成 blocked、不写原因,任务列表那一行只剩一个橙色 的「挂起」,必须逐层点进 org 图 → work 图 → 节点详情才知道发生了什么。改为把 「卡在哪个节点 + 什么 fail_reason + 判词摘要」写进 tasks.blocked_reason。 原因绝不带 UPSTREAM_BLOCK_PREFIX —— 带了会被调度器当成依赖推导出的 blocked 自动 推回 queued,而这类 blocked 本来就等着人处置(守卫在 task-blocked-reason.test.js)。 测试:126 文件 / 1201 用例全绿。 Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
-
goal 从「人写一句话」变成「agent 拆成一张 task DAG、人确认后下达」, 收敛时由 org-validator 在 goal 层再验一次。 ## 交付 - task-planning 本体(毕业判据实测通过:agent.md + soul.md 一次写完、 不带 _base 哨兵、路径按 cwd 深度 3 实算核对) - 拆分链路:3 轮 errors 原样回喂 → 不过就降级成 1 条同描述 task, goal 绝不卡在 planning;token 记 goals.planning_tokens - goal 级 org-validator 验收:≥2 条 task 全 completed 才调,单 task 跳过, 有 failed 直接 failed 不调(省一次真花钱的调用) - 控制台四栏 + GoalTaskPane 两级树 + 两步表单(拆分中给逃生口) - 中断恢复:启动时补跑验收与汇报 ## 三条跨进程竞态,全部用真探针实跑复现后才判定修好 1. runGoalSplit 无条件把 goal 写回 draft,抹掉逃生口刚下达的 active —— 而触发它的正是表单自己推荐的那个逃生口。后果是一个正在烧钱的 goal 显示成「草稿」,且从此永不收敛(OKR 不写、上级不唤醒、无日志) 2. CAS 把最终态提前写进库,验收窗口内重启即丢,且 verdict=NULL 与 「单 task 合法跳过」形态相同,查不出来 → 占位判词 + 启动重推 3. 认领语句 SET verdict=RESUMING WHERE verdict IN (PENDING, RESUMING) —— 写进去的值就在 WHERE 里,changes 恒为 1。而函数注释白纸黑字 写着「认领写的是另一个占位值」。注释是对的,代码没兑现。 实测:org-validator 调 2 次 / OKR 写 2 条 / token 双记 → claim 带唯一 token + 时间戳租约,回写条件更新决胜,主路径同闸门 ## 与设计正文的偏离(已记进文档 §十四) 拆分后 goal 落 draft 而非 active(active 的语义已被 markGoalDispatched 钉死为「已下达」);mode 三级继承对显式 tasks[] 同样生效;占位判词不出 API;新增 planning_error / reported_at 两列,后者迁移带回填(否则升级后 第一次启动会把历史终态 goal 全部重报一遍)。 ## 过程 四轮 26 个 agent,复核报出 22 条缺陷,其中 6 条是修复自己引入的。 第四轮修完挂了 3 条测试,全是测试在钉住缺陷本身 —— 其中一条的注释 写着「模拟进程死后重启」,构造的却是新鲜占位值:注释描述 A 场景、 代码构造 B 场景、断言按 A 场景写。 全量:118 文件 / 1112 测试全绿,web:build 通过。 Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
-
控制台原先只能看引擎的事件轨(stream.log / timeline.ndjson),里面是结构化事件、 自由文本还被截断到 600 字;引擎更是根本不消费流式 chunk(onAcpEvent 只取 session/result 的 usage)。所以 LLM 的逐字输出从来不在它的轨道上。 新端点 GET /api/graph-runs/:id/nodes/:nodeRunId/transcript **惰性读** Claude CLI 自己的会话文件:不进 SSE、不进节点行、不落第二份库 —— 那正是引擎当初决定不存全文的 三条理由要避免的(输出无上限而 getRunState 每次轮询 SELECT * 全量回传 / 产物已有 output_ref 这个唯一真相源 / fail_reason 是选边匹配键不能掺自由文本)。 这里没有推翻那个设计,只是多开一个读取入口。 目录推导与条目规范化抽到 server/services/agent-transcript.js, scripts/tail-agent.js 改为复用它 —— 一份实现两个入口。今天已经修过三次 「两份必须保持一致的实现漂了」,不想制造第四次。 ## 界面上明说的三个前提(不藏) 1. transcript 按 (公司, 角色) 分、**不按节点分**,只能用节点 started_at/completed_at 截时间窗口 —— 近似而非精确对齐,窗口边界原样显示。 2. <env_status>(harness 每轮注入的环境块,几 KB 机器噪音)服务端剥掉, 但**剥了几处如实显示**。静默删内容比留噪音更坏。 3. 默认只看 agent 说的话;喂进去的内容(提示词全文、工具返回)要勾选才出来 —— 提示词里有写入边界与公司上下文,不默认摊开,但可以看。 subgraph 节点不给这个 tab(它自己不调 agent,活在子图里)—— 给了就是个空 tab, 而空 tab 会被读成「没记录」。正在跑的节点靠「刷新」取最新,**不轮询** (整份会话几百 KB,跟着 run 状态轮询太贵)。 ## 三处「看着对、实际错」都有用例钉住 ① listRoles 的目录前缀差一个 '-':path.join 丢掉空的最后一段,切出来的角色名 全带前导 '-'(实测 '-sdd-planning')。我是靠肉眼看输出发现的,所以补回归测试。 ② 路由取本体取错层:本体绑在定义层节点上,graph_run_nodes 只有 def_node_id, 第一版直接读运行时行 → SqliteError: no such column。 ③ 找不到文件时回 ok:false + 期望目录,不回空列表 —— 空列表会被读成「这个 agent 没说过话」,而真相是「我们没找到文件」。 另外测试当场抓到我自己那个诚实机制的漏洞:整条正文都是 env_status 的条目会被剥空, normalize 早返回 null 导致它剥掉的那一处**没计入总数** —— 号称如实回报却少报。 改成 parts 空但剥过东西时仍返回,由 readEntries 先记账再决定入不入列表。 ## 验证 880 全绿(88 文件)。3 处变异精确变红后逐字还原。 运行中的实例上走查过:org-planner-sdd 的原文逐条带时间戳显示, 第一条就是它去读上游 prd.md / contract.json —— R-19 那条链路被 agent 真的用上了。 subgraph 节点(org-planner)确认没有这个 tab。 Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
-
## 为什么加 「输入输出」tab 把产物的绝对路径摆出来了,但那是服务器本地路径 —— 浏览器里点不开, 走查时只能靠肉眼确认「路径长得对」,而真正要确认的是「这份 brd.md 里写了什么、 下游读到的是不是它」。 ## 前端 新增 web/src/components/graph-console/FilePreviewModal.vue,输入/输出两处路径 改成可点按钮。渲染三档:.md 走 marked(已是既有依赖,没新增包)、.json 重新缩进、 其它原文。两处刻意的选择: - .json 解析失败时**退回原文**并说明,不替它藏起来 —— 产物 json 写坏了本身就是要看的信息 - 超过 512KB 时后端回 truncated,界面如实说「不是完整内容」,不装作读全了 output_ref 那一行不做成可点:它是目录不是文件。 后端没有新造端点:复用现成的 GET /api/company/:cid/files/content,它的根目录正是 data/companies/<cid>,而 graph_files.rel_path 本来就是相对公司根的,正好对上。 ## 修掉六处路径越界(真漏洞) company.js 里 3 个 GET + 3 个 PUT(templates / company / workspace)用的是同一个写法: if (!absPath.startsWith(safeBoundary)) → 403 「一个目录名是另一个的前缀」时它会放行: cid = co-a,path = ../co-a-evil/company.json → abs = .../data/companies/co-a-evil/company.json → startsWith('.../data/companies/co-a') === true → 放行 于是公司 co-a 能读 co-a-evil 的文件;PUT 那三处是同一缝隙上的跨公司**写**。 抽 resolveInside() 用 path.relative 判断,六处共用一份(复制六份判据迟早会漂)。 新增 7 条用例走真 HTTP 验,PUT 那条断言的是**文件没被改**而不只是响应码。 ## 顺带修掉一个被你的实际使用触发的 bug 跑全套时 graph-seed-service 的对账用例红了,报 `org_graph_nodes WHERE company_id='mycompany' expected 10 / actual 9`。 不是并发偶发 —— 单跑也红。原因:seedCompanyAgents 对 type='meta-bootstrap' 的角色 是 continue(既不落 org_graph_nodes 也不落 system_agents),而 verifyCounts 复算期望值时把 agents[] 全算进去。mycompany 的 10 个角色里 orggraph-planning 正是 meta-bootstrap → 差 1。 也就是说:**界面上点一遍新建公司就会踩到**。这条缺陷上一轮就被预告过 (当时那个 agent 说「不在我的独占文件里」没修),今天被真实使用兑现了。 修法是让 verifyCounts 复用同一个 isMetaBootstrap 判据,不复制那个 type 判断。 新增独立测试文件(不并进 graph-seed-service.test.js —— 往它的 hermetic 夹具里 加角色会连带改既有断言),用 GRAPH_SEED_ROOT 自建最小夹具。 那个文件里第二条用例是刻意的:只断言「对账干净」时,seed 一个都没种也会“通过”, 两种原因症状相同。第一版就是这么错的 —— 我误以为 runStartupSeed 会种公司角色 (它只做 reconcile + 全局 agent + 模板),是第二条断言把「夹具没种」和 「过滤没生效」分开的。 ## 验证 871 全绿(87 文件)。3 处变异精确变红后逐字还原 (startsWith 回退 → 精确打红跨公司读/写两条;verifyCounts 去掉过滤 → 打红对账条)。 拿运行中的实例 + 用户真实公司 mycompany 走查过:读到真实 brd.md 内容, `../idearun/company.json` 与 `/etc/hosts` 均 403。web:build 通过。 Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> -
R-19.A 把 declareEdgeContract 的调用方补上之后,inboundContracts 终于非空, 「沿边传递」这类数据流在真跑里生效了(真实规划 agent 自己在边上写出了 produces/needs 声明)。本次收掉它留下的三个缺口。 1) role 落库(第 14 次「四环漏一环」) normalizeContracts 产出 role,declareEdgeContract 入参没有它、表也没这列 —— 产生 → 传递(丢) → 落库 → 读回。后果不止是控制台不精确:规则 6(data-contract) 靠「有人 needs 但没人 produces」判错,只存 kind 就没法从库里重算,而 patchGraph 第 5 步的重新校验读的正是库 —— 增量 PATCH 又恰恰是 「此前满足的 needs 失去产出方」的唯一发生地,校验偏偏在最该生效的通道上失效。 - graph_edge_contracts 加 role 列(CHECK + 老库 ALTER 后回填 produces: NULL 在规则 6 里既不算产出也不算需求,会误拒一张合法的图;闸门宁可漏判不可错拦) - 两层调用点透传 role;readGraph 把 contracts 读回来并递进 validateGraph 2) 控制台三字段(前端在、后端没喂) GET /api/graph-runs/:id 补 edges[].contracts / companyRoot / taskFiles, 否则 R19-C 那三块界面整块降级:声明和索引都在库里,界面上看不见。 contracts 只在非空时出现,与 failReason 同一个约定。 3) 收拢 companyRootDir/taskDirRel 镜像 goal-contract.js 里那份镜像靠注释约定「与 graph-engine 逐字同构」维持, 控制台路由成为第三个调用方时这个约定就不成立了。抽到 company-paths.js, GRAPH_RUNS_DIR 改为调用时读(原先两个模块各自在加载时快照, 加载顺序不同会算出不同的根)。goal-contract 那条「镜像漂了就报警」的用例 按其自身预告改成比函数返回值。 测试 826 全绿(+11:role 8 / 路由 3),既有断言未改。 11 处变异逐一验证精确变红后逐字还原;其中一条断言初版在 fixture 上永远自洽 (图里没有无声明的边),补了一条无声明的边才真正有判别力。 Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> -
测试 788/788 全绿(76 文件,起点 786),未改任何既有断言。 ## 1. idleTimeoutMs 硬编码 120s(「work 节点 → success」跑不通的唯一技术原因) agent-manager.js 里 `this.config?...?.idleTimeout || 120_000`,且 `...options` 摊在前面被下一行覆盖,两个后果叠加: - 默认 120 秒,比 stream-executor 自己 JSDoc 写的 30 分钟(1_800_000)小一个数量级, 也和同进程 ClaudeCliProtocol 早已放到 24h 的 idle 上限完全对不上 - 调用方**无法覆写** —— 传了 options.idleTimeoutMs 也会被盖掉 真 CLI 下的后果:任何「先读几千行源码再动笔」的节点都在动笔前被杀 (readme-writer: idle timeout: no stream data for 120000ms)。 改成 调用方 > agent 配置 > DEFAULT_IDLE_TIMEOUT_MS(30min),并把常量真的定义出来 —— 上一轮 Master agent 自己诊断出这个问题也动手改了,但引用了未定义的 DEFAULT_IDLE_TIMEOUT_MS,跑起来是 ReferenceError。 ## 2. W7 判据在零边最小图上失效 判「org graph 成型了没有」原先看**边数**,理由是「节点 hire() 自己就会造, 拿节点数当信号会废掉『连雇两个人第二个不入图』」——理由成立,但边只是 「writeGraph 跑过」的代理,而真跑里 orggraph-planning 裁出过一张**零条边的单节点图**, 代理当场失效:三条判据全落空 → work 层本体被写进 org_graph_nodes, 下一次下达任务时被 advanceOne 当成 org 节点执行。 改成记录**来源**而不是猜:org_graph_nodes 加 authored_by(idempotent ALTER), writeGraph 写 'planner'、hire 写 'hire',判据看有没有 planner 写下的节点。 hire 先记的行随后被 planner 纳入时升格,反向不降级。 存量行 authored_by 为 NULL,回落到原来的边数代理,行为不变。 新增两条用例(既有 9 例造的全是有边的成型图,正好绕开这个形状), 并做过变异验证:把判据改回纯边数,两条精确变红,还原后逐字一致。 ## 3. 前后端「能不能下达任务」的规则各写一份且不一致 前端 ACTIVE_RUN 含 blocked、后端 ACTIVE_ROOT_RUN_STATUS 不含(唯一索引 idx_graph_runs_one_active_root 里也没有)。后果:一家公司只要失败过一次, 控制台上就再也下不了第二个任务,而后端其实放行。 规则只留服务端一处:GET /graph-runs 返回 canDispatch / activeRootRunId, 前端照抄结果,不再自己复述取值域。字段缺失时保守放行,交给端点 409 兜底。 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>
-
## W14 · POST /:cid/tasks 补上前端调用方 该端点此前**全仓库没有任何前端调用方** —— 界面走查确认过:用户在控制台上 没有任何办法给公司下达任务,只能 curl。这是「实现在、零调用方」在 P3 里的 第 N 次出现(W8 刚给 replan 补上,tasks 还欠着)。 新增 DispatchTaskButton.vue: - 手动/自动**在下达时就选**,不是跑起来再改 —— execution_mode 是 run 的属性, 起 run 时定;后补一个下拉会让人以为能中途换 - 自动模式在这一步就给成本预警(真 CLI 一次中等任务 $10-20 / 1-2 小时), GraphRunPane 的「启动」那道确认是针对已有 run 的,下达是更早的闸门 - 409(v1 并发约束)连同服务端 hint 原样透出,比翻译成「出错了」有用 - run 在跑时按钮直接不出现,而不是让人点了吃 409 挂载:有图未跑 run 时给主操作位(这时候它是页面唯一该做的事), 有 run 时收进标题栏。顺手修 .left-actions 缺 gap 导致两个按钮重叠。 ## 第二次真 CLI 冒烟(worktree 隔离,主仓库 data/ 零写入) 链路比上一轮走得远得多,两个硬缺陷的修复都在真跑中直接验证: 1. **R-18.1 端到端成立**:POST /create 自动触发 orggraph-planning 真跑, 它自己把图落库(3 节点 4 边,含两条 backward fail 边)**并自己雇了 org-planner / org-coder / org-validator** —— Step 7 的招聘真执行了。 2. **W5/W6 自雇再次验证,且规划质量明显更高**:workgraph-planning 规划出 brd → prd → benchmark → validator 四节点主干,两条回退边一条带 fail_reason=input_underspecified、一条无 reason 作兜底 —— 它自己用上了 D.2.2 的细分路由并满足 fail-fallback-edge 规则。四个本体全部自雇。 3. **守卫归属修复直接命中**:timeline 里 「本次调用窗口内有 1 处 agent 运行态文件改动,无法归属到本节点,不计入越界 unattributable = ['M system/agents/agent-creator/.claude/scheduled_tasks.json']」 ——正是上一轮把成功节点判成 fail 的那个文件,这次被正确摘出, org-planner-brd → **success**(上一轮它跑起来了但被误判)。 4. tokens 真的在计量(24,218),mock 下恒为 0。 产出位置正确:brd.md 落在 runs/<rootRunId>/nodes/<nodeRunId>/, 项目根 projects/p-4hjo36 按 root run 分配。worktree 源码跑完已复原到跑前状态。 测试 760/760 全绿(72 文件)。 Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> -
真 CLI 冒烟(worktree 隔离,PORT 3010)九轮来首次把 work 节点跑起来: orggraph-planning 真跑 3 分钟自主裁成单 org node 零边图 → workgraph-planning 第 1 轮产出合法图 → **自己按 Step 6 把 brd-planning / planner-validator 雇进公司** (W5/W6 核心验收成立,且 W7 判据生效、两者都没写进 org_graph_nodes)→ 第一个 work 节点 brd-planning 真起 CLI 子进程,产出 brd.md / contract.json / attempt-0.json 全部落在 run 目录内。图内预算仅 2 次调用 / 13998 tokens(上限 15)。 W5/W6 · workgraph-planning 自雇:撤掉「你不招人也不辞人」,Step 6 加招聘环节, 写死「先雇、再提交图」的顺序,给出失败分级与幂等要求 W7 · work 层招聘不写 org_graph_nodes:按 type 与 work graph 骨架点名两条判据区分层级, P2 「hire org 角色 → org graph 出现该节点」的语义保持不变 W8 · 控制台「规划组织结构」按钮(抽成 ReplanOrgGraphButton.vue,带过渡态与秒表), 接 POST /:companyId/org-graph/replan(该端点此前无任何前端调用方); 新增 fixtures/devloop-mock/orggraph-planning.json W12 · 节点失败留痕:node.output 带 output_excerpt、新增 node.error 事件。 真跑当场救场——守卫误判那条归因正是靠它才查得出来, 换成之前看到的只有「节点 fail、无原因、无痕迹」 测试 753/753 全绿(71 文件,起点 736/68)。 已知未修(下一轮):子 run 转终态不回写父 node_run 导致任务永久卡死; applyBoundaryGuard 用整仓 git diff 判归属会把并行 agent 的写算到当前节点头上; W12 的 fail_reason 未落库(概览 tab 仍为空);POST /:cid/tasks 无前端调用方。 Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
-
界面走查(真 server + HTTP + 真 AgentManager,底层 mock 协议)已把 manual 模式全流程点通:org 节点起子图 → 下钻 work graph → 单步 → 第 3 步触发回退(徽标 0/3→1/3、run 级 1/5 双层计数同时可见)→ 归因记录与 remediation_note 完整送达 → 收敛后父节点结算、左栏前移。 mock 侧补两处缺失接线(都是「四环漏一环」,非新功能) - ClaudeCliProtocol._sendMockPrompt 按 agent 类型查 fixture:图执行侧的 agent 名带公司前缀(resolveAgentName 返回 {cid}:{id}),fixture 不该 按公司复制一份。DevLoop 侧名字不含冒号,行为不变 - graph-engine.defaultAgentExecutor 接住 mock/files 事件:此前只有 DevLoop 的 loop-controller 接,图执行侧没接,于是 mock 下 readNodeProduct 永远找不到 attempt-{n}.json,validator 系节点恒 blocked。 写入限制在节点产物目录内,越界丢弃并留痕 新增 5 份 P3 fixture(workgraph-planning / prd-planning / sdd-planning / coder-validator / validator-triager),coder-validator 用 sequence 演示 一次回退。图必须放 chunks 不能只放 result——callAgent 的 output 来自 流式 chunks,session/result 的文本不进 output。 控制台入口:CompanyDashboard 加「🕸️ 执行控制台」按钮(路由早已注册, 此前无任何入口,只能手敲 URL)。 scripts/p3-demo-setup.js:手工测试准备脚本(雇人+写图+起 run),头部 写明它是两个已知缺口的绕行,缺口修好后第 1 步即可删。 _registry.json 补齐 6 条本体登记(brd/prd/sdd-planning、goal-benchmark、 benchmark/testdata-validator)——同轮新增的 template-refs 防线测试正是 因为缺这 6 条而变红,防线抓到了「交付与报告不符」。 文档 - 27-REQ R-18:招聘归 workgraph-planning(方案 a)、停用 mock 改真 CLI - 27-P3B 真实运行前置(新增):11 个工作项分三批,含现状核实 10 条证据 (seedTemplates 无运行时调用方、10 条悬空 company_hired 行、 FAILING_VERDICTS 不含 "fail" 导致验收假放行等) 测试 719/719 全绿(66 文件)。 Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> -
按 27-p3-p4-work-graph-console.md v0.3 实现,三轮开发+校验后测试全绿 (693/693,P2 26/26、DevLoop 230/230 未被打破,web:build 干净)。 服务层 - work-graph-db.js 定义层(work_graph_*) + 运行时层(graph_runs/graph_run_nodes/ graph_run_loop_records) 五张表;状态转换表照 unit-registry 模式; 复用 org-graph-service 四项校验 + 新增第五项 fail-fallback-edge - graph-engine.js advanceOne 幂等原语;agent_call / subgraph 两种 executor; 手动与自动共用同一原语;双层熔断(单边 loop_count + 按 root_run_id 共池的 backward_count);任务级预算挂 root run;三层暂停/停止级联; 重试按 contract_hash unchanged 判据 - graph-run-sse.js 按 run_id 广播,状态转换+timeline+SSE 三者原子化 - goal-contract.js 验收契约格式与执行器(R-15.6 验收先行) 引擎泛化(R-15.4):org graph 与 work graph 走同一套 advanceOne, 定义层两套、运行时层一套,三层下钻用 parent_run_id 链。 R-16 失败归因:validator-reflection 专职归因节点;fail_reason 多边路由 (精确匹配→兜底边→死路);子 run 收敛透传 success/fail + fail_reason + remediation_note 三值;infra_flake 不烧任何计数。 路由 / 前端 / 模板 - routes/graph-run.js 八个端点;company.js 任务入口 - WorkGraphCanvas.vue 扩展 UnitsDAG(subgraph 角标、backward 虚线曲线、 N/3 循环徽标、异常流程视觉降权);GraphConsole.vue 三栏 + 四 tab 详情 - 五个新 agent 模板:validator-reflection / org-validator / planner-validator / coder-validator / workgraph-planning 命名统一(R-15.3 + NAMING §三):org 节点改为 org-{职能}, 三个 org-graph 模板末节点收敛到 org-validator;org_graph_edges 加 fail_reason 列并把唯一索引补上该列(避免精确边与兜底边互相吞掉)。 三轮校验修掉的主要缺陷:subgraph 重跑不起新子 run 导致永久死锁; SSE/timeline 零调用方;org 侧 fail_reason 写入被丢弃;fail-fallback-edge 只做了一层;backward_count 跨 run 树重置架空熔断外层; seedEntryNodes 误点亮只有 fail 入边的节点。 已知缺口见后续提交:remediation_note 仅在 backward 边落库、 total_tokens 预算维度无生产方。 Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
-
■ 前端路由遮蔽(既有 bug,被 P2 的 T8 暴露) web/src/router/index.js: CompanyAgentChat 的 path 是 /:id/agents/:agentId? —— agentId 可选,导致它抢占 /:id/agents,而导航栏「Team」正是指向这个地址。 结果 CompanyDashboard 的团队 tab(连同 P2 新增的 Org Graph 区块)完全不可达, 点 Team 打开的一直是 AgentChat。改为 :agentId 必填。 ■ Org Graph 空边时凭空画出流程链(P2 T8 的 bug) 0 条 forward 边时所有节点入度都是 0,全部落进拓扑序且 degraded=false, 模板照常在节点间渲染 → 箭头,凭空捏造出一条并不存在的流转顺序。 P0 迁移进来的存量公司(有节点无边)全部中招。新增 orgGraphNoEdges 判定: 这种情况只平铺、不画箭头,并明确提示「尚未定义流转顺序」。 ■ create() 仍在建 goals/ 目录(我在 OKR 正名 74ea1ff 里的遗漏) company-service.js 的 subdirs 列表没跟着 goals→okr 一起改,新建公司仍然产出 goals/ 空目录。改为 okr/。 ■ test-company-e2e.js 从「第 4 个断言就崩」修到 114/114 全绿 该脚本长期整体失效,HEAD 版本同样全断言失败。四类问题: 1. 路径过期:data/{id}/ → data/companies/{id}/;data/templates/ → system/templates/;data/agents/master → system/agents/master 2. Phase 4 用 ceo 模板测「骨架是否完整复制」——但 system/templates/ceo/ 只有 plan.md + todo.md,没有 agent.md/soul.md/config.json,测不出东西,且缺 config.json 就没有 type='cxo',company.ceo 也标不上。改用同为 cxo 且文件 完整的 coo。(ceo 模板本身的残缺是另一个待补的问题) 3. 断言停留在 P1 之前:P1 虚拟引用(226489d)之后 agent.md 不再物理拷贝, 改为 config.json.systemAgentRef + company-context.md。按新模型改写 4. 断言停留在 T5b 之前:模板不存在时返回 hired_from_base 而非 training 顺带记录一个设计缺口(未改,仅在测试注释里说明):system/templates/base/ 目前只有 agent.md + config.json,所以 base 继承出的骨架不含 soul.md / identity.md / tools.md / todo.md,也不含 AgentScaffold 的标准子目录结构 (memory/short-term、knowledge、workspace 等)。这些依赖 agent-creator 填充。 另删除 OKR 迁移的 *.bak-goals 备份目录及其 .gitignore 规则。 验证:npm run test:unit 676 全绿;test-company-e2e 114/114;web:build 通过; Chrome 实机确认 Team tab 可达、空边提示正确。 Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
-
用 9 个并行 agent 按「文件独占」划分实现 P2 的 T1-T9(T0 已于 2255f09 完成)。 详见 docs/todo/system-design/27-p2-org-graph.md §五。 阶段 A · 数据层 - graph-db.js: org_graph_nodes 加 status/reports_to_node_id(PRAGMA 探测后 ALTER, 幂等);全量唯一索引换成 WHERE status='active' 的部分索引,使「fire 后重新 hire 同角色」可行;org_graph_edges 重建为执行流边(condition/edge_kind/status) - graph-service.js: ensureOrgGraphNodeIndex 同步改建部分索引,且 upsertOrgGraphNode 的 ON CONFLICT 必须写成 ON CONFLICT(company_id, role_name) WHERE status='active' —— SQLite 的冲突目标要与部分索引谓词逐字对应,否则整条 INSERT 直接失效 - org-graph-service.js(新): validateGraph 四项校验 + writeGraph/patchGraph/ getGraph/removeNode,事务化,节点软删除级联失效相关边 - routes/company.js: 四个端点 POST/PATCH/GET /org-graph + POST /org-graph/replan; /create 接入自动招聘 orggraph-planning + 异步触发(失败降级为空壳公司); /fire 接入节点软删除 阶段 B · 自动生成 - system/org-graph-templates/{dev,content,ops}.json + README:三张三段式骨架 (规划→执行→验收,验收失败回退到执行节点),角色名遵循 {domain}-{职能} - system/templates/orggraph-planning/:新 system agent(type='meta-bootstrap'), 含 §4.1 八步工作流 - company-service.js: 模板不存在时从 system/templates/base/ 元 agent 继承骨架 (自动带 RESEARCH→PLAN→EXECUTE→VERIFY 四段式)+ agent-creator 填充, 新建 agent scope='company'。这是 27-E2E §八bis 元 agent 继承的落地点 阶段 C · 展示 - CompanyDashboard.vue: 组织流程拓扑链渲染 + 空态降级 + 环深度保护 并行编排中发现并修复的三处(均不在原任务划分内): - AppNav.vue 建公司表单缺 goal 输入框 —— T0 只改了后端,前端表单没同步, company-goal 实际传不进来。这是上一轮 T0 的遗漏 - graph-seed-service.js 会把 type='meta-bootstrap' 的 orggraph-planning 塞回 org graph,与 hire() 的 guard 不一致 - graph-agent-p1-acceptance.test.js: hire 未知角色的返回从 needs_training 改为 hired_from_base(T5b 的行为变更),断言同步 验证(独立复核,非 agent 自述): - npm run test:unit 676 passed / 63 files(基线 652,+24 为新增的 org-graph 用例) - npm run web:build 通过 - 三个模板 JSON 实跑 validateGraph 全部通过;四类非法图各自被对应 rule 拒绝; writeGraph→getGraph→removeNode 级联验证通过(删中间节点后 3 条边全部失效) Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
-
代码层: - server/services/goals.js → okr-service.js;GoalsService → OkrService · this.goalsDir → okrDir,目录 goals/ → okr/ · ID 前缀 G- → O-;落盘文件 goal.json → objective.json · updateGoal → updateObjective,_nextGoalId/_saveGoal 等同步改名 · parseNodeId 层级名 ['Goal','Objective','KeyResult','SubTask'] → ['Objective','KeyResult','SubTask','SubTask'](OKR 无 Goal 这一层) - server/routes/goals.js → okr.js;:goalId → :objectiveId - 7 处调用点同步:index.js / agent-server.js / agent-chat.js / company.js / company-heartbeat-service.js / prompt-builder.js / test-company-e2e.js - 前端 OkrDashboard.vue / CompanyDashboard.vue 切到 /api/okr(前后端命名终于一致) - bin/lemon.js 新增 okr create/add-node/list/status 向后兼容(不破坏任何现有调用方): - /api/goals/* 与 /api/company/:cid/goals/* 全部保留为别名,与新路径同时挂载 - task dispatch/report 同时接受 objectiveId(新) 与 goalId(旧),写入时两字段都留 - bin/lemon.js 保留 goal * 命令别名 迁移脚本 scripts/migrate-goals-to-okr.js(npm run okr:migrate): - 目录 data/{,companies/*/}goals/ → okr/;条目 G-xxx → O-xxx - 改写 objective.json 的 id / nodes 的 key / children 数组、_index.json、 progress.json 的 goalId、history.log 文本、system/tasklog/*.json 的 goalId+nodeId - --dry-run 预演;幂等;迁移前自动备份为 *.bak-goals(已加入 .gitignore) - 处理一个反直觉边界:OkrService 构造函数会自动 mkdir 目标目录,"okr/ 已存在" 不等于"已迁移过"——只要服务被 require 过一次就留下空壳。用 isEmptyOkrDir() 区分空壳与真实数据,空壳移除后继续迁移。这个 bug 是在 fixture 上验证时发现的。 - 同样在 fixture 上发现并修掉:nodeId 的值漏改写、tasklog 迁移不幂等 验证:新增 server/tests/unit/okr-service.test.js(7 例,覆盖新命名工作正常 + 迁移纯函数的 ID 改写);全量 npm run test:unit 652 例全绿。 范围说明:NAMING §五 的 benchmark 三分(skill-/agent-/goal-)本轮未动代码—— 该节自身的建议就是存量保持现状、只对新增代码强制前缀,因为 benchmark_runs 等表 服务于线上 Arena 排行榜,改表名/路由是另一次独立迁移。 §二-四 的新 agent id 尚不存在实体,待 P2/P3 实现时按规范创建。 已知遗留(非本次引入):server/scripts/test-company-e2e.js 早已失效——它按 data/{id}/ 找公司,而 company-service 用的是 data/companies/{id}/,在 HEAD 版本 同样全部断言失败。本次只同步了其中的 OKR 命名,未修这个路径问题。 Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
-
First successful real-CLI agent invocation. After REAL.1 (system-prompt injection) + REAL.2 (mtime-diff file detection) wired, the only remaining gate was Claude auth. Once CLAUDE_CODE_OAUTH_TOKEN was added to the project .env, scripts/real-pm-smoke.js completed cleanly: Wire-up status: ✓ process spawn ✓ stream chunks (3) ✓ result text (Claude returned "DONE") ✓ files written (6: prd/index, feature-tree, user-flows, product/overview, assets/shell.{css,js}) ✓ git commit (8cb0493) 5/5 checks passed · elapsed 163s PM output quality (real Claude, not mock): - valid <article data-doc="prd" data-rev="1"> + <section data-rev="1"> structure per system prompt - nav links use correct relative paths across 4 chapters - pid (p-7gwlbl) embedded in HTML metadata - 中文 prose in the requested 克制 voice Spec-deviation confirmed (no MCP tool gateway yet — Claude only has built-in Read/Write/Bash): - ✗ agent-state/pm.json (no update_runtime_state tool) - ✗ agent-state/pm-todo.json (no write_todolist tool) - ✗ history/prd-rev-001.html (no archive_doc tool) - ✗ timeline.ndjson 'prd_drafted' event (no timeline_append tool) - ✓ core PRD site IS produced — sufficient to prove pipeline ──── code ──── - scripts/real-pm-smoke.js — loads root .env via dotenv resolved from server/node_modules (script dir has no node_modules of its own). ──── ambient ──── Files modified by user/linter while real-CLI work was in flight; merged without revert: - server/routes/devloop.js — new GET /:pid/requirements endpoint - server/services/devloop/path-resolver.js — listProjects() includes archived flag + helpers; supports project archive lifecycle - server/services/devloop/git-vault.js — commit() now accepts files[] to scope which paths the commit covers (avoids dragging linked-existing user's unstaged files into chore commits) - server/src/core/devloop/loop-controller.js — createProject uses explicit files:['project.json','timeline.ndjson'] for first chore commit (avoids same issue) - server/tests/devloop/path-resolver.test.js — coverage for archive/ patch/hardDelete helpers - web/src/components/devloop/RequirementListSection.vue (new) - web/src/views/DevLoopNewRequirement.vue (new) - web/src/views/DevLoopDashboard.vue — mounts RequirementListSection - web/src/views/DevLoopProjects.vue — list page polish - web/src/router/index.js — adds /devloop/:pid/requirements/new route - web/src/components/devloop/DashboardHeader.vue — back link tweak Test results: 233/233 vitest pass (was 230 → +3 path-resolver cases). ──── ⚠ SECURITY NOTE ──── .env is currently TRACKED in git (committed in b1a348b) even though .gitignore lists it. Existing committed contents include credentials for DOUBAO / FEISHU / GITHUB / GOOGLE / JWT. The CLAUDE_CODE_OAUTH_TOKEN + AZURE_OPENAI_API_KEY I just added to .env are NOT in this commit — they stay in your working tree only. Recommended follow-up (separate commit): git rm --cached .env git commit -m "chore: stop tracking .env (already gitignored)" And rotate every key that was in the previous committed .env. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> -
Two parallel pieces of plumbing — neither has been exercised end-to-end yet (real CLI gated on `claude /login`; Projects list view served alongside existing pages): ──── real-CLI wire-up (REAL.1 + REAL.2) ──── LemonBoss now has a clean toggle between mock & real Claude CLI: - packages/acp-core/protocol/ClaudeCliProtocol.js * `options.systemPrompt` → `--append-system-prompt <prompt>` so each devloop agent receives its role-specific prompt.md without losing Claude's default tool-use conventions. * `options.maxBudgetUsd` → `--max-budget-usd` (note: only effective in `--print` mode; documented inline). - server/src/core/devloop/loop-controller.js * callAgent now branches on `opts.mock`: - mock (P1-P5 path, untouched): fixture sequence + `mock/files` event - real: read system/templates/{agent}/prompt.md, pass as systemPrompt, snapshot project file mtimes pre-call, diff post-call to compute `files_written` — no fixture, no mock/files needed. * `_snapshotMtimes(root)` helper walks the project tree (skipping .git / node_modules / .cache / .tmp) and returns Map<relPath,mtime>. * timeline event payload now carries `real: true` flag. - scripts/real-pm-smoke.js — minimal real-CLI sanity: spawns claude, injects PM prompt, prints which files were written + git commit sha. Hard timeout 5min. Single agent → expected spend $0.10-0.30 per run when authenticated. Current status: process spawn + system-prompt injection + stream-json flow all verified up to the `Not logged in · Please run /login` gate. Auth is the only remaining blocker for executing the real smoke. ──── project CRUD routes ──── server/routes/devloop.js + server/services/devloop/path-resolver.js add the lifecycle pieces the Projects list view needs: - GET /projects?include_archived=true list w/ archive filter - PATCH /projects/:pid edit name + idea_summary - DELETE /projects/:pid soft delete (archive) - DELETE /projects/:pid?hard=true hard delete (rm -rf sandbox; unregister linked) - POST /projects/:pid/restore un-archive path-resolver exposes matching helpers: listProjects({includeArchived}), patchProjectMeta(pid,patch), hardDeleteProject(pid). ──── UI ──── - web/src/views/DevLoopProjects.vue (320 lines, new) — Projects list - web/src/router/index.js — adds `/devloop` → DevLoopProjects - web/src/components/devloop/DashboardHeader.vue — back-link now points to `/devloop` (project list) instead of `/company`. ──── housekeeping ──── - CLAUDE.md / start.sh — start.sh now boots server/index.js (full route surface incl. /api/devloop) instead of the historical agent-server.js; docs updated to reflect this. ──── tests (+12) ──── - server/tests/devloop/routes-crud.test.js — 12 cases: PATCH validation (4) · soft DELETE + list filter (4) · POST /restore (1) · hard DELETE (2) · GET /projects default behavior (1). Results: - phase0-verify .. phase5-verify: 8+7+7+6+9+9+7 all pass - vitest devloop+acp-core: 230/230 (was 218 → +12) Specs: - docs/prd/newfunction/_spec/arch-acp-bridge.md · Mock Mode - docs/prd/newfunction/_spec/plan-migration.md · "自举乐趣" (real path prep) Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> -
…b-pages + UI endpoints) Completes the §P4 acceptance UI scope that was deferred in commit 0594b1d. Adds the full Vue Dashboard + Ops sub-pages with live SSE stream + auto-reconnect, unit DAG with detail drawer, PRD/SDD diff panel, feedback modal, and 4 ops views (Bugs / Loops / Changelog / Progress). Vue surface (≈1480 lines): - web/src/views/DevLoopDashboard.vue (~110 lines) * 4-region grid: status header / loop bar / units DAG / live stream / PRD diff. Polls /state every 2.5s; opens feedback modal & unit drawer; mounts Sign Off / Abandon controls. - web/src/views/DevLoopOps.vue (~50 lines) — tab container. - web/src/components/devloop/DashboardHeader.vue * Status badge (7 states color-coded), NEW REQUIREMENT button, Sign Off / Abandon buttons (disabled per FSM), Ops nav link. - web/src/components/devloop/LoopStatusBar.vue * 4-phase pipeline (Docs → L1 → L2 → Ship), highlights active phase. - web/src/components/devloop/UnitsDAG.vue * SVG DAG rendered from topological waves; per-unit status color; click → emits select → opens UnitDrawer. - web/src/components/devloop/UnitDrawer.vue * Slide-in panel showing unit metadata + last 3 runs + result summary + coder.log tail (last 1KB). - web/src/components/devloop/LiveAgentStream.vue * EventSource subscriber listening to project.status, unit.state, integration.result, triage.result, sdd.updated, prd.updated, human_intervention_needed, etc. Manual 5s reconnect on disconnect (browser's built-in Last-Event-ID is honored). - web/src/components/devloop/PrdDiffPanel.vue * Reads changelog.ndjson, renders prd_rev / sdd_rev entries with trigger labels. - web/src/components/devloop/FeedbackModal.vue * POSTs /feedback with PM incremental — shows rev bump on success. - web/src/components/devloop/ops/BuglistView.vue * Filterable bug table; status badges; severity / category columns. - web/src/components/devloop/ops/LoopLogView.vue * Timeline grouped by L1 (unit.*) / L2 (integration/triage/sdd/l2_*) / L3 (project.status/shipped/prd.updated/human_intervention) / System (rest). Free-text substring filter. - web/src/components/devloop/ops/ChangelogView.vue * Tabular prd_rev/sdd_rev entries with by/trigger/summary columns. - web/src/components/devloop/ops/ProgressView.vue * 6 metric cards (status, PRD rev, SDD rev, units passed bar, L2 rounds bar, open bugs) + per-unit breakdown table. Router: - web/src/router/index.js — adds: * /devloop/:pid → DevLoopDashboard * /devloop/:pid/ops/:tab(bugs|loops|changelog|progress) → DevLoopOps Backend UI-supporting endpoints (server/routes/devloop.js): - GET /api/devloop/projects/:pid/timeline?limit=N Reads timeline.ndjson, returns last N events reversed. - GET /api/devloop/projects/:pid/changelog Returns full changelog.ndjson entries reversed. - GET /api/devloop/projects/:pid/units/:unitId Returns { unit, runs (last 3 result.json), coder_log_tail }. 404 on unknown unit. Tests (+5 cases): - server/tests/devloop/routes.test.js — new P5 UI endpoints block: * timeline / changelog / units happy-paths * 404 on unknown unit and unknown pid Acceptance: - scripts/phase5-verify.js — 7 steps: ① Vue build artifacts (DevLoopDashboard.js + DevLoopOps.js chunks) ② POST /projects → state returns status + units ③ GET /timeline returns events ④ GET /changelog returns entries ⑤ GET /units/todo-be returns unit + runs ⑥ GET /bugs returns bug list ⑦ SSE /stream delivers ≥1 event after a triggering feedback POST Vue build: - npm run web:build → DevLoopDashboard chunk 15.63 kB, DevLoopOps chunk 9.09 kB, both with co-loaded CSS bundles. Results — all 7 phase gates green: - phase0-verify: 8/8 - phase0-test-call: 7/7 - phase1-verify: 7/7 - phase2-verify: 6/6 - phase3-verify: 9/9 - phase4-verify: 9/9 - phase5-verify: 7/7 - vitest devloop+acp-core: 218/218 (was 213 → +5) Specs: docs/prd/newfunction/_spec/plan-migration.md · P4 L3 + UI Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
-
1. Added global time range selector (1h/24h/7d/30d/all) that uniformly restricts the dataset for the whole dashboard. 2. Added 'Search' inputs and 'Sort' dropdowns for Agent Ranking, Task Breakdown, and Recent Logs tabs. 3. Decoupled global filteredData state from original rawData to allow smooth, consistent indicator rendering.
-
Converted the Quota Monitor's vertical scroll layout into a clean 4-tab interface: 1. Trend Statistics (使用趋势统计) 2. Agent Ranking (各 Agent 计算力消耗排行榜) 3. Task Breakdown (任务级成本分析) 4. Recent Logs (最近的大模型调用日志) This significantly improves usability and avoids excessive scrolling while keeping the top overview indicators universally visible.
-
Parses convId strings (e.g. task-T-xxx, callback-T-xxx) to group billing records by task ID. Provides a consolidated view showing total cost, token consumption, duration, and the agent pipeline sequence for each task, along with an expandable detailed breakdown per agent call. This allows easier identification of wasteful agent patterns.
-
1. Workspace page: left file tree + right detail/editor panel - File info: name, path, size, created/modified timestamps - Three view modes: Code / Preview / Edit with save - HTML files auto-open in Preview tab (sandboxed iframe) 2. Backend APIs: - GET/PUT /:companyId/workspace/files (list + content + save) - PUT /:companyId/files/content (company file save) 3. Navbar: removed Skills/Jobs/Pipeline, added Workspace 4. All nav links open in new tabs (target=_blank)
-
- Added inline editing for template description and type fields - Implemented Delete Template functionality (removes both file system and registry entry) - Added confirmation safeguards for the destructive delete action
-
Architecture fix for long-running tool execution: 1. ClaudeCliProtocol: Two-tier idle timeout - Chat mode: 45s (detect API hang/silent rate limit) - Tool execution mode: 5min (Bash long tasks like pip install) - Automatically switches on tool_use_start / content_block_stop events 2. Provision API: POST /templates/:templateId/provision - Runs shell commands directly via child_process.exec - Bypasses Claude ACP entirely (no idle timeout issue) - 10min per-command timeout, security blocklist - Frontend button with prompt for custom commands 3. Template UI: Added 🔧 安装依赖 button (teal)
-
…aruncreate skill paths - Upload skill files to .claude/skills/ (Claude Code ACP reads from here) - Add conversation type filter (user/callback/task/train) to AgentChat - Parse messages.log for richer conversation history display - Fix idearuncreate template & company agent skill directory structure - Add adm-zip dependency for ZIP extraction - Add fs/path top-level requires in company.js
-
- Add TaskTimeline.vue: two-pane dashboard with task list + message timeline - Add task-service.js: aggregate cross-agent conversations into task tree - 4-strategy parent-child inference (explicit meta, time-overlap, conv→tpl, master→T) - Read messages.log for full tool call details (not just history.json) - Add tasks.js API routes: GET /api/tasks, GET /api/tasks/:taskId/timeline - Mount /api/tasks in agent-server.js - Add 'Task Logs' nav entry in AppNav.vue after Templates - Support taskId in URL (/tasks/:taskId?) for sharing/bookmarking - Add --parent flag to CLI task dispatch for explicit parentTaskId - Auto-detect parentTaskId in task/dispatch from sender's active task - Add --instructions flag to template train CLI command - Update master tools.md with new parameters
-
…th time-based multi-dimension token tracking charts
-
…en costs across agents