-
承接 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>
-
设计见 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>
-
代码层: - 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>
-
…to prevent EADDRINUSE
-
Phase 2 改进: 1. 工作日历系统 (ScheduleService): - 新增 schedule-service.js: 公司级日程管理 - 支持按小时调度、按周几过滤、时区感知 - 心跳触发时自动检查到期 slots 并触发 Agent - 执行去重(同日同 slot 不重复触发) - CRUD API: GET/POST/PUT/DELETE /api/company/:id/schedule/slots - CLI: schedule add / schedule list 2. 告警通道 (Alert Channel): - Pipeline 步骤超时自动告警 Master Agent - 心跳异常自动告警 Master Agent - _sendAlertToMaster() 统一告警接口 3. CEO → Pipeline 自动生成: - CEO 模板从 3 步升级为 5 步工作流 - 新增 Step 2: Pipeline JSON 设计(含 loop/cron/steps 结构) - 新增 Step 4: OKR 创建 - Pipeline 设计输出为 CTO 搭建流水线的蓝图 4. Master 晨会日报: - 每天 08:00 自动生成全公司运营日报 - 包含公司状态、Pipeline 运行、OKR 进度、Agent 活跃度 - 自动推送给 Master Agent - 防重复机制(每天只生成一次) 5. Pipeline 驳回信息注入: - 驳回步骤被心跳重新触发时,__rejection 信息注入 prompt - 让 Agent 知道被驳回的原因和重做次数 - 替换原有 curl 汇报指令为 task report CLI
-
- CompanyHeartbeatService: company-level heartbeat with timer registration - Auto-trigger: cron-based pipeline scheduling (intervalHours) - Active run driving: dispatch tasks to agents, timeout detection - CEO heartbeat: periodic company status check - Pipeline cron field support in definitions - Registered in server startup alongside agent heartbeat - E2E test: 113/113 passed (all phases + autonomous loop)