@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
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tea-agent/loop-agent",
3
- "version": "0.8.0",
3
+ "version": "0.10.0",
4
4
  "type": "module",
5
5
  "bin": {
6
6
  "loop-agent": "bin/loop-agent.js",
@@ -43,7 +43,9 @@
43
43
  "prepublishOnly": "npm run typecheck && npm test && npm run build",
44
44
  "lint": "tsc --noEmit",
45
45
  "typecheck": "tsc --noEmit",
46
- "test": "vitest run",
46
+ "test": "node scripts/run-tests.mjs",
47
+ "test:fast": "vitest run --config vitest.fast.config.ts",
48
+ "test:integration": "vitest run --config vitest.integration.config.ts",
47
49
  "docs:dev": "npm --prefix website start",
48
50
  "docs:build": "npm --prefix website run build",
49
51
  "docs:serve": "npm --prefix website run serve",
@@ -5,9 +5,13 @@ ROOT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
5
5
  cd "${ROOT_DIR}"
6
6
 
7
7
  feature_dirs=()
8
- while IFS= read -r acceptance; do
9
- feature_dirs+=("$(dirname "$acceptance")")
10
- done < <(find dogfood/features -mindepth 2 -maxdepth 2 -name acceptance.yaml -type f | sort)
8
+ while IFS= read -r feature_dir; do
9
+ if [[ ! -f "${feature_dir}/acceptance.yaml" ]]; then
10
+ echo "product-line docs check failed: incomplete feature packet missing acceptance.yaml: ${feature_dir}" >&2
11
+ exit 1
12
+ fi
13
+ feature_dirs+=("${feature_dir}")
14
+ done < <(find dogfood/features -mindepth 1 -maxdepth 1 -type d | sort)
11
15
 
12
16
  if [[ ${#feature_dirs[@]} -eq 0 ]]; then
13
17
  echo "product-line docs check skipped: no feature packets found"
@@ -21,7 +21,7 @@ scan_paths=(
21
21
  )
22
22
 
23
23
  matches="$(rg -n --path-separator / '[.]task-pool' "${scan_paths[@]}" 2>/dev/null || true)"
24
- matches="$(printf '%s\n' "${matches}" | rg -v '^(README\.md|AGENTS\.md):.*gitignore|^src/commands/init\.ts:.*("[.]task-pool/"|legacy [.]task-pool residue)|^test/init-command\.test\.ts:.*toContain\("[.]task-pool/"\)' || true)"
24
+ matches="$(printf '%s\n' "${matches}" | rg -v '^(README\.md|AGENTS\.md):.*gitignore|^src/commands/init\.ts:.*("[.]task-pool/"|legacy [.]task-pool residue)|^test/init-command\.test\.ts:.*toContain\("[.]task-pool/"\)|^website/docs/reference/cli\.md:.*旧顶层.*[.]task-pool' || true)"
25
25
 
26
26
  if [[ -n "${matches}" ]]; then
27
27
  echo "Task Pool root 检查失败:活跃源码、测试、脚本或用户文档仍引用已废弃的顶层 runtime path:" >&2
@@ -50,6 +50,7 @@ docs/reports/YYYY-MM-DD-init-evolution-review.md
50
50
  报告保持短小,包含:
51
51
 
52
52
  - changed surface
53
+ - 可由 Git 解析的 Base 和 Head commit/ref;严格检查要求 Base 精确匹配所选 `--base`,Head 可以是运行时当前 `HEAD` 或它的一个可解析祖先提交。若 Head 是祖先,则 `reportHead..HEAD` 区间内一旦出现新的 `model-review` 高影响路径就会拒绝该报告;仅有 `advisory` 或 `surface-check` 变化不会让已完成的高影响审查失效。`working tree`、不可解析文字、无关历史报告都不能为其他变更范围放行严格检查。
53
54
  - decision: no init impact / surface check only / init update required
54
55
  - files updated
55
56
  - verification commands and results
@@ -47,6 +47,7 @@ loop-agent doctor
47
47
  loop-agent dag doctor
48
48
  loop-agent dag report --latest --markdown
49
49
  loop-agent dag closeout-draft --run-id <run-id>
50
+ loop-agent dag reconcile-run --run-id <run-id>
50
51
  loop-agent dag reconcile-tasks --glob '<pattern>' --markdown
51
52
  loop-agent dag final-verification <task-id> --output <temp-dir>/<task-id>-final-verification-dag.json
52
53
  loop-agent status <task-id> --json
@@ -246,6 +247,9 @@ loop-agent dag run-task <task-id> --dry-run --cwd <repo-root> # generate + vali
246
247
  loop-agent dag status --run-id <run-id> # 单次 run JSON 摘要(approvalFlow, healthIssues)
247
248
  loop-agent dag doctor # 扫描 active/paused/completed runs;advisoryOnly health report
248
249
  loop-agent dag report [--run-id <run-id>] [--lifecycle active|paused|completed|all] [--json|--markdown] [--failed-only] [--latest] [--paused-latest] [--action <recovery-action>] # derived per-node 聚合(只读);JSON 锁定于 docs/templates/agent-dag-report.schema.json;--paused-latest 聚焦最新 paused run;playbook: docs/agent-dag-recovery-playbook.md
250
+ loop-agent dag reconcile-run --run-id <run-id> # 只读检查 effectiveStatus 与恢复/收口资格
251
+ loop-agent dag reconcile-run --run-id <run-id> --action supersede --reason "..." # 显式保留证据并标记为任务已另行完成
252
+ loop-agent dag reconcile-run --run-id <run-id> --action abandon --reason "..." # 显式保留证据并收口为已放弃
249
253
  loop-agent dag reconcile-tasks --glob '<pattern>' # 仅报告的 task/run/artifact/verify drift audit
250
254
  loop-agent dag final-verification <task-id> # 生成 closeout DAG,closeout artifact 后再 final verify
251
255
  loop-agent dag decision inspect --run-id <run-id> [--node-id <node-id>] # dry-run envelope 重解析;除 run 缺失外 exit 0
@@ -267,6 +271,7 @@ loop-agent dag resume --run-id <run-id> # approve 后继续
267
271
  - 需 operator 关注的 run 用 `dag report --failed-only`、`--latest`、`--action <recovery-action>` 收窄。category→action 映射见 `docs/agent-dag-recovery-playbook.md`。
268
272
  - 只读扫描 `.harness/dag-runs/` 下所有 run 的生命周期 health issue 与建议 action 用 `dag doctor`(`advisoryOnly: true`;不 mutate facts)。
269
273
  - approve/resume 前用 `dag status --run-id <id>` 看单次 lifecycle、`approvalFlow`、`hasHumanApproval`。
274
+ - lifecycle、raw status 与 liveness 冲突时先用 `dag reconcile-run --run-id <id>` 只读检查。只有 runner 已证明停止且 operator 明确给出 `supersede|abandon` 与 reason 时才允许收口;它保存原始 state,不把未执行节点标成成功。
270
275
  - task status、source/artifacts、DAG outcome、verification 记录可能 drift 时用 `dag reconcile-tasks --glob '<pattern>'`。默认仅报告;`--patch` 显式且不能伪造 verification evidence。
271
276
  - 大型 PRD closeout 用 `dag final-verification <task-id>` 生成确定性 DAG,final verification 在 closeout artifact 创建之后。
272
277
  - 从 run facts dry-run envelope 解析用 `dag decision inspect|validate`;`validate` 在无效 envelope 时 exit 1;永不自动 resume/retry。
@@ -379,6 +384,14 @@ loop-agent knowledge curate --markdown --output docs/reports/<task-id>-learned-p
379
384
  agent-worker task validate <task.yaml> # 三层校验 TaskSpec,输出 JSON
380
385
  agent-worker task explain-profile <task.yaml> # 解释业务 type/risk -> DAG governance profile 映射
381
386
  agent-worker task validate-feature <feature-dir> # 校验完整 feature packet 的验收、依赖、TaskSpec 和验证命令
387
+ agent-worker feature review --feature-dir <feature-dir> --repo <repo-root> [--json]
388
+ agent-worker feature run --feature-dir <feature-dir> --repo <repo-root> [--dry-run] [--git-mode checkpoint] [--keep-failed-diff] [--json]
389
+ agent-worker feature verify-final --feature-dir <feature-dir> --repo <repo-root> --task-id <qa-execute-id> [--json]
390
+ agent-worker feature delivery --feature-dir <feature-dir> --repo <repo-root> --qa-evidence <path> --final-verification <path> [--waivers <path>] [--dry-run] [--json]
391
+ agent-worker feature closeout --feature-dir <feature-dir> --repo <repo-root> [--apply --owner <owner>] [--json]
392
+ agent-worker report metrics --repo <repo-root> --month <YYYY-MM> [--json]
393
+ agent-worker task draft-followup <task-id> --worker-run-id <id> --feature-dir <feature-dir> --repo <repo-root> [--json]
394
+ agent-worker feature approve-followup --feature-dir <feature-dir> --followup-id <id> --repo <repo-root> --owner <owner> [--dry-run] [--json]
382
395
  agent-worker task retry <task-id> --repo <repo-root> [--reason "<已修复的原因>"]
383
396
  agent-worker batch run-ready \
384
397
  --feature-dir <feature-dir> \ # 含 tasks/task-graph.yaml
@@ -401,6 +414,14 @@ agent-worker observe snapshot --repo <repo-root> # 输出 GlobalSnapshot JSON
401
414
  - Worker runtime state 落在目标 repo 的 `.harness/task-pool/`(artifacts、JSONL/state、晨报、failure handoffs)。自 0.8.0 起该目录是唯一受支持的 Task Pool runtime root;旧路径不读取、不迁移、不合并、不重映射。
402
415
  - preflight 在 `new-task` 前跑 `loop-agent --version`、`inspect`、`docs-audit`、`git status --short --branch`,可选 `--check-repo`。一次夜间批处理期间不升级控制器,记录实际 `loop-agent` 版本。
403
416
  - `batch run-ready` 默认在 stderr 输出人类可读进度(批次起止、每个 task 的阶段与耗时、report 决策),stdout 只保留最终 JSON,便于管道取用;加 `--quiet` 可关闭进度。
417
+ - `feature review` 只读派生 Feature 状态、required AC 覆盖、阻塞、证据和唯一下一步。默认输出简洁的人类摘要,`--json` 输出 schemaVersion 1 JSON;损坏事实会显式降级,不会写 Feature Packet 或 Task Pool。
418
+ - `feature run` 薄编排 validation、preflight、现有 run-ready、morning report、Observe snapshot 和最终 review。`--dry-run` 零写入;Git checkpoint 可用前单次最多推进一个 Ready 写任务。
419
+ - `feature run` 遇到业务 Task 失败时仍刷新证据,但返回 `needs-action` 和非零退出码;无 Ready 是正常结果,并通过 `noReadyReason` 说明 Closed、Deliverable、AwaitingQA、NeedsAction、依赖阻塞或空 Feature。
420
+ - `feature run --git-mode checkpoint` 是唯一 checkpoint 授权:要求 clean repo,在本地 `agent/<feature-id>` 分支按成功 Task commit;失败先保存 patch/untracked/boundary audit 再恢复 clean。默认不 commit;从不 stash/push/merge/创建远程 PR。`--keep-failed-diff` 会停止 Feature,不继续后续 Task。
421
+ - `feature verify-final` 在 clean Delivery HEAD 上复用已完成的 `qa-execute` TaskSpec 运行独立 DAG,跳过 promotion/closeout,原子生成 canonical QA aggregate 和 HEAD-bound final verification;相同 HEAD 的 canonical 成功 run 可幂等复用。
422
+ - `feature delivery` 复用 transaction record,校验 Git history/trailers/changed files、成功 run、canonical QA/final verification 和 required AC,原子生成 manifest、coverage 与 `PR.md`;`--dry-run` 零写入。`feature closeout` 默认只读复验全部 gates,显式 `--apply --owner` 才原子写回,stale facts 或 post-validation 失败会整体回滚。
423
+ - `report metrics` 按 UTC 月去重投影 Feature/Failure/Follow-up/Delivery/AC/decision/recovery/boundary 指标,同时写 JSON 与 Markdown;每项保留 numerator、denominator、sampleSize 和 missingData。
424
+ - `task draft-followup` 会按全部 failure category 生成 TaskDraft 或人工行动卡:ProductBug/TestBug/FlakyTest/DependencyFailure 可批准;EnvFailure 连续两次后才生成 ENV-CHECK;Spec/Contract/Risk/Human/Unknown 只给行动卡。人工以 `feature approve-followup --dry-run` 预览,再带非空 `--owner` 批准 TaskDraft;行动卡不能批准。批准在 staging validation 后写 TaskSpec、graph、Ready/approval/event,原失败事实不改写,并有 rename/state/approval/index/event 回滚门禁。
404
425
  - `task retry` 是失败 Task 的唯一重试入口。它会保留原有运行记录和 failure handoff,并让下一次 `batch run-ready` 使用新的 `workerRunId`;不要删除运行态文件或手动修改状态来重试。
405
426
  - `observe serve` 是独立于执行过程的本地只读看板,默认监听 `127.0.0.1:8787`;`observe snapshot` 只输出同一份运行态快照 JSON。两者都不会启动、暂停或重试 Task / Worker / DAG。
406
427
  - 当前 Worker 仍是 v0(库 + CLI + dogfood),未接入定时/CI 驱动;`report morning` 只能从已有 Task Pool runs 汇总。
@@ -7,11 +7,12 @@
7
7
  `harness.json.workflowPolicy` 现声明 Agent DAG 为首选 implementation workflow:
8
8
 
9
9
  - `defaultImplementationWorkflow=agent-dag`
10
- - `dag.defaultEntry=dag run-task`
11
- - `dag.profileRouting`:`minimal|standard -> standard-dag`,`reviewed -> review-gated-dag`,`supervised -> supervised-implementation`
10
+ - `dag.defaultEntry=dag run-task`
11
+ - `dag.outputLanguage=zh-CN`;未配置时也默认中文,显式设为 `en` 可切换英文
12
+ - `dag.profileRouting`:`minimal|standard -> standard-dag`,`reviewed -> review-gated-dag`,`supervised -> supervised-implementation`
12
13
  - `humanGatePolicy.defaultMode=record-only`;需求不清、架构/公共契约风险、凭据/费用/部署风险、重复 gate failure 或高风险决策时升级人工介入
13
14
 
14
- 此 policy 驱动 `dag run-task --profile auto`:CLI 仍要求显式 `dag run-task`、`dag validate`、`run-dag`,但 `--profile auto` 在确定性 candidate `governanceProfile` 推断后应用 `workflowPolicy.dag.profileRouting`。`humanGatePolicy` 是默认人机边界声明;真实暂停仍由 DAG 节点的 `decisionGate.mode: "pause-on-human"` 与 decision envelope 触发。无 profile 的 `dag run-task <task-id>` 仍为 standard-compatible,供 legacy/review workflow。
15
+ 此 policy 驱动 `dag run-task --profile auto`:CLI 仍要求显式 `dag run-task`、`dag validate`、`run-dag`,但 `--profile auto` 在确定性 candidate `governanceProfile` 推断后应用 `workflowPolicy.dag.profileRouting`。生成器还会把 `outputLanguage` 写入 DagSpec,runner 在每个 Pi/Cursor 节点 prompt 中注入语言规则;代码、命令、路径、JSON 字段与 gate token 保持原样。`humanGatePolicy` 是默认人机边界声明;真实暂停仍由 DAG 节点的 `decisionGate.mode: "pause-on-human"` 与 decision envelope 触发。无 profile 的 `dag run-task <task-id>` 仍为 standard-compatible,供 legacy/review workflow。
15
16
 
16
17
  ### DAG workflow 层级
17
18
 
@@ -46,7 +46,7 @@ product-line taxonomy 的事实源是 `docs/design/state-and-failure-taxonomy.md
46
46
  ```json
47
47
  {
48
48
  "verifyPreset": "auto",
49
- "verifyMode": "parallel",
49
+ "verifyMode": "serial",
50
50
  "verifyRetryCount": 0,
51
51
  "verifyFailFast": false
52
52
  }
@@ -54,11 +54,16 @@ product-line taxonomy 的事实源是 `docs/design/state-and-failure-taxonomy.md
54
54
 
55
55
  - `verifyPreset`:`auto | quick | standard | full`
56
56
  - `auto`:`small -> quick`,`medium -> standard`,`large -> full`
57
- - 默认 `parallel`
58
- - 命令争抢共享资源时用 `serial`
57
+ - 默认 `serial`,优先避免本机测试、构建和治理检查互相争抢资源
58
+ - 确认命令互不影响且机器资源充足时,才显式使用 `parallel`
59
59
  - `verifyFailFast` 仅在 `serial` mode 有意义
60
60
  - retry 保持小;用于 flaky 环境问题,不要掩盖真实失败
61
61
 
62
+ ### 长输出处理
63
+
64
+ - DAG shell 命令和 Worker 子进程只在内存中保留最近一段 stdout/stderr,并在结果中标明是否截断及原始字节数。
65
+ - 需要完整日志时读取运行 artifact 中的 `stdout.txt`、`stderr.txt` 或 DAG 节点的 `commands/*.stdout.txt`、`commands/*.stderr.txt`;不要依赖页面摘要还原全部输出。
66
+
62
67
  ### Verify 后的 goal completion audit
63
68
  - 有 active task goal 且 `verify` 通过时,loop-agent 跑 goal completion audit。
64
69
  - 若 `source/需求.md` 仍有未勾 checklist(`- [ ]`),task **不会**以 completed 结束。