@tea-agent/loop-agent 0.24.11-beta.0 → 0.25.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 (84) hide show
  1. package/CHANGELOG.md +28 -5
  2. package/dist/commands/init.js +16 -2
  3. package/dist/executors/dag-pi-executor.js +74 -13
  4. package/dist/executors/pi-executor.js +25 -7
  5. package/dist/executors/pi-prompt-transport.js +198 -0
  6. package/dist/executors/pi-sdk-executor.js +1 -1
  7. package/dist/executors/process-tree.js +33 -0
  8. package/dist/executors/shell-executor.js +332 -24
  9. package/dist/executors/shell-verification.js +4 -2
  10. package/dist/infrastructure/harness/task-store.js +31 -0
  11. package/dist/shared/operator/capabilities.js +6 -0
  12. package/dist/verification/maven/cache.js +142 -0
  13. package/dist/verification/maven/index.js +120 -0
  14. package/dist/verification/maven/plan-commands.js +421 -0
  15. package/dist/verification/maven/pom-static.js +136 -0
  16. package/dist/verification/maven/scope-resolve.js +153 -0
  17. package/dist/verification/maven/stale.js +130 -0
  18. package/dist/verification/maven/types.js +23 -0
  19. package/dist/verification/maven/workspace-graph.js +322 -0
  20. package/dist/worker/cli.js +236 -21
  21. package/dist/worker/delivery/final-verification.js +12 -0
  22. package/dist/worker/delivery/git-transaction.js +32 -7
  23. package/dist/worker/delivery/package.js +9 -5
  24. package/dist/worker/delivery/verification-bundle.js +26 -5
  25. package/dist/worker/feature/advance.js +301 -0
  26. package/dist/worker/feature/doctor.js +223 -0
  27. package/dist/worker/feature/next-action.js +11 -3
  28. package/dist/worker/feature/scaffold.js +798 -0
  29. package/dist/worker/observe/dag-run-artifacts.js +90 -0
  30. package/dist/worker/observe/node-input.js +444 -0
  31. package/dist/worker/observe/routes.js +17 -0
  32. package/dist/worker/observe/static/api.js +9 -0
  33. package/dist/worker/observe/static/constants.js +9 -0
  34. package/dist/worker/observe/static/state.js +14 -0
  35. package/dist/worker/observe/static/styles.css +74 -0
  36. package/dist/worker/observe/static/views/dag-inspector.js +371 -15
  37. package/dist/worker/outcomes/projector.js +5 -1
  38. package/dist/worker/runner/run-ready.js +41 -1
  39. package/dist/workflows/dag/backend-test-markdown-workflow.js +202 -9
  40. package/dist/workflows/dag/backend-test-result-contract.js +103 -0
  41. package/dist/workflows/dag/failure-category.js +5 -1
  42. package/dist/workflows/dag/frontend-implementation-contract.js +4 -0
  43. package/dist/workflows/dag/frontend-prewrite-gate.js +0 -17
  44. package/dist/workflows/dag/frontend-test-result-contract.js +106 -41
  45. package/dist/workflows/dag/init-hybrid.js +220 -32
  46. package/dist/workflows/dag/node-execution.js +3 -2
  47. package/dist/workflows/dag/reconcile-run.js +24 -0
  48. package/dist/workflows/dag/types.js +46 -0
  49. package/dist/workflows/dag/validate.js +19 -2
  50. package/docs/architecture/dag-execution.md +5 -1
  51. package/docs/architecture/runtime-boundaries.md +11 -1
  52. package/docs/architecture/worker-and-feature.md +2 -0
  53. package/docs/templates/backend-test-dag.json +3 -3
  54. package/docs/templates/product-line/README.md +17 -1
  55. package/docs/templates/product-line/feature-scaffold-batch.example.yaml +31 -0
  56. package/docs/templates/product-line/scaffold-samples/README.md +36 -0
  57. package/docs/templates/product-line/scaffold-samples/backend-only/acceptance.yaml +13 -0
  58. package/docs/templates/product-line/scaffold-samples/backend-only/design.md +14 -0
  59. package/docs/templates/product-line/scaffold-samples/backend-only/feature.yaml +3 -0
  60. package/docs/templates/product-line/scaffold-samples/backend-only/requirement.md +6 -0
  61. package/docs/templates/product-line/scaffold-samples/backend-only/tasks/BE-IMPL-001.yaml +83 -0
  62. package/docs/templates/product-line/scaffold-samples/backend-only/tasks/task-graph.yaml +14 -0
  63. package/docs/templates/product-line/scaffold-samples/fe-with-api/acceptance.yaml +15 -0
  64. package/docs/templates/product-line/scaffold-samples/fe-with-api/design.md +18 -0
  65. package/docs/templates/product-line/scaffold-samples/fe-with-api/feature.yaml +3 -0
  66. package/docs/templates/product-line/scaffold-samples/fe-with-api/requirement.md +6 -0
  67. package/docs/templates/product-line/scaffold-samples/fe-with-api/tasks/BE-IMPL-001.yaml +84 -0
  68. package/docs/templates/product-line/scaffold-samples/fe-with-api/tasks/CONTRACT-001.yaml +84 -0
  69. package/docs/templates/product-line/scaffold-samples/fe-with-api/tasks/FE-IMPL-001.yaml +86 -0
  70. package/docs/templates/product-line/scaffold-samples/fe-with-api/tasks/task-graph.yaml +40 -0
  71. package/docs/templates/product-line/scaffold-samples/frontend-only/acceptance.yaml +13 -0
  72. package/docs/templates/product-line/scaffold-samples/frontend-only/design.md +14 -0
  73. package/docs/templates/product-line/scaffold-samples/frontend-only/feature.yaml +3 -0
  74. package/docs/templates/product-line/scaffold-samples/frontend-only/requirement.md +6 -0
  75. package/docs/templates/product-line/scaffold-samples/frontend-only/tasks/FE-IMPL-001.yaml +85 -0
  76. package/docs/templates/product-line/scaffold-samples/frontend-only/tasks/task-graph.yaml +14 -0
  77. package/examples/l5-report-coms-process-definition.html +322 -0
  78. package/package.json +1 -1
  79. package/skills/agent-worker/references/agent-worker-operator.md +84 -0
  80. package/skills/frontend-implementation/references/node-contracts.md +2 -2
  81. package/skills/loop-agent/SKILL.md +8 -8
  82. package/skills/loop-agent/references/command-reference.md +14 -2
  83. package/skills/loop-agent/references/harness-policy.md +22 -0
  84. package/skills/loop-agent/references/task-workflow.md +5 -0
@@ -461,10 +461,11 @@ function validateShellTaskConfig(task, spec, issues) {
461
461
  !shell.backendTestPipeline &&
462
462
  !shell.frontendPrewriteGate &&
463
463
  !shell.frontendVerificationBundle &&
464
- !shell.frontendReviewContext) {
464
+ !shell.frontendReviewContext &&
465
+ !shell.frontendTestEvidenceValidation) {
465
466
  issues.push({
466
467
  type: "missing-shell-commands",
467
- message: `shell task ${task.id} requires shell.preset, shell.verdictGate, shell.jsonArtifactGate, shell.backendTestPipeline, and/or non-empty shell.commands`,
468
+ message: `shell task ${task.id} requires a supported shell operation or non-empty shell.commands`,
468
469
  });
469
470
  }
470
471
  if (commands.some((command) => command.trim().length === 0)) {
@@ -603,6 +604,21 @@ function validateOutputProtocolTaskConfig(task, issues) {
603
604
  });
604
605
  }
605
606
  }
607
+ function validateWriterOutcomePolicyTaskConfig(task, issues) {
608
+ if (task.writerOutcomePolicy === undefined)
609
+ return;
610
+ const isBoundedPiWriter = task.executor === "pi" &&
611
+ task.toolProfile === "write" &&
612
+ task.role === "implementer" &&
613
+ task.writePolicy === "exclusive" &&
614
+ (task.writeSet?.length ?? 0) > 0;
615
+ if (!isBoundedPiWriter) {
616
+ issues.push({
617
+ type: "invalid-writer-outcome-policy",
618
+ message: `task ${task.id} declares writerOutcomePolicy but is not a bounded exclusive Pi implementer writer`,
619
+ });
620
+ }
621
+ }
606
622
  function validateDecisionGateTaskConfig(task, issues) {
607
623
  if (!task.decisionGate?.enabled) {
608
624
  return;
@@ -757,6 +773,7 @@ export function validateDagSpec(spec) {
757
773
  validateDecisionGateTaskConfig(task, issues);
758
774
  validateRetryPolicyTaskConfig(task, issues);
759
775
  validateOutputProtocolTaskConfig(task, issues);
776
+ validateWriterOutcomePolicyTaskConfig(task, issues);
760
777
  validateProjectGovernanceTaskConfig(task, spec, issues);
761
778
  validateFailureAwareDependsOn(task, spec, issues);
762
779
  }
@@ -128,7 +128,7 @@ decision envelope 中的 **model verdict**(`decision` / `riskLevel` 等解析
128
128
 
129
129
  - **pause → approve → resume**:`dag approve` 在 paused run 写 `human-approval.json`,将状态改回 `running` 并把目录迁回 `active/`;随后 `resumeDagRun`(`runner.ts`)要求 active lifecycle + approval artifact,并用 `prepareSkillSnapshotForContinuation` 复用 run-owned snapshot。
130
130
  - **completed 写入**:只有 runner 在终态 `persistState({ allowCompletedFactsWrite: true })`(`runner.ts`)才能写 completed 目录;该 flag 经 `completed-facts-guard.ts` 校验。
131
- - **显式 recovery mutation**:`dag reconcile-run`(`src/commands/dag-reconcile-run.ts`,命令层)默认仅检查;只有给出 `--action supersede|abandon` + reason,且 liveness 证明 runner 已停止时,才在原 lifecycle 写 reconciliation/state 并迁移到 `completed/`。它不是修改既有 completed history 的通用入口。Observe / status / doctor 始终只读。
131
+ - **显式 recovery mutation**:`dag reconcile-run`(`src/commands/dag-reconcile-run.ts`,命令层)默认仅检查;只有给出 `--action supersede|abandon` + reason,且 liveness 证明 runner 已停止时,才在原 lifecycle 写 reconciliation/state 并迁移到 `completed/`。仍为 `RUNNING` 的节点保持失败语义,但以 `reconciledAt - startedAt` 补齐节点和当前 attempt 的耗时,原始状态继续冻结在 `reconciliation.json`。它不是修改既有 completed history 的通用入口。Observe / status / doctor 始终只读。
132
132
  - **status 枚举**:`DagRunState.status`;`TERMINAL_RUN_STATUSES` 判终态;`isTerminalDagRunStatus` 工具函数。
133
133
 
134
134
  ## convergence(可选、supervised)
@@ -142,6 +142,10 @@ decision envelope 中的 **model verdict**(`decision` / `riskLevel` 等解析
142
142
 
143
143
  完成声明的权威是 shell command 的新鲜 exit code 与归档输出。验证命令执行在 `src/executors/shell-executor.ts`,环境与 preset helper 在 `src/executors/shell-verification.ts`;DAG authoring 写入的 `task.shell.verifyEvidence` 元数据由 `src/workflows/dag/node-execution.ts` 复制到 `node.verifyEvidence`。model verdict、Observe 或报告都不能替代这些 shell facts。
144
144
 
145
+ supervised 的 `soft-verify-shell` 只运行聚焦命令,明确排除无参数的 `npm test`、`npm run test` 与 `scripts/ci.sh` 等 full-suite 入口;`hard-verify-shell` 保留一次完整 final 集合。task 与 adapter 命令合并时会解包可证明安全的单命令 `bash -lc` wrapper,并以规范化 cwd、argv、env、timeout 做语义去重;`verifyEvidence.commandCount/commandLabels/commandTexts` 必须对应去重后实际执行的命令。
146
+
147
+ Pi SDK 正常路径继续在内存中传递 system prompt;只有 CLI fallback / `cli-only` 才通过权限收紧的系统临时文件传给 `--append-system-prompt`,归档命令只保存占位符。transport 解析并记录真实 temp root,持有 prompt 文件句柄,并冻结 temp root、随机私有目录、固定文件名三层 identity;收口时先用句柄清空正文,三层 identity 均匹配才精确 `unlink` 文件并非递归 `rmdir` 空目录。未知 sibling、symlink/junction 或 identity 漂移都会拒绝扩大删除范围。shell 与 Pi 子进程以独立进程组启动;超时在 Windows 使用 tree termination、在 POSIX 对进程组发信号,防止 npm/Vitest/tsx 后代在节点结束后继续持有 IPC 或临时文件。
148
+
145
149
  ## Dynamic Workflow
146
150
 
147
151
  Dynamic Workflow 是 DAG runtime 上方的逻辑编排/编译层,**不**重写 runner:
@@ -18,6 +18,9 @@ Application layer (src/application/,逐步引入)
18
18
  Workflow runtime (src/workflows/)
19
19
  └─ DAG / Dynamic / Loop 核心执行规则;不应依赖 commands
20
20
 
21
+ Verification planners (src/verification/)
22
+ └─ 生成期/执行期验证规划(如 Maven workspace 静态图与冻结计划);纯库模块,不跑 CLI
23
+
21
24
  Executors (src/executors/)
22
25
  └─ Pi / Shell / Static 等受治理外部工具适配;不应依赖 commands 或 CLI formatting
23
26
 
@@ -66,11 +69,18 @@ Governance (scripts/check-*.sh, src/governance/)
66
69
  - **允许依赖**:`src/executors/**`、`src/task/**`、`src/records/**`、`src/shared/**`、application use-case(目标态)。
67
70
  - **禁止**:`import` 来自 `src/commands/**`(见下方过渡例外)。
68
71
 
72
+ ### Verification planners
73
+
74
+ - **位置**:`src/verification/**`(当前含 `src/verification/maven/**`)
75
+ - **职责**:在 DAG 生成阶段与 `verify-shell` 执行前,对任务作用域驱动的验证命令做静态规划与冻结计划复核(例如 Maven Workspace Graph、`-f/-pl/-am` 重写、`.harness/cache/` 图缓存、`verification-plan-stale`)。
76
+ - **允许依赖**:`src/adapters/types`(`VerifyCommand`)、Node 标准库;由 `src/workflows/dag/**` 与 `src/executors/shell-executor.ts` 调用。
77
+ - **禁止**:执行 Maven/npm 等外部 goal 做发现;依赖 `src/commands/**` 或 CLI;把独立 POM 拼成伪 reactor;按 first-match/深度/字典序/启动 cwd 选择目标。
78
+
69
79
  ### Executors
70
80
 
71
81
  - **位置**:`src/executors/**`
72
82
  - **职责**:封装 Pi SDK、shell 执行、static 输出与 write guard。受治理 Agent runtime 只有 Pi。
73
- - **允许依赖**:`src/shared/**`、外部 SDK(不含 `@cursor/sdk`)。
83
+ - **允许依赖**:`src/shared/**`、`src/verification/**`(执行前计划复核)、外部 SDK(不含 `@cursor/sdk`)。
74
84
  - **禁止**:依赖 `src/commands/**`、CLI 输出格式,或 import `src/sidecars/**` / `@cursor/sdk`。
75
85
 
76
86
  ### Sidecars
@@ -88,6 +88,8 @@ controller identity 与 DAG skill snapshot 是两个不同冻结层(前者跨
88
88
  | 入口 | 职责 |
89
89
  | --- | --- |
90
90
  | `agent-worker feature verify-final` | **唯一** canonical writer:Feature Verification Bundle、`qa-pass.json`、`final-verification.json` |
91
+ | `agent-worker feature advance` | 编排 verify-final → delivery → closeout preview[/apply](ADR 0007 运维入口) |
92
+ | `agent-worker feature doctor` | 只读诊断证据/Pool/dirty worktree;建议下一步命令 |
91
93
  | Feature Packet `FINAL-VERIFY-*`(若保留) | 可选 **local smoke recipe**(样本 `verify:final` / reports);Task Done ≠ Final Verification Record |
92
94
  | `feature delivery` | 重验 verify-final 证据;省略路径时默认 `.harness/task-pool/evidence/<featureId>/{qa-pass,final-verification}.json` |
93
95
  | `feature closeout` | 只认 Delivery manifest + Final Verification Record 链 |
@@ -250,7 +250,7 @@
250
250
  ".harness/dag-runs/**",
251
251
  "artifacts/**"
252
252
  ],
253
- "outputContract": "One scoped pytest execution over Markdown-mapped scripts producing a valid pytest-html report with per-case captured output, self-contained reports/backend-test.html and reports/backend-test.md, plus internal reports/backend-test-facts.md evidence; exit 0/1 with valid evidence continues.",
253
+ "outputContract": "One scoped pytest execution over Markdown-mapped scripts producing a valid pytest-html report with per-case captured output, self-contained reports/backend-test.html, reports/backend-test.md, reports/backend-test-facts.md, and a deterministic self-contained reports/backend-test-l5-dashboard.html (machine-computed L-5 metrics, no JSON); exit 0/1 with valid evidence continues.",
254
254
  "subtask_prompt": "Resolve the final Markdown Automation Notes/自动化映射 to a unique, safe set of testcase/**/test_*.py targets and execute only those scripts exactly once. Prefer the deterministic module one-to-one path when a mapped script is missing but the module stem file exists. Generate a native pytest-html self-contained report, then render the primary self-contained Chinese HTML report from the same pytest-html plus final Markdown case metadata without rerun. Keep 测试结论, quality status, failure overview, and a polished per-case result card with concise scenario, automation test name, result, duration, and redacted bounded HTTP request parameters/response results for both passed and failed cases. Do not render a technical/execution evidence section in HTML; retain auditable paths and hashes in facts.",
255
255
  "shell": {
256
256
  "commands": [
@@ -283,8 +283,8 @@
283
283
  ".harness/dag-runs/**",
284
284
  "artifacts/**"
285
285
  ],
286
- "outputContract": "Final Markdown report and L-5 conclusion under docs/test-reports/**; no JSON.",
287
- "subtask_prompt": "Generate the final Markdown report from upstream facts and run-owned environment, advisory case-validation, advisory traceability, pytest-html and HTML evidence. Do not emit JSON.\n\nUse this exact human-facing section order: 测试结论 → 执行概览 → 质量校验 → 失败分析 → 风险与建议 → 证据与 L-5. Put the decision and key numbers first, use compact tables/bullets, and keep headings concise. Do not paste entire upstream reports, duplicate per-case tables already present in facts, or repeat the same evidence in multiple sections; link to paths/hashes and quote only the findings needed for the conclusion.\n\nAlways state the exact PASS/FAIL status and findings from nodes 4 and 6. Their FAIL status does not block pytest, but it must remain visible as a quality/traceability risk and must never be rewritten as PASS.\n\nInclude environment, case quality/review, automation mapping, exact pytest facts, failure classification/analysis, risks, regression recommendations, evidence paths/hashes, coverage availability, and L-5 READY/NOT READY.\n\nNever override Shell/pytest-html facts. L-5 requires pass=100%, AC=100%, automation>=90%, line>=80%, branch>=70%, skipped=0 and no blocking Critical risk.\n\nWrite only under docs/test-reports/**."
286
+ "outputContract": "Final Markdown report and L-5 conclusion under docs/test-reports/**; the deterministic L-5 dashboard at reports/backend-test-l5-dashboard.html is the authoritative visualization and must be linked, not re-rendered; no JSON.",
287
+ "subtask_prompt": "Generate the final Markdown report from upstream facts and run-owned environment, advisory case-validation, advisory traceability, pytest-html and HTML evidence. Do not emit JSON.\n\nUse this exact human-facing section order: 测试结论 → 执行概览 → 质量校验 → 失败分析 → 风险与建议 → 证据与 L-5. Put the decision and key numbers first, use compact tables/bullets, and keep headings concise. Do not paste entire upstream reports, duplicate per-case tables already present in facts, or repeat the same evidence in multiple sections; link to paths/hashes and quote only the findings needed for the conclusion.\n\nThe L-5 metrics and visualization are already produced deterministically by node 7 at reports/backend-test-l5-dashboard.html (rendered from computeL5ReportMetrics). Link to that dashboard as the authoritative L-5 view; do not recompute pass/AC/automation/coverage numbers or re-render an HTML dashboard yourself. Quote its L-5 decision verbatim.\n\nAlways state the exact PASS/FAIL status and findings from nodes 4 and 6. Their FAIL status does not block pytest, but it must remain visible as a quality/traceability risk and must never be rewritten as PASS.\n\nInclude environment, case quality/review, automation mapping, exact pytest facts, failure classification/analysis, risks, regression recommendations, evidence paths/hashes, coverage availability, and L-5 READY/NOT READY.\n\nNever override Shell/pytest-html facts. L-5 requires pass=100%, AC=100%, automation>=90%, line>=80%, branch>=70%, skipped=0 and no blocking Critical risk.\n\nWrite only under docs/test-reports/**."
288
288
  }
289
289
  ],
290
290
  "sourceBinding": {
@@ -1,6 +1,22 @@
1
1
  # Product-line feature packet
2
2
 
3
- Copy this directory for each product feature. Replace angle-bracket placeholders, keep IDs stable, and run:
3
+ **推荐入口(确定性脚手架):**
4
+
5
+ ```bash
6
+ agent-worker feature scaffold --repo . --template backend-only \
7
+ --feature-id F-2026-010 --title "..." \
8
+ --be-path services/example/** \
9
+ --verify-command "npm run typecheck" --verify-command "npm test"
10
+ agent-worker task validate-feature features/F-2026-010
11
+ ```
12
+
13
+ 批量示例见 [`feature-scaffold-batch.example.yaml`](feature-scaffold-batch.example.yaml)。
14
+
15
+ **生成快照(可读、防漂移,非 dogfood)**见 [`scaffold-samples/`](scaffold-samples/):`backend-only` / `frontend-only` / `fe-with-api`。刷新:`node --import tsx/esm scripts/generate-scaffold-samples.mjs`;校验:同脚本 `--check` 或 `bash scripts/check-scaffold-samples.sh`。
16
+
17
+ 操作说明以 skill 包内 `skills/agent-worker/references/agent-worker-operator.md` § Feature Packet Scaffold 为准(不依赖 website 是否随包)。
18
+
19
+ 也可手工复制本目录占位文件,替换 angle-bracket placeholders,保持 IDs 稳定,然后运行:
4
20
 
5
21
  ```bash
6
22
  agent-worker task validate-feature <feature-dir>
@@ -0,0 +1,31 @@
1
+ # Example batch for: agent-worker feature scaffold --batch <this-file> --repo <repo>
2
+ # Every feature_id must be explicit (v1 does not auto-allocate IDs).
3
+ # Any invalid row fails the whole batch with zero writes.
4
+
5
+ features:
6
+ - feature_id: F-2026-010
7
+ title: Banner 拉取欢迎语
8
+ template: fe-with-api
9
+ description: 前端 Banner 调用薄 API 展示欢迎语
10
+ fe_paths:
11
+ - apps/web/src/welcome/**
12
+ be_paths:
13
+ - services/welcome/**
14
+ verify_commands:
15
+ - npm run typecheck
16
+ - npm test
17
+ acceptance:
18
+ - id: AC-001
19
+ title: 页面展示非空 message
20
+ given: 欢迎语接口可用
21
+ when: 用户打开页面
22
+ then: 页面展示非空 message
23
+
24
+ - feature_id: F-2026-011
25
+ title: 设置页主题切换
26
+ template: frontend-only
27
+ fe_paths:
28
+ - apps/web/src/settings/theme/**
29
+ verify_commands:
30
+ - npm run typecheck
31
+ - npm test
@@ -0,0 +1,36 @@
1
+ # Scaffold samples (generated snapshots)
2
+
3
+ > **身份**:由 `agent-worker feature scaffold` **同一套 typed builders** 生成的只读快照,供人阅读与防漂移对照。
4
+ > **不是** 运行中的 dogfood Feature,**不是** 默认模板源(生成器仍以 `src/worker/feature/scaffold.ts` 为准)。
5
+ > **不要** 复制进 `features/` 当业务 Feature;日常请直接跑 `feature scaffold`。
6
+
7
+ ## 目录
8
+
9
+ | 子目录 | 模板 | 快照 feature_id |
10
+ | --- | --- | --- |
11
+ | `backend-only/` | pure backend | `F-2099-901` |
12
+ | `frontend-only/` | pure frontend | `F-2099-902` |
13
+ | `fe-with-api/` | contract + BE + FE | `F-2099-903` |
14
+
15
+ ID 使用 `F-2099-*` 号段,避免与 `features/F-2026-*` dogfood 混淆。
16
+
17
+ ## 刷新 / 校验
18
+
19
+ ```bash
20
+ # 按当前 scaffold 实现重写本目录
21
+ node --import tsx/esm scripts/generate-scaffold-samples.mjs
22
+
23
+ # CI / 本地:快照必须与当前 builder 一致
24
+ node --import tsx/esm scripts/generate-scaffold-samples.mjs --check
25
+ npx vitest run test/worker/feature/scaffold-samples.test.ts
26
+ ```
27
+
28
+ `scripts/check-repo.sh` 会调用 `--check`。若你改了 scaffold 模板语义,请先 generate 再提交快照。
29
+
30
+ ## 与真实 Packet 的关系
31
+
32
+ | 路径 | 用途 |
33
+ | --- | --- |
34
+ | 本目录 | 文档可读快照 + 漂移门禁 |
35
+ | `features/F-2026-*` | 仓库内真实 / dogfood Feature |
36
+ | 用户目标仓 `features/F-YYYY-NNN/` | `feature scaffold --repo <target>` 写入处 |
@@ -0,0 +1,13 @@
1
+ schema_version: 1
2
+ feature_id: F-2099-901
3
+ acceptance:
4
+ - id: AC-001
5
+ title: Scaffold sample — backend-only
6
+ priority: must
7
+ type: behavior
8
+ given: 需求与路径边界已冻结
9
+ when: Feature Packet 内实现任务完成
10
+ then: 验收目标达成且 verify.commands 通过
11
+ verification:
12
+ expected_task_refs:
13
+ - BE-IMPL-001
@@ -0,0 +1,14 @@
1
+ # Design — Scaffold sample — backend-only
2
+
3
+ ## Goals
4
+
5
+ Generated snapshot for docs/templates/product-line/scaffold-samples. Not a live dogfood Feature.
6
+
7
+ ## Paths
8
+
9
+ - Backend allowed paths:
10
+ - `services/sample-backend/**`
11
+
12
+ ## Artifacts
13
+
14
+ - `BE-IMPL-001` produces `backend-impl`
@@ -0,0 +1,3 @@
1
+ schema_version: 1
2
+ feature_id: F-2099-901
3
+ profile: generic
@@ -0,0 +1,6 @@
1
+ # Scaffold sample — backend-only
2
+
3
+ Generated snapshot for docs/templates/product-line/scaffold-samples. Not a live dogfood Feature.
4
+
5
+ Feature ID: `F-2099-901`
6
+ Template: `backend-only`
@@ -0,0 +1,83 @@
1
+ schema_version: 1
2
+ id: BE-IMPL-001
3
+ feature_id: F-2099-901
4
+ title: Scaffold sample — backend-only — 后端实现
5
+ description: Generated snapshot for
6
+ docs/templates/product-line/scaffold-samples. Not a live dogfood Feature.
7
+ repo:
8
+ name: loop-agent
9
+ path_ref: .
10
+ default_branch: main
11
+ type: backend-feature
12
+ priority: P2
13
+ risk_level: medium
14
+ depends_on: []
15
+ source_docs:
16
+ requirement: ../requirement.md
17
+ acceptance: ../acceptance.yaml
18
+ design: ../design.md
19
+ acceptance_refs:
20
+ - AC-001
21
+ scope:
22
+ goals:
23
+ - 实现后端变更并满足验收
24
+ non_goals:
25
+ - 不扩展到模板外的 Task 节点(无 BE-TEST/FE-TEST/FINAL-VERIFY)
26
+ assumptions:
27
+ - verify.commands 由 scaffold 调用方显式提供
28
+ open_questions: []
29
+ constraints:
30
+ allowed_paths:
31
+ - services/sample-backend/**
32
+ - docs/progress/F-2099-901/be/status.md
33
+ - docs/progress/F-2099-901/be/**
34
+ forbidden_paths:
35
+ - config/prod/**
36
+ - .env
37
+ - .env.*
38
+ - secrets/**
39
+ - apps/**
40
+ hard_constraints:
41
+ - 不读取生产密钥
42
+ - 不绕过 scaffold 冻结的 depends/produces/consumes
43
+ execution:
44
+ workflow: agent-dag
45
+ verify:
46
+ preset: standard
47
+ mode: serial
48
+ quota: full
49
+ commands:
50
+ - id: verify-1
51
+ label: npm run typecheck
52
+ command: npm run typecheck
53
+ required: true
54
+ timeout_ms: 300000
55
+ - id: verify-2
56
+ label: npm test
57
+ command: npm test
58
+ required: true
59
+ timeout_ms: 300000
60
+ worker:
61
+ execution_mode: generate-validate-run
62
+ max_attempts: 1
63
+ timeout_ms: 7200000
64
+ require_clean_worktree: true
65
+ require_human_review: true
66
+ create_worktree: false
67
+ loop_agent:
68
+ profile_policy: mapped
69
+ strict_models: true
70
+ strict_governance: true
71
+ max_concurrent: 1
72
+ outputs:
73
+ required:
74
+ - dag_json
75
+ - dag_validate_json
76
+ - run_record
77
+ - dag_report_json
78
+ - shell_verification
79
+ - closeout_or_failure_handoff
80
+ failure_policy:
81
+ failed_run_promote: false
82
+ generate_closeout_draft: true
83
+ create_followup_task: true
@@ -0,0 +1,14 @@
1
+ schema_version: 1
2
+ feature_id: F-2099-901
3
+ nodes:
4
+ - id: BE-IMPL-001
5
+ task: BE-IMPL-001.yaml
6
+ type: backend-feature
7
+ depends_on: []
8
+ produces:
9
+ - kind: backend-impl
10
+ schemaId: backend-impl-v1
11
+ path: services/sample-backend
12
+ parallel_policy:
13
+ max_parallel_tasks: 1
14
+ disallow_same_file_parallel_writes: true
@@ -0,0 +1,15 @@
1
+ schema_version: 1
2
+ feature_id: F-2099-903
3
+ acceptance:
4
+ - id: AC-001
5
+ title: Scaffold sample — fe-with-api
6
+ priority: must
7
+ type: behavior
8
+ given: 需求与路径边界已冻结
9
+ when: Feature Packet 内实现任务完成
10
+ then: 验收目标达成且 verify.commands 通过
11
+ verification:
12
+ expected_task_refs:
13
+ - CONTRACT-001
14
+ - BE-IMPL-001
15
+ - FE-IMPL-001
@@ -0,0 +1,18 @@
1
+ # Design — Scaffold sample — fe-with-api
2
+
3
+ ## Goals
4
+
5
+ Generated snapshot for docs/templates/product-line/scaffold-samples. Not a live dogfood Feature.
6
+
7
+ ## Paths
8
+
9
+ - Backend allowed paths:
10
+ - `services/sample-api/**`
11
+ - Frontend allowed paths:
12
+ - `apps/web/src/sample-api/**`
13
+ - Contract path: `docs/contracts/F-2099-903/api.md`
14
+
15
+ ## Artifacts
16
+
17
+ - `CONTRACT-001` produces `api-contract`
18
+ - `BE-IMPL-001` / `FE-IMPL-001` consume `api-contract` (only formal consumers)
@@ -0,0 +1,3 @@
1
+ schema_version: 1
2
+ feature_id: F-2099-903
3
+ profile: generic
@@ -0,0 +1,6 @@
1
+ # Scaffold sample — fe-with-api
2
+
3
+ Generated snapshot for docs/templates/product-line/scaffold-samples. Not a live dogfood Feature.
4
+
5
+ Feature ID: `F-2099-903`
6
+ Template: `fe-with-api`
@@ -0,0 +1,84 @@
1
+ schema_version: 1
2
+ id: BE-IMPL-001
3
+ feature_id: F-2099-903
4
+ title: Scaffold sample — fe-with-api — 后端实现
5
+ description: Generated snapshot for
6
+ docs/templates/product-line/scaffold-samples. Not a live dogfood Feature.
7
+ repo:
8
+ name: loop-agent
9
+ path_ref: .
10
+ default_branch: main
11
+ type: backend-feature
12
+ priority: P2
13
+ risk_level: medium
14
+ depends_on:
15
+ - CONTRACT-001
16
+ source_docs:
17
+ requirement: ../requirement.md
18
+ acceptance: ../acceptance.yaml
19
+ design: ../design.md
20
+ acceptance_refs:
21
+ - AC-001
22
+ scope:
23
+ goals:
24
+ - 按契约实现后端
25
+ non_goals:
26
+ - 不扩展到模板外的 Task 节点(无 BE-TEST/FE-TEST/FINAL-VERIFY)
27
+ assumptions:
28
+ - verify.commands 由 scaffold 调用方显式提供
29
+ open_questions: []
30
+ constraints:
31
+ allowed_paths:
32
+ - services/sample-api/**
33
+ - docs/progress/F-2099-903/be/status.md
34
+ - docs/progress/F-2099-903/be/**
35
+ forbidden_paths:
36
+ - config/prod/**
37
+ - .env
38
+ - .env.*
39
+ - secrets/**
40
+ - apps/**
41
+ hard_constraints:
42
+ - 不读取生产密钥
43
+ - 不绕过 scaffold 冻结的 depends/produces/consumes
44
+ execution:
45
+ workflow: agent-dag
46
+ verify:
47
+ preset: standard
48
+ mode: serial
49
+ quota: full
50
+ commands:
51
+ - id: verify-1
52
+ label: npm run typecheck
53
+ command: npm run typecheck
54
+ required: true
55
+ timeout_ms: 300000
56
+ - id: verify-2
57
+ label: npm test
58
+ command: npm test
59
+ required: true
60
+ timeout_ms: 300000
61
+ worker:
62
+ execution_mode: generate-validate-run
63
+ max_attempts: 1
64
+ timeout_ms: 7200000
65
+ require_clean_worktree: true
66
+ require_human_review: true
67
+ create_worktree: false
68
+ loop_agent:
69
+ profile_policy: mapped
70
+ strict_models: true
71
+ strict_governance: true
72
+ max_concurrent: 1
73
+ outputs:
74
+ required:
75
+ - dag_json
76
+ - dag_validate_json
77
+ - run_record
78
+ - dag_report_json
79
+ - shell_verification
80
+ - closeout_or_failure_handoff
81
+ failure_policy:
82
+ failed_run_promote: false
83
+ generate_closeout_draft: true
84
+ create_followup_task: true
@@ -0,0 +1,84 @@
1
+ schema_version: 1
2
+ id: CONTRACT-001
3
+ feature_id: F-2099-903
4
+ title: Scaffold sample — fe-with-api — API 契约
5
+ description: 冻结 docs/contracts/F-2099-903/api.md;正式 consumers 仅为 BE-IMPL-001 与 FE-IMPL-001。
6
+ repo:
7
+ name: loop-agent
8
+ path_ref: .
9
+ default_branch: main
10
+ type: architecture
11
+ priority: P1
12
+ risk_level: low
13
+ depends_on: []
14
+ source_docs:
15
+ requirement: ../requirement.md
16
+ acceptance: ../acceptance.yaml
17
+ design: ../design.md
18
+ acceptance_refs:
19
+ - AC-001
20
+ scope:
21
+ goals:
22
+ - 冻结 API 契约文档
23
+ - 声明正式 consumers 仅为 BE-IMPL / FE-IMPL
24
+ non_goals:
25
+ - 不扩展到模板外的 Task 节点(无 BE-TEST/FE-TEST/FINAL-VERIFY)
26
+ assumptions:
27
+ - verify.commands 由 scaffold 调用方显式提供
28
+ open_questions: []
29
+ constraints:
30
+ allowed_paths:
31
+ - docs/contracts/F-2099-903/api.md
32
+ - docs/progress/F-2099-903/contract/status.md
33
+ - docs/progress/F-2099-903/contract/**
34
+ forbidden_paths:
35
+ - config/prod/**
36
+ - .env
37
+ - .env.*
38
+ - secrets/**
39
+ - services/**
40
+ - apps/**
41
+ hard_constraints:
42
+ - 不读取生产密钥
43
+ - 不绕过 scaffold 冻结的 depends/produces/consumes
44
+ execution:
45
+ workflow: agent-dag
46
+ verify:
47
+ preset: standard
48
+ mode: serial
49
+ quota: full
50
+ commands:
51
+ - id: verify-1
52
+ label: npm run typecheck
53
+ command: npm run typecheck
54
+ required: true
55
+ timeout_ms: 300000
56
+ - id: verify-2
57
+ label: npm test
58
+ command: npm test
59
+ required: true
60
+ timeout_ms: 300000
61
+ worker:
62
+ execution_mode: generate-validate-run
63
+ max_attempts: 1
64
+ timeout_ms: 7200000
65
+ require_clean_worktree: true
66
+ require_human_review: true
67
+ create_worktree: false
68
+ loop_agent:
69
+ profile_policy: mapped
70
+ strict_models: true
71
+ strict_governance: true
72
+ max_concurrent: 1
73
+ outputs:
74
+ required:
75
+ - dag_json
76
+ - dag_validate_json
77
+ - run_record
78
+ - dag_report_json
79
+ - shell_verification
80
+ - closeout_or_failure_handoff
81
+ failure_policy:
82
+ failed_run_promote: false
83
+ generate_closeout_draft: true
84
+ create_followup_task: true