@tea-agent/loop-agent 0.11.0 → 0.12.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 (76) hide show
  1. package/CHANGELOG.md +25 -0
  2. package/README.md +3 -2
  3. package/dist/application/dag/generate-task-dag.js +15 -0
  4. package/dist/application/dag/run-dag.js +10 -0
  5. package/dist/application/dag/validate-dag.js +11 -0
  6. package/dist/commands/init.js +74 -7
  7. package/dist/shared/package-metadata.js +135 -0
  8. package/dist/task/config-types.js +1 -0
  9. package/dist/worker/cli.js +3 -1
  10. package/dist/worker/observability/event-history.js +216 -0
  11. package/dist/worker/observability/read-model.js +312 -83
  12. package/dist/worker/observe/paths.js +17 -0
  13. package/dist/worker/observe/routes.js +165 -21
  14. package/dist/worker/observe/server.js +59 -1
  15. package/dist/worker/observe/static/api.js +27 -0
  16. package/dist/worker/observe/static/app.js +120 -2598
  17. package/dist/worker/observe/static/constants.js +148 -0
  18. package/dist/worker/observe/static/copy.js +67 -0
  19. package/dist/worker/observe/static/dag-helpers.js +172 -0
  20. package/dist/worker/observe/static/dag-model.js +72 -0
  21. package/dist/worker/observe/static/dom.js +61 -0
  22. package/dist/worker/observe/static/format-pool.js +67 -0
  23. package/dist/worker/observe/static/format.js +292 -0
  24. package/dist/worker/observe/static/index.html +300 -82
  25. package/dist/worker/observe/static/kpi.js +94 -0
  26. package/dist/worker/observe/static/relations.js +128 -0
  27. package/dist/worker/observe/static/router.js +85 -0
  28. package/dist/worker/observe/static/run-processing.js +148 -0
  29. package/dist/worker/observe/static/shell-chrome.js +68 -0
  30. package/dist/worker/observe/static/state.js +253 -0
  31. package/dist/worker/observe/static/styles.css +1719 -495
  32. package/dist/worker/observe/static/views/batch.js +226 -0
  33. package/dist/worker/observe/static/views/dag-graph.js +172 -0
  34. package/dist/worker/observe/static/views/dag-inspector.js +477 -0
  35. package/dist/worker/observe/static/views/dag.js +362 -0
  36. package/dist/worker/observe/static/views/dashboard.js +442 -0
  37. package/dist/worker/observe/static/views/failures.js +143 -0
  38. package/dist/worker/observe/static/views/feature.js +453 -0
  39. package/dist/worker/observe/static/views/pool.js +347 -0
  40. package/dist/worker/observe/static/views/run.js +453 -0
  41. package/dist/worker/observe/static/views/session-timeline.js +205 -0
  42. package/dist/worker/observe/static/views/shell.js +7 -0
  43. package/dist/worker/observe/static/views/task.js +260 -0
  44. package/dist/worker/observe/static/views/timeline.js +163 -0
  45. package/dist/workflows/dag/controller-identity.js +104 -0
  46. package/dist/workflows/dag/init-hybrid.js +396 -3
  47. package/dist/workflows/dag/node-execution.js +123 -29
  48. package/dist/workflows/dag/repair-artifact.js +91 -0
  49. package/dist/workflows/dag/report.js +50 -0
  50. package/dist/workflows/dag/retry-policy.js +138 -0
  51. package/dist/workflows/dag/runner.js +32 -0
  52. package/dist/workflows/dag/runtime-contract.js +87 -0
  53. package/dist/workflows/dag/skill-snapshot.js +2 -0
  54. package/dist/workflows/dag/types.js +44 -1
  55. package/dist/workflows/dag/validate.js +68 -4
  56. package/docs/agent-dag-runner.md +26 -1
  57. package/docs/architecture/dag-execution.md +6 -0
  58. package/docs/architecture/evolution.md +4 -3
  59. package/docs/architecture/facts-and-state.md +1 -1
  60. package/docs/design/README.md +4 -3
  61. package/docs/exec-plans/active/README.md +1 -3
  62. package/docs/exec-plans/completed/README.md +11 -0
  63. package/docs/feature-workflow.md +28 -0
  64. package/docs/progress/README.md +18 -0
  65. package/docs/reports/README.md +8 -2
  66. package/docs/templates/agent-dag-report.schema.json +17 -0
  67. package/docs/templates/agent-dag.schema.json +69 -1
  68. package/docs/templates/agent-dag.supervised-implementation.json +8 -2
  69. package/docs/templates/backend-test-dag.generate-pytest.prompt.md +139 -0
  70. package/docs/templates/backend-test-dag.json +276 -0
  71. package/docs/templates/backend-test-dag.retrospect.prompt.md +125 -0
  72. package/docs/templates/backend-test-dag.review-cases.prompt.md +81 -0
  73. package/package.json +1 -1
  74. package/skills/loop-agent/references/command-reference.md +1 -0
  75. package/skills/loop-agent/references/hybrid-dag.md +22 -3
  76. package/skills/loop-agent/references/verification-and-failure-handling.md +6 -0
@@ -0,0 +1,276 @@
1
+ {
2
+ "$schema": "./agent-dag.schema.json",
3
+ "version": 3,
4
+ "title": "Backend test DAG template",
5
+ "runtimeContract": {
6
+ "schemaVersion": 1,
7
+ "agentRuntime": "pi-only",
8
+ "repairWriterProtocol": "explicit-node-v1"
9
+ },
10
+ "objective": "End-to-end backend functional testing pipeline: analyze requirements → generate functional test cases → review cases → generate pytest automation → execute pytest → retrospective with maturity rating. Covers the full chain from requirement analysis to test maturity assessment.",
11
+ "successCriteria": [
12
+ "analyze-inputs-pi returns a read-only test analysis contract covering scope, risks, and strategy",
13
+ "generate-backend-functional-cases-pi produces structured test cases with BE-<MODULE>-<NNN> IDs under testcase/md/",
14
+ "review-backend-cases-pi returns VERDICT: pass or request-revision with coverage assessment",
15
+ "review-backend-cases-gate-shell blocks pytest generation unless the review verdict is VERDICT: pass",
16
+ "generate-backend-pytest-pi converts reviewed cases into pytest code with 1:1 traceability under testcase/",
17
+ "execute-backend-pytest-shell runs pytest and produces HTML report under reports/",
18
+ "test-retrospect-pi generates retrospective report with A/B/C/D maturity rating under docs/test-reports/",
19
+ "Full traceability from acceptance criteria → functional test case ID → pytest function name"
20
+ ],
21
+ "globalConstraints": [
22
+ "Replace every REPLACE/WITH/... placeholder with concrete repo paths before execution; do not leave template placeholders in production DAG JSON.",
23
+ "Do not commit runtime traces under .harness/dag-runs/.",
24
+ "Use only existing executors: pi, shell. Pi writer nodes must set toolProfile=write.",
25
+ "Read-only nodes must not write repository files, including root artifacts/**.",
26
+ "Exclusive writer nodes must stay within declared writeSet.",
27
+ "Every task must explicitly declare executor; defaults.executor is schema-only and not a runtime fallback.",
28
+ "Functional test case IDs must use BE-<MODULE>-<NNN> format.",
29
+ "pytest execution must produce HTML reports under reports/.",
30
+ "Backend-test-dag nodes must maintain traceability from requirements to functional cases to pytest automation.",
31
+ "pytest automation scripts must use test_ filename prefix for pytest discovery.",
32
+ "generate-backend-pytest-pi must only create new test files under testcase/; modifying existing framework files (conftest.py, pytest.ini, pyproject.toml) is forbidden.",
33
+ "review-backend-cases-gate-shell must block pytest generation unless the review verdict is exactly VERDICT: pass.",
34
+ "If a target test filename already exists under testcase/, add a numeric suffix (_01, _02, ...); never overwrite or append to existing files.",
35
+ "execute-backend-pytest-shell must not modify test assertions or production code to make tests pass; test failures indicate potential implementation issues and must be reported honestly.",
36
+ "Prompt templates must not ask main session to write artifacts; node output is the artifact and runner archives it under .harness/dag-runs/.",
37
+ "Actual file operation paths must be macOS/Windows compatible; use / only for stable repo refs, JSON/Markdown evidence refs, and glob conventions.",
38
+ "Same-rank exclusive writeSet entries must be disjoint."
39
+ ],
40
+ "defaults": {
41
+ "executor": "pi",
42
+ "contextProfile": "slim",
43
+ "skills": [
44
+ "ai-engineering-context"
45
+ ],
46
+ "writePolicy": "read-only"
47
+ },
48
+ "skillsByRole": {
49
+ "planner": [
50
+ "loop-agent"
51
+ ],
52
+ "scout": [],
53
+ "implementer": [
54
+ "test-driven-development",
55
+ "verification-before-completion"
56
+ ],
57
+ "reviewer": [
58
+ "requesting-code-review",
59
+ "code-review-core"
60
+ ],
61
+ "verifier": [
62
+ "verification-before-completion",
63
+ "systematic-debugging"
64
+ ],
65
+ "closeout": [
66
+ "loop-agent",
67
+ "verification-before-completion"
68
+ ]
69
+ },
70
+ "executorModels": {
71
+ "pi": {
72
+ "LOW": "gpt-5.3-codex-spark",
73
+ "MED": "glm-5.2",
74
+ "HIGH": "gpt-5.5"
75
+ }
76
+ },
77
+ "tasks": [
78
+ {
79
+ "id": "analyze-inputs-pi",
80
+ "depends_on": [],
81
+ "complexity": "MED",
82
+ "executor": "pi",
83
+ "role": "planner",
84
+ "writePolicy": "read-only",
85
+ "allowedPaths": [
86
+ "REPLACE/WITH/SOURCE/PATH/**"
87
+ ],
88
+ "forbiddenPaths": [
89
+ ".harness/**",
90
+ "artifacts/**"
91
+ ],
92
+ "outputContract": "Structured Markdown extracting core content from source documents. No file writes.",
93
+ "retryPolicy": {
94
+ "maxAttempts": 3,
95
+ "backoff": "exponential",
96
+ "initialDelayMs": 2000,
97
+ "maxDelayMs": 30000,
98
+ "retryCategories": [
99
+ "timeout",
100
+ "network",
101
+ "rate-limit",
102
+ "unavailable"
103
+ ]
104
+ },
105
+ "subtask_prompt": "Read the task source materials and extract the following structured content for downstream test generation.\n\n## Required Output Sections:\n\n### 1. API Endpoints\nList all API endpoints: Method, Path, Description, Request params, Response format.\n\n### 2. Data Model\nFor each table/collection: fields, types, constraints, descriptions.\n\n### 3. Business Logic\nCore business rules, validation rules, calculation formulas.\n\n### 4. State Transitions\nState machines (e.g. order status: pending → paid → shipped → completed).\n\n### 5. Error Scenarios & Error Codes\nAll error codes, error messages, and when they occur.\n\n### 6. External Dependencies\nThird-party services, databases, message queues. Include timeout settings if documented.\n\n### 7. Acceptance Criteria\nExtract ALL acceptance criteria from 需求.md. Number them AC-001, AC-002, etc. If not explicitly listed, derive from functional requirements.\n\n### 8. Risk Areas\nHigh-risk areas requiring extra test coverage.\n\n## Conditional Sections (include ONLY if mentioned in requirements):\n- Authentication & Authorization: include ONLY if requirements mention auth mechanism (JWT, OAuth2, API Key, etc.)\n- Timeout Handling: include ONLY if requirements mention timeout configuration or degradation strategy\n- Concurrency & Idempotency: include ONLY if requirements mention concurrency, idempotency rules, or locking mechanisms\n- State Transitions: include ONLY if requirements mention business state machines\n- If not mentioned in requirements, do NOT include these sections\n\nThis output will be used directly by downstream nodes. Be thorough and structured.\nRead-only: do not modify code, docs, artifacts, or repository files."
106
+ },
107
+ {
108
+ "id": "generate-backend-functional-cases-pi",
109
+ "depends_on": [
110
+ "analyze-inputs-pi"
111
+ ],
112
+ "complexity": "MED",
113
+ "executor": "pi",
114
+ "role": "implementer",
115
+ "toolProfile": "write",
116
+ "writePolicy": "exclusive",
117
+ "writeSet": [
118
+ "testcase/md/**"
119
+ ],
120
+ "allowedPaths": [
121
+ "testcase/md/**"
122
+ ],
123
+ "forbiddenPaths": [
124
+ ".harness/**",
125
+ "artifacts/**"
126
+ ],
127
+ "outputContract": "Structured backend functional test cases in Markdown under testcase/md/. Each case uses BE-<MODULE>-<NNN> ID format.",
128
+ "subtask_prompt": "Based on the upstream analyze-inputs-pi output, generate structured backend functional test cases.\n\n## Output Steps (do in order):\n1. First, output a brief summary: how many modules, how many cases planned per module\n2. Then write each test case file under testcase/md/\n\n## Format Rules:\n- Each test case ID: BE-<MODULE>-<NNN> (e.g. BE-ORDER-001)\n- Each file covers one module\n- Case structure: ID, Title, Precondition, Steps, Expected Result\n- Map each case to acceptance criteria (AC-xxx)\n\n## Coverage Requirements:\n- Positive paths: happy path for each acceptance criterion\n- Negative paths: error scenarios (invalid input, not found, state violations)\n- Boundary conditions: empty input, max length, edge values\n\n## Conditional Coverage (include ONLY if mentioned in upstream analysis):\n- State transitions: include ONLY if upstream analyze-inputs-pi mentions state machine\n- Authentication scenarios: include ONLY if upstream analyze-inputs-pi mentions auth mechanism\n- Timeout scenarios: include ONLY if upstream analyze-inputs-pi mentions timeout handling\n- Concurrency scenarios: include ONLY if upstream analyze-inputs-pi mentions concurrency/idempotency rules\n- If not mentioned, do NOT generate these test cases\n\n## Constraints:\n- Stay within writeSet: testcase/md/**\n- Do NOT re-read source documents — use the upstream analyze-inputs-pi output only\n- Do not write root artifacts/**"
129
+ },
130
+ {
131
+ "id": "review-backend-cases-pi",
132
+ "depends_on": [
133
+ "generate-backend-functional-cases-pi"
134
+ ],
135
+ "complexity": "HIGH",
136
+ "executor": "pi",
137
+ "role": "reviewer",
138
+ "writePolicy": "read-only",
139
+ "allowedPaths": [
140
+ "**"
141
+ ],
142
+ "forbiddenPaths": [
143
+ ".harness/**",
144
+ "artifacts/**"
145
+ ],
146
+ "outputContract": "Plain Markdown whose first non-empty line is VERDICT: pass or VERDICT: request-revision; followed by Findings and Coverage Assessment. No file writes.",
147
+ "retryPolicy": {
148
+ "maxAttempts": 3,
149
+ "backoff": "exponential",
150
+ "initialDelayMs": 2000,
151
+ "maxDelayMs": 30000,
152
+ "retryCategories": [
153
+ "timeout",
154
+ "network",
155
+ "rate-limit",
156
+ "unavailable"
157
+ ]
158
+ },
159
+ "subtask_prompt_markdown": "./backend-test-dag.review-cases.prompt.md"
160
+ },
161
+ {
162
+ "id": "review-backend-cases-gate-shell",
163
+ "depends_on": [
164
+ "review-backend-cases-pi"
165
+ ],
166
+ "complexity": "LOW",
167
+ "executor": "shell",
168
+ "role": "verifier",
169
+ "writePolicy": "read-only",
170
+ "allowedPaths": [
171
+ "**"
172
+ ],
173
+ "forbiddenPaths": [
174
+ ".harness/**",
175
+ "artifacts/**"
176
+ ],
177
+ "outputContract": "Deterministic backend case review gate: exit 0 only when review-backend-cases-pi emits VERDICT: pass.",
178
+ "subtask_prompt": "Deterministic gate: block pytest generation unless backend case review emitted VERDICT: pass.",
179
+ "shell": {
180
+ "commands": [],
181
+ "verdictGate": {
182
+ "fromNodeId": "review-backend-cases-pi",
183
+ "accept": [
184
+ "VERDICT: pass"
185
+ ],
186
+ "label": "backend case review",
187
+ "lineMode": "first-verdict-line"
188
+ },
189
+ "cwd": ".",
190
+ "timeoutMs": 60000
191
+ }
192
+ },
193
+ {
194
+ "id": "generate-backend-pytest-pi",
195
+ "depends_on": [
196
+ "review-backend-cases-gate-shell"
197
+ ],
198
+ "complexity": "HIGH",
199
+ "executor": "pi",
200
+ "role": "implementer",
201
+ "toolProfile": "write",
202
+ "writePolicy": "exclusive",
203
+ "writeSet": [
204
+ "testcase/**/test_*.py"
205
+ ],
206
+ "allowedPaths": [
207
+ "testcase/**/test_*.py"
208
+ ],
209
+ "forbiddenPaths": [
210
+ ".harness/**",
211
+ "artifacts/**"
212
+ ],
213
+ "outputContract": "Pytest test files under testcase/ with 1:1 mapping to functional test case IDs. Summary lists generated files, test function count, and any skipped cases with reasons.",
214
+ "subtask_prompt_markdown": "./backend-test-dag.generate-pytest.prompt.md"
215
+ },
216
+ {
217
+ "id": "execute-backend-pytest-shell",
218
+ "depends_on": [
219
+ "generate-backend-pytest-pi"
220
+ ],
221
+ "complexity": "LOW",
222
+ "executor": "shell",
223
+ "role": "verifier",
224
+ "writePolicy": "read-only",
225
+ "allowedPaths": [
226
+ "**"
227
+ ],
228
+ "forbiddenPaths": [
229
+ ".harness/**",
230
+ "artifacts/**"
231
+ ],
232
+ "outputContract": "Archived pytest stdout/stderr with exit codes and HTML report path; no source or test file modifications.",
233
+ "subtask_prompt": "Run pytest for the backend test suite and capture results.",
234
+ "shell": {
235
+ "commands": [
236
+ "python -m pytest testcase/ --html=reports/backend-test-report.html -v"
237
+ ],
238
+ "verifyEvidence": {
239
+ "phase": "final",
240
+ "quota": "full",
241
+ "commandSource": "inline",
242
+ "commandCount": 1,
243
+ "commandLabels": [
244
+ "backend pytest execution"
245
+ ],
246
+ "finalFullRequired": true
247
+ },
248
+ "cwd": ".",
249
+ "timeoutMs": 300000
250
+ }
251
+ },
252
+ {
253
+ "id": "test-retrospect-pi",
254
+ "depends_on": [
255
+ "execute-backend-pytest-shell"
256
+ ],
257
+ "complexity": "MED",
258
+ "executor": "pi",
259
+ "role": "closeout",
260
+ "toolProfile": "write",
261
+ "writePolicy": "exclusive",
262
+ "writeSet": [
263
+ "docs/test-reports/**"
264
+ ],
265
+ "allowedPaths": [
266
+ "docs/test-reports/**"
267
+ ],
268
+ "forbiddenPaths": [
269
+ ".harness/**",
270
+ "artifacts/**"
271
+ ],
272
+ "outputContract": "Markdown retrospective report under docs/test-reports/ with coverage summary, review findings, pytest results, and maturity rating (A/B/C/D).",
273
+ "subtask_prompt_markdown": "./backend-test-dag.retrospect.prompt.md"
274
+ }
275
+ ]
276
+ }
@@ -0,0 +1,125 @@
1
+ # Backend Test DAG Retrospect Prompt Template
2
+
3
+ ## Purpose
4
+
5
+ Use this prompt for a **test retrospective** node: `executor: "pi"`, `role: "closeout"`, `toolProfile: "write"`, `writePolicy: "exclusive"`. The closeout agent reads upstream review reports and pytest execution results, then generates a retrospective report with an objective maturity rating.
6
+
7
+ Do **not** create a new executor type. This is a standard `executor: pi` writer node.
8
+
9
+ ## Recommended DAG Node Shape
10
+
11
+ ```json
12
+ {
13
+ "id": "test-retrospect-pi",
14
+ "depends_on": ["execute-backend-pytest-shell"],
15
+ "complexity": "MED",
16
+ "executor": "pi",
17
+ "role": "closeout",
18
+ "toolProfile": "write",
19
+ "writePolicy": "exclusive",
20
+ "writeSet": ["docs/test-reports/**"],
21
+ "allowedPaths": ["docs/test-reports/**"],
22
+ "forbiddenPaths": [".harness/**", "artifacts/**"],
23
+ "outputContract": "Markdown retrospective report under docs/test-reports/ with coverage summary, review findings, pytest results, and maturity rating (A/B/C/D).",
24
+ "subtask_prompt_markdown": "./backend-test-dag.retrospect.prompt.md"
25
+ }
26
+ ```
27
+
28
+ ## Prompt Body
29
+
30
+ You are the Backend Test DAG **test retrospective** agent.
31
+
32
+ Your job is to read upstream outputs (review report + pytest results) and generate a retrospective report with a maturity rating. Write the report under `docs/test-reports/` only. Stay within `writeSet`. Do not write root `artifacts/**`.
33
+
34
+ ### Output Steps (do in order)
35
+
36
+ 1. First, output the maturity rating on the first line: `Rating: A/B/C/D`
37
+ 2. Then write the full report under `docs/test-reports/`
38
+
39
+ ### Inputs
40
+
41
+ 1. **Review report** — `review-backend-cases-pi` output (VERDICT, findings, coverage assessment).
42
+ 2. **Pytest output** — `execute-backend-pytest-shell` stdout/stderr and exit code.
43
+ 3. **HTML report** — `reports/backend-test-report.html` (if generated).
44
+
45
+ Do NOT re-read source documents. Use upstream outputs only.
46
+
47
+ ### Maturity Rating Criteria
48
+
49
+ | Rating | Coverage | Pass Rate | Review Findings |
50
+ |--------|----------|-----------|-----------------|
51
+ | **A** | 100% acceptance criteria covered | 100% pytest pass | No Critical or Important findings |
52
+ | **B** | ≥80% acceptance criteria covered | ≥90% pytest pass | Only Informational findings |
53
+ | **C** | ≥60% acceptance criteria covered | ≥70% pytest pass | No Critical findings (Important allowed) |
54
+ | **D** | Below C thresholds | Below C thresholds | Or any Critical finding unresolved |
55
+
56
+ #### Rating Rules
57
+
58
+ - **Coverage** = (acceptance criteria with ≥1 covering test case) / (total acceptance criteria) × 100%
59
+ - **Pass rate** = (passed pytest functions) / (total non-skipped pytest functions) × 100%
60
+ - If `review-backend-cases-pi` returned `VERDICT: request-revision` and revision was not completed, cap at **D**.
61
+ - If pytest exit code is non-zero and >30% tests failed, cap at **D** regardless of coverage.
62
+ - Skipped tests (`@pytest.mark.skip`) count as "not covered" for pass rate but not as failures.
63
+
64
+ ### Report Structure
65
+
66
+ Write the report as a Markdown file named `backend-test-retrospect-<date>.md` under `docs/test-reports/`.
67
+
68
+ ```markdown
69
+ # Backend Test Retrospective Report
70
+
71
+ **Date:** <YYYY-MM-DD>
72
+ **Task:** <task-id>
73
+ **Maturity Rating:** <A|B|C|D>
74
+
75
+ ## 1. Test Coverage Summary
76
+
77
+ | Metric | Value |
78
+ |--------|-------|
79
+ | Total acceptance criteria | N |
80
+ | Covered by test cases | N (X%) |
81
+ | Total functional test cases | N |
82
+ | Positive path cases | N |
83
+ | Negative path cases | N |
84
+ | Boundary cases | N |
85
+
86
+ ## 2. Automation Results
87
+
88
+ | Metric | Value |
89
+ |--------|-------|
90
+ | Total pytest functions | N |
91
+ | Passed | N |
92
+ | Failed | N |
93
+ | Skipped | N |
94
+ | Pass rate | X% |
95
+ | Pytest exit code | N |
96
+
97
+ ### Failed Test Analysis
98
+
99
+ | Test Case ID | Function | Failure Reason | Root Cause |
100
+ |--------------|----------|----------------|------------|
101
+ | ... | ... | ... | ... |
102
+
103
+ ## 3. Review Findings
104
+
105
+ | Severity | Finding | Status |
106
+ |----------|---------|--------|
107
+ | Critical | ... | Resolved / Unresolved |
108
+ | Important | ... | Resolved / Unresolved |
109
+ | Informational | ... | Resolved / Unresolved |
110
+
111
+ ## 4. Maturity Rating Rationale
112
+
113
+ Explain which threshold was met or missed, and why the specific rating was assigned.
114
+
115
+ ## 5. Recommendations
116
+
117
+ - Actionable items for improving the rating in the next iteration.
118
+ - Specific gaps to close (uncovered criteria, flaky tests, missing negative paths).
119
+ ```
120
+
121
+ ### Output Shape (after rating line)
122
+
123
+ After the mandatory maturity rating line, provide a brief summary paragraph before writing the full report file.
124
+
125
+ Do not include chain-of-thought. Do not write root `artifacts/**`.
@@ -0,0 +1,81 @@
1
+ # Backend Test DAG Review Cases Prompt Template
2
+
3
+ ## Purpose
4
+
5
+ Use this prompt for a read-only **backend test case review** node: `executor: "pi"`, `role: "reviewer"`, `writePolicy: "read-only"`. The reviewer audits generated backend functional test cases for completeness, format compliance, and traceability to source requirements. Downstream `generate-backend-pytest-pi` depends on a `VERDICT: pass` to proceed.
6
+
7
+ Do **not** create `executor: reviewer`. Reviewer is a **role** on `executor: pi`.
8
+
9
+ ## Recommended DAG Node Shape
10
+
11
+ ```json
12
+ {
13
+ "id": "review-backend-cases-pi",
14
+ "depends_on": ["generate-backend-functional-cases-pi"],
15
+ "complexity": "HIGH",
16
+ "executor": "pi",
17
+ "role": "reviewer",
18
+ "writePolicy": "read-only",
19
+ "allowedPaths": ["**"],
20
+ "forbiddenPaths": [".harness/**", "artifacts/**"],
21
+ "outputContract": "Plain Markdown whose first non-empty line is VERDICT: pass or VERDICT: request-revision; followed by Findings and Coverage Assessment. No file writes.",
22
+ "subtask_prompt_markdown": "./backend-test-dag.review-cases.prompt.md"
23
+ }
24
+ ```
25
+
26
+ ## Prompt Body
27
+
28
+ You are the Backend Test DAG **test case reviewer** (read-only).
29
+
30
+ Your job is to audit the generated backend functional test cases for completeness, format compliance, requirement coverage, and traceability. You are **not** an implementer or test generator. Do not edit repository files, including root `artifacts/**`.
31
+
32
+ ### Mandatory First Line
33
+
34
+ The **first non-empty line** of your response must be exactly one of:
35
+
36
+ - `VERDICT: pass`
37
+ - `VERDICT: request-revision`
38
+
39
+ No preamble, heading, or blank lines before the verdict line.
40
+
41
+ ### Inputs to Review
42
+
43
+ 1. **Acceptance criteria** — from upstream `analyze-inputs-pi` output (AC-001, AC-002, ...).
44
+ 2. **Generated test cases** — files under `testcase/md/`.
45
+
46
+ Do NOT re-read source documents. Use upstream outputs only.
47
+
48
+ ### Review Checklist
49
+
50
+ | Area | Check | Severity if Missing |
51
+ |------|-------|---------------------|
52
+ | **ID format** | Every test case ID matches `BE-<MODULE>-<NNN>` (e.g. `BE-ORDER-001`) | Critical |
53
+ | **Positive path coverage** | Happy-path scenarios for each acceptance criterion | Critical |
54
+ | **Negative path coverage** | Error/exception scenarios (invalid input, not found, state violations) | Important |
55
+ | **Boundary conditions** | Edge cases (empty input, max length, edge values) | Important |
56
+ | **State transitions** | Illegal state changes covered | Important |
57
+ | **Requirement traceability** | Each acceptance criterion (AC-xxx) maps to at least one test case ID | Critical |
58
+ | **Case structure** | Each case has: ID, Title, Precondition, Steps, Expected Result | Important |
59
+ | **No duplicate IDs** | All test case IDs are unique across files | Critical |
60
+
61
+ ### Conditional Coverage (check ONLY if mentioned in upstream analysis)
62
+
63
+ - **Authentication coverage**: check ONLY if `analyze-inputs-pi` mentions auth mechanism (JWT, OAuth2, API Key, etc.)
64
+ - **Timeout coverage**: check ONLY if `analyze-inputs-pi` mentions timeout handling or degradation strategy
65
+ - If not mentioned in upstream analysis, do NOT flag as missing
66
+
67
+ ### Verdict Rules
68
+
69
+ | Condition | Verdict |
70
+ |-----------|---------|
71
+ | All Critical checks pass, Important checks have no more than 2 findings | `VERDICT: pass` |
72
+ | Any Critical check fails | `VERDICT: request-revision` |
73
+ | More than 2 Important findings | `VERDICT: request-revision` |
74
+ | Only Informational findings | `VERDICT: pass` (with findings listed) |
75
+
76
+ ### Output Shape (after verdict line)
77
+
78
+ 1. **Coverage Assessment** — table mapping each AC to covering test case IDs (or "uncovered").
79
+ 2. **Findings** — bullet list tagged `Critical`, `Important`, or `Informational`.
80
+ 3. **Statistics** — total case count, positive/negative/boundary breakdown, module distribution.
81
+ 4. **Required revisions** (only when `request-revision`) — numbered items for the upstream generator to fix.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tea-agent/loop-agent",
3
- "version": "0.11.0",
3
+ "version": "0.12.0",
4
4
  "type": "module",
5
5
  "bin": {
6
6
  "loop-agent": "bin/loop-agent.js",
@@ -276,6 +276,7 @@ loop-agent dag resume --run-id <run-id> # approve 后继续
276
276
  - Decision Gate prompt 可用 `buildDagDecisionGateEvidence()`(`src/workflows/dag/decision-evidence.ts`)做与 `dag report --json`、`docs/templates/agent-dag-report.schema.json` 对齐的只读摘要;不 mutate run state,不执行 retry/resume。
277
277
  - 仅当有意在 `.harness/dag-runs/active/` 下要 active run snapshot 时用 `run-dag --dry-run`。
278
278
  - task source 应从 `harness.json.workflowPolicy.dag.profileRouting` 与确定性 candidate `governanceProfile` 选 standard / review-gated / supervised template 时用 `dag run-task --profile auto`。无 `--profile` 仅用于旧 standard-compatible 输出;强制 template family 用 `--profile minimal|standard|reviewed|supervised`。
279
+ - 业务专用 DAG 通过 `task.json.taskKind` 选择,不扩充 governance profile:`frontend-implementation` 选择前端实现模板,`backend-test` 选择需求分析 → 功能用例 → 评审 → pytest 生成/执行 → 复盘的后端测试模板。
279
280
 
280
281
  ### Saved Dynamic Workflow operator UX
281
282
  ```bash
@@ -14,6 +14,8 @@
14
14
 
15
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。
16
16
 
17
+ `task.json.taskKind` 负责选择业务专用模板,不扩充 governance profile:`frontend-implementation` 选择前端实现 DAG,`backend-test` 选择后端测试 DAG。后端测试链为 `analyze-inputs-pi → generate-backend-functional-cases-pi → review-backend-cases-pi → review-backend-cases-gate-shell → generate-backend-pytest-pi → execute-backend-pytest-shell → test-retrospect-pi`,治理等级仍由既有 `minimal|standard|reviewed|supervised` 规则推断。
18
+
17
19
  ### DAG workflow 层级
18
20
 
19
21
  | 优先级 | 入口 | 使用场景 |
@@ -42,7 +44,7 @@ loop-agent run-dag --dag <temp-dir>/hybrid-dag.json --init-only --canvas-path <t
42
44
  **v2 字段**(均可选;缺失时行为同 v1):
43
45
 
44
46
  - 顶层:`objective`、`successCriteria`、`globalConstraints`、`defaults`、`skillsByRole`、`executorModels`
45
- - 每 node:`role`、`skills`、`writePolicy`、`writeSet`、`piStep`、`shell`、`outputContract`、`executor`(`pi` | `shell` | `static`);Pi 写入节点额外声明 `toolProfile: "write"`
47
+ - 每 node:`role`、`skills`、`writePolicy`、`writeSet`、`piStep`、`shell`、`outputContract`、`executor`(`pi` | `shell` | `static`);Pi 写入节点额外声明 `toolProfile: "write"`;安全只读 Pi 节点可选声明 `retryPolicy`(生成器自动注入默认值)
46
48
 
47
49
  **Model 生成 DAG 的 template 卫生**:
48
50
 
@@ -75,7 +77,7 @@ loop-agent run-dag --dag <temp-dir>/hybrid-dag.json --init-only --canvas-path <t
75
77
  - **Prompt source**:每个 task 仅用一种 prompt source。v1-compatible DAG 用 inline `subtask_prompt`;markdown-backed prompt 用 canonical `subtask_prompt_markdown`。同时提供两字段、皆不提供、或用连字符 alias `subtask_prompt-markdown` 均 fail fast。
76
78
  - **勿宣称 live smoke 已通过**,除非真实 `run-dag` execution 中 Pi read-only、Pi writer、显式 Cursor 或 shell node 均按 DAG 完成。
77
79
 
78
- 可复用 template:`docs/templates/agent-dag.base.json`(model 生成 DAG 的首选 base template)、`docs/templates/agent-dag.schema.json`(JSON Schema)、`docs/templates/agent-dag.supervised-implementation.json`(supervised implementation:writeSet audit、soft/hard verify、process supervisor、repair、review verdict gate)、`docs/templates/agent-dag-process-supervisor.prompt.md`、`docs/templates/agent-dag-review-verdict.prompt.md`、`docs/templates/agent-dag-authority-surface-audit.prompt.md`(可选 authority surface verifier;authority signal 或显式 enablement 匹配时由 `dag init-hybrid` 插入)、`examples/hybrid-loop-agent-dag.json`、`docs/templates/hybrid-dag.json`。
80
+ 可复用 template:`docs/templates/agent-dag.base.json`(model 生成 DAG 的首选 base template)、`docs/templates/agent-dag.schema.json`(JSON Schema)、`docs/templates/agent-dag.supervised-implementation.json`(supervised implementation:writeSet audit、soft/hard verify、process supervisor、repair、review verdict gate)、`docs/templates/backend-test-dag.json`(后端测试专用模板)、`docs/templates/agent-dag-process-supervisor.prompt.md`、`docs/templates/agent-dag-review-verdict.prompt.md`、`docs/templates/agent-dag-authority-surface-audit.prompt.md`(可选 authority surface verifier;authority signal 或显式 enablement 匹配时由 `dag init-hybrid` 插入)、`examples/hybrid-loop-agent-dag.json`、`docs/templates/hybrid-dag.json`。
79
81
 
80
82
  ### Supervised implementation flow(减少 main-session intervention)
81
83
 
@@ -107,9 +109,13 @@ contract-pi → scout-src ∥ scout-tests → plan-pi → write-set-audit-pi
107
109
 
108
110
  **Verdict gate contract(`shell.verdictGate`)**:声明 `fromNodeId`、`accept[]`、可选 `label`、可选 `lineMode`。runner 展开为一条 shell command,从 injected current run directory 读 `$HARNESS_DAG_RUN_DIR/<fromNodeId>.json`,对 extracted `assistantText ?? stdout` verdict line 与 `accept[]` exact-match。默认 `lineMode` 为 `first-non-empty` 以兼容;supervised gate 用 `first-verdict-line` 选 Pi 在 preamble 或常见整行 Markdown emphasis(如 `**VERDICT: pass**`)后第一条 normalized `VERDICT:` line。勿用 `result.summary.md`、grep VERDICT、latest-active-run discovery 或 multi-command stateful gate。`--strict-governance` 对 anti-pattern fail。supervisor 仍为 `executor: pi` 上的 `role: supervisor`。
109
111
 
112
+ **Repair artifact gate contract(`shell.repairArtifactGate`)**:声明 `fromNodeId`(supervisor artifact 节点)与 `repairNodeId`(承接修订的 Pi 修复节点)。runner **不再**按节点名(历史 `repair-cursor` / `repair-pi`)猜测 repair 节点:显式 `repairNodeId` 必须存在、直接 `depends_on` gate、且是受治理 Pi writer(`executor: pi`、`toolProfile: write`、`writePolicy: exclusive`、`allowedPaths`+`writeSet` 非空且 `writeSet` 不与 `forbiddenPaths` 冲突)。新生成的 supervised DAG 总是写入 `repairNodeId`;旧 DAG 缺失时只在能唯一、安全地推导出下游 Pi writer 时兼容,零个或多个候选、或候选不满足契约都在执行前 fail closed。validation 覆盖存在性、直接下游、writer 属性与路径边界。
113
+
114
+ **Runtime contract 与 controller identity**:新生成的 DagSpec 使用 `version: 3`,并必须携带 `runtimeContract`(`schemaVersion` / `agentRuntime: "pi-only"` / `repairWriterProtocol: "explicit-node-v1"` / 可选 `minimumControllerVersion`)。v3 是旧 controller 无法忽略的解析边界;capability 与最低版本是新 controller 的执行前兼容门。`init-hybrid` 不硬编码 `minimumControllerVersion`,手写 spec 可按需 pin。每个新 run 必须解析并冻结 controller identity(package version、binary SHA-256、portable fingerprint)到 `controller-identity.json`;解析失败不创建 run。`dag report` 展示 identity 与 runtime-contract compatibility,resume 对漂移、篡改或 legacy-unpinned run 全部 fail closed;legacy run 仍可只读报告或显式 reconcile。
115
+
110
116
  Prompt invariant:`docs/templates/agent-dag-process-supervisor.prompt.md`、`docs/templates/agent-dag-review-verdict.prompt.md`、`docs/templates/agent-dag-authority-surface-audit.prompt.md`(启用时)。测试:`npx vitest run test/dag-supervised-template.test.ts test/authority-surface.test.ts`。完整叙述:`docs/agent-dag-runner.md` §「Why main-session interventions happened」。
111
117
 
112
- **未实现**:`executor: supervisor`、automatic retry/resume、`executor: human`/`decision`、browser executor,或 read-only node 对 root `artifacts/**` 的 exemption
118
+ **未实现**:`executor: supervisor`、whole-run automatic retry/resume、`executor: human`/`decision`、browser executor,或 read-only node 对 root `artifacts/**` 的 exemption。注:有界只读 Pi 节点重试已实现(见下「只读 Pi 节点安全重试」)。
113
119
 
114
120
  ### Level 3 task-to-DAG(`dag init-hybrid` / `dag run-task`)
115
121
 
@@ -179,6 +185,19 @@ loop-agent dag resume --run-id <run-id> # approve 后继续
179
185
 
180
186
  **In-flight DAG run 期间的 governance**:live run 内 shell verify node 须用 `HARNESS_ALLOW_ACTIVE_DAG_RUNS=1 bash scripts/check-repo.sh`。run 归档到 `completed/` 后,在 DAG 外跑裸 `bash scripts/check-repo.sh`。
181
187
 
188
+ ### 只读 Pi 节点安全重试(read-only retry)
189
+
190
+ planner/scout/reviewer/verifier/closeout 角色的安全只读 Pi 节点可声明 `retryPolicy`,在同一 run 内有界重试模型连接中断、provider 限流、临时不可用或请求 timeout。生成模板自动注入默认策略(总尝试 3 次,手工配置最多 5 次,指数退避,单次等待上限 30s)。supervisor 与 implementer 明确不重试。
191
+
192
+ - 仅重试原始分类:`timeout`、`network`、`rate-limit`、`unavailable`。`quota` **不**是 rate limit,不重试;`auth`、`invalid-output`、`write-guard`、`decision-envelope` 与未知失败同样不重试。
193
+ - 资格由确定性 helper 判断,executor 内不硬编码循环;仅 `writePolicy=read-only|none`(或 Pi 默认只读)的上述角色可用。supervisor / implementer / writer / docs-only / dynamic / shell / static / decision-gate 节点声明 `retryPolicy` 会在 DAG validation 阶段失败。
194
+ - 每次 attempt 写入独立不可变证据 `<node-id>/attempt-<n>.json`(run-relative path),最终 node record `attempts` 字段引用完整历史;后一次成功不覆盖前一次失败证据。
195
+ - 重试复用同一 run、controller identity、skill snapshot、prompt、model 与上游输入;退避等待刷新 `lastActivityAt` 避免误判 node-quiet。
196
+ - 节点终态聚合全部 attempts 的耗时、Token 与事件数;当前 backoff 等待会占用该节点的并发槽。
197
+ - 未声明 `retryPolicy` 的历史 DAG 行为不变(单次执行,不新增 attempt artifact)。
198
+
199
+ 实现:`src/workflows/dag/retry-policy.ts`、`node-execution.ts`、`validate.ts`。测试:`npx vitest run test/dag-node-retry.test.ts test/dag-validate.test.ts test/dag-init-hybrid.test.ts`。
200
+
182
201
  ### Evidence summary guidance(practice convention — 非 runtime)
183
202
 
184
203
  review-heavy DAG 中长 shell stdout 可能掩盖 proof 时,用 **evidence-summary-shell** 作为 authoring pattern。**不是** runtime executor、schema field 或 parser。
@@ -72,6 +72,12 @@ product-line taxonomy 的事实源是 `docs/design/state-and-failure-taxonomy.md
72
72
  - 独立 audit 报告用 `handoff coverage <task-id> [--json|--markdown]`。
73
73
  - task status、source/artifacts、DAG outcome、verification 记录可能 drift 时用 `dag reconcile-tasks --glob '<pattern>' [--json|--markdown]`。默认仅报告;`--patch` 不能伪造 verification evidence。
74
74
 
75
+ ### supervised repair gate 与 runtime contract 失败
76
+
77
+ - `repair artifact gate failed: ... no unique governed Pi writer` / `declares repairNodeId "..." but no task with that id exists`:DagSpec 的 `shell.repairArtifactGate` 未声明 `repairNodeId`,或声明的修复节点缺失、不是 gate 直接下游、不是受治理 Pi writer(`executor: pi`、`toolProfile: write`、`writePolicy: exclusive`、`allowedPaths`/`writeSet` 非空且不与 `forbiddenPaths` 冲突)。用当前 controller 重新生成 supervised DAG,或按上述契约补齐修复节点,不要靠改节点名绕过。
78
+ - `incompatible DAG runtime contract` / `runtime contract requires ...`:DagSpec 的 `runtimeContract` 要求的能力超出当前 controller。升级 controller 或用当前 controller 重新生成 DAG;该 preflight 在任何节点执行前失败,不会留下半执行的 run。
79
+ - `controller identity drifted` / `artifact was tampered with`:resume 时的 controller 与 run 创建时冻结的 identity 不一致(package 内容、binary 或 fingerprint 变化),或 `controller-identity.json` 被篡改。启动新 run,而不是在漂移后 resume;completed run facts 保持只读。
80
+
75
81
  ### Verify 默认保存进度
76
82
  `verify` 成功后,loop-agent 默认:
77
83