• ## 决策 D:能自动查的自动查,不能自动查的把回查成本降到几秒
    
    「这条结论对不对」机器判不了,需要理解内容 —— **不假装有自动判据**。
    能自动做的只有两件,两件都做了:
    
    ① **引用真伪可以自动查**:提炼产物的 sources 必须都出自这一轮真喂进去的原料,
       编一个出处直接拒(前置闸门,连去敏判定都不用调)。
       编了出处的经验是「无法验证」最危险的形态 —— 人抽查时顺着一个不存在的指针放弃,
       然后**默认它是真的**。
    ② **auditDistilled()**:把每条结论与它引用的原料原文并排列出来,
       指针悬空标 null(原料被清理过 / 出处是编的)。
    
    真跑那 4 条实测:**8 条引用全部取得回原文**,模型没编出处。
    ⚠️ auditDistilled 的输出**不是质量分**,别当成那个用。
    
    ## 任务态清理(28 §5.6)
    
    四道判据全过才删:① 公司在 company_agents 名册里;② 目录名在**任务态白名单**里;
    ③ mtime 早于 N 天(默认 14);④ run_* 对应的 run 已到终态。默认 dry-run。
    
    **第 ② 条是踩出来的**:第一版写成黑名单(「不在保护名单里的都算任务态」),
    dry-run 直接选中了 trend-scout-global/idearun/venv 和 youtube-crawler/idearun/data
    —— 一个 Python 虚拟环境、一个数据目录,都在**真公司**底下,都不是任务态。
    **删错不可逆,留着最多占磁盘 —— 判据必须是「认得出才删」,不是「不认识就删」。**
    
    读不到名册时一家公司都不认(fail-closed),守卫里单独钉了这条。
    公司态(memory/ conversations/)永远走「不许清」那条分支 —— 那是 dream 的唯一原料,
    删掉不可再生(28 §5.6b)。
    
    实跑 30 天窗口:待删 0,跳过 955(556 还新 / 74 不在名册 / 60 公司态 / 11 白名单外)。
    
    全量:145 文件 / 1338 测试全绿。
    
    Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
    yibo authored
     
    Browse Dir »
  • ## 前置:存量记忆的搬家(19 文件 / 269 行)
    
    写入侧上一轮改了,但**存量不会自己搬家**。实查现有 `## 关键事实` 里
    **没有一条真事实** —— 全是重复心跳行、工具调用 id、和以 `...` 开头的半句。
    而 memory.md 会被注入**每一轮**提示词,这些东西一直在冒充事实。
    
    scripts/migrate-memory-raw-section.js 把它们搬进「原始记录(未提炼)」。
    先 dry-run 再 --apply,改前逐个 .bak(这些是 gitignore 的运行态,没有 git 历史兜底)。
    
    判据刻意窄:只搬 `- [YYYY-MM-DD] … → …` 这一种形状(旧自动追加的唯一形状)。
    **搬错比留错更坏** —— 留下最多多一条噪声,搬错是把人写的东西降级成日志。
    
    ## 真跑:innovator-evolver,40 条原料
    
        { "distilled": 4, "accepted": 4, "rejected": [] }   耗时 114s
    
    四条产出都做到了抽象:yt-dlp / Invidious → 「本地下载工具 → 备用镜像源」;
    scorer.js / SKILL_v1.md / system/templates/... 一个都没出现。
    
    **顺着 sources 抽查过**(可追溯的第一次实际用途):4 条引用全部对得上原料。
    「按关键词覆盖率打分会被刷到虚高分」那条引了 #21/#22/#27/#28,而 #27 原文正是
    「从零重写,采用 expected_output 逐 case rubric + dimCeil 上限机制,杜绝 coverage-based」。
    **它是跨 4 条记录归纳出来的**,不是逐条改写 —— 正是「一次调用吃掉全部原料」
    那个选择要换来的东西。
    
    ## 闸门单独验过:零拒绝 ≠ 闸门有效
    
    真跑里 4 条全过,说明去敏闸门**一次都没触发**。所以单独喂了三条给 dream-screener 真跑:
    · 含公司名+域名+绝对路径 → false,理由点名「域名 lemonai.ai 和绝对路径 /Users/…」
    · 心跳日志原文摘录 → false,理由点名「原文搬运」「工具调用 ID 可关联到具体运行实例」
    · 干净的抽象经验 → true
    
    三条判据都按 agent.md 写的那样生效,**且拒绝理由都点到了具体是哪几个字** ——
    那是 agent.md 里明确要求的。
    
    ## 空转保护实跑
    
    第二次调用(原料没变):{"skipped":"no-new-material"},一次 agent 调用都没起。
    
    ## 还没做的
    
    定时挂载(决策 C)、写定义文件(SKILL.md / soul.md / agent.md)、
    决策 D(质量怎么评 —— §5.5 那次抽查是**人工**顺着 sources 回查的,不是自动的)。
    
    Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
    yibo authored
     
    Browse Dir »
  • ## ① system/tasklog/ 改名保留(§十二.5)
    派单存储统一进 tasks 表后,旧目录改名为 system/tasklog.bak-unify/ 而不是
    直接删 —— 跑顺一个版本再清。回填脚本改成**两处都认**(先原位置再备份位置,
    顺序不能反:万一有人从备份恢复出一份新的 tasklog,那份才是要回填的)。
    
    ## ② agent 提示词里的端口 3000 → 3010
    packages/agent-core/base/ 下那几份是**所有 agent 的工具说明**,印着
    curl http://localhost:3000/... 而实际端口是 3010。agent 照着打拿到的是
    连接被拒、不是「端口错了」,它多半会去猜别的原因。
    
    这不是假想:批 5 回填出来的历史派单正文里,有人手写了「(端口 3010,
    不是 3000)」在纠正它 —— 靠人肉在每条任务书里打补丁。
    
    守卫 agent-docs-port.test.js:扫 base 模板与 agent 本体,禁 localhost:3000。
    判据刻意宽松(不校验「必须等于 config.port」—— 端口可被 PORT 覆盖,写死会在
    部署环境误报)。带「样本非空」前置断言。第一版扫出 5 条误报,全是某 agent
    目录下 Python venv 里 playwright 的 ThirdPartyNotices —— 那是第三方文件不是
    提示词,已把 venv/site-packages/workspace/conversations/train 一并跳过。
    
    ## ③ 边界守卫不再把并行会话的改动算到 agent 头上(§15.5 第 1 条)
    守卫的前提是「窗口内新增的仓库改动 = 这个节点写的」。多会话共用 worktree 时
    这个前提是假的 —— git status 的差集里没有「谁写的」这一维。实测已发生:
    批 3 的开发改动把一条 run 判成 boundary_escape 卡住。
    
    可检测的信号:节点**开跑那一刻**仓库就已经有源码目录的未提交改动 → 有人正在
    这个 worktree 上开发 → 窗口内新增的源码改动无法归属 → **降级为只记证据、
    不判罚**(与既有的 unattributable 桶同一语义),而不是关掉守卫:证据照留,
    人一眼看得出「这次没判罚,因为当时仓库是脏的」。
    
    BOUNDARY_GUARD=strict 强制判罚(CI / 干净环境),=record 一律只记。
    守卫 8 例,含关键对照:仓库脏时不判、干净时同样一处越界仍判 fail ——
    守卫没被削弱,只是不再乱扣帽子。
    
    ## ④ TaskTimeline 的标签不再撒谎
    conversationCount 在批 5 之后只会是 0/1(「有没有起过执行会话」),而界面
    写的是 "Convs: N" —— 读的人会以为这条任务只有一次对话。改成有/无的表达。
    agents 的语义变化在注释里说明。
    
    注:innovator-hunt/todo.md 与 reddit-scraper/todo.md 里的端口也改了,
    但它们是 gitignored 的运行态文件,不入库。
    
    全量:134 文件 / 1268 测试全绿,web:build 通过。
    
    Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
    yibo authored
     
    Browse Dir »
  • 两类回填合在同一个脚本里(§十二.5 的要求):同一次数据形态变更分两个
    脚本,只会让「跑了哪个没跑哪个」变成新问题。
    
    **沿用原 taskId,不新发一个** —— 这是这一步最要紧的判断。conversations
    目录名是 task-{taskId}、汇报链路按 taskId 找回这条派单、summary 里互相
    引用。换 id 等于把这些引用全断掉,而回填的目的恰恰是「别让历史消失」。
    
    落点:
    - executor='agent'、assignee_agent_id ← dispatch 的 to、parent_task_id ← 派单链
    - company_id 落 _global:tasklog 的行没有 company 这一维(from/to 都是本体 id),
      全局 agent 的会话本来就落在这个保留 id 下(28 §5.1)。不去猜某条派单
      「其实属于哪家公司」—— 猜错会让它出现在错误的公司列表里,比都归 _global 更难发现
    - 每条派单自带一个 goal:tasks.goal_id 是 NOT NULL 真外键,而派单没有「人提的需求」
      那一层。与 §六.3 给 POST /:cid/tasks 设计的兼容路径同一条,不给 goal_id 开可空口子
    - 标题把 <br> 还原成换行再取首行,否则整条正文糊成一长条
    - dispatched → running(派出去了还没回话,不是终态)
    
    实跑:4 条派单全部回填成功、零失败;再跑一次全部跳过、零新增。
    回填后 executor='agent' 的行指向 hunter / digester / master / agent-creator,
    原 taskId 一个没变。
    
    守卫:server/tests/unit/tasklog-backfill.test.js(4 例)
    
    顺带修掉自己踩的一个:新测试用 Date.now() 拼临时库路径,撞了
    test-id-stability 那条守卫 —— 和另一个会话昨天踩的是同一个。改用
    fs.mkdtempSync(仓库既有写法,graph-engine.test.js 的 runsDir 就是它)。
    
    全量:131 文件 / 1251 测试全绿。
    
    Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
    yibo authored
     
    Browse Dir »

  • 把「人类提的一个需求」与「机器执行的一件活」拆成两级。这不是新概念:
    27-NAMING §四 早就定义了 goal 1 : task N,graph_runs.goal_id / task_id
    两列从 P3 起就一直在写,却没有任何表接得住 —— 本次补上那两张缺席的表。
    
    ## 交付
    - goals / tasks 两张表 + CRUD + depends_on 环检测 + ID 生成器
      T-{base36}-{4hex}:原格式同毫秒必撞,而 tasks.id 是主键,
      「一个 goal 拆 N 条 task」是循环建行,撞了就是 500
    - goal / task 全套端点;POST /:cid/tasks 向后兼容(不带 goal_id 自动
      建 goal);退役 /api/goals 与 /:cid/goals 两个 OKR 别名(零调用方)
    - 终态回写 + goal 收敛 + OKR 写一次:钩子挂在唯一漏斗
      graph-run-sse.transitionRun 上,而不是枚举路径 —— stopRun 与
      「预算耗尽 → blocked」两条最常见的释放路径都不走 settleRun,
      枚举一次漏一次。goal 收敛用 CAS 闸门,并行完成的 N 个 task 只有
      一个赢家做不可重放的副作用(写 OKR / 唤醒上级)
    - blocked 在 task/goal 两层都不是终态:它是「挂起等人介入」,
      与 completed/failed/cancelled 不同类。否则预算耗尽后加预算恢复、
      跑完,两次条件更新静默命中 0 行,最终 run=completed 而
      task=blocked/goal=failed/OKR=failed 永久对不上(实跑复现过)
    - goal 级是唯一汇报出口:删掉 run 级 reportRunOutcome(零其它调用方),
      1 goal:1 task 形态下它会把上级 agent 就同一件事唤醒两次
    - dispatch 挑第一条可跑的 draft,而不是恒取 seq 最小那条 ——
      否则「第 1 条依赖第 2 条」这种合法输入会让 goal 永远下达不了
    - 路径缺陷:writeTaskGoalArtifact 不认 GRAPH_RUNS_DIR 而读侧认,
      设了 env 就写进 A 处、从 B 处读,describeTask 拿到 null 后静默退回
      兜底文案「执行图节点任务」;三处模块加载时快照改为调用时读
    - 存量回填脚本(幂等 + --dry-run):不做的话批 1 反而让历史任务
      更看不见 —— 正是本批要修的问题的反向放大
    
    ## 过程
    三轮多 agent 编排 + 每轮对抗复核,共报出 19 条缺陷(10 条首轮实现的、
    4 条第二轮修复引入的、5 条判定为非问题)。全部已修并有用例覆盖。
    新增测试 4 个文件,含不变式测试 runs-root-single-holder(凡是声明了
    GRAPH_RUNS_DIR 覆盖的模块,该覆盖必须真的被用到)。
    
    全量:116 文件 / 1057 测试全绿。
    
    ## 未做(属批 2-5)
    task-planning 与 goal 级 org-validator 验收(批 2)、调度器与
    run_status='queued'(批 3)、并行(批 4)、两套任务体系统一(批 5)。
    
    Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
    yibo authored
     
    Browse Dir »
  • system/templates/ 已随 28 号改造整体并入 system/agents/,目录在磁盘和 git 里都已不存在。
    但引用还散在各处,其中几处是 agent 运行时真会照着读写的:
    
    本体提示词(读不到就静默降级,不报错)
      workgraph-planning/agent.md   system/templates/base/ ×3、模板库路径 ×1
      orggraph-planning/agent.md    同上 ×1
      orggraph-planning/tools.md    ×1
      org-innovator/agent.md        四条产出落点 system/templates/weibo-scraper/train/*
    
    skill 代码里的硬编码目标
      evolver-youtube-crawler 的 refactor.js / mock_setup.js / evolve.js 共 4 处
      innovator-hunt/collect_seed.js —— 这处是真 bug 且已发作过:
        写的是裸相对路径 'system/templates/…',相对 cwd 解析,于是在 agent 自己目录下
        造出一棵野生嵌套树 system/agents/innovator-hunt/system/templates/…
        现在改成由 __dirname 推导,不再依赖 cwd(cwd 已经是深度 3 的任务态目录)
    
    图模板契约(work-graph-templates / org-graph-templates 的 README)
      CI 防线的三条规则写的还是「在 system/templates/ 下必须有目录」「在
      system/templates/_registry.json 里必须有条目」,与实际执行的检查已经对不上
    
    DevLoop PRD(13 份 HTML + 重新生成的 52 份 _spec + build-manifest + search-index)
      写的是 system/templates/devloop-pm.md(扁平 .md)。根和形状都错:
      loop-controller.js:166 实际读的是 system/agents/{agentName}/prompt.md。
      按真实形状改,然后跑 spec:extract / extract-manifest / build-search-index 重新生成。
    
    顺带订正两处早于本次改造就已过期的内容:
    - 「避开 6 个命名冲突 id」这条约束列的 digester / evolver / hunter / innovator
      四个 id 根本不存在(早已改名),而它的理由(两个目录下各有一份、内容不同步)
      也已随合并消失。约束保留(元 agent 本来就不该进执行流),理由与清单按实际本体重写。
    - orggraph-planning/agent.md 里「真相源是 company.json.agents[]」——
      28 号起真相源是 company_agents 表,company.json.agents[] 仅作兼容保留。
    
    刻意不动的三类(改了是净损失):
      历史说明   server/ 下解释「原来指向 X、批次 1 并进了 Y」的注释、docs/done/、tasks/
      完成证明   server/tests/ 里断言该目录已不存在的守卫
      运行态记录 未跟踪的 workspace/ conversations/ 与 train/ 下的历次训练报告
    
    新增 server/tests/unit/no-stale-templates-path.test.js 守住活定义这一档:
    扫 system/ 与 fixtures/ 下被 git 跟踪的文件(跟踪=人工维护的定义,
    未跟踪=运行态产物),零例外。带「样本非空」前置断言防 git 失灵时退化成永远通过。
    改坏一处实测能精确点名到文件行号。
    
    Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
    yibo authored
     
    Browse Dir »
  • 28 号把本体根从 system/templates/ 搬到 system/agents/,agent-locator 就是
    为了当这个路径的唯一持有者而建的。但搬完之后仓库里仍有 13 处自己拼这个路径,
    等于 locator 只是多了一份副本、没有真正收敛:
    
      server/routes/company.js            9 处(6 个 TEMPLATES_DIR + 3 个 DATA_DIR,
                                              同一文件里只有 1 处用了 locator)
      server/services/task-service.js     1 处
      server/src/core/skill-config-loader.js  1 处
      server/src/core/devloop/loop-controller.js  1 处
      scripts/extract-agent-prompts.js    1 处
    
    危害不是「不好看」,而是下一次再搬时改 12 处、漏 1 处:漏掉的那处指向一个
    不存在的目录,而本仓库读这类路径几乎都包在 fs.existsSync() 守卫里 ——
    目录没了不报错,只是静默跳过。这个形状刚在 scripts/demo-harness-company.js
    上实测过(base 本体没挂上,demo 跑出来的 agent 没有四段式骨架,脚本照常打印成功)。
    
    局部变量名保留不动(TEMPLATES_DIR / DATA_DIR / SYSTEM_AGENTS_DIR / agentsRoot /
    OUT_DIR),只把取值改成 locator.AGENTS_ROOT —— 名字是局部别名,无害;
    「路径这个事实」则收敛成一处,下次再搬只改 agent-locator.js。
    
    新增 server/tests/unit/agents-root-single-holder.test.js 锁住这条不变式:
    扫 server/ packages/ scripts/ 下所有源码,禁止 path.resolve/join 自己拼
    「以 ../ 开头、以 system/agents 结尾」的字面量。带「样本非空」前置断言,
    防止扫描路径写错时退化成永远通过。改坏一处实测能精确点名到文件行号。
    
    线索来自并行会话(它在准备改 company.js 时发现同一文件里 7 份定义)。
    实际比它看到的更多:它只查了 TEMPLATES_DIR,同文件另有 3 个 DATA_DIR、
    另外 3 个文件各 1 处。
    
    Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
    yibo authored
     
    Browse Dir »
  • 设计见 docs/done/system-design/28-agent-registry-unification.md。
    
    改造前 Agent 本体散在三处(system/agents/ 11 个、system/templates/ 50 个、
    data/companies/{id}/agents/ 17 个),同一个 AgentScaffold 被三个 baseDir 实例化。
    后果是同一角色在 N 家公司下有 N 份互不相干的副本,模板更新不会同步;
    org-coder / org-planner 这类走 hireFromBaseMetaAgent 造出来的本体
    legacy_path 指回自己公司目录,永远无法被第二家公司复用。
    
    本次:
    - G1 单一注册表:system/templates/ 整体并入 system/agents/,base → _base。
      7 个同名 id 逐个裁决,被丢弃的一份归档到 docs/_archive/ 而非删除。
      source_kind(template/global_agent/company_hired) → origin(builtin/created)。
    - G2 运行态下沉:CLI 的 cwd 从本体根改为 system/agents/{aid}/{cid}/{taskId}/。
      memory / conversations 落公司态 {aid}/{cid}/,按公司隔离不串。
      sessionPool 的 key 含 (companyId, taskId),两家公司调同一 agent 不复用会话。
    - G2b 产物不下沉:交付物仍落 data/companies/{cid}/,system/agents/ 只留运行痕迹。
      写入边界按链路分叉——graph 节点走节点私有目录(被 indexNodeOutputs 索引),
      chat 走公司 workspace,同一提示词里不再出现两条互斥指令。
    - G3 公司只存引用:data/companies/{id}/agents/ 删除,新增 company_agents 关联表。
      不复用 org_graph_nodes——后者是执行流图,work 层本体被雇时不写它,天生覆盖不全。
    - G4 缺则创建:本体缺失时从 _base 复制骨架进 system/agents/{id}/,
      agent-creator 填 agent.md/soul.md 后才从 draft 转 active(哨兵判据,
      骨架未填时哨兵仍在,不许被 hire)。产物即刻是全系统可复用的本体。
    
    新增 server/services/agent-locator.js 收编原先散在 6 处的寻址逻辑。
    
    边界守卫(graph-engine)的豁免从「本体根上五个文件名」放宽为整棵 system/agents/:
    新本体的骨架本来就要进 git,gitignore 挡不住 ?? system/agents/{newId}/,
    旧判据会把一个真正成功的招聘节点判成 boundary_escape fail。
    
    存量迁移见 scripts/migrate-agent-registry.js(幂等,备份到 data/_migration-backup-*)。
    
    真 Claude CLI E2E 已验证:新建公司 → orggraph-planning 自动规划 →
    自动招聘 org-planner/org-coder/org-validator 三节点流水线;
    data/companies/{cid}/agents/ 不存在,company_agents 4 行,
    system_agents 56→56(零新建私有本体,纯复用),git status 零增量。
    
    Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
    yibo authored
     
    Browse Dir »
  • 用户授权清理 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 Dir »

  • 控制台原先只能看引擎的事件轨(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>
    yibo authored
     
    Browse Dir »
  • 控制台「运行日志」看不到 LLM 逐字输出,不是坏了,是引擎按设计不存:
    
    1. **引擎根本不消费流式 chunk**:defaultAgentExecutor 的 onAcpEvent 只处理
       session/result(累 usage)与 mock/files,文本 chunk 一个字都不接。
    2. **事件里的自由文本截断到 600 字**(EVENT_TEXT_MAX),graph-engine.js 那段注释
       写了三条理由:完整输出无上限而 getRunState 每次轮询 SELECT * 全量回传;
       完整产物已有地址(output_ref)不该有第二个真相源;fail_reason 是选边的匹配键
       不能掺自由文本。
    所以 stream.log / timeline.ndjson 里只有结构化事件 + 短摘要。
    
    但 Claude CLI 自己把完整会话写在
      ~/.claude/projects/<cwd 路径的 / 换成 ->/<sessionId>.jsonl
    而 agent 的 cwd 就是 data/companies/<公司>/agents/<角色>,目录名可推。
    这个脚本把那份 jsonl 渲染成可读的实时流:
    
      node scripts/tail-agent.js <公司>                  列出哪些角色有 transcript
      node scripts/tail-agent.js <公司> <角色>            跟看(增量轮询,Ctrl+C 退出)
      node scripts/tail-agent.js <公司> <角色> --last 40  只看最后 40 条
    
    只渲染 assistant 的 text 当「LLM 输出」:user 侧的 text 是喂进去的东西(提示词全文、
    每轮注入的 <env_status>),跟看时纯噪音 —— 第一版没滤,实测满屏 env_status。
    user 侧只留 tool_result(agent 到底读到了什么,这个有用)。
    
    在运行中的实例上验过:mycompany/sdd-planning 正在跑时列表、--last、跟看三种都对,
    角色名写错时明确报「目录不存在 + 先跑列表看有哪些」,不静默空跑。
    
    ponytail: projects 目录名按 CLI 现行的「/ → -」规则推导,规则变了会找不到目录
    (会明说,不会假装没输出)。
    
    Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
    yibo authored
     
    Browse Dir »

  • 测试 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 Dir »
  • 界面走查(真 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>
    yibo authored
     
    Browse Dir »
  • 命名轴是「节点在哪一层图里」,把散落的老 agent 归到它实际所处的层级:
    
      innovator → org-innovator      type='cxo',是 org graph 层的节点
      hunter    → innovator-hunt     innovator work graph 第 1 阶段
      digester  → innovator-digest   第 2 阶段(输入是 hunt 产出)
      evolver   → innovator-evolver  第 3 阶段
    
    依据:retrain-pipeline.js 的 stepConfigs 就是按 hunter → digester → evolver 顺序
    跑的,行 231 明写 steps: ['re_hunt','re_digest','evolve'] —— 这三个本来就是
    innovator 的 work graph 三阶段,只是名字没体现出来。
    
    ■ 迁移(scripts/migrate-agent-naming.js,--dry-run + 幂等可重跑)
    - 8 个目录(system/agents/ + system/templates/),用 git mv 保留历史
    - system_agents 表 4 行的 id 与 legacy_path
    - 公司实例目录与 company.json.agents[](本次无公司雇过这四个,实际 0 条)
    
    ■ 代码引用点(5 处,手工改)
    - retrain-pipeline.js: stepConfigs 的 agent 字段 ×3、agentToStep 映射的 key ×3、
      call_sub_agent 的 evolver 判断
    - agent-chat.js: agent 列表过滤里的 innovator
    - company.js: 模板训练触发的 agentId
    
    ■ 刻意不动的三类同形异义(改了会坏)
    1. skill 内部子目录名 {skillDir}/hunter/knowhow.md —— 那是 hunt/digest/evolve
       三阶段的产物目录约定,与 agent 名同形但不同义。涉及 open-api.js:402、
       retrain-pipeline.js:148/374、evolution-loop.js:178、sync-skills.js 的 INTERNAL_DIRS
    2. skill 命名空间白名单 —— skill-dir-manager.js 的 CORE_SKILLS、
       migrate-trained-skills.js 的 SYSTEM_SKILLS,那里的 'innovator' 指同名 skill
    3. conversations/ 与 system/tasklog/ 下的历史记录 —— 运行态数据,不改写历史
    
    evolver-youtube-crawler 按 §3.4 列为待定,迁移脚本按精确目录名匹配,未误伤。
    
    这四个重命名顺带解决了 27 号文档 §七 挂了很久的 6 个命名冲突 id —— 重命名后
    system/agents/ 与 system/templates/ 下不再有同名目录(只剩 agent-creator 与
    evolver-youtube-crawler 两个,前者是基础设施角色按规则不改名)。
    
    验证:npm run test:unit 693 全绿(64 files);test-company-e2e 114/114;
    迁移脚本二次执行 dirs=0 dbRows=0 skipped=8(幂等)。
    
    未触碰另一进程正在进行的 P3 文件(graph-engine.js / graph-run-sse.js /
    work-graph-db.js / 27-p3-p4-work-graph-console.md / 27-requirement.md)。
    
    Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
    yibo authored
     
    Browse Dir »

  • 代码层:
    - 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>
    yibo authored
     
    Browse Dir »
  • # Conflicts:
    #	system/agents/master/.claude/scheduled_tasks.json
    yibo authored
     
    Browse Dir »
  • Adds server/services/graph-db.js (new data/graph.sqlite: system_agents,
    org_graph_nodes, org_graph_edges) and graph-seed-service.js, which scans
    system/agents/, system/templates/, and data/companies/*/company.json into
    seed rows without touching company-service.js's existing hire/copy path.
    
    Real repo data diverged from the design doc's original estimates (8 not 10
    global agents; 39 not 34 template dirs; system/agents/ and system/templates/
    turn out to share 6 ids describing the "same" agent from two different
    files) — documented in docs/todo/system-design/27-graph-agent-architecture.md
    section 7 for P1/P2 to resolve.
    
    Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
    yibo authored
     
    Browse Dir »

  • 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>
    yibo authored
     
    Browse Dir »
  • 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>
    yibo authored
     
    Browse Dir »
  • Self-bootstrap demo: hits the same HTTP API a human would, asking
    DevLoop to add a /restart endpoint to itself. End-to-end:
      1. POST /projects  (PM + Architect scaffold)
      2. GET  /state
      3. POST /run        (L1 + L2 → ship)
      4. GET  /{bugs,timeline,changelog,units/todo-be}
      5. POST /feedback   (PM incremental → PRD rev 1→2)
      6. POST /run        (re-ship)
      7. POST /sign-off   (→ shipped-final)
      8. POST /feedback   (→ 400 InvalidProjectStatusTransition)
    
    Run: node scripts/self-bootstrap.js (artifacts retained for inspection)
    
    Output proves the three-layer Loop survives a real curl-equivalent
    session: 12 git commits auto-generated, 20 timeline events emitted,
    prd_rev bumped, sdd_rev unchanged (happy path), bugs.ndjson empty
    (no integration failures), .git contains full agent provenance.
    
    For production: drop LEMONBOSS_CLAUDE_MODE=mock — the protocol layer
    will route to real Claude CLI without any code change in
    LoopController / routes.
    
    Specs: docs/prd/newfunction/_spec/plan-migration.md · "自举乐趣"
    
    Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
    yibo authored
     
    Browse Dir »
  • …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>
    yibo authored
     
    Browse Dir »
  • Implements the §P4 acceptance gate from plan-migration.md, with one
    scope adjustment confirmed up-front: full Vue Dashboard (~1650 lines)
    deferred to a future UI phase, replaced by extending the existing
    P3 static status page with Sign Off / Abandon / Feedback controls.
    All P4 backend acceptance criteria are scripted (phase4-verify.js).
    
    Project status FSM (project.json.status):
    - server/src/core/devloop/loop-controller.js
      * draft  →  running  →  shipped  →  shipped-final | abandoned
                    ↓             ↓
              l2_blocked    (feedback flips back to running)
              l2_exhausted
      * `_setProjectStatus` validates transitions via STATUS_TRANSITIONS,
        emits SSE `project.status`, writes timeline event.
      * createProject seeds status=draft; runDocsPhase end → running;
        runProject(shipped) → shipped; all dead-end branches (l2_blocked,
        l2_exhausted) also propagate to status via _safeSetStatus.
    
    L3 helpers:
    - signOff(pid, opts) — requires status=shipped → shipped-final; commits
      a `chore: sign-off` git entry; rejects other source states with
      InvalidProjectStatusTransition.
    - abandon(pid, opts) — any non-terminal → abandoned; commits + calls
      sseBroker.close(pid) to send SSE close frame to subscribers.
    - submitFeedback(pid, text, opts) — rejects in shipped-final/abandoned;
      invokes PM in incremental mode; on prd_rev bump writes
      changelog.ndjson prd_rev entry + emits prd.updated SSE; if prior
      status was shipped, flips back to running so next runProject can
      rebuild.
    
    PM incremental mock fixture:
    - fixtures/devloop-mock/devloop-pm.json — converted to sequence form:
      * sequence[0] (init) — original P1 fixture (PRD rev=1, 14 files).
      * sequence[1] (incremental) — appends a new section to
        prd/feature/feature-tree.html, bumps article data-rev to 2,
        writes history/prd-rev-002.html.
    
    Baseline happy-path Integrator:
    - fixtures/devloop-mock/devloop-integrator.json — single-shot pass.
      Makes vanilla runProject ship without a scenario override.
    
    P4 happy-path scenario:
    - fixtures/devloop-mock-scenarios/happy_path/devloop-architect.json —
      single-unit (todo-be only) Architect so end-to-end ship works with
      the baseline Coder/Tester (which only know todo-be paths).
    
    Routes:
    - server/routes/devloop.js:
      * POST /projects/:pid/sign-off — 400 InvalidProjectStatusTransition
        when status != 'shipped'; 200 returns { status }.
      * POST /projects/:pid/abandon  — body { by?, reason?, note? }; 400 on
        terminal state; 200 returns { status: 'abandoned' }.
      * POST /projects/:pid/feedback — body { text (req), by?,
        mockFixtureDir? }; 400 on missing text or shipped-final/abandoned;
        200 returns { prd_rev_before, prd_rev_after, status }.
      * POST /projects: now accepts optional `mockFixtureDir` so the same
        fixture dir threads through both the create call and later
        feedback (keeps mock-sequence counters aligned).
    
    Static status page (replaces full Vue Dashboard for P4):
    - server/public/devloop-status.html — adds:
      * Status badge in header (color-coded per status).
      * Sign Off / Abandon control buttons (disabled per current state).
      * Feedback textarea + Submit button → POST /feedback.
      * Buttons reflect FSM (signoff only when shipped; abandon/feedback
        locked at terminal states).
    
    Acceptance:
    - scripts/phase4-verify.js — 9 steps, full HTTP path:
      ① POST /projects → running
      ② POST /run → shipped
      ③ POST /feedback → PRD rev 1→2 + running (+ changelog entry)
      ④ POST /run again → shipped
      ⑤ POST /sign-off → shipped-final
      ⑥ POST /feedback (after sign-off) → 400
      ⑦ POST /sign-off (after sign-off) → 400
      ⑧ second project: POST /abandon → abandoned
      ⑨ POST /abandon (after abandon) → 400
    
    Tests (+19 cases):
    - server/tests/devloop/p4-l3-feedback.test.js
      * 14 FSM cases covering happy path + abandon path + signOff
        pre-conditions + empty feedback rejection.
      * 5 route cases via fetch on ephemeral express app.
    
    Results:
    - 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
    - vitest devloop+acp-core: 213/213 (was 194 → +19)
    
    Spec deviations explicit:
    - Full Vue DevLoopDashboard.vue + Ops 4 sub-pages NOT implemented;
      static status page handles the demoable surface area instead.
    - All backend endpoints from §P4 (sign-off, abandon, feedback) are
      complete and tested.
    
    Specs: docs/prd/newfunction/_spec/plan-migration.md · P4 L3 + UI
    
    Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
    yibo authored
     
    Browse Dir »
  • Implements the §P3 acceptance gate from plan-migration.md: a single
    POST /api/devloop/projects/:pid/run drives the full project from L1
    through L2 with 4 distinct BugTriager branches, observability via SSE
    stream + bugs.ndjson + changelog.ndjson, and a tiny static status page.
    
    Mock protocol — fallback dir:
    - packages/acp-core/protocol/ClaudeCliProtocol.js
      * New options.mockFallbackDir: when scenario dir lacks a per-agent
        fixture, fall back to the baseline fixtures/devloop-mock/.
        Enables scenario dirs to override only the agents that differ
        (Integrator + Triager + sometimes Architect).
    
    Scenario fixtures — 4 L2 branches:
    - fixtures/devloop-mock-scenarios/contract_mismatch/
      * Architect: sequence[init, patch] — patch bumps sdd_rev → 2,
        units.json l2_rounds → 1, marks todo-be back to pending.
      * Integrator: sequence[fail (500 vs 201), pass].
      * Triager: contract_mismatch confidence 0.85 with proposed_sdd_patch.
    - fixtures/devloop-mock-scenarios/impl_bug/
      * Integrator: sequence[fail (ReferenceError), pass].
      * Triager: impl_bug confidence 0.78 affected=[todo-be], proposed=null.
    - fixtures/devloop-mock-scenarios/spec_ambiguous/
      * Triager: confidence 0.4 → LoopController emits human_intervention.
    - fixtures/devloop-mock-scenarios/infra_flake/
      * Integrator: sequence[crashed (EADDRINUSE), pass].
      * Triager: infra_flake confidence 0.95 affected=[].
    - Each scenario also includes a 1-unit (todo-be) Architect.init fixture
      so baseline Coder/Tester (todo-be) can drive L1.
    
    LoopController:
    - server/src/core/devloop/loop-controller.js — adds:
      * runProject(pid, opts) — wave-scheduled L1 via _groupUnitsByWave,
        runIntegrator (devloop-integrator), runTriager (devloop-triager),
        then branch dispatch:
          - contract_mismatch+conf≥0.5 → Architect(patch) writes new
            units.json (already pending, l2_rounds++); emits sdd.updated +
            changelog sdd_rev entry; loop back to L1.
          - impl_bug+conf≥0.5 → unitRegistry.reset(affected); loop, no
            budget burn.
          - spec_ambiguous OR conf<0.5 → emit human_intervention_needed
            SSE, exit l2_blocked.
          - infra_flake → loop directly (no reset, no budget burn).
      * runDocsPhase + runUnit + callAgent all thread opts.mockFixtureDir
        through to the protocol.
      * Auto-attaches sseBroker to unit-registry and bug-tracker on module
        load — every FSM transition + bug op fires an SSE event.
      * bug_open at integration failure, bug_transition → fixed when
        subsequent L2 round passes.
    
    Routes:
    - server/routes/devloop.js:
      * POST /projects/:pid/run now defaults to full runProject; ?only=<id>
        still drills into single-unit runUnit (P2 compatibility).
      * GET  /projects/:pid/stream — SSE with Last-Event-ID replay.
      * GET  /projects/:pid/bugs?status=&unit_id=&severity= — bug list.
    - server/index.js + agent-server.js mount /public for static assets.
    
    Static status page:
    - server/public/devloop-status.html (~100 lines) — pure HTML, polls
      GET /state every 2s, renders unit DAG with status pills + timeline
      tail. URL ?pid= or input box.
    
    Acceptance:
    - scripts/phase3-verify.js — 9 steps across 4 scenarios + observability:
      ① contract_mismatch ships at sdd_rev=2 l2_rounds=1, sdd.updated SSE,
        changelog sdd_rev entry, bug open → fixed.
      ② impl_bug ships, sdd_rev=1, l2_rounds=0 (no budget burn).
      ③ spec_ambiguous → l2_blocked + human_intervention_needed SSE.
      ④ infra_flake ships, rerun_integrator action, l2_rounds=0.
      ⑤ Observability: timeline/bugs/changelog/stream.log present.
      ⑥ SSE replay from Last-Event-ID returns ≥2 historical events.
    
    Tests (+13 cases):
    - server/tests/devloop/run-project.test.js (11) — 4 scenarios end to
      end + SSE event capture.
    - server/tests/devloop/routes.test.js (+2) — full-project mode + bugs
      404. Updated P2 ?only stub test → full-project 404 on unknown pid.
    
    Results:
    - phase0-verify: 8/8
    - phase0-test-call: 7/7
    - phase1-verify: 7/7
    - phase2-verify: 6/6
    - phase3-verify: 9/9
    - vitest devloop+acp-core: 194/194 (was 181 → +13)
    
    Specs:
    - docs/prd/newfunction/_spec/plan-migration.md · P3 验收
    - docs/prd/newfunction/_spec/loops-l2.md (failure attribution + budget)
    - docs/prd/newfunction/_spec/agents-integrator.md
    - docs/prd/newfunction/_spec/agents-triager.md
    
    Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
    yibo authored
     
    Browse Dir »
  • Implements the §P2 acceptance gate from plan-migration.md: a single
    POST /api/devloop/projects/:pid/run?only=todo-be drives the L1 inner
    loop (Coder → Tester → fail → Coder → Tester → pass), with the second
    Coder pass demonstrably reflecting on the first failure.
    
    Mock protocol — stateful sequences:
    - packages/acp-core/protocol/ClaudeCliProtocol.js
      * Mock fixtures now support `sequence: [{chunks,result,files}, ...]`.
        Each protocol.connect() + sendPrompt() consumes the next variant;
        sticks on the last entry after exhausted.
      * Static `ClaudeCliProtocol.resetMockState()` clears counters between
        test runs.
    
    Fixtures:
    - fixtures/devloop-mock/devloop-architect.json — units.json now has
      status:pending + retries:0 + retry_budget per unit, plus
      units/{todo-be,todo-db,todo-fe}/spec.json so Tester has acceptance
      criteria to read.
    - fixtures/devloop-mock/devloop-coder.json — sequence: implement (with
      intentional missing 400 branch) → retry (reflective fix, coder.log
      attempt:2 has last_failure/last_cause/this_fix/rationale).
    - fixtures/devloop-mock/devloop-tester.json — sequence: fail (1/3
      failure with hint pointing at missing body validation) → pass (3/3).
    
    LoopController:
    - server/src/core/devloop/loop-controller.js — adds:
      * runUnit(pid, unitId, opts) — drives the L1 loop via unit-registry
        FSM (pending → coding → testing → failed → coding → testing →
        passed/blocked). Calls Coder then Tester per attempt; on failure,
        builds a retry context summarizing prior coder.log + tester
        failures and feeds it into the next Coder prompt.
      * _buildRetryContext + _findLatestTesterResult helpers.
      * callAgent now rewrites units.json.project_id to the real pid after
        mock writes (so unit-registry validation passes).
    
    Route:
    - server/routes/devloop.js — adds POST /projects/:pid/run?only=<unitId>.
      Without ?only, returns 501 (full project run lands in P3).
    
    Acceptance:
    - scripts/phase2-verify.js — 6 steps:
      1. POST /projects (PM + Architect)
      2. POST /run?only=todo-be returns ok=true, attempts=2, final=passed
      3. FSM trail matches expected 6-step transition sequence
      4. coder.log second entry has all 4 reflection fields
      5. runs/ has ≥2 result.json with first.ok=false, last.ok=true
      6. sandbox cross-unit + prd writes blocked by ToolSandboxError
    
    Tests (5 new cases):
    - server/tests/devloop/run-unit.test.js (4) — FSM trail, coder.log
      reflection, runs/ result chain, sandbox enforcement.
    - server/tests/devloop/routes.test.js (+3) — POST /run validation,
      full P2 loop, 404 on unknown unit.
    
    Results:
    - phase0-verify: 8/8
    - phase0-test-call: 7/7
    - phase1-verify: 7/7
    - phase2-verify: 6/6
    - vitest devloop+acp-core: 181/181 (was 174 → +7)
    
    Specs:
    - docs/prd/newfunction/_spec/plan-migration.md · P2 验收
    - docs/prd/newfunction/_spec/loops-l1.md (retryWithReflection)
    - docs/prd/newfunction/_spec/agents-coder.md
    - docs/prd/newfunction/_spec/agents-tester.md
    
    Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
    yibo authored
     
    Browse Dir »
  • Implements the §P1 acceptance gate from plan-migration.md: a single
    POST /api/devloop/projects produces a runnable todo-demo project with
    multi-page PRD/SDD sites, units.json, integration spec, agent-state,
    and history snapshots — all via mock agents (no real Claude CLI cost).
    
    Code additions:
    - packages/acp-core/protocol/ClaudeCliProtocol.js
      * mock mode now emits an extra `mock/files` acp_event when the fixture
        contains a files[] array. LoopController applies it to the project
        root, letting mock agents produce real outputs.
    - server/src/core/devloop/loop-controller.js (now ~280 lines)
      * callAgent(pid, agentName, prompt, opts) — single-agent invocation:
        reads system/templates/{agent}/prompt.md, runs mock protocol,
        applies fixture files[], timeline-logs, auto-commits.
      * runDocsPhase(pid, requirement) — orchestrates PM → Architect with
        `docs.complete` timeline marker.
      * getProjectState(pid) — returns project.json + units + prd_rev/sdd_rev
        + timeline tail for the GET /state endpoint.
    - server/routes/devloop.js (new)
      * POST /api/devloop/projects — createProject + runDocsPhase
      * GET  /api/devloop/projects
      * GET  /api/devloop/projects/:pid/state
    - server/index.js / server/agent-server.js — mount /api/devloop.
    
    Mock fixtures (drive the full acceptance file tree):
    - fixtures/devloop-mock/devloop-pm.json
      * 14 files: prd/{index,reading-guide,product/*,feature/*,flow/*,prototype/*}.html,
        prd/assets/{shell.css,shell.js,search-index.json},
        agent-state/{pm.json,pm-todo.json}, history/prd-rev-001.html.
    - fixtures/devloop-mock/devloop-architect.json
      * 13 files: sdd/{index,mvcp/*}.html, sdd/assets/*,
        units.json (3 units, DAG), integration/spec.json,
        agent-state/{architect.json,architect-todo.json}, history/sdd-rev-001.html.
    
    Acceptance:
    - scripts/phase1-verify.js — spins ephemeral express app, POSTs the
      todo-demo project, asserts 23 expected paths exist + 3 units with
      l2_rounds/l2_budget + git ≥4 commits + timeline events.
    
    Tests (12 new cases):
    - server/tests/devloop/loop-controller.test.js (7) — callAgent +
      runDocsPhase + state.
    - server/tests/devloop/routes.test.js (5) — POST validation, full
      POST, GET state, 404 on unknown pid.
    
    Results:
    - phase0-verify: 8/8
    - phase0-test-call: 7/7
    - phase1-verify: 7/7
    - vitest devloop+acp-core: 174/174 (was 162 → +12)
    
    Specs: docs/prd/newfunction/_spec/plan-migration.md · P1 Docs MVP
    
    Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
    yibo authored
     
    Browse Dir »
  • Final P0 deliverables to make the system bootable in mock mode and
    pass `scripts/phase0-verify.js` + `scripts/phase0-test-call.js` end-to-end.
    
    ClaudeCliProtocol (mock mode):
    - LEMONBOSS_CLAUDE_MODE=mock or { mock: true } in constructor enables
      mock mode. connect() becomes a no-op; sendPrompt reads fixtures from
      fixtures/devloop-mock/{agentName}.json and emits scripted session_update
      chunks + session/result(mock=true). Falls back to default.json.
    
    Agent registry:
    - 6 entries added to system/templates/_registry.json (devloop-pm,
      devloop-architect, devloop-coder, devloop-tester, devloop-integrator,
      devloop-triager).
    - Per-agent dirs system/templates/devloop-{role}/ with:
      * prompt.md   — auto-extracted from agents-{role}.html §2.2
      * config.json — cli.toolPolicy.allowedTools + sandbox.writeAllowList
    
    Tooling:
    - scripts/extract-agent-prompts.js  — regex-extracts §2.2 system prompts
      from 6 agent HTML pages to system/templates/devloop-{role}/prompt.md.
    - server/src/tools/devloop/index.js — central export (tools Map,
      bashHooks, dispatch).
    - server/src/core/devloop/loop-controller.js (P0 skeleton) — exposes
      createProject (sandbox alloc + git init + first commit + timeline) and
      commitAfterAgent (per-agent kind-routed git commit + timeline event).
    
    Mock fixtures:
    - fixtures/devloop-mock/default.json + devloop-pm.json
    
    Acceptance scripts:
    - scripts/phase0-verify.js   — 8 static checks (35 tools loadable,
      6 agents registered, prompt+config wired, bash guard exported, services
      require, fixtures present, git-vault interface, loop-controller).
    - scripts/phase0-test-call.js — 7 end-to-end steps under mock mode
      (createProject → CLI connect → sendPrompt chunks → no-op commit returns
      null → real write commits → git log ≥2 → timeline has both events).
    
    vitest.config.js: include packages/**/*.test.js so the mock smoke test
    runs in the suite.
    
    Results:
    - 162/162 devloop + acp-core tests pass (up from 159).
    - phase0-verify: 8/8.
    - phase0-test-call: 7/7.
    
    Specs: docs/prd/newfunction/_spec/plan-migration.md · Quick-Start step 7
    
    Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
    yibo authored
     
    Browse Dir »
  • The 50-page PRD HTML totals ~520KB; loading it all costs Claude ~222K
    tokens just for context. This adds a token-efficient sibling layer:
    
    - scripts/extract-spec.js → npm run spec:extract / spec:check
      Walks docs/prd/newfunction/*.html and produces stripped MD into _spec/.
      Strategy varies per page (full-extract for SDD/process/data,
      shell-strip for agents to keep long system prompts intact).
      Result: 327.9KB MD (~84K tokens) — 38% of full load, saves ~138K tokens
      for every Agent invocation that reads the spec.
    
    - scripts/git-hooks/pre-commit + scripts/install-hooks.sh
      Pre-commit guard: when any docs/prd/newfunction/*.html changes, the
      hook checks the corresponding _spec/*.md is up to date; fails commit
      if stale, telling user to `npm run spec:extract`. Auto-installed via
      package.json `prepare` script on `npm install`.
    
    - docs/prd/newfunction/_spec/ (51 .md files + CONVENTIONS.md)
      Machine-readable mirror of HTML. Used by:
      - Coder/Architect/Tester agents when reading spec at runtime
      - External Claude Code sessions doing reproducibility
      - CI checks (npm run spec:check)
      NOT hand-edited; regenerated from HTML by extract-spec.js.
    
    - CLAUDE.md: 1-line note directing future agents to read _spec/*.md
      preferentially, fall back to *.html only for wireframes/SVG/full
      human-readable context.
    
    This is the user's pre-existing scaffolding that the previous commits
    hadn't pulled in yet. Now tracked + enforced by hook.
    
    Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
    yibo authored
     
    Browse Dir »
  • DevLoop: a 3-layer Loop (L1 Unit / L2 Integration / L3 Human) auto-development
    system that takes a one-line human requirement and produces multi-page HTML
    PRD + SDD + units.json + full backend/frontend code via 6 specialized agents.
    
    This commit adds the complete documentation set:
    
    50 HTML pages organized in 8 sections (3-level menu + global search):
    - 01 Overview · 02 PRD · 03 Design (loops + 6 agents)
    - 04 SDD (MVCP × 4) · 05 Prototype · 06 Architecture
    - 07 API · 08 Ops · 09 Plan
    
    Key specs:
    - 6 agent skills (PM/Architect/Coder/Tester/Integrator/BugTriager), each with
      full system prompt, 13-17 tool signatures, 3 E2E samples, helper source code
    - 52 MVCP definitions, 100% machine-extractable via data-* anchors
    - 79 tool signatures with implementation guidance (arch-tool-registry)
    - ACP bridge spec (arch-acp-bridge): how LoopController calls into LemonBoss
      agent-manager without breaking existing Master/Innovator flows
    - 5-phase plan P0→P4 (~9.5 weeks): P0 bootstrap (tool impl + ACP bridge),
      P1 docs MVP, P2 single unit L1, P3 L1+L2 loop, P4 L3 feedback + UI
    - Persistence layer: AgentState (M-10), Memory (M-11), Todolist (M-12),
      Timeline (M-13), Bugs (M-14), Changelog (M-15) + crash recovery (P-8)
    - Cost & concurrency budgets (plan-cost-concurrency)
    - Code lifecycle: stay-in-sandbox v1 + export API + future GitHub PR (v2)
    
    Plus supporting scripts (zero deps, regex-based):
    - scripts/extract-manifest.js: extracts MVCP defs to build-manifest.json,
      used to verify all definitions have path + shape (currently 100%)
    - scripts/build-search-index.js: builds assets/search-index.json (183KB),
      enables Ctrl+K global search across all 50 pages
    
    The PRD itself is meta-executable: a future Claude Code session reading
    plan-reproducibility.html can rebuild the entire DevLoop runtime from the
    docs alone.
    
    Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
    yibo authored
     
    Browse Dir »


  • scripts/demo-harness-company.js creates a company, hires a Base Agent
    worker, and simulates the full RPEV lifecycle with real API calls:
    - Company creation (skipBootstrap)
    - Agent hiring with base template
    - meta-research initial skill mount
    - 3 transition API calls (plan → execute → verify)
    - Hot Swap verification at each stage
    - Artifact production validation
    yibo authored
     
    Browse Dir »
  • scripts/test-harness.js covers:
    - Meta-Skill file existence & content
    - Base Agent template completeness
    - Hot Swap simulation
    - Context Flush simulation
    - _lessons.md injection
    - billing.log format
    - GoalsService new statuses
    - CLI registration
    - Transition API route verification
    - Optional --online mode for live API tests
    yibo authored
     
    Browse Dir »


  • - Implement OKR GoalsService with hierarchical node tracking
    - Add /api/goals routes and integrate with dispatch/report APIs
    - Create Innovator agent with Hunt→Digest→Evolving pipeline
    - Create Hunter (l3-hunt), Digester (l2-digest), Evolver (evolving) meta agents
    - Copy L1/L2 dependency skills into each agent's .claude/skills/
    - Fix buildSystemPrompt to scan ALL skill subdirectories (critical)
    - Fix agent list sorting: master pinned top, rest by lastActiveAt
    - Rename master-001→master, innovator-001→innovator
    - Establish meta agent output convention: write to target agent dir
    - Add CXO agent base class for management agents
    - Update CEO agent with delegation-first management model
    yibo authored
     
    Browse Dir »

  • - Agent as Micro-Container: each agent lives in data/agents/{id}/ with full encapsulation
    - Persona vs Capability split: agent.md (identity) + .claude/skills/main_skill/SKILL.md (workflow)
    - Conversations co-located: data/agents/{id}/conversations/ replaces global dir
    - Meta Skills renamed: meta_hunt, meta_digest, meta_creator, meta_evolving, meta_benchmark, meta_research
    - Dynamic Hot-Reload: AgentManager.getAgentConfig() falls back to filesystem scan
    - Parallel Sub-Agent orchestration via Promise.all with multi-terminal UI
    - Removed SQLite dependency, global skills/ directory, and legacy conversations/
    - Full architecture docs: 18-local-filesystem-first-agent-encapsulation.md
    yibo authored
     
    Browse Dir »