@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.
- package/AGENTS.md +2 -0
- package/CHANGELOG.md +51 -1
- package/README.md +20 -0
- package/dist/application/dag/args.js +9 -2
- package/dist/cli/command-definitions.js +7 -0
- package/dist/cli/program.js +6 -1
- package/dist/commands/dag-reconcile-run.js +118 -0
- package/dist/commands/init.js +12 -3
- package/dist/executors/shell-executor.js +74 -8
- package/dist/governance/manifest-types.js +4 -0
- package/dist/shared/reference-context.js +48 -22
- package/dist/task/config-types.js +1 -1
- package/dist/task/runtime.js +1 -1
- package/dist/worker/cli.js +216 -0
- package/dist/worker/closeout/apply.js +73 -0
- package/dist/worker/closeout/preview.js +30 -0
- package/dist/worker/delivery/final-verification.js +158 -0
- package/dist/worker/delivery/git-transaction.js +354 -0
- package/dist/worker/delivery/package.js +449 -0
- package/dist/worker/feature/decision-loader.js +68 -0
- package/dist/worker/feature/discover.js +14 -0
- package/dist/worker/feature/next-action.js +74 -0
- package/dist/worker/feature/reducer.js +133 -0
- package/dist/worker/feature/review.js +502 -0
- package/dist/worker/feature/run.js +313 -0
- package/dist/worker/feature/types.js +1 -0
- package/dist/worker/follow-up/approve.js +270 -0
- package/dist/worker/follow-up/factory.js +234 -0
- package/dist/worker/follow-up/paths.js +25 -0
- package/dist/worker/follow-up/policy.js +26 -0
- package/dist/worker/follow-up/schema.js +93 -0
- package/dist/worker/follow-up/store.js +96 -0
- package/dist/worker/loop-agent/loop-agent-client.js +51 -10
- package/dist/worker/metrics/projector.js +139 -0
- package/dist/worker/observability/read-model.js +256 -15
- package/dist/worker/observe/paths.js +17 -5
- package/dist/worker/observe/routes.js +78 -20
- package/dist/worker/observe/server.js +8 -6
- package/dist/worker/observe/static/app.js +1045 -177
- package/dist/worker/observe/static/index.html +70 -43
- package/dist/worker/observe/static/styles.css +553 -610
- package/dist/worker/pool/run-store.js +14 -2
- package/dist/worker/pool/validation.js +59 -0
- package/dist/worker/report/morning-report.js +41 -6
- package/dist/worker/run-task/run-task.js +1 -1
- package/dist/worker/runner/run-ready.js +19 -5
- package/dist/workflows/dag/init-hybrid.js +3 -1
- package/dist/workflows/dag/lifecycle.js +146 -0
- package/dist/workflows/dag/node-execution.js +3 -0
- package/dist/workflows/dag/prompt.js +16 -0
- package/dist/workflows/dag/report.js +2 -0
- package/dist/workflows/dag/runner.js +133 -104
- package/dist/workflows/dag/types.js +3 -0
- package/docs/README.md +21 -0
- package/docs/agent-dag-recovery-playbook.md +1 -1
- package/docs/architecture/runtime-boundaries.md +3 -2
- package/docs/design/README.md +13 -7
- package/docs/exec-plans/active/README.md +2 -2
- package/docs/exec-plans/completed/README.md +15 -0
- package/docs/loop-agent-harness.md +45 -2
- package/docs/progress/README.md +2 -0
- package/docs/reports/README.md +13 -0
- package/docs/templates/agent-dag-report.schema.json +5 -3
- package/docs/templates/harness.schema.json +7 -2
- package/docs/templates/init-evolution-review.md +4 -2
- package/docs/verification-matrix.md +7 -0
- package/harness.json +4 -3
- package/package.json +4 -2
- package/scripts/check-product-line-docs.sh +7 -3
- package/scripts/check-task-pool-root.sh +1 -1
- package/skills/init-capability-evolution/SKILL.md +1 -0
- package/skills/loop-agent/references/command-reference.md +21 -0
- package/skills/loop-agent/references/hybrid-dag.md +4 -3
- 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
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
const
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
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
|
-
|
|
263
|
-
|
|
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
|
-
|
|
266
|
-
tasksById: dynamicInput.tasksById,
|
|
304
|
+
reduction: task.dynamicReduction,
|
|
267
305
|
state: dynamicInput.state,
|
|
306
|
+
runDir: dynamicInput.runDir,
|
|
268
307
|
});
|
|
269
|
-
}
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
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
|
-
|
|
343
|
+
state,
|
|
344
|
+
tasksById,
|
|
305
345
|
runDir,
|
|
306
|
-
|
|
307
|
-
executeDynamicNode,
|
|
308
|
-
observer: input.observer,
|
|
346
|
+
cwd,
|
|
309
347
|
persistState,
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
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
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
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
|
-
|
|
322
|
-
|
|
374
|
+
oldRunDir: runDirBeforeTransfer,
|
|
375
|
+
nodes: state.nodes,
|
|
323
376
|
});
|
|
324
|
-
if (
|
|
325
|
-
|
|
326
|
-
break;
|
|
327
|
-
}
|
|
328
|
-
if (convergenceDecision.retry) {
|
|
329
|
-
continue;
|
|
377
|
+
if (state.convergence) {
|
|
378
|
+
relocateConvergenceArtifactPaths(state.convergence, runDirBeforeTransfer, runDir);
|
|
330
379
|
}
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
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
|
-
|
|
348
|
-
|
|
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 模板
|
|
@@ -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
|
-
-
|
|
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 并迁移 lifecycle。Observe、status 和 doctor 始终只读。
|
|
82
|
+
- **禁止**:把 raw path mutation 扩散给 runner、loop action 或 command handler。
|
|
82
83
|
|
|
83
84
|
### Governance
|
|
84
85
|
|
package/docs/design/README.md
CHANGED
|
@@ -4,18 +4,24 @@
|
|
|
4
4
|
|
|
5
5
|
## 文档
|
|
6
6
|
|
|
7
|
-
| 文档 | 用途 |
|
|
8
|
-
|---|---|
|
|
9
|
-
|
|
|
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
|
-
| `
|
|
17
|
-
| `
|
|
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-
|
|
9
|
+
- `2026-07-12-observe-warm-console-redesign.md` — 以暖白、细边界和高密度信息架构重构 Observe Dashboard。
|
|
10
10
|
|
|
11
|
-
-
|
|
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
|
|
package/docs/progress/README.md
CHANGED
package/docs/reports/README.md
CHANGED
|
@@ -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
|
-
"
|
|
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
|
-
"
|
|
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",
|