• SessionPool 此前只有三条回收路径:换新会话 / reset() / killActive()。「正常跑完」和
    「不可重试的报错」都不在其中,而 getKey 里带了 taskId —— 每个图节点一个新 key,于是
    一节点一进程、永不释放,且**不报错**。实测 23 小时漏出 7 个图执行进程。
    
    修法与 agent-chat 侧同一套:调用开始时停表(getOrCreate 里 cancel),调用结束时上弦
    (agent-manager 两个出口调 armIdle),计时器只在没有在途请求的间隙走,所以再长的单次
    生成也不会被 TTL 打断。旋钮共用 AGENT_SESSION_IDLE_MS(默认 30 分钟)。
    
    守卫:server/tests/unit/session-pool-idle-reclaim.test.js
    
    Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
    yibo authored
     
    Browse Dir »

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

  • 测试 788/788 全绿(76 文件,起点 786),未改任何既有断言。
    
    ## 1. idleTimeoutMs 硬编码 120s(「work 节点 → success」跑不通的唯一技术原因)
    
    agent-manager.js 里 `this.config?...?.idleTimeout || 120_000`,且 `...options`
    摊在前面被下一行覆盖,两个后果叠加:
    - 默认 120 秒,比 stream-executor 自己 JSDoc 写的 30 分钟(1_800_000)小一个数量级,
      也和同进程 ClaudeCliProtocol 早已放到 24h 的 idle 上限完全对不上
    - 调用方**无法覆写** —— 传了 options.idleTimeoutMs 也会被盖掉
    
    真 CLI 下的后果:任何「先读几千行源码再动笔」的节点都在动笔前被杀
    (readme-writer: idle timeout: no stream data for 120000ms)。
    
    改成 调用方 > agent 配置 > DEFAULT_IDLE_TIMEOUT_MS(30min),并把常量真的定义出来
    —— 上一轮 Master agent 自己诊断出这个问题也动手改了,但引用了未定义的
    DEFAULT_IDLE_TIMEOUT_MS,跑起来是 ReferenceError。
    
    ## 2. W7 判据在零边最小图上失效
    
    判「org graph 成型了没有」原先看**边数**,理由是「节点 hire() 自己就会造,
    拿节点数当信号会废掉『连雇两个人第二个不入图』」——理由成立,但边只是
    「writeGraph 跑过」的代理,而真跑里 orggraph-planning 裁出过一张**零条边的单节点图**,
    代理当场失效:三条判据全落空 → work 层本体被写进 org_graph_nodes,
    下一次下达任务时被 advanceOne 当成 org 节点执行。
    
    改成记录**来源**而不是猜:org_graph_nodes 加 authored_by(idempotent ALTER),
    writeGraph 写 'planner'、hire 写 'hire',判据看有没有 planner 写下的节点。
    hire 先记的行随后被 planner 纳入时升格,反向不降级。
    存量行 authored_by 为 NULL,回落到原来的边数代理,行为不变。
    
    新增两条用例(既有 9 例造的全是有边的成型图,正好绕开这个形状),
    并做过变异验证:把判据改回纯边数,两条精确变红,还原后逐字一致。
    
    ## 3. 前后端「能不能下达任务」的规则各写一份且不一致
    
    前端 ACTIVE_RUN 含 blocked、后端 ACTIVE_ROOT_RUN_STATUS 不含(唯一索引
    idx_graph_runs_one_active_root 里也没有)。后果:一家公司只要失败过一次,
    控制台上就再也下不了第二个任务,而后端其实放行。
    
    规则只留服务端一处:GET /graph-runs 返回 canDispatch / activeRootRunId,
    前端照抄结果,不再自己复述取值域。字段缺失时保守放行,交给端点 409 兜底。
    
    Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
    yibo authored
     
    Browse Dir »

  • 代码层:
    - 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 Dir »
  • # Conflicts:
    #	system/agents/master/.claude/scheduled_tasks.json
    yibo authored
     
    Browse Dir »
  • hire() now checks system_agents (source_kind='template') before provisioning a new
    company agent: if the role has a shared template row, skip copying agent.md and
    instead let AgentManager.getAgentConfig()/PromptBuilder.build() resolve the prompt
    from the shared legacy_path at call time, with per-company context assembled from a
    new company-context.md. Roles without a template row (including the 6 ids that exist
    in both system/agents/ and system/templates/, e.g. evolver-youtube-crawler) fall back
    to the existing full-copy behavior unchanged.
    
    - server/services/graph-service.js (new): lookupSharedAgentMd(), upsertOrgGraphNode()
    - server/services/company-service.js: hire() reference-mode branch, _provisionReferenceAgent()
    - server/src/core/agent-manager.js: getAgentConfig() resolves prompt/companyContextPath
    - server/src/core/prompt-builder.js: build() concatenates company-context.md
    - unit + integration tests covering all 6 acceptance criteria from
      docs/todo/system-design/27-p1-virtual-reference.md §6, including a regression test
      against the real idearun:evolver-youtube-crawler naming-collision case
    
    Full regression suite (587 tests) passes; independent adversarial review found 0
    blocking/major issues.
    
    Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
    yibo authored
     
    Browse Dir »

  • First successful real-CLI agent invocation. After REAL.1 (system-prompt
    injection) + REAL.2 (mtime-diff file detection) wired, the only remaining
    gate was Claude auth. Once CLAUDE_CODE_OAUTH_TOKEN was added to the
    project .env, scripts/real-pm-smoke.js completed cleanly:
    
      Wire-up status:
        ✓ process spawn
        ✓ stream chunks       (3)
        ✓ result text          (Claude returned "DONE")
        ✓ files written        (6: prd/index, feature-tree, user-flows,
                                  product/overview, assets/shell.{css,js})
        ✓ git commit           (8cb0493)
      5/5 checks passed · elapsed 163s
    
    PM output quality (real Claude, not mock):
    - valid <article data-doc="prd" data-rev="1"> + <section data-rev="1">
      structure per system prompt
    - nav links use correct relative paths across 4 chapters
    - pid (p-7gwlbl) embedded in HTML metadata
    - 中文 prose in the requested 克制 voice
    
    Spec-deviation confirmed (no MCP tool gateway yet — Claude only has
    built-in Read/Write/Bash):
    - ✗ agent-state/pm.json (no update_runtime_state tool)
    - ✗ agent-state/pm-todo.json (no write_todolist tool)
    - ✗ history/prd-rev-001.html (no archive_doc tool)
    - ✗ timeline.ndjson 'prd_drafted' event (no timeline_append tool)
    - ✓ core PRD site IS produced — sufficient to prove pipeline
    
    ──── code ────
    
    - scripts/real-pm-smoke.js — loads root .env via dotenv resolved
      from server/node_modules (script dir has no node_modules of its own).
    
    ──── ambient ────
    
    Files modified by user/linter while real-CLI work was in flight; merged
    without revert:
    - server/routes/devloop.js — new GET /:pid/requirements endpoint
    - server/services/devloop/path-resolver.js — listProjects() includes
      archived flag + helpers; supports project archive lifecycle
    - server/services/devloop/git-vault.js — commit() now accepts files[]
      to scope which paths the commit covers (avoids dragging linked-existing
      user's unstaged files into chore commits)
    - server/src/core/devloop/loop-controller.js — createProject uses
      explicit files:['project.json','timeline.ndjson'] for first chore
      commit (avoids same issue)
    - server/tests/devloop/path-resolver.test.js — coverage for archive/
      patch/hardDelete helpers
    - web/src/components/devloop/RequirementListSection.vue (new)
    - web/src/views/DevLoopNewRequirement.vue (new)
    - web/src/views/DevLoopDashboard.vue — mounts RequirementListSection
    - web/src/views/DevLoopProjects.vue — list page polish
    - web/src/router/index.js — adds /devloop/:pid/requirements/new route
    - web/src/components/devloop/DashboardHeader.vue — back link tweak
    
    Test results: 233/233 vitest pass (was 230 → +3 path-resolver cases).
    
    ──── ⚠ SECURITY NOTE ────
    
    .env is currently TRACKED in git (committed in b1a348b) even though
    .gitignore lists it. Existing committed contents include credentials for
    DOUBAO / FEISHU / GITHUB / GOOGLE / JWT. The CLAUDE_CODE_OAUTH_TOKEN +
    AZURE_OPENAI_API_KEY I just added to .env are NOT in this commit — they
    stay in your working tree only.
    
    Recommended follow-up (separate commit):
      git rm --cached .env
      git commit -m "chore: stop tracking .env (already gitignored)"
    And rotate every key that was in the previous committed .env.
    
    Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
    yibo authored
     
    Browse Dir »
  • Two parallel pieces of plumbing — neither has been exercised end-to-end yet
    (real CLI gated on `claude /login`; Projects list view served alongside
    existing pages):
    
    ──── real-CLI wire-up (REAL.1 + REAL.2) ────
    
    LemonBoss now has a clean toggle between mock & real Claude CLI:
    
    - packages/acp-core/protocol/ClaudeCliProtocol.js
      * `options.systemPrompt` → `--append-system-prompt <prompt>` so each
        devloop agent receives its role-specific prompt.md without losing
        Claude's default tool-use conventions.
      * `options.maxBudgetUsd` → `--max-budget-usd` (note: only effective in
        `--print` mode; documented inline).
    
    - server/src/core/devloop/loop-controller.js
      * callAgent now branches on `opts.mock`:
        - mock (P1-P5 path, untouched): fixture sequence + `mock/files` event
        - real: read system/templates/{agent}/prompt.md, pass as systemPrompt,
          snapshot project file mtimes pre-call, diff post-call to compute
          `files_written` — no fixture, no mock/files needed.
      * `_snapshotMtimes(root)` helper walks the project tree (skipping
        .git / node_modules / .cache / .tmp) and returns Map<relPath,mtime>.
      * timeline event payload now carries `real: true` flag.
    
    - scripts/real-pm-smoke.js — minimal real-CLI sanity:
      spawns claude, injects PM prompt, prints which files were written +
      git commit sha. Hard timeout 5min. Single agent → expected spend
      $0.10-0.30 per run when authenticated.
    
    Current status: process spawn + system-prompt injection + stream-json
    flow all verified up to the `Not logged in · Please run /login` gate.
    Auth is the only remaining blocker for executing the real smoke.
    
    ──── project CRUD routes ────
    
    server/routes/devloop.js + server/services/devloop/path-resolver.js
    add the lifecycle pieces the Projects list view needs:
    
    - GET    /projects?include_archived=true   list w/ archive filter
    - PATCH  /projects/:pid                    edit name + idea_summary
    - DELETE /projects/:pid                    soft delete (archive)
    - DELETE /projects/:pid?hard=true          hard delete (rm -rf sandbox;
                                                unregister linked)
    - POST   /projects/:pid/restore            un-archive
    
    path-resolver exposes matching helpers: listProjects({includeArchived}),
    patchProjectMeta(pid,patch), hardDeleteProject(pid).
    
    ──── UI ────
    
    - web/src/views/DevLoopProjects.vue (320 lines, new)  — Projects list
    - web/src/router/index.js — adds `/devloop` → DevLoopProjects
    - web/src/components/devloop/DashboardHeader.vue — back-link now points
      to `/devloop` (project list) instead of `/company`.
    
    ──── housekeeping ────
    
    - CLAUDE.md / start.sh — start.sh now boots server/index.js (full route
      surface incl. /api/devloop) instead of the historical agent-server.js;
      docs updated to reflect this.
    
    ──── tests (+12) ────
    
    - server/tests/devloop/routes-crud.test.js — 12 cases:
      PATCH validation (4) · soft DELETE + list filter (4) · POST /restore
      (1) · hard DELETE (2) · GET /projects default behavior (1).
    
    Results:
    - phase0-verify .. phase5-verify: 8+7+7+6+9+9+7 all pass
    - vitest devloop+acp-core: 230/230 (was 218 → +12)
    
    Specs:
    - docs/prd/newfunction/_spec/arch-acp-bridge.md · Mock Mode
    - docs/prd/newfunction/_spec/plan-migration.md · "自举乐趣" (real path
      prep)
    
    Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
    yibo authored
     
    Browse Dir »
  • Implements the §P4 acceptance gate from plan-migration.md, with one
    scope adjustment confirmed up-front: full Vue Dashboard (~1650 lines)
    deferred to a future UI phase, replaced by extending the existing
    P3 static status page with Sign Off / Abandon / Feedback controls.
    All P4 backend acceptance criteria are scripted (phase4-verify.js).
    
    Project status FSM (project.json.status):
    - server/src/core/devloop/loop-controller.js
      * draft  →  running  →  shipped  →  shipped-final | abandoned
                    ↓             ↓
              l2_blocked    (feedback flips back to running)
              l2_exhausted
      * `_setProjectStatus` validates transitions via STATUS_TRANSITIONS,
        emits SSE `project.status`, writes timeline event.
      * createProject seeds status=draft; runDocsPhase end → running;
        runProject(shipped) → shipped; all dead-end branches (l2_blocked,
        l2_exhausted) also propagate to status via _safeSetStatus.
    
    L3 helpers:
    - signOff(pid, opts) — requires status=shipped → shipped-final; commits
      a `chore: sign-off` git entry; rejects other source states with
      InvalidProjectStatusTransition.
    - abandon(pid, opts) — any non-terminal → abandoned; commits + calls
      sseBroker.close(pid) to send SSE close frame to subscribers.
    - submitFeedback(pid, text, opts) — rejects in shipped-final/abandoned;
      invokes PM in incremental mode; on prd_rev bump writes
      changelog.ndjson prd_rev entry + emits prd.updated SSE; if prior
      status was shipped, flips back to running so next runProject can
      rebuild.
    
    PM incremental mock fixture:
    - fixtures/devloop-mock/devloop-pm.json — converted to sequence form:
      * sequence[0] (init) — original P1 fixture (PRD rev=1, 14 files).
      * sequence[1] (incremental) — appends a new section to
        prd/feature/feature-tree.html, bumps article data-rev to 2,
        writes history/prd-rev-002.html.
    
    Baseline happy-path Integrator:
    - fixtures/devloop-mock/devloop-integrator.json — single-shot pass.
      Makes vanilla runProject ship without a scenario override.
    
    P4 happy-path scenario:
    - fixtures/devloop-mock-scenarios/happy_path/devloop-architect.json —
      single-unit (todo-be only) Architect so end-to-end ship works with
      the baseline Coder/Tester (which only know todo-be paths).
    
    Routes:
    - server/routes/devloop.js:
      * POST /projects/:pid/sign-off — 400 InvalidProjectStatusTransition
        when status != 'shipped'; 200 returns { status }.
      * POST /projects/:pid/abandon  — body { by?, reason?, note? }; 400 on
        terminal state; 200 returns { status: 'abandoned' }.
      * POST /projects/:pid/feedback — body { text (req), by?,
        mockFixtureDir? }; 400 on missing text or shipped-final/abandoned;
        200 returns { prd_rev_before, prd_rev_after, status }.
      * POST /projects: now accepts optional `mockFixtureDir` so the same
        fixture dir threads through both the create call and later
        feedback (keeps mock-sequence counters aligned).
    
    Static status page (replaces full Vue Dashboard for P4):
    - server/public/devloop-status.html — adds:
      * Status badge in header (color-coded per status).
      * Sign Off / Abandon control buttons (disabled per current state).
      * Feedback textarea + Submit button → POST /feedback.
      * Buttons reflect FSM (signoff only when shipped; abandon/feedback
        locked at terminal states).
    
    Acceptance:
    - scripts/phase4-verify.js — 9 steps, full HTTP path:
      ① POST /projects → running
      ② POST /run → shipped
      ③ POST /feedback → PRD rev 1→2 + running (+ changelog entry)
      ④ POST /run again → shipped
      ⑤ POST /sign-off → shipped-final
      ⑥ POST /feedback (after sign-off) → 400
      ⑦ POST /sign-off (after sign-off) → 400
      ⑧ second project: POST /abandon → abandoned
      ⑨ POST /abandon (after abandon) → 400
    
    Tests (+19 cases):
    - server/tests/devloop/p4-l3-feedback.test.js
      * 14 FSM cases covering happy path + abandon path + signOff
        pre-conditions + empty feedback rejection.
      * 5 route cases via fetch on ephemeral express app.
    
    Results:
    - phase0-verify: 8/8
    - phase0-test-call: 7/7
    - phase1-verify: 7/7
    - phase2-verify: 6/6
    - phase3-verify: 9/9
    - phase4-verify: 9/9
    - vitest devloop+acp-core: 213/213 (was 194 → +19)
    
    Spec deviations explicit:
    - Full Vue DevLoopDashboard.vue + Ops 4 sub-pages NOT implemented;
      static status page handles the demoable surface area instead.
    - All backend endpoints from §P4 (sign-off, abandon, feedback) are
      complete and tested.
    
    Specs: docs/prd/newfunction/_spec/plan-migration.md · P4 L3 + UI
    
    Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
    yibo authored
     
    Browse Dir »
  • 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 Dir »
  • Implements the §P2 acceptance gate from plan-migration.md: a single
    POST /api/devloop/projects/:pid/run?only=todo-be drives the L1 inner
    loop (Coder → Tester → fail → Coder → Tester → pass), with the second
    Coder pass demonstrably reflecting on the first failure.
    
    Mock protocol — stateful sequences:
    - packages/acp-core/protocol/ClaudeCliProtocol.js
      * Mock fixtures now support `sequence: [{chunks,result,files}, ...]`.
        Each protocol.connect() + sendPrompt() consumes the next variant;
        sticks on the last entry after exhausted.
      * Static `ClaudeCliProtocol.resetMockState()` clears counters between
        test runs.
    
    Fixtures:
    - fixtures/devloop-mock/devloop-architect.json — units.json now has
      status:pending + retries:0 + retry_budget per unit, plus
      units/{todo-be,todo-db,todo-fe}/spec.json so Tester has acceptance
      criteria to read.
    - fixtures/devloop-mock/devloop-coder.json — sequence: implement (with
      intentional missing 400 branch) → retry (reflective fix, coder.log
      attempt:2 has last_failure/last_cause/this_fix/rationale).
    - fixtures/devloop-mock/devloop-tester.json — sequence: fail (1/3
      failure with hint pointing at missing body validation) → pass (3/3).
    
    LoopController:
    - server/src/core/devloop/loop-controller.js — adds:
      * runUnit(pid, unitId, opts) — drives the L1 loop via unit-registry
        FSM (pending → coding → testing → failed → coding → testing →
        passed/blocked). Calls Coder then Tester per attempt; on failure,
        builds a retry context summarizing prior coder.log + tester
        failures and feeds it into the next Coder prompt.
      * _buildRetryContext + _findLatestTesterResult helpers.
      * callAgent now rewrites units.json.project_id to the real pid after
        mock writes (so unit-registry validation passes).
    
    Route:
    - server/routes/devloop.js — adds POST /projects/:pid/run?only=<unitId>.
      Without ?only, returns 501 (full project run lands in P3).
    
    Acceptance:
    - scripts/phase2-verify.js — 6 steps:
      1. POST /projects (PM + Architect)
      2. POST /run?only=todo-be returns ok=true, attempts=2, final=passed
      3. FSM trail matches expected 6-step transition sequence
      4. coder.log second entry has all 4 reflection fields
      5. runs/ has ≥2 result.json with first.ok=false, last.ok=true
      6. sandbox cross-unit + prd writes blocked by ToolSandboxError
    
    Tests (5 new cases):
    - server/tests/devloop/run-unit.test.js (4) — FSM trail, coder.log
      reflection, runs/ result chain, sandbox enforcement.
    - server/tests/devloop/routes.test.js (+3) — POST /run validation,
      full P2 loop, 404 on unknown unit.
    
    Results:
    - phase0-verify: 8/8
    - phase0-test-call: 7/7
    - phase1-verify: 7/7
    - phase2-verify: 6/6
    - vitest devloop+acp-core: 181/181 (was 174 → +7)
    
    Specs:
    - docs/prd/newfunction/_spec/plan-migration.md · P2 验收
    - docs/prd/newfunction/_spec/loops-l1.md (retryWithReflection)
    - docs/prd/newfunction/_spec/agents-coder.md
    - docs/prd/newfunction/_spec/agents-tester.md
    
    Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
    yibo authored
     
    Browse Dir »
  • Implements the §P1 acceptance gate from plan-migration.md: a single
    POST /api/devloop/projects produces a runnable todo-demo project with
    multi-page PRD/SDD sites, units.json, integration spec, agent-state,
    and history snapshots — all via mock agents (no real Claude CLI cost).
    
    Code additions:
    - packages/acp-core/protocol/ClaudeCliProtocol.js
      * mock mode now emits an extra `mock/files` acp_event when the fixture
        contains a files[] array. LoopController applies it to the project
        root, letting mock agents produce real outputs.
    - server/src/core/devloop/loop-controller.js (now ~280 lines)
      * callAgent(pid, agentName, prompt, opts) — single-agent invocation:
        reads system/templates/{agent}/prompt.md, runs mock protocol,
        applies fixture files[], timeline-logs, auto-commits.
      * runDocsPhase(pid, requirement) — orchestrates PM → Architect with
        `docs.complete` timeline marker.
      * getProjectState(pid) — returns project.json + units + prd_rev/sdd_rev
        + timeline tail for the GET /state endpoint.
    - server/routes/devloop.js (new)
      * POST /api/devloop/projects — createProject + runDocsPhase
      * GET  /api/devloop/projects
      * GET  /api/devloop/projects/:pid/state
    - server/index.js / server/agent-server.js — mount /api/devloop.
    
    Mock fixtures (drive the full acceptance file tree):
    - fixtures/devloop-mock/devloop-pm.json
      * 14 files: prd/{index,reading-guide,product/*,feature/*,flow/*,prototype/*}.html,
        prd/assets/{shell.css,shell.js,search-index.json},
        agent-state/{pm.json,pm-todo.json}, history/prd-rev-001.html.
    - fixtures/devloop-mock/devloop-architect.json
      * 13 files: sdd/{index,mvcp/*}.html, sdd/assets/*,
        units.json (3 units, DAG), integration/spec.json,
        agent-state/{architect.json,architect-todo.json}, history/sdd-rev-001.html.
    
    Acceptance:
    - scripts/phase1-verify.js — spins ephemeral express app, POSTs the
      todo-demo project, asserts 23 expected paths exist + 3 units with
      l2_rounds/l2_budget + git ≥4 commits + timeline events.
    
    Tests (12 new cases):
    - server/tests/devloop/loop-controller.test.js (7) — callAgent +
      runDocsPhase + state.
    - server/tests/devloop/routes.test.js (5) — POST validation, full
      POST, GET state, 404 on unknown pid.
    
    Results:
    - phase0-verify: 8/8
    - phase0-test-call: 7/7
    - phase1-verify: 7/7
    - vitest devloop+acp-core: 174/174 (was 162 → +12)
    
    Specs: docs/prd/newfunction/_spec/plan-migration.md · P1 Docs MVP
    
    Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
    yibo authored
     
    Browse Dir »
  • Final P0 deliverables to make the system bootable in mock mode and
    pass `scripts/phase0-verify.js` + `scripts/phase0-test-call.js` end-to-end.
    
    ClaudeCliProtocol (mock mode):
    - LEMONBOSS_CLAUDE_MODE=mock or { mock: true } in constructor enables
      mock mode. connect() becomes a no-op; sendPrompt reads fixtures from
      fixtures/devloop-mock/{agentName}.json and emits scripted session_update
      chunks + session/result(mock=true). Falls back to default.json.
    
    Agent registry:
    - 6 entries added to system/templates/_registry.json (devloop-pm,
      devloop-architect, devloop-coder, devloop-tester, devloop-integrator,
      devloop-triager).
    - Per-agent dirs system/templates/devloop-{role}/ with:
      * prompt.md   — auto-extracted from agents-{role}.html §2.2
      * config.json — cli.toolPolicy.allowedTools + sandbox.writeAllowList
    
    Tooling:
    - scripts/extract-agent-prompts.js  — regex-extracts §2.2 system prompts
      from 6 agent HTML pages to system/templates/devloop-{role}/prompt.md.
    - server/src/tools/devloop/index.js — central export (tools Map,
      bashHooks, dispatch).
    - server/src/core/devloop/loop-controller.js (P0 skeleton) — exposes
      createProject (sandbox alloc + git init + first commit + timeline) and
      commitAfterAgent (per-agent kind-routed git commit + timeline event).
    
    Mock fixtures:
    - fixtures/devloop-mock/default.json + devloop-pm.json
    
    Acceptance scripts:
    - scripts/phase0-verify.js   — 8 static checks (35 tools loadable,
      6 agents registered, prompt+config wired, bash guard exported, services
      require, fixtures present, git-vault interface, loop-controller).
    - scripts/phase0-test-call.js — 7 end-to-end steps under mock mode
      (createProject → CLI connect → sendPrompt chunks → no-op commit returns
      null → real write commits → git log ≥2 → timeline has both events).
    
    vitest.config.js: include packages/**/*.test.js so the mock smoke test
    runs in the suite.
    
    Results:
    - 162/162 devloop + acp-core tests pass (up from 159).
    - phase0-verify: 8/8.
    - phase0-test-call: 7/7.
    
    Specs: docs/prd/newfunction/_spec/plan-migration.md · Quick-Start step 7
    
    Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
    yibo authored
     
    Browse Dir »
  • Adds the DevLoop Agent tool layer (CommonJS) under server/src/tools/devloop:
    - _errors.js / _sandbox.js — shared infra (3 error classes + path allow-list w/ {unitId})
    - tool-registry.js — loadAllTools / dispatch / listToolNames / getDevLoopTools
    - persistence-tools.js (5) — write_todolist · update_todo_item · update_runtime_state · timeline_append · record_memory
    - doc-tools.js (12) — bootstrap_prd_site · bootstrap_sdd_site · write_chapter · write_mvcp_page · archive_doc · diff_html · diff_units · echo_diff · update_search_index · validate_prd_site · validate_sdd_consistency · hash_contract
    - coder-tools.js (3) — contract_bridge · sandbox_check · append_coder_log (retry fields required)
    - tester-tools.js (5) — parse_vitest · hint_builder · bug_open · bug_transition · bug_list
    - integrator-tools.js (6) — port_picker · spawn_units · health_wait · run_case · parse_placeholder · collect_stderr
    - triager-tools.js (4) — extract_evidence · category_classifier · diff_contract_vs_impl · find_similar_bug
    - bash-json-guard.js — preExecute hook blocking inline JSON in Bash (CLAUDE.md L91-99)
    
    Total: 35 callable devloop tools.
    
    Tests: 88 cases across 9 files, all passing; combined with P0.0 services
    suite the project now has 159 green tests.
    
    Specs:
    - docs/prd/newfunction/_spec/arch-tool-registry.md
    - docs/prd/newfunction/_spec/agents-{pm,architect,coder,tester,integrator,triager}.md
    
    Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
    yibo authored
     
    Browse Dir »


  • - System agents: 只保留 master (data/system/agents/master)
    - Templates: 所有可复用 agent 模板 (data/system/templates/)
    - Companies: 公司创建时自动部署 5 个元 Agent (innovator/hunter/digester/evolver/agent-creator)
    
    路径修复:
    - agent-chat.js: /list 扫描路径修正 (system/agents + companies/*/agents)
    - agent-manager.js: 动态 agent 查找路径修正
    - skill-config-loader.js: 修正 agents root
    - pipeline-service.js: pipelines 输出到 companies/{id}/pipelines/
    - billing.log: 移至 companies/{id}/logs/ 下
    
    Skills 标准化:
    - 所有 template agent 建立 .claude/skills/main_skill/SKILL.md
    - company-service._copyTemplate() 新增 .claude/ 目录复制
    - innovator SKILL.md v3.0: 移除旧 l3-hunt/l2-digest 命名
    - 清理重复 agent_creator, 统一为 agent-creator
    
    清理:
    - 移除 data/agents, data/workspace, data/logs, data/goals 旧目录
    - 清除所有未使用的 DATA_DIR 声明
    - 清除 template 中的 conversations/logs/memory 运行态数据
    yibo authored
     
    Browse Dir »
  • The plugin bootstrap was calling resolveOpenclawDist() synchronously
    at module load time, which crashed the entire server if the optional
    @mas/openclaw-dist package wasn't installed. Now all three call sites
    defer resolution to runtime with try/catch graceful fallback.
    yibo authored
     
    Browse Dir »

  • …ter Agent cognitive auto-recovery loop
    
    - Refactored CompanyDashboard into read-only Observer UI
    - Enforced strict companyId:roleId namespacing across Node APIs and AgentManager
    - Added dynamic <env_status> injection to PromptBuilder for robust context
    - Introduced bin/lemon.js CLI for structured LLM tool execution
    - Implemented in-stream error interceptors for implicit silent retry loop
    yibo authored
     
    Browse Dir »


  • - Implement OKR GoalsService with hierarchical node tracking
    - Add /api/goals routes and integrate with dispatch/report APIs
    - Create Innovator agent with Hunt→Digest→Evolving pipeline
    - Create Hunter (l3-hunt), Digester (l2-digest), Evolver (evolving) meta agents
    - Copy L1/L2 dependency skills into each agent's .claude/skills/
    - Fix buildSystemPrompt to scan ALL skill subdirectories (critical)
    - Fix agent list sorting: master pinned top, rest by lastActiveAt
    - Rename master-001→master, innovator-001→innovator
    - Establish meta agent output convention: write to target agent dir
    - Add CXO agent base class for management agents
    - Update CEO agent with delegation-first management model
    yibo authored
     
    Browse Dir »

  • - Agent as Micro-Container: each agent lives in data/agents/{id}/ with full encapsulation
    - Persona vs Capability split: agent.md (identity) + .claude/skills/main_skill/SKILL.md (workflow)
    - Conversations co-located: data/agents/{id}/conversations/ replaces global dir
    - Meta Skills renamed: meta_hunt, meta_digest, meta_creator, meta_evolving, meta_benchmark, meta_research
    - Dynamic Hot-Reload: AgentManager.getAgentConfig() falls back to filesystem scan
    - Parallel Sub-Agent orchestration via Promise.all with multi-terminal UI
    - Removed SQLite dependency, global skills/ directory, and legacy conversations/
    - Full architecture docs: 18-local-filesystem-first-agent-encapsulation.md
    yibo authored
     
    Browse Dir »