• 只做了这一件事,没有跟着做「dream 改成 org/work graph 来跑」——两者被
    单独评估过:org/work graph 是单公司作用域(org graph=公司级 workflow,
    work graph=公司内某任务的节点图),dream 却是跨公司扫描,套进去要么破坏
    作用域假设要么得新开图类型;且 graph 引擎自带的验收机制(goal-contract
    benchmark/test-script)判的是「产物过没过验收脚本」,对「经验提炼得对
    不对」这种自由文本判断没有对应机制——不管套不套 graph 都得单独设计
    rubric,是同一件事。用户明确只要 REST/控制台这一半。
    
    ## REST(server/routes/dream.js,挂 /api/dream)
    
    路由本身没有新业务逻辑,全部委托给已测过的 dream-service.js:
    GET /agents(总览)、GET /agents/:id(详情,含定义文件可写性 + 经验
    审计)、POST /agents/:id/run(手动跑一次,dryRun 只看有没有新原料不
    起 LLM)、POST /sweep + GET /sweep/status(全量扫描后台跑 + 轮询,内存
    态并发锁防止连点两下)。
    
    ## 控制台(web/src/views/DreamConsole.vue,路由 /dream)
    
    一个表格 + 两个弹窗:本体列表(详情/跑一次/dry-run)+ 全量扫描按钮
    (15 秒轮询状态)。导航栏加 🌙 Dream 入口。
    
    ## 验证
    
    server/tests/unit/dream-routes.test.js 4 例,monkeypatch 掉
    dream-service 导出对象上的六个函数(不走真文件系统,不误扫真仓库
    76 个本体),只验路由层自己的逻辑:端点接线、sweep 并发锁状态机。
    
    真起服务器打了真数据:GET /agents/innovator-evolver 正确报
    SKILL.md 因没进 git 历史而不可写、经验审计吐出上次真跑沉淀的 4 条
    经验及原文;dry-run 正确报 no-new-material,没多花一次 LLM 调用。
    浏览器里走了一遍列表→详情→dry-run,与直接打 API 结果一致。
    
    955 个单测全绿。
    
    文档:29-dream-design.md §5.7 记录实现与「为什么不做 graph 化」的
    理由;28-followups.md / docs/README.md 同步更新 dream 现状。
    
    Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
    yibo authored
     
    Browse File »

  • ## 决策 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 File »
  • ## 前置:存量记忆的搬家(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 File »
  • ## 两个本体(都过得了毕业闸门)
    
    · dream-distiller —— 把一批原始记录提炼成可复用经验,交 ```json 数组
      {title, body, sources};没有值得留的就交 []。
    · dream-screener —— 逐条判「这条能不能给别家公司看」,交 {shareable, reason}。
    
    **决策 A 的独立性写在两处,缺一不可**:
    · 代码层:判定**一条一次调用**,提示词里只放 title + body,**不放原料**;
    · 本体层:dream-screener/agent.md 明写「你看不到原料,也看不到是哪家公司
      —— 这是故意的」。守卫里有一条专门断言这句话在 —— 否则下一个人会顺手把原料
      塞进提示词「让它判得更准」,而那恰好把独立性拆掉了。
    
    soul.md 也承担判据的一半:screener 的人格写的是「你是一道闸门,不是审稿人。
    审稿人的本能是帮它改好,闸门的本能是不确定就不放」。
    
    ## 两处失效方向都是硬的
    
    · 提炼取不出 JSON → **抛**,不是静默返回空。「产出格式坏了」和「没提炼出东西」
      是两件事,混为一谈会让前者以后者的形式永远藏下去 ——
      每天显示「今天没经验可沉淀」,而真相是解析一直在失败。
    · 判定解析不了 / shareable 不是布尔(比如给了字符串 "true")→ 判否,
      并把原文片段带进 reason,让人看得出是「判否」还是「判炸」。
    
    ## 纠了自己两次
    
    ① 测试第一版把解析与失效分支**在测试里重抄了一遍**再断言 —— 那是在验一份复制品,
       代码改了它照样绿。改成加一条 setDreamAgentCaller 缝,只换掉「真起 CLI」那一层,
       解析、判空、失效方向全走真代码。
    ② agent.md 的相对引用按 **cwd 深度 3**({aid}/{cid}/{taskId}/)解析,不是按文件
       自身位置 —— 仓库根是 ../../../../../。我按文件位置写了 ../../../,
       agent-md-refs.test.js 当场判红。**守卫替我抓的,不是我自己发现的。**
    
    ## 还没做的,写进文档 §5.4(别当成 dream 上线了)
    
    · 定时挂载没做(决策 C 说每日一次):现在只有 dreamOnce(agentId) 这个可调用单元,
      没挂调度、没 REST 入口。
    · 还没写定义文件:只写本体根的 memory/experience.md(纯经验积累,删掉无副作用)。
      三个 git 跟踪的定义留给下一步,闸门与 definitionWritability() 已就位,
      缺的是「往里写什么、写成什么形状」那半边设计。
    · **没有一次真 CLI 验收**:CI 里换掉的是 callDreamAgent 那一层,验的是解析与失效方向,
      不是模型写得好不好。两个本体的提示词**至今没有被任何模型读过** ——
      这正是 P3B W4 记过的形态(mock 从不读提示词)。
    · 决策 D(提炼质量怎么评)仍未定;可追溯是它的便宜起步,不是替代品。
    
    全量:144 文件 / 1323 测试全绿。
    
    Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
    yibo authored
     
    Browse File »
  • ## 步骤 2:「有哪些公司」只认 company_agents 表
    
    system/agents/{aid}/{cid}/ 是**约定不是校验**。实查 96 个二级目录里混着
    train/ workspace/ 和带时间戳的测试残留(tmp-w7-*-1786986291739-*)。
    拿目录枚举公司 = 把测试夹具当经验原料喂给提炼 agent。
    
    改成查表,另补保留段 _global(全局 agent 的运行态落点,没人「雇」它所以不在表里)。
    **目录从此只用来定位文件,不用来枚举公司。**
    守卫里真造了 train/ 和 tmp-w7-* 两个目录,断言它们不进原料。
    
    ## 空转保护:水位线按「条数」不按 mtime
    
    实查 75 份 memory.md 只有 7 份有非模板内容 —— 每日跑起来绝大多数 agent 没有新原料。
    不拦的话每天几十次「读完发现没东西」的 LLM 调用在烧钱。
    
    **判据用条数而不是 mtime**:mtime 会被任何一次无关写入推动(例如别处重写整份
    memory.md),条数只在真的多出记录时增长。用 mtime 的话,空转保护会在
    「文件被碰过但内容没变」时失效。
    
    ## 决策 A 的失效方向写进代码
    
    去敏判定 agent **抛异常也算拒绝**,并把「为什么」写进 rejected[]。
    否则现场只看到「少了一条」,查不出是判否还是判炸。
    「少沉淀一条经验」与「泄漏一次机密」代价不对称,判据必须偏向贵的那一侧。
    
    ## 步骤 5:可追溯
    
    每条原料带 source({公司}:memory.md#{行号}),提炼产物落盘时把 sources
    写进 experience.md 的引用行。没有它,dream 的产出无法验证对错 ——
    与 FDE 那边「LLM 自己汇报分数」是同一个问题。
    
    ## 步骤 3 还差什么(写在文档 §5.3,别当成做完了)
    
    编排 / 空转 / 闸门 / 落盘 / 可追溯都跑通了(6 例守卫),
    **缺两次真 agent 调用的默认实现**:提炼 agent 与去敏判定 agent 的本体还不存在。
    默认实现现在是一句显式 throw(「尚未接线」)而**不是静默返回空** ——
    静默返回空会让调用方以为「跑了但没提炼出东西」,那是本仓库反复出现的失效形态。
    
    也还没写定义文件:writeDistilled 目前只写本体根的 memory/experience.md
    (纯经验积累,删掉无副作用)。三个 git 跟踪的定义留给下一步,
    definitionWritability() 已能报出「现在能不能写、不能写是为什么」。
    
    全量:144 文件 / 1316 测试全绿。
    
    Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
    yibo authored
     
    Browse File »
  • 29-DREAM §四 的五步里先落两步。
    
    ## 步骤 4:本体定义文件的 git 历史闸门(决策 B.3)
    
    用户定案:soul.md / agent.md **直接落盘**,但写之前必须确认这份文件已经在
    git 历史里 —— 别导致直接修改而没有历史。
    
    definition-write-gate.js 两条判据都满足才放行:
    ① 文件被 git 跟踪;② 该文件没有未提交改动。
    判不出来(不在仓库 / git 不可用)一律拒绝 —— fail-closed。
    
    **为什么是「拒绝并报告」而不是「脏就先替它提交一把」**:后者看着更顺手,
    但那正是本仓库记过的一类事故 —— 多会话共用同一个 worktree(27-P3C §15.4)。
    一份未提交的改动很可能是**另一个会话正在写的东西**,替它提交等于把别人的
    半成品写进 main 且署错名。把「要不要提交」留给人。
    
    守卫 5 例,含「拒绝时必须给出下一步」那条 —— 撞上闸门的人(或 agent)
    要能照着做,否则只能猜。
    
    ## 步骤 1:memory.md 的自动写入不再冒充「关键事实」
    
    原实现取任务与结果的第一行、砍到 80/100 字符,写进 `## 关键事实`。
    那不是提炼,是搬运 + 截断。实测产物(cto/_global/memory/memory.md):
    
        - [2026-08-20] [SYSTEM HEARTBEAT] → 🔧 [TOOL_CALL] Bash (ID: toolu_01RsQ3gh...)
    
    **工具调用 id 被当成了「关键事实」**,而 memory.md 会被注入每一轮提示词。
    28 §5.6b 点名的错误版本是「自动把原文写进共享 SKILL.md」——
    这套已经是那个错误的单公司版,只是还没跨公司共享所以还没造成泄漏。
    
    改法:
    · 换段 —— 自动写入落到「原始记录(未提炼)」,`## 关键事实` 只由提炼产物填。
      读的人和 agent 一眼分得清「日志」和「结论」;这一段同时是 dream 的输入面。
    · 滤掉确定的噪声(工具调用标记 / 空结果 / 只有心跳标记的任务),
      但**不猜「哪条重要」**——猜重要性需要理解内容,那是 dream 的活,
      在这里做等于把提炼下放到一个正则里。
    · 不再截成半句:上限放宽到 200 并取完整第一行。截断残渣读起来像事实、
      其实缺主语,比不留更坏。
    
    ⚠️ 踩到一条:噪声判据初版有「任务与结果都短于 8 个字符就丢」。那是按英文长度
    想出来的阈值 —— 中文 8 个字是一句完整的话,实测「结果甲甲甲甲甲」(7 字)
    整条被丢。已删该规则。**凡是拿长度当信息量代理的判据,先问一句这是按哪种文字算的。**
    
    全量:143 文件 / 1310 测试全绿。
    
    Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
    yibo authored
     
    Browse File »
  • 28-followups §1.1 一直是「方向已定、设计未定」。这份把取舍摆出来并记下拍板结果。
    
    ## 先看清原料:它现在是脏的(全部实查,不是推测)
    
    · **写进 memory 的不是「事实」,是截断的日志行**。appendToMemoryMd 的全部逻辑是
      「取第一行、砍到 80/100 字符」。cto/_global 的实际内容里,三条「关键事实」是
      `🔧 [TOOL_CALL] Bash (ID: toolu_01RsQ...)` —— 工具调用 id。
      §5.6b 点名的错误版本是「自动把原文写进共享 SKILL.md」;**现在这套已经是那个错误的
      单公司版**,只是还没跨公司共享,所以还没造成泄漏。
    · 长期记忆是一个 3000 字符的滚动窗口,没有按重要性保留的机制。
    · 96 个「公司态目录」里混着 train/ workspace/ 和**带时间戳的测试残留**
      (tmp-w7-*-1786986291739-*、qroute-co-13/14)。dream 第一步「枚举所有公司」
      现在没有可靠答案 —— 可靠的答案在 company_agents 表里,目录只能用来定位文件。
    · 75 份 memory.md 里只有 7 份有非模板内容。**dream 现在几乎没有原料。**
    
    ## 四条拍板(2026-08-20)
    
    A 去敏 = 独立判定 agent + 写作要求。失效方向是「少沉淀」不是「泄漏」——
      两种错代价不对称时判据偏向贵的那侧,与 P3B §八 FAILING_VERDICTS 同一条经验。
    B 落点 = memory/ 与 SKILL.md 都写,**必要时迭代 soul.md / agent.md**。
    C 触发 = 定时每日一次。
    D 顺序 = 上游修复与 dream 一起做。
    
    ## B 把范围扩大了,随之而来的约束单列一节
    
    「本体只有一份」意味着写 agent.md / soul.md 影响**所有雇了它的公司**,
    而不是提炼出这条经验的那一家。所以四个落点按可逆性分层,并记了四条硬约束:
    · agent.md 有一处 2000 字符截断 —— **作用点要说准**:那是给规划 agent 看的
      「角色定义摘录」(graph-engine.js:915),agent 自己那条装配链不截断。
      判据因此是「保证前 2000 字符仍然自足」,不是「不许追加」。
      (初稿我按记忆写成「装配时只读前 2000 字」,查了代码才改对。)
    · 这四个里三个是 git 跟踪的**定义**,不是运行态 —— dream 改它们会进 git status。
    · 毕业闸门读这些文件,写坏会让本体雇不进任何公司。
    · 必须能分别回滚:经验写坏只影响上下文,agent.md 写坏影响所有公司。
    
    ## 还没定的
    
    决策 D(提炼质量怎么评);B.2 里「定义文件直接写还是走提案」——
    我建议走提案并写进了推进步骤,但那是建议不是拍板。
    
    Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
    yibo authored
     
    Browse File »