-
手工扫了两轮,扫出的是三类会持续复发的失真,不是零星笔误: ① package.json 里 12 处引用指向从未在 git 历史存在过的文件(server/src/cli/auto-dev.js 一族) ② CLAUDE.md 的 docs/ 那行列了 5 个文件名,文档移进 done/ 之后全成死链 ③ 数据存储整节把两个不同的 data 根当成一个写,server/conversations/ 这个路径根本不存在 共性是**不报错、不影响测试、git status 干净**,只有照着做的人(或 agent)撞墙才发现。 而 CLAUDE.md 是每个会话都会加载进上下文的文件 —— 写错等于把错误信息直接灌给每一个后来者。 四条扫描: - CLAUDE.md 里的仓库路径都存在 - CLAUDE.md 里出现的每条 npm run 都在 package.json 里(守反方向:删脚本忘改文档) - package.json 的 scripts / bin / main 指向的文件都存在 - docs/README.md 的相对链接都指向真实文件 判据刻意窄(本仓库有过「防线被整条注释掉」的教训):路径只认「以仓库顶层目录开头 + 含 /」, 且跳过 gitignored 的 —— 那是运行态产物(web/dist/、data/companies/、skills/),在干净机器上 本来就不存在,缺席不是文档错误;这与 no-stale-templates-path.test.js 用的是同一条判据。 上下文里的相对片段(_base/、todo/future/)、glob、<repo>/… 示意写法一律不判。 四条各带「样本非空」下限断言(当前 26 路径 / 16 script 名 / 6 入口引用 / 22 链接), 下限取当前值一半左右:正则一写错就会以「零违例」全绿,那和没有这条测试是一回事。 验证:把同一套判据跑在旧 revision 的文件内容上(只读 git,不碰工作区)—— 3e718aa:路径 ❌3 条、入口 ❌10 条 d6214f8:路径 ❌4 条、入口 ❌10 条 HEAD :全绿 顺带修掉自己写的一处假路径占位符(`data/xxx` → 「以 `data/` 开头的路径」), 文档里本来就不该出现假路径。 28-followups 守卫清单补到第六条,并写明后两条与前四条的形状差异。 npm run test:unit 1061/1061 绿。 Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
-
承接 310a2b2 的两个遗留: ① 四类被错标成心跳 company-heartbeat-service._sendAgentChat 给五类调用(心跳巡检 / Pipeline 步骤 / 日程 / 告警 / 日报)无差别打 isHeartbeat:true,于是对话列表里全都显示成 「⏱️ 自主心跳巡检」、meta.type 一律 'heartbeat'。改成显式传 kind,五类各自标注。 isHeartbeat 仍然发,但只对真心跳为真,老消费方行为不变。 ② 310a2b2 让 Pipeline 重试变成了冷启动 Pipeline 步骤的 convId 是 `pipeline-{runId}-step-{i}`,被驳回重做时**复用同一个**。 310a2b2 按 isHeartbeat 一刀切回收,等于每次重试都要走 buildPrompt 场景 C 重注入历史。 现在回收策略挂在 CALL_KINDS 表上,判据只有一条:**convId 会不会被下一轮复用** —— 会复用的(pipeline / 人类对话)留着走 TTL,不复用的(心跳 / 日程 / 告警 / 日报)跑完即回收。 不按「是不是后台调用」分:五类后台调用里 pipeline 就是要留的那一类。 守卫补到 12 条(原 3 + kind 标注 5 + 回收策略 4)。对 310a2b2 跑过:8 红 4 绿。 convId 一律用固定字面量而非拼时间戳 —— 撞上 test-id-stability 那道防线后按它的判据改的, 固定之后第二次跑还顺带走了「复用已有对话」那条分支。 文档: - CLAUDE.md 注意事项加一条(新增会话创建路径时必须同时定回收路径,附症状与守卫位置) - 28-followups 守卫清单补第五条,并把「前四条守单一持有者」与第五条「守资源生命周期」 的形状差异写明;顺手修掉表格已有 4 行、结尾却仍写「这三条」的失配 - .env.example 补 AGENT_SESSION_IDLE_MS 全量单测 667/667 绿。重启后 /api/health 正常,心跳照常挂载。 Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
-
27-P3C 批 1 沉淀的不变式测试,与前三条守的是同一件事:同一个事实 只能有一处持有者。断言的是「凡是把 process.env.GRAPH_RUNS_DIR 绑到 标识符上的模块,那个标识符必须在代码里真正被用到」。 来历一并记下:goal-contract.js 里曾有一行 RUNS_ROOT,注释写着 「与 graph-engine.RUNS_ROOT 是同一个变量(测试隔离在用)」,全文件 却零引用。声明了意图、代码不兑现的常量比没有更容易骗人 —— 读的人 会据此认为该模块认这个覆盖,然后写侧写进临时目录、读侧去仓库里找, 两个方向都静默错位。 四条共有的「样本非空」前置断言仍是重点:扫不到文件时这类测试会以 「零违例」的形式全绿,那正是它自己变成零调用方的方式。 Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
-
主文档新增 §11.4b,记 dd319bb 那轮清掉的内容与「不清会怎样」: 四份本体提示词、三个 skill js、两份图模板 README 的 CI 防线规则、 DevLoop PRD 13 份 HTML(连带重生成的 52 份 _spec + manifest + search-index)。 其中两条值得单独记: - innovator-hunt/collect_seed.js 是真 bug 且已发作过 —— 裸相对路径相对 cwd 解析, 在 agent 自己目录下造出一棵野生嵌套树。 - DevLoop PRD 写的 system/templates/devloop-pm.md 根和形状都错 (实际是 system/agents/{agentName}/prompt.md),由此推出一条方法论: 批量替换字符串时,替换的正确性取决于替换后的整体是否成立, 而不是被替换的那一段是否过期。 同时订正两处早于本次改造就已过期的内容(「6 个命名冲突 id」清单里四个 id 根本不存在;orggraph-planning 被告知的真相源仍是 company.json.agents[]), 并写明刻意不动的三类:历史说明 / 迁移完成的证明 / 运行态记录。 followups 新增 §五,登记本轮立起来的三条不变式测试 (agents-root-single-holder / no-stale-templates-path / repo-hygiene), 写明它们共有的「样本非空」前置断言为什么不能省,以及改动它们前要想清楚的事。 §四 那条「脚本路径需要跟着更新」已在 cd2066a 完成,改成实跑结论。 交付状态从「未 commit、未 push」更新为已推送(ca468ab..dd319bb)。 Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
-
设计见 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>