• 承接 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>
    yibo authored
     
    Browse File »
  • 设计见 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 File »

  • 代码层:
    - 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 File »


  • 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
    yibo authored
     
    Browse File »

  • - 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)
    yibo authored
     
    Browse File »