• 设计见 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 »

  • Implements the §P3 acceptance gate from plan-migration.md: a single
    POST /api/devloop/projects/:pid/run drives the full project from L1
    through L2 with 4 distinct BugTriager branches, observability via SSE
    stream + bugs.ndjson + changelog.ndjson, and a tiny static status page.
    
    Mock protocol — fallback dir:
    - packages/acp-core/protocol/ClaudeCliProtocol.js
      * New options.mockFallbackDir: when scenario dir lacks a per-agent
        fixture, fall back to the baseline fixtures/devloop-mock/.
        Enables scenario dirs to override only the agents that differ
        (Integrator + Triager + sometimes Architect).
    
    Scenario fixtures — 4 L2 branches:
    - fixtures/devloop-mock-scenarios/contract_mismatch/
      * Architect: sequence[init, patch] — patch bumps sdd_rev → 2,
        units.json l2_rounds → 1, marks todo-be back to pending.
      * Integrator: sequence[fail (500 vs 201), pass].
      * Triager: contract_mismatch confidence 0.85 with proposed_sdd_patch.
    - fixtures/devloop-mock-scenarios/impl_bug/
      * Integrator: sequence[fail (ReferenceError), pass].
      * Triager: impl_bug confidence 0.78 affected=[todo-be], proposed=null.
    - fixtures/devloop-mock-scenarios/spec_ambiguous/
      * Triager: confidence 0.4 → LoopController emits human_intervention.
    - fixtures/devloop-mock-scenarios/infra_flake/
      * Integrator: sequence[crashed (EADDRINUSE), pass].
      * Triager: infra_flake confidence 0.95 affected=[].
    - Each scenario also includes a 1-unit (todo-be) Architect.init fixture
      so baseline Coder/Tester (todo-be) can drive L1.
    
    LoopController:
    - server/src/core/devloop/loop-controller.js — adds:
      * runProject(pid, opts) — wave-scheduled L1 via _groupUnitsByWave,
        runIntegrator (devloop-integrator), runTriager (devloop-triager),
        then branch dispatch:
          - contract_mismatch+conf≥0.5 → Architect(patch) writes new
            units.json (already pending, l2_rounds++); emits sdd.updated +
            changelog sdd_rev entry; loop back to L1.
          - impl_bug+conf≥0.5 → unitRegistry.reset(affected); loop, no
            budget burn.
          - spec_ambiguous OR conf<0.5 → emit human_intervention_needed
            SSE, exit l2_blocked.
          - infra_flake → loop directly (no reset, no budget burn).
      * runDocsPhase + runUnit + callAgent all thread opts.mockFixtureDir
        through to the protocol.
      * Auto-attaches sseBroker to unit-registry and bug-tracker on module
        load — every FSM transition + bug op fires an SSE event.
      * bug_open at integration failure, bug_transition → fixed when
        subsequent L2 round passes.
    
    Routes:
    - server/routes/devloop.js:
      * POST /projects/:pid/run now defaults to full runProject; ?only=<id>
        still drills into single-unit runUnit (P2 compatibility).
      * GET  /projects/:pid/stream — SSE with Last-Event-ID replay.
      * GET  /projects/:pid/bugs?status=&unit_id=&severity= — bug list.
    - server/index.js + agent-server.js mount /public for static assets.
    
    Static status page:
    - server/public/devloop-status.html (~100 lines) — pure HTML, polls
      GET /state every 2s, renders unit DAG with status pills + timeline
      tail. URL ?pid= or input box.
    
    Acceptance:
    - scripts/phase3-verify.js — 9 steps across 4 scenarios + observability:
      ① contract_mismatch ships at sdd_rev=2 l2_rounds=1, sdd.updated SSE,
        changelog sdd_rev entry, bug open → fixed.
      ② impl_bug ships, sdd_rev=1, l2_rounds=0 (no budget burn).
      ③ spec_ambiguous → l2_blocked + human_intervention_needed SSE.
      ④ infra_flake ships, rerun_integrator action, l2_rounds=0.
      ⑤ Observability: timeline/bugs/changelog/stream.log present.
      ⑥ SSE replay from Last-Event-ID returns ≥2 historical events.
    
    Tests (+13 cases):
    - server/tests/devloop/run-project.test.js (11) — 4 scenarios end to
      end + SSE event capture.
    - server/tests/devloop/routes.test.js (+2) — full-project mode + bugs
      404. Updated P2 ?only stub test → full-project 404 on unknown pid.
    
    Results:
    - phase0-verify: 8/8
    - phase0-test-call: 7/7
    - phase1-verify: 7/7
    - phase2-verify: 6/6
    - phase3-verify: 9/9
    - vitest devloop+acp-core: 194/194 (was 181 → +13)
    
    Specs:
    - docs/prd/newfunction/_spec/plan-migration.md · P3 验收
    - docs/prd/newfunction/_spec/loops-l2.md (failure attribution + budget)
    - docs/prd/newfunction/_spec/agents-integrator.md
    - docs/prd/newfunction/_spec/agents-triager.md
    
    Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
    yibo authored
     
    Browse File »