-
## 第 6 步:调度器只管图任务(一行判据,但漏了是静默的) listQueue / deriveQueueBlocks / sweep 三处都加 executor='graph'。 派单任务虽然也进 tasks 表,但它的执行载体是「直接起一次 agent 对话」, 由 /task/dispatch 自己触发。漏这一条的后果:调度器拿一条根本没有 run 行的 task 去出队 → syncRunNodesToDef 判空 → abandonRun → **把一条正在被 agent 执行的派单收成 cancelled**。守卫用例把它摆成「最像可出队」的样子 (queued + auto + 无依赖),只有 executor 这一维拦得住它。 ## 第 5 步:GET /api/tasks 改读表,删掉 122 行的会话反推 原来的 getAggregatedTasks 是启发式:扫全部 agent 的 conversations,按会话 id 里的 T-xxx 归组,再用三条策略(meta 的 parentTaskId / from agent 的活跃会话 时间包含 / master conv 的标题相似)**猜**父子关系。猜出来的树没法验证对错, 而且每次请求都要遍历所有 agent 的会话目录 —— route 那 10 秒缓存就是为它加的。 现在父子关系是 tasks.parent_task_id,派单时就显式写下来了,不用猜。 task-service.js 391 行 → 236 行;_inferParentChild / _loadTaskMetas / TASK_META_DIR 一并删除(改完就是零调用方)。 **getTaskTimeline 保留**,但来源拆清楚:任务树从表来(parent_task_id, 可验证),时间线正文仍从 agent 的 conversations/ 扫 —— 那是一手记录, 没有替代品。删掉的只是「从会话反推任务树」那一半,不是会话本身。 两处口径变化(写在代码注释里): - agents:原来是「会话里出现过的 agent 集合」,现在是「谁派的 + 派给谁」。 对派单任务这两者本来就是同一件事 - conversationCount:原来是扫出来的文件数,现在是「有没有起过执行会话」(0/1)。 为一个列表字段遍历所有 agent 的会话目录,正是这次要去掉的那笔开销; 真要看内容走 /api/tasks/:taskId/timeline,那条仍读一手记录 ## 漏改一个消费方,真打接口才发现 routes/tasks.js 自己还在算 t.conversations.length,而 conversations 是会话 反推那套的产物、已随之删除 → 500「Cannot read properties of undefined」。 测试没覆盖这条路(它只在真跑接口时才走到)。已改成用 t.conversationCount。 真打验证:GET /api/tasks 返回 17 条、12 个字段齐全 —— 条数比改前多, 因为测试跑出来的派单现在也进表了,这本身就是「存储真的换了」的证据。 全量:132 文件 / 1257 测试全绿。 Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
-
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> -
设计见 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>
-
…_DIR move, stray files - CLAUDE.md: document DevLoop subsystem (spec-first workflow, project root/git-vault, mock mode, L1 loop, unit layout, audit trail) and add missing test commands - server/routes/agent-chat.js, server/services/task-service.js: TASK_META_DIR moved from system/agents/.tasks to system/tasklog - system/agents/master/.claude/scheduled_tasks.json: scheduled task state update - remove stray memory/daily/2026-04-02.md and a garbled-filename artifact left under system/agents/digester-youtube-crawler/ Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
-
- Moved data/system/ → system/ (agents, templates, skills, data, workspace) - Updated all server route/service path references - Updated all script path references - Updated all documentation references - Restructured .gitignore for cleaner system/ vs data/ boundary system/ = platform-shared assets (system agents, template library) data/ = tenant-specific company instance data
-
- Add TaskTimeline.vue: two-pane dashboard with task list + message timeline - Add task-service.js: aggregate cross-agent conversations into task tree - 4-strategy parent-child inference (explicit meta, time-overlap, conv→tpl, master→T) - Read messages.log for full tool call details (not just history.json) - Add tasks.js API routes: GET /api/tasks, GET /api/tasks/:taskId/timeline - Mount /api/tasks in agent-server.js - Add 'Task Logs' nav entry in AppNav.vue after Templates - Support taskId in URL (/tasks/:taskId?) for sharing/bookmarking - Add --parent flag to CLI task dispatch for explicit parentTaskId - Auto-detect parentTaskId in task/dispatch from sender's active task - Add --instructions flag to template train CLI command - Update master tools.md with new parameters