@tea-agent/loop-agent 0.8.0 → 0.10.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (74) hide show
  1. package/AGENTS.md +2 -0
  2. package/CHANGELOG.md +51 -1
  3. package/README.md +20 -0
  4. package/dist/application/dag/args.js +9 -2
  5. package/dist/cli/command-definitions.js +7 -0
  6. package/dist/cli/program.js +6 -1
  7. package/dist/commands/dag-reconcile-run.js +118 -0
  8. package/dist/commands/init.js +12 -3
  9. package/dist/executors/shell-executor.js +74 -8
  10. package/dist/governance/manifest-types.js +4 -0
  11. package/dist/shared/reference-context.js +48 -22
  12. package/dist/task/config-types.js +1 -1
  13. package/dist/task/runtime.js +1 -1
  14. package/dist/worker/cli.js +216 -0
  15. package/dist/worker/closeout/apply.js +73 -0
  16. package/dist/worker/closeout/preview.js +30 -0
  17. package/dist/worker/delivery/final-verification.js +158 -0
  18. package/dist/worker/delivery/git-transaction.js +354 -0
  19. package/dist/worker/delivery/package.js +449 -0
  20. package/dist/worker/feature/decision-loader.js +68 -0
  21. package/dist/worker/feature/discover.js +14 -0
  22. package/dist/worker/feature/next-action.js +74 -0
  23. package/dist/worker/feature/reducer.js +133 -0
  24. package/dist/worker/feature/review.js +502 -0
  25. package/dist/worker/feature/run.js +313 -0
  26. package/dist/worker/feature/types.js +1 -0
  27. package/dist/worker/follow-up/approve.js +270 -0
  28. package/dist/worker/follow-up/factory.js +234 -0
  29. package/dist/worker/follow-up/paths.js +25 -0
  30. package/dist/worker/follow-up/policy.js +26 -0
  31. package/dist/worker/follow-up/schema.js +93 -0
  32. package/dist/worker/follow-up/store.js +96 -0
  33. package/dist/worker/loop-agent/loop-agent-client.js +51 -10
  34. package/dist/worker/metrics/projector.js +139 -0
  35. package/dist/worker/observability/read-model.js +256 -15
  36. package/dist/worker/observe/paths.js +17 -5
  37. package/dist/worker/observe/routes.js +78 -20
  38. package/dist/worker/observe/server.js +8 -6
  39. package/dist/worker/observe/static/app.js +1045 -177
  40. package/dist/worker/observe/static/index.html +70 -43
  41. package/dist/worker/observe/static/styles.css +553 -610
  42. package/dist/worker/pool/run-store.js +14 -2
  43. package/dist/worker/pool/validation.js +59 -0
  44. package/dist/worker/report/morning-report.js +41 -6
  45. package/dist/worker/run-task/run-task.js +1 -1
  46. package/dist/worker/runner/run-ready.js +19 -5
  47. package/dist/workflows/dag/init-hybrid.js +3 -1
  48. package/dist/workflows/dag/lifecycle.js +146 -0
  49. package/dist/workflows/dag/node-execution.js +3 -0
  50. package/dist/workflows/dag/prompt.js +16 -0
  51. package/dist/workflows/dag/report.js +2 -0
  52. package/dist/workflows/dag/runner.js +133 -104
  53. package/dist/workflows/dag/types.js +3 -0
  54. package/docs/README.md +21 -0
  55. package/docs/agent-dag-recovery-playbook.md +1 -1
  56. package/docs/architecture/runtime-boundaries.md +3 -2
  57. package/docs/design/README.md +13 -7
  58. package/docs/exec-plans/active/README.md +2 -2
  59. package/docs/exec-plans/completed/README.md +15 -0
  60. package/docs/loop-agent-harness.md +45 -2
  61. package/docs/progress/README.md +2 -0
  62. package/docs/reports/README.md +13 -0
  63. package/docs/templates/agent-dag-report.schema.json +5 -3
  64. package/docs/templates/harness.schema.json +7 -2
  65. package/docs/templates/init-evolution-review.md +4 -2
  66. package/docs/verification-matrix.md +7 -0
  67. package/harness.json +4 -3
  68. package/package.json +4 -2
  69. package/scripts/check-product-line-docs.sh +7 -3
  70. package/scripts/check-task-pool-root.sh +1 -1
  71. package/skills/init-capability-evolution/SKILL.md +1 -0
  72. package/skills/loop-agent/references/command-reference.md +21 -0
  73. package/skills/loop-agent/references/hybrid-dag.md +4 -3
  74. package/skills/loop-agent/references/verification-and-failure-handling.md +8 -3
@@ -1,4 +1,5 @@
1
1
  import { readdir, readFile } from "node:fs/promises";
2
+ import { hostname } from "node:os";
2
3
  import path from "node:path";
3
4
  import { CANONICAL_TASK_ID_PATTERN, formatLocalCompactDate, } from "../../task/runtime.js";
4
5
  import { getDagRunDir, isTerminalDagRunStatus, locateDagRun, readHumanApprovalArtifact, requireActiveDagRun, } from "./lifecycle.js";
@@ -12,7 +13,7 @@ import { buildNodePrompt, buildNodePromptWithResolvedSkillInstructions, executeD
12
13
  import { runConvergencePassController, shouldEnableDagConvergence, } from "./convergence/controller.js";
13
14
  import { executeDagRanksOnce, isConditionSkippedReason, } from "./scheduler.js";
14
15
  import { topoSortToRanks } from "./topo.js";
15
- import { parseDagSpec, } from "./types.js";
16
+ import { parseDagSpec, resolveModelForTask, } from "./types.js";
16
17
  import { executeDynamicCondition } from "./dynamic-runtime/condition.js";
17
18
  import { executeDynamicLoopUntil } from "./dynamic-runtime/loop-until.js";
18
19
  import { executeDynamicMapExpansion } from "./dynamic-runtime/map.js";
@@ -109,6 +110,9 @@ export function createInitialRunState(spec, opts, ranks, runId = opts.runId ?? "
109
110
  status: "PENDING",
110
111
  executor: task.executor,
111
112
  complexity: task.complexity,
113
+ ...(resolveModelForTask(task, spec.executorModels)
114
+ ? { model: resolveModelForTask(task, spec.executorModels) }
115
+ : {}),
112
116
  };
113
117
  }
114
118
  return {
@@ -117,6 +121,12 @@ export function createInitialRunState(spec, opts, ranks, runId = opts.runId ?? "
117
121
  runId,
118
122
  cwd: opts.cwd,
119
123
  startedAt: new Date().toISOString(),
124
+ runner: {
125
+ pid: process.pid,
126
+ hostname: hostname(),
127
+ startedAt: new Date().toISOString(),
128
+ heartbeatAt: new Date().toISOString(),
129
+ },
120
130
  status: opts.initOnly || opts.dryRun ? "pending" : "running",
121
131
  ranks,
122
132
  nodes,
@@ -213,6 +223,13 @@ export async function resumeDagRun(opts) {
213
223
  }
214
224
  const maxConcurrent = Math.max(1, opts.maxConcurrent ?? 4);
215
225
  state.status = "running";
226
+ const resumedAt = new Date().toISOString();
227
+ state.runner = {
228
+ pid: process.pid,
229
+ hostname: hostname(),
230
+ startedAt: resumedAt,
231
+ heartbeatAt: resumedAt,
232
+ };
216
233
  const activeRunDir = getDagRunDir(opts.cwd, "active", state.runId);
217
234
  const completedRunDir = getDagRunDir(opts.cwd, "completed", state.runId);
218
235
  const pausedRunDir = getDagRunDir(opts.cwd, "paused", state.runId);
@@ -243,124 +260,136 @@ async function executeDagCheckpoint(input) {
243
260
  stateWriteQueue = stateWriteQueue.then(() => writeRunState(runDir, state, options));
244
261
  await stateWriteQueue;
245
262
  };
246
- const tasksById = new Map(spec.tasks.map((task) => [task.id, task]));
247
- const baseExecuteNode = input.executeNode ??
248
- createDagNodeExecutor({
249
- runDir,
250
- runId: state.runId,
251
- spec,
252
- });
253
- const executeDynamicNode = async (dynamicInput) => {
254
- const { task } = dynamicInput;
255
- if (task.dynamicExpansion) {
256
- return executeDynamicMapExpansion({
257
- ...dynamicInput,
258
- expansion: task.dynamicExpansion,
259
- executeDynamicNode,
263
+ const heartbeatTimer = setInterval(() => {
264
+ if (!state.runner)
265
+ return;
266
+ state.runner.heartbeatAt = new Date().toISOString();
267
+ void persistState().catch(() => { });
268
+ }, 15_000);
269
+ heartbeatTimer.unref();
270
+ try {
271
+ const tasksById = new Map(spec.tasks.map((task) => [task.id, task]));
272
+ const baseExecuteNode = input.executeNode ??
273
+ createDagNodeExecutor({
274
+ runDir,
275
+ runId: state.runId,
276
+ spec,
260
277
  });
261
- }
262
- if (task.dynamicCondition) {
263
- return executeDynamicCondition({
278
+ const executeDynamicNode = async (dynamicInput) => {
279
+ const { task } = dynamicInput;
280
+ if (task.dynamicExpansion) {
281
+ return executeDynamicMapExpansion({
282
+ ...dynamicInput,
283
+ expansion: task.dynamicExpansion,
284
+ executeDynamicNode,
285
+ });
286
+ }
287
+ if (task.dynamicCondition) {
288
+ return executeDynamicCondition({
289
+ task,
290
+ condition: task.dynamicCondition,
291
+ tasksById: dynamicInput.tasksById,
292
+ state: dynamicInput.state,
293
+ });
294
+ }
295
+ if (task.dynamicLoopUntil) {
296
+ return executeDynamicLoopUntil({
297
+ ...dynamicInput,
298
+ loop: task.dynamicLoopUntil,
299
+ executeDynamicNode,
300
+ });
301
+ }
302
+ return executeDynamicReduction({
264
303
  task,
265
- condition: task.dynamicCondition,
266
- tasksById: dynamicInput.tasksById,
304
+ reduction: task.dynamicReduction,
267
305
  state: dynamicInput.state,
306
+ runDir: dynamicInput.runDir,
268
307
  });
269
- }
270
- if (task.dynamicLoopUntil) {
271
- return executeDynamicLoopUntil({
272
- ...dynamicInput,
273
- loop: task.dynamicLoopUntil,
274
- executeDynamicNode,
275
- });
276
- }
277
- return executeDynamicReduction({
278
- task,
279
- reduction: task.dynamicReduction,
280
- state: dynamicInput.state,
281
- runDir: dynamicInput.runDir,
282
- });
283
- };
284
- let pausedByNodeId;
285
- while (true) {
286
- pausedByNodeId = await executeDagRanksOnce({
287
- state,
288
- ranks,
289
- tasksById,
290
- maxConcurrent,
291
- persistState,
292
- createExecuteNodeForRank: (rankCursorNodeIds) => buildRankAwareExecuteNode({
293
- baseExecuteNode,
294
- customExecuteNode: input.executeNode,
295
- rankCursorNodeIds,
296
- tasksById,
297
- meta: { runDir, runId: state.runId, spec },
298
- }),
299
- executeScheduledNode: (nodeId, executeNode, onPause) => executeDagNode({
300
- nodeId,
301
- tasksById,
308
+ };
309
+ let pausedByNodeId;
310
+ while (true) {
311
+ pausedByNodeId = await executeDagRanksOnce({
302
312
  state,
313
+ ranks,
314
+ tasksById,
315
+ maxConcurrent,
316
+ persistState,
317
+ createExecuteNodeForRank: (rankCursorNodeIds) => buildRankAwareExecuteNode({
318
+ baseExecuteNode,
319
+ customExecuteNode: input.executeNode,
320
+ rankCursorNodeIds,
321
+ tasksById,
322
+ meta: { runDir, runId: state.runId, spec },
323
+ }),
324
+ executeScheduledNode: (nodeId, executeNode, onPause) => executeDagNode({
325
+ nodeId,
326
+ tasksById,
327
+ state,
328
+ spec,
329
+ cwd,
330
+ runDir,
331
+ executeNode,
332
+ executeDynamicNode,
333
+ observer: input.observer,
334
+ persistState,
335
+ onPause,
336
+ }),
337
+ });
338
+ if (pausedByNodeId) {
339
+ break;
340
+ }
341
+ const convergenceDecision = await runConvergencePassController({
303
342
  spec,
304
- cwd,
343
+ state,
344
+ tasksById,
305
345
  runDir,
306
- executeNode,
307
- executeDynamicNode,
308
- observer: input.observer,
346
+ cwd,
309
347
  persistState,
310
- onPause,
311
- }),
312
- });
313
- if (pausedByNodeId) {
348
+ });
349
+ if (convergenceDecision.pausedByNodeId) {
350
+ pausedByNodeId = convergenceDecision.pausedByNodeId;
351
+ break;
352
+ }
353
+ if (convergenceDecision.retry) {
354
+ continue;
355
+ }
314
356
  break;
315
357
  }
316
- const convergenceDecision = await runConvergencePassController({
317
- spec,
318
- state,
319
- tasksById,
358
+ state.finishedAt = new Date().toISOString();
359
+ const runDirBeforeTransfer = runDir;
360
+ if (pausedByNodeId) {
361
+ state.status = "paused";
362
+ await persistState();
363
+ await notifyRunObserver(input.observer, "onRunFinish", state);
364
+ runDir = await moveToPausedRunDir(runDir, pausedRunDir);
365
+ }
366
+ else {
367
+ finalizeTerminalRunStatus(state, spec.tasks.length);
368
+ await persistState();
369
+ await notifyRunObserver(input.observer, "onRunFinish", state);
370
+ runDir = await moveToCompletedRunDir(runDir, completedRunDir);
371
+ }
372
+ await relocateRunArtifactPaths({
320
373
  runDir,
321
- cwd,
322
- persistState,
374
+ oldRunDir: runDirBeforeTransfer,
375
+ nodes: state.nodes,
323
376
  });
324
- if (convergenceDecision.pausedByNodeId) {
325
- pausedByNodeId = convergenceDecision.pausedByNodeId;
326
- break;
327
- }
328
- if (convergenceDecision.retry) {
329
- continue;
377
+ if (state.convergence) {
378
+ relocateConvergenceArtifactPaths(state.convergence, runDirBeforeTransfer, runDir);
330
379
  }
331
- break;
332
- }
333
- state.finishedAt = new Date().toISOString();
334
- const runDirBeforeTransfer = runDir;
335
- if (pausedByNodeId) {
336
- state.status = "paused";
337
- await persistState();
338
- await notifyRunObserver(input.observer, "onRunFinish", state);
339
- runDir = await moveToPausedRunDir(runDir, pausedRunDir);
340
- }
341
- else {
342
- finalizeTerminalRunStatus(state, spec.tasks.length);
343
- await persistState();
344
- await notifyRunObserver(input.observer, "onRunFinish", state);
345
- runDir = await moveToCompletedRunDir(runDir, completedRunDir);
380
+ await persistState({ allowCompletedFactsWrite: true });
381
+ return {
382
+ title: spec.title,
383
+ runId: state.runId,
384
+ status: state.status,
385
+ ranks,
386
+ nodes: state.nodes,
387
+ runDir,
388
+ };
346
389
  }
347
- await relocateRunArtifactPaths({
348
- runDir,
349
- oldRunDir: runDirBeforeTransfer,
350
- nodes: state.nodes,
351
- });
352
- if (state.convergence) {
353
- relocateConvergenceArtifactPaths(state.convergence, runDirBeforeTransfer, runDir);
390
+ finally {
391
+ clearInterval(heartbeatTimer);
354
392
  }
355
- await persistState({ allowCompletedFactsWrite: true });
356
- return {
357
- title: spec.title,
358
- runId: state.runId,
359
- status: state.status,
360
- ranks,
361
- nodes: state.nodes,
362
- runDir,
363
- };
364
393
  }
365
394
  async function notifyRunObserver(observer, event, state) {
366
395
  try {
@@ -234,9 +234,12 @@ export const dagExecutorModelsSchema = z
234
234
  pi: dagModelsSchema.optional(),
235
235
  })
236
236
  .partial();
237
+ export const dagOutputLanguageSchema = z.enum(["zh-CN", "en"]);
238
+ export const DEFAULT_DAG_OUTPUT_LANGUAGE = "zh-CN";
237
239
  export const dagSpecSchema = z.object({
238
240
  version: dagVersionSchema,
239
241
  title: z.string().min(1),
242
+ outputLanguage: dagOutputLanguageSchema.optional(),
240
243
  objective: z.string().optional(),
241
244
  successCriteria: z.array(z.string()).optional(),
242
245
  globalConstraints: z.array(z.string()).optional(),
package/docs/README.md CHANGED
@@ -12,6 +12,14 @@
12
12
  - `verification-matrix.md` — 验证命令选择
13
13
  - `production-readiness.md` — Production Readiness v0.1 范围、证据与 DAG hardening 标准
14
14
  - `loop-agent-harness.md` — runtime 与 command surface 概览
15
+ - `exec-plans/completed/2026-07-11-m2-01-feature-review-model.md` — 第二月 Feature read model 与 `feature review` 已完成实施合同
16
+ - `exec-plans/completed/2026-07-12-m2-02-feature-run-orchestration.md` — 第二月 Feature run 薄编排已完成实施合同
17
+ - `exec-plans/completed/2026-07-12-m2-03-follow-up-tracer-bullet.md` — 第二月 ProductBug Follow-up tracer bullet 已完成合同
18
+ - `exec-plans/completed/2026-07-12-m2-04-follow-up-hardening.md` — 第二月 Follow-up 全分类与事务故障注入已完成合同
19
+ - `exec-plans/completed/2026-07-12-m2-05-git-transaction.md` — 第二月显式授权 Git checkpoint 与失败恢复已完成合同
20
+ - `exec-plans/completed/2026-07-12-m2-06-delivery-closeout-preview.md` — 第二月 Delivery、Acceptance Coverage 与 Closeout preview 已完成合同
21
+ - `exec-plans/completed/2026-07-12-m2-07-feature-decision-metrics.md` — 第二月 Feature 决策体验与 metrics 已完成合同
22
+ - `exec-plans/completed/2026-07-12-m2-08-closeout-dogfood-release.md` — 第二月 Closeout apply、真实 dogfood 与发布证据已完成合同
15
23
  - `agent-dag-runner.md` — Agent DAG runner 指南
16
24
  - `cursor-executor-usage.md` — Cursor executor 用法
17
25
  - `dynamic-workflow-dag-engine-roadmap.md` — Dynamic Workflow DAG Engine 路线图与适配分析
@@ -37,6 +45,19 @@
37
45
  - `reports/2026-07-11-round3-worker-expansion.md` — Round 3 Worker 扩量、0.7.4 FE green、QA review blocker 与第二轮 owner decision
38
46
  - `reports/2026-07-11-observe-dag-visualization.md` — Observe DAG edges、SVG 图形化、交互与真实 Chrome smoke 验证证据
39
47
  - `reports/2026-07-11-0.7.5-init-evolution-review.md` — 0.7.5 package/version 变化对目标项目初始化 surface 的影响审查
48
+ - `reports/2026-07-11-command-performance-audit.md` — 命令并发、验证、Observe 和子进程输出的性能审计
49
+ - `reports/2026-07-11-command-performance-followups.md` — Observe 快照复用、输出缓冲和 reference index 遍历优化的验证记录
50
+ - `reports/2026-07-11-observe-terminal-dag-kpi.md` — 终态 DAG 被误计为活跃数的修复记录
51
+ - `reports/2026-07-12-observe-warm-console-redesign.md` — 暖白运行控制台视觉重构与桌面验证记录
52
+ - `reports/2026-07-12-dag-state-reconciliation.md` — DAG 实际状态判定、安全收口命令与历史失联运行处理记录
53
+ - `reports/2026-07-12-dag-state-reconciliation-init-evolution-review.md` — DAG 状态收口能力对初始化 surface 的影响审查
54
+ - `reports/2026-07-12-observe-dag-node-model.md` — Dashboard DAG 节点模型显示与历史运行兼容修复记录
55
+ - `reports/2026-07-12-observe-dag-node-model-init-evolution-review.md` — 节点模型持久化与 Observe 投影对初始化 surface 的影响审查
56
+ - `reports/2026-07-12-dag-output-language.md` — Agent DAG 默认中文输出与可配置语言规则实现记录
57
+ - `reports/2026-07-12-dag-output-language-init-evolution-review.md` — DAG 输出语言配置对初始化 surface 的影响审查
58
+ - `reports/2026-07-12-init-evolution-strict-report-range.md` — 严格 init 演化校验拒绝无关历史报告的修复与验证证据
59
+ - `reports/2026-07-12-dag-liveness-recovery.md` — DAG runner 心跳、孤儿运行诊断与 Observe 活跃筛选的修复记录
60
+ - `reports/2026-07-12-dag-liveness-init-evolution-review.md` — DAG 活性元数据对初始化投影和旧项目兼容性的审查
40
61
  - `decisions/README.md` — 架构决策
41
62
  - `skills/README.md` — repo-local skill registry and vetting notes
42
63
  - `templates/` — 可复用的规划、报告与 DAG 模板
@@ -15,7 +15,7 @@ product_line_failure_category
15
15
  recommended_follow_up
16
16
  ```
17
17
 
18
- Product-line taxonomy 定义见 `design/state-and-failure-taxonomy.md`。
18
+ Product-line taxonomy 定义见 `docs/design/state-and-failure-taxonomy.md`。
19
19
 
20
20
  **非目标(本 playbook 不覆盖、runner 不实现):**
21
21
 
@@ -77,8 +77,9 @@ Governance (scripts/check-*.sh, src/governance/)
77
77
  ### Infrastructure / Store
78
78
 
79
79
  - **位置**:`src/infrastructure/harness/**`(按计划逐步引入);过渡期部分逻辑仍在 `src/workflows/dag/lifecycle.ts`、`src/records/**`。
80
- - **职责**:`.harness/tasks`、`.harness/dag-runs`、`.harness/runs`、loop state 的集中读写;completed run facts 只读约束。
81
- - **禁止**:把 raw path mutation 扩散给 runner、loop action command handler
80
+ - **职责**:`.harness/tasks`、`.harness/dag-runs`、`.harness/runs`、loop state 的集中读写;completed run facts 只读约束。
81
+ - **DAG recovery mutation**:`dag reconcile-run` 是显式 operator 边界;默认仅检查,只有给出 action + reason 且 runner 已证明停止时才能保存原始快照、写 terminal reconciliation facts 并迁移 lifecycleObserve、status 和 doctor 始终只读。
82
+ - **禁止**:把 raw path mutation 扩散给 runner、loop action 或 command handler。
82
83
 
83
84
  ### Governance
84
85
 
@@ -4,18 +4,24 @@
4
4
 
5
5
  ## 文档
6
6
 
7
- | 文档 | 用途 |
8
- |---|---|
9
- | `产品线共享知识库.md` | 产品线文档仓库作为上游事实源 |
7
+ | 文档 | 用途 |
8
+ |---|---|
9
+ | `DESIGN-cursor.md` | Observe 暖白运行控制台采用的 Cursor 风格视觉参考与设计 token |
10
+ | `DESIGN-lovable.md` | Lovable 风格的暖色视觉系统参考 |
11
+ | `产品线共享知识库.md` | 产品线文档仓库作为上游事实源 |
10
12
  | `研发模式.md` | 10 个工作日 Feature 团队工作流 |
11
- | `1个月规划.md` | 首月落地计划 |
12
- | `1月wbs.md` | 首月 WBS 与分工 |
13
13
  | `六个月规划.md` | 六个月路线图与目标架构 |
14
14
  | `taskspec-to-loop-agent-mapping.md` | 将产品线 TaskSpec 适配为 `loop-agent` task 的契约 |
15
15
  | `state-and-failure-taxonomy.md` | 文档、Task Pool、DAG、Loop 共用的 canonical status 与 failure taxonomy |
16
- | `observe-ui.md` | 已实现的 agent-worker 本地只读可观测 UI(事件流 / SSE / stale 诊断)设计、事件契约与验收边界 |
17
- | `observe-ui-optimization.md` | 2026-07-10:**已实现** Observe UI 中文化、DAG-first 总览、进行中 DAG 置顶、read-model enrichment、Pi `session-events.jsonl` 落盘与过程时间线(UI-1~UI-9) |
16
+ | `archive/2026-07-07-agent-worker-plan.md` | 已归档:Worker 落地计划(基线 0.3.0,M1-M7 物化/调用/Task Pool/batch/morning report 路线图;已随 0.8.0 发布实现于 `src/worker/`) |
17
+ | `archive/2026-07-07-taskspec-plan.md` | 已归档:TaskSpec v0.1 schema 设计(基线 0.3.0,TaskSpec/AcceptanceSpec/TaskGraphSpec schema materialize 规则;已实现于 `src/worker/task-spec/`) |
18
18
  | `archive/2026-07-10-下一阶段任务-功能开发完成.md` | 已归档:真实样本、失败硬化与 QA 闭环的功能性开发完成记录 |
19
+ | `archive/2026-07-10-observe-ui.md` | 已归档:agent-worker 本地只读可观测 UI v0 设计(事件流 / SSE / stale 诊断、事件契约与验收边界;OBS-001~010 已完成,0.9.0 暖白重设计在其上演进) |
20
+ | `archive/2026-07-10-observe-ui-optimization.md` | 已归档:Observe UI 中文化、DAG-first 总览、进行中 DAG 置顶、read-model enrichment、Pi `session-events.jsonl` 落盘与过程时间线(UI-1~UI-9 已实现) |
21
+ | `archive/2026-07-10-observe-ui-goal.md` | 已归档:OBS-001~010 逐任务进度看板(全部 ✅ done) |
22
+ | `archive/2026-07-11-第一月规划.md` | 已归档:首月落地计划(0.8.0 发布 + Round 1/2/3 累计 20 runs / 10 success / 50% / 两次 owner morning decision,第一个月闭环目标全部达成) |
23
+ | `archive/2026-07-11-第一月wbs.md` | 已归档:首月 WBS 与分工(与第一月规划配套,任务编号与估算为历史记录) |
24
+ | `archive/2026-07-12-第二月规划.md` | 已归档:第二月本地 Feature 交付闭环计划(M2-01~08 全部完成;F-2026-002 完整 Closeout、F-2026-003 真实失败恢复闭环、月末硬指标全达成;完成审计见 `docs/reports/2026-07-12-m2-completion-audit.md`) |
19
25
 
20
26
  ## 命名约定(2026-07-09 起)
21
27
 
@@ -6,6 +6,6 @@
6
6
 
7
7
  当前 active execution plan:
8
8
 
9
- - `2026-07-10-release-0.6.0-nightly-drill.md` — 技术演练已完成;等待 0.6.0 发布 owner 对 Day-1 provisional remediation 作明确 ratify / revise / reject
9
+ - `2026-07-12-observe-warm-console-redesign.md` — 以暖白、细边界和高密度信息架构重构 Observe Dashboard
10
10
 
11
- - 已归档:`../completed/2026-07-11-observe-dag-visualization.md`、`../completed/2026-07-11-round-2-interactive-ui-productization.md`、`../completed/2026-07-11-interactive-ui-writer-routing.md`、`../completed/2026-07-10-harness-json-schema.md`、`../completed/2026-07-10-next-stage-worker-evidence.md` 及更早计划。
11
+ - 已归档:第二月 M2-01~M2-08、`../completed/2026-07-11-observe-dashboard-page-system.md`、`../completed/2026-07-11-observe-dashboard-detail-refinement.md`、`../completed/2026-07-11-observe-terminal-dag-kpi.md`、`../completed/2026-07-11-observe-polling-efficiency.md`、`../completed/2026-07-11-command-performance-guardrails.md` 及更早计划。
@@ -4,10 +4,25 @@
4
4
 
5
5
  npm 包携带本 README 作为目录契约。具体 completed plan 属于目标仓库历史,不从 loop-agent 源码历史复制。
6
6
 
7
+ - [`2026-07-11-m2-01-feature-review-model.md`](2026-07-11-m2-01-feature-review-model.md) — 第二月首个纵向切片:严格派生 Feature 状态、AC/Delivery/Closeout 证据与只读 `feature review`
8
+ - [`2026-07-12-m2-02-feature-run-orchestration.md`](2026-07-12-m2-02-feature-run-orchestration.md) — Feature 级 dry-run 与复用现有 Worker pipeline 的薄编排入口
9
+ - [`2026-07-12-m2-03-follow-up-tracer-bullet.md`](2026-07-12-m2-03-follow-up-tracer-bullet.md) — ProductBug 失败到人工批准 FIX、依赖重连、Ready 与 verified lineage 的纵向闭环
10
+ - [`2026-07-12-m2-04-follow-up-hardening.md`](2026-07-12-m2-04-follow-up-hardening.md) — 全 failure-category ActionCard/TaskDraft、EnvFailure 阈值、supersede 与审批事务故障回滚
11
+ - [`2026-07-12-m2-05-git-transaction.md`](2026-07-12-m2-05-git-transaction.md) — Feature branch checkpoint、失败证据/恢复、ignored 隔离与事务完整性
12
+ - [`2026-07-12-m2-06-delivery-closeout-preview.md`](2026-07-12-m2-06-delivery-closeout-preview.md) — Delivery Package、canonical AC evidence 与只读 Closeout gates
13
+ - [`2026-07-12-m2-07-feature-decision-metrics.md`](2026-07-12-m2-07-feature-decision-metrics.md) — 共享 Feature Decision Summary、Observe 层级、corruption 降级与月度 metrics
14
+ - [`2026-07-12-m2-08-closeout-dogfood-release.md`](2026-07-12-m2-08-closeout-dogfood-release.md) — Closeout apply、第二真实 Feature、真实 Follow-up 恢复、package/init/browser 与月度收口证据
15
+ - [`2026-07-11-observe-dashboard-page-system.md`](2026-07-11-observe-dashboard-page-system.md) — 完成 Observe 全页面信息层级与桌面布局优化,按用户确认收口归档。
16
+ - [`2026-07-11-observe-dashboard-detail-refinement.md`](2026-07-11-observe-dashboard-detail-refinement.md) — 完成 DAG 详情输出、依赖图与执行过程的轮询状态保持和桌面节点布局优化,按用户确认收口归档。
17
+ - [`2026-07-11-observe-terminal-dag-kpi.md`](2026-07-11-observe-terminal-dag-kpi.md) — 修复终态 DAG 因遗留未执行节点被误计为活跃的问题。
18
+ - [`2026-07-11-observe-polling-efficiency.md`](2026-07-11-observe-polling-efficiency.md) — 完成详情页终态停轮询、非重叠调度和后台降频。
19
+ - [`2026-07-11-command-performance-guardrails.md`](2026-07-11-command-performance-guardrails.md) — 完成命令并发参数、串行验证与 Observe SSE 的资源峰值护栏。
20
+ - [`2026-07-11-command-performance-followups.md`](2026-07-11-command-performance-followups.md) — 完成 Observe 快照复用、命令输出有界缓冲和 reference index 遍历优化。
7
21
  - [`2026-07-02-loop-agent-subject-restructure.md`](2026-07-02-loop-agent-subject-restructure.md) — 将原 `tools/code-agent` runtime 提升到仓库根、重命名为 `loop-agent`,移除旧 memory plugin 产品线
8
22
  - [`2026-07-04-remove-level1-fallback.md`](2026-07-04-remove-level1-fallback.md) — 移除历史顺序 Level 1 fallback,runtime、文档与 command surface 收敛到 DAG 执行
9
23
  - [`2026-07-04-runtime-boundary-remediation.md`](2026-07-04-runtime-boundary-remediation.md) — 整合 CLI/skill/runtime 边界,抽出 DAG/Loop runtime seam,集中 harness store/guard 策略
10
24
  - [`2026-07-10-next-stage-worker-evidence.md`](2026-07-10-next-stage-worker-evidence.md) — Worker retry、EnvFailure、边界治理、初始化投影与真实 BE/FE/QA dogfood evidence 闭环
25
+ - [`2026-07-10-release-0.6.0-nightly-drill.md`](2026-07-10-release-0.6.0-nightly-drill.md) — 发布 0.6.0、首轮夜间演练(6 worker runs / 3 success)、Observe 过程时间线验证;C6 owner gate 由 Round 3 morning decision 满足后正式关闭
11
26
  - [`2026-07-10-harness-json-schema.md`](2026-07-10-harness-json-schema.md) — 新增 `harness.json` IDE JSON Schema、初始化投影、旧项目 update 修复和漂移防护
12
27
  - [`2026-07-11-interactive-ui-writer-routing.md`](2026-07-11-interactive-ui-writer-routing.md) — 新增 interactive-ui writer-only HIGH 路由、UI 交付契约、真实 React dogfood fixture 与 Round-2 A/B/C 实验入口
13
28
  - [`2026-07-11-round-2-interactive-ui-productization.md`](2026-07-11-round-2-interactive-ui-productization.md) — 完成 owner gate、0.7.0–0.7.4 发布、React A/B/C、20 个 Worker runs、外部 nightly、产品线模板与 docs CI
@@ -33,15 +33,58 @@ npm 包包含运行与说明 harness 所需的静态能力资产:`bin/`、`dis
33
33
 
34
34
  `loop-agent init --profile full --merge` 会把 schema 投影到目标项目,并在生成的 `harness.json` 写入与 `governanceRoot` 匹配的 `$schema`。旧初始化项目可通过 `loop-agent init check-update` 查看缺失项,并用 `loop-agent init update --apply-safe` 安全补齐 schema 文件和 `$schema` 引用;该安全更新只允许修改 `$schema`,不会重写用户已有 harness 配置。
35
35
 
36
+ DAG run state 会记录 runner PID、hostname 和定期 heartbeat,并为节点记录最近活动时间。`loop-agent dag status` 和 `loop-agent dag doctor --run-id <run-id> --markdown` 会将同主机且 PID 已消失的运行识别为 `orphaned`,将进程仍在但 heartbeat 过期的运行识别为 `stale`,将 runner 存活但当前节点超过 5 分钟没有状态活动标记为 `node-quiet`;跨主机运行只标记为 `unknown-host`,不会据此判断远端进程死亡。Observe 使用同一组字段过滤活跃 DAG,并在详情中显示 lifecycle 与 liveness;`node-quiet` 仍视为活跃,只提示操作者检查 session events 和 executor logs。
37
+
38
+ Observe 和 `dag status` 还会给出 `effectiveStatus`、`stateConsistent` 与 `recoveryEligibility`。主状态以 lifecycle + canonical status + liveness 的综合判定为准,原始 `state.status` 只作为诊断事实展示。遇到历史 `paused/` 目录仍记录 `status=running`、或 active runner 已明确 `orphaned` 时,先运行只读检查:
39
+
40
+ ```bash
41
+ loop-agent dag reconcile-run --run-id <run-id>
42
+ ```
43
+
44
+ 确认不应继续后,必须显式选择收口含义并填写原因:
45
+
46
+ ```bash
47
+ loop-agent dag reconcile-run --run-id <run-id> --action supersede --reason "implementation completed elsewhere"
48
+ loop-agent dag reconcile-run --run-id <run-id> --action abandon --reason "operator cancelled obsolete work"
49
+ ```
50
+
51
+ 收口会保存 `reconciliation.json` 原始快照,将仍为 RUNNING 的节点标为 ERROR,并把 run 归档到 `completed/`;不会把未执行节点伪造成成功。同机 runner 仍存活、仅 `node-quiet`、heartbeat stale 但 PID 仍存在、跨主机或无法证明停止时都会拒绝收口。
52
+
53
+ DAG 节点的模型由 `executorModels[executor][complexity]` 路由。新 run 会将解析后的 Pi/Cursor 模型写入节点 state;Observe 读取历史 run 时会从 `run.json` 补算缺失模型。Shell 和 Static 节点不使用模型,因此模型列保持 `-`。
54
+
55
+ DAG agent 节点的输出语言由 `harness.json.workflowPolicy.dag.outputLanguage` 控制,支持 `zh-CN` 和 `en`。未配置时默认 `zh-CN`;`dag run-task` 会把配置写入生成的 DagSpec,手写 DagSpec 缺少该字段时 prompt envelope 同样默认中文。语言规则只约束说明、分析、报告、总结和文档正文,不翻译代码、命令、路径、标识符、JSON 字段、VERDICT 行及其他精确协议字面量。
56
+
36
57
  ## Command Surface
37
58
 
38
59
  - `new-task`、`status`、`inspect`、`doctor`
39
- - `dag run-task`、`dag validate`、`run-dag`、`dag report`、`dag resume`
60
+ - `dag run-task`、`dag validate`、`run-dag`、`dag report`、`dag resume`、`dag reconcile-run`
40
61
  - `delegate`、`harvest`、`promote-run`、`closeout`
41
62
  - `loop init`、`loop run`、`loop status`、`loop closeout`
42
63
  - `pi-prompt`、`cursor-prompt`
43
64
  - `docs audit`、`handoff check`、`spine audit`、`knowledge curate`
44
- - `agent-worker task validate|explain-profile|retry`、`agent-worker batch run-ready`、`agent-worker report morning`、`agent-worker observe serve|snapshot`
65
+ - `agent-worker feature review|run|verify-final|delivery|closeout|approve-followup`、`agent-worker task validate|explain-profile|retry|draft-followup`、`agent-worker batch run-ready`、`agent-worker report morning|metrics`、`agent-worker observe serve|snapshot`
66
+
67
+ ## Feature Review
68
+
69
+ `agent-worker feature review --feature-dir <feature-dir> --repo <target-repo>` 是只读的 Feature 级决策入口。它复用 Feature Packet validation、task graph 和 `.harness/task-pool/` 事实,派生 `Draft`、`Ready`、`Running`、`NeedsAction`、`AwaitingQA`、`Deliverable`、`Closed`,同时展示 required AC 覆盖、阻塞、证据和唯一主行动。
70
+
71
+ 默认输出按结果、原因、下一步、证据组织;`--json` 输出 schemaVersion 1 JSON。缺失或损坏的 Packet、state、JSONL 或 closeout 会暴露 validation error / projection warning,不会被误判为无数据、可交付或已关闭。该命令不写 Feature Packet、Task Pool 或 Git。
72
+
73
+ `agent-worker feature run --feature-dir <feature-dir> --repo <target-repo>` 是薄编排入口:先执行 Feature validation 和一次目标仓库 preflight,再复用 `runReadyTasks()` 推进 Ready Task,最后刷新 morning report、`.harness/task-pool/observability/snapshot.json` 与 Feature review。`--dry-run` 只读取 Packet/Task Pool 并列出 Ready IDs、步骤和预期产物。默认无 Git 授权时单次最多执行一个 Ready 写任务;checkpoint 模式可按 `--limit` 串行推进,并在每个 Task 后建立 clean boundary。
74
+
75
+ `agent-worker feature verify-final` 在 clean Delivery HEAD 上以已完成的 `qa-execute` TaskSpec 运行独立最终 DAG,跳过 promotion/task closeout,避免 repo write 或 HEAD 移动,并原子生成 canonical QA aggregate 与 HEAD-bound final verification。`agent-worker feature delivery` 从同一 Git transaction 和 Task Pool facts 生成带 hash 的 manifest、Acceptance Coverage 与稳定 `PR.md`,拒绝 dirty/wrong branch、历史或 trailer 漂移、缺失 run/QA/final verification 和 required AC 缺口。`agent-worker feature closeout` 默认只读预览 gates;显式 `--apply --owner` 才原子写回 Closeout,并在 stale facts、写入或 post-validation 失败时恢复原状态。
76
+
77
+ Morning report 顶部和 Observe 首页直接消费共享 Feature read model,固定从 Status、Next Action、Why、Evidence 开始。`agent-worker report metrics --month YYYY-MM` 写入 `.harness/task-pool/artifacts/metrics/monthly-YYYY-MM.json|md`,每项指标保留分母、样本量、窗口和 missingData。
78
+
79
+ 显式 `--git-mode checkpoint` 会在 clean preflight 后创建或复用受 transaction record 管理的 `agent/<feature-id>` 本地分支。成功任务只有在 changed/untracked/sensitive 与 TaskSpec allowed/forbidden audit 通过后才 commit;失败任务的 patch、inventory、untracked content 与 boundary audit 写入 `.harness/task-pool/artifacts/features/<feature-id>/git/failures/`,随后 reset/clean 到最近 checkpoint 并再次验证 clean。默认模式不触碰 Git;`--keep-failed-diff` 只保留现场并停止,不允许继续下一个写任务。任何模式都不授权 stash、push、remote PR 或 merge。
80
+
81
+ 业务 Task 失败不会跳过报告与最终 review,但命令返回 `needs-action` 和非零退出码;`noReadyReason` 用于区分 Closed、Deliverable、AwaitingQA、NeedsAction、dependency blocked 与 empty。
82
+
83
+ ## Follow-up 决策与批准
84
+
85
+ `agent-worker task draft-followup <task-id> --worker-run-id <id> --feature-dir <feature-dir> --repo <target-repo>` 从失败 run、TaskSpec 和 task graph 生成 `FU-<parent>-NN` 决策产物。ProductBug/TestBug/FlakyTest/DependencyFailure 生成可批准 TaskDraft;连续两次 EnvFailure 生成 `ENV-CHECK-*`,单次只建议 retry;SpecUnclear/ContractMismatch/RiskyChange/NeedsHuman/Unknown 生成人工行动卡。产物与 evidence/index 位于 `.harness/task-pool/artifacts/features/<feature-id>/follow-ups/`;生成过程受 Feature lock 和 dedupe key 保护,不写 Feature Packet、Ready state 或原失败事实。新 run 会 supersede 同 parent 的旧 unresolved 产物,但不会删除历史。
86
+
87
+ 人工批准只接受 TaskDraft;行动卡不能批准或进入 Ready。批准会校验 draft/evidence hash、repo/path containment、Feature baseline 和冲突,在 staging validation 后写 TaskSpec、graph、Ready、approval/index 与 event。rename、state、approval、index、event 五个故障点均有注入回滚测试;重复批准幂等复用首次结果。`--dry-run` 零写入,`--json` 失败保持 stdout JSON、stderr 无噪声和非零退出码。
45
88
 
46
89
  ## Worker Retry
47
90
 
@@ -1,3 +1,5 @@
1
1
  # 进度日志
2
2
 
3
3
  本目录存放应超越聊天上下文的简洁 handoff 日志。
4
+
5
+ - [`2026-07-11-m2-feature-delivery-loop.md`](2026-07-11-m2-feature-delivery-loop.md) — 第二月 Feature 交付闭环分阶段进度与剩余硬验收
@@ -2,8 +2,21 @@
2
2
 
3
3
  本目录存放验证、审计、benchmark 与 closeout 报告。
4
4
 
5
+ - [`2026-07-12-m2-completion-audit.md`](2026-07-12-m2-completion-audit.md) — 对第二月规划完成定义、P0、硬指标、非目标与最终门禁的逐项审计
6
+ - [`2026-07-12-m2-08-dogfood-release-evidence.md`](2026-07-12-m2-08-dogfood-release-evidence.md) — 第二个真实 Feature Closeout、真实 Follow-up 恢复、metrics、package/init 与 Observe 浏览器证据
7
+ - [`2026-07-12-m2-08-init-evolution-review.md`](2026-07-12-m2-08-init-evolution-review.md) — M2-08 命令/包能力与空 Feature init 脚本修复的初始化影响审查
5
8
  - [`2026-07-12-production-readiness-hardening.md`](2026-07-12-production-readiness-hardening.md)
9
+ - [`2026-07-11-m2-01-init-evolution-review.md`](2026-07-11-m2-01-init-evolution-review.md) — Feature review 命令对 init/package surface 的影响审查
10
+ - [`2026-07-12-m2-02-init-evolution-review.md`](2026-07-12-m2-02-init-evolution-review.md) — Feature run 命令对 init/package surface 的影响审查
11
+ - [`2026-07-12-m2-03-init-evolution-review.md`](2026-07-12-m2-03-init-evolution-review.md) — ProductBug Follow-up 命令对 init/package surface 的影响审查
12
+ - [`2026-07-12-m2-04-init-evolution-review.md`](2026-07-12-m2-04-init-evolution-review.md) — Follow-up 全分类与事务 hardening 对 init/package surface 的影响审查
13
+ - [`2026-07-12-m2-05-init-evolution-review.md`](2026-07-12-m2-05-init-evolution-review.md) — Feature Git checkpoint runtime 对 init/package surface 的影响审查
14
+ - [`2026-07-12-m2-06-init-evolution-review.md`](2026-07-12-m2-06-init-evolution-review.md) — Delivery / Acceptance Coverage / Closeout preview 对 init/package surface 的影响审查
15
+ - [`2026-07-12-m2-07-init-evolution-review.md`](2026-07-12-m2-07-init-evolution-review.md) — Feature Decision Summary、Observe 与 metrics 对 init/package surface 的影响审查
6
16
  - [`2026-07-10-next-stage-dogfood-runs.md`](2026-07-10-next-stage-dogfood-runs.md) — 发布控制器下的 BE/FE/QA Worker 样本、retry 与 Observe 证据
7
17
  - [`2026-07-10-init-evolution-review.md`](2026-07-10-init-evolution-review.md) — Worker 初始化投影演进审查
8
18
  - [`2026-07-10-session-events-dogfood.md`](2026-07-10-session-events-dogfood.md) — Pi SDK DAG 新 run 产生非空 `session-events.jsonl` 与 Observe 过程时间线 API 证据
19
+ - [`2026-07-11-command-performance-followups.md`](2026-07-11-command-performance-followups.md) — Observe 快照复用、输出缓冲和 reference index 遍历优化的验证记录
20
+ - [`2026-07-11-observe-terminal-dag-kpi.md`](2026-07-11-observe-terminal-dag-kpi.md) — 终态 DAG 被误计为活跃数的修复记录
21
+ - [`2026-07-12-observe-warm-console-redesign.md`](2026-07-12-observe-warm-console-redesign.md) — 暖白运行控制台视觉重构与桌面验证记录
9
22
  - [`2026-07-02-repository-analysis.md`](2026-07-02-repository-analysis.md) — 仓库能力基线分析(2026-07-10 再采样:0.5.0 + Observe UI 优化 UI-1~UI-9 / Unreleased)
@@ -400,9 +400,11 @@
400
400
  "pending",
401
401
  "running",
402
402
  "finished",
403
- "partial_failed",
404
- "failed",
405
- "paused"
403
+ "partial_failed",
404
+ "failed",
405
+ "paused",
406
+ "superseded",
407
+ "abandoned"
406
408
  ]
407
409
  },
408
410
  "runDir": { "type": "string", "minLength": 1 },
@@ -56,8 +56,13 @@
56
56
  "dag": {
57
57
  "type": "object",
58
58
  "additionalProperties": false,
59
- "properties": {
60
- "defaultEntry": {
59
+ "properties": {
60
+ "outputLanguage": {
61
+ "enum": ["zh-CN", "en"],
62
+ "description": "DAG agent 节点的默认输出语言。未配置时使用简体中文;代码、命令和机器契约不翻译。",
63
+ "default": "zh-CN"
64
+ },
65
+ "defaultEntry": {
61
66
  "enum": ["dag run-task", "run-dag"],
62
67
  "description": "默认 DAG 入口,用于任务 DAG 生成或直接 DAG 执行。",
63
68
  "default": "dag run-task"
@@ -1,8 +1,10 @@
1
1
  # Init Evolution Review
2
2
 
3
3
  Date:
4
- Base:
5
- Head:
4
+ Base: `<full commit SHA or resolvable --base ref>`
5
+ Head: `<full commit SHA for the reviewed HEAD>`
6
+
7
+ `bash scripts/check-init-evolution-needed.sh --strict --base <ref>` 接受 Base 精确匹配该 `<ref>`、Head 为当前 `HEAD` 或其可解析祖先提交的报告。历史报告、`working tree` 等不可解析文字不能为其他变更范围放行严格检查。当 Head 是祖先时,`reportHead..HEAD` 区间内出现新的 `model-review` 高影响路径会使报告失效;仅 `advisory` 或 `surface-check` 的后续变化不影响已完成的高影响审查。
6
8
 
7
9
  ## Changed Surface
8
10
 
@@ -7,6 +7,11 @@
7
7
  | 仅文档或治理 | `bash scripts/check-repo.sh` | `bash scripts/ci.sh` |
8
8
  | TypeScript runtime | `npm run typecheck` | `npm test` |
9
9
  | CLI 行为 | `npm run typecheck` + 定向 Vitest | `npm test` + CLI smoke |
10
+ | Feature reducer/review | `npx vitest run test/worker/feature test/worker/agent-worker-cli.test.ts` | `npm test` + `node bin/agent-worker.js feature review --help` |
11
+ | Feature run orchestration | `npx vitest run test/worker/feature test/worker/runner/run-ready.test.ts test/worker/agent-worker-cli.test.ts` | `npm test` + `node bin/agent-worker.js feature run --help` |
12
+ | Follow-up 分类与事务 | `npx vitest run test/worker/follow-up test/worker/feature test/worker/pool test/worker/report test/worker/agent-worker-cli.test.ts` | `npm test` + `node bin/agent-worker.js task draft-followup --help` + `node bin/agent-worker.js feature approve-followup --help` |
13
+ | Feature Git transaction | `npx vitest run test/worker/delivery test/worker/feature test/worker/runner test/worker/agent-worker-cli.test.ts` | `npm test` + `node bin/agent-worker.js feature run --help` + temporary Git repo smoke |
14
+ | Final verification / Delivery / Closeout | `npx vitest run test/worker/delivery test/worker/closeout test/worker/feature test/worker/agent-worker-cli.test.ts` | `npm test` + verify-final/Delivery/Closeout CLI help + temporary Git repo evidence/hash/tamper/apply rollback smoke |
10
15
  | DAG 工作流 | 定向 DAG 测试 | `npm test` |
11
16
  | Production readiness hardening | `bash scripts/check-repo.sh` + 定向 DAG/CLI 测试 | `bash scripts/ci.sh` + docs build + package smoke |
12
17
  | 脚本或 CI | 运行变更的脚本 | `bash scripts/ci.sh` |
@@ -26,6 +31,8 @@ npm run dev -- --help
26
31
  npm pack --dry-run
27
32
  ```
28
33
 
34
+ 测试资源策略:`npm test` 会先运行可并行的纯测试,再串行运行会启动 CLI、`tsx` 或 Git 子进程的集成测试。纯测试根据 `os.availableParallelism()` 自适应使用 1 至 4 个 Worker;可用 `LOOP_AGENT_FAST_TEST_WORKERS` 在 CI 或受限机器上显式覆盖。传入测试文件时,例如 `npm test -- test/worker/observe/server.test.ts`,仍按常规 Vitest 方式只运行该范围,不会启动两阶段完整测试。
35
+
29
36
  产品线 Feature/Task/QA 文档或 TaskSpec 约束变更还应运行:
30
37
 
31
38
  ```bash
package/harness.json CHANGED
@@ -5,9 +5,10 @@
5
5
  "governanceRoot": "docs",
6
6
  "workflowPolicy": {
7
7
  "defaultImplementationWorkflow": "agent-dag",
8
- "dag": {
9
- "defaultEntry": "dag run-task",
10
- "profileRouting": {
8
+ "dag": {
9
+ "defaultEntry": "dag run-task",
10
+ "outputLanguage": "zh-CN",
11
+ "profileRouting": {
11
12
  "minimal": "standard-dag",
12
13
  "standard": "standard-dag",
13
14
  "reviewed": "review-gated-dag",