@tea-agent/loop-agent 0.17.2 → 0.18.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/CHANGELOG.md +92 -47
- package/dist/executors/shell-executor.js +62 -2
- package/dist/governance/spine-audit.js +5 -2
- package/dist/workflows/dag/backend-test-intake-context.js +148 -0
- package/dist/workflows/dag/backend-test-markdown-workflow.js +528 -0
- package/dist/workflows/dag/init-hybrid.js +93 -109
- package/dist/workflows/dag/types.js +4 -0
- package/dist/workflows/loop/benchmark.js +1 -1
- package/docs/README.md +84 -39
- package/docs/architecture/README.md +8 -4
- package/docs/architecture/dag-execution.md +8 -1
- package/docs/architecture/evolution.md +38 -25
- package/docs/architecture/facts-and-state.md +2 -0
- package/docs/architecture/system-overview.md +6 -5
- package/docs/architecture/worker-and-feature.md +15 -8
- package/docs/init-surface.manifest.json +10 -1
- package/docs/templates/agent-dag-decision-gate-dogfood-report.md +1 -1
- package/docs/templates/backend-test-dag.json +74 -219
- package/docs/templates/branch-merge-report.md +1 -1
- package/docs/templates/exec-plan.md +2 -0
- package/docs/templates/progress-log.md +3 -0
- package/package.json +1 -1
- package/skills/init-capability-evolution/SKILL.md +1 -1
- package/skills/loop-agent/references/command-reference.md +1 -1
- package/skills/loop-agent/references/hybrid-dag.md +2 -2
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
{
|
|
2
|
-
"version":
|
|
2
|
+
"version": 4,
|
|
3
3
|
"title": "Backend test DAG: Backend test template",
|
|
4
4
|
"runtimeContract": {
|
|
5
5
|
"schemaVersion": 1,
|
|
@@ -28,12 +28,11 @@
|
|
|
28
28
|
"Root artifacts/ is reserved for explicit exclusive write nodes, not read-only scout/reviewer output",
|
|
29
29
|
"exclusive implementer nodes must use narrow, concrete writeSet paths; never keep ** or repo root",
|
|
30
30
|
"Replace REPLACE/WITH/NARROW/IMPLEMENT/PATHS/** with concrete paths before executing the implementation writer",
|
|
31
|
-
"backend-test-dag uses exactly
|
|
32
|
-
"
|
|
33
|
-
"
|
|
34
|
-
"
|
|
35
|
-
"Functional
|
|
36
|
-
"pytest writers may only create the initially declared testcase assets; production code, config, skip/xfail, swallowed failures and mock substitution are forbidden."
|
|
31
|
+
"backend-test-dag uses exactly 8 real top-level tasks and executes pytest exactly once.",
|
|
32
|
+
"Model nodes produce Markdown and pytest assets, never backend-test business JSON envelopes.",
|
|
33
|
+
"Environment, Markdown validation, traceability, JUnit, HTML and execution facts are deterministic fail-closed evidence.",
|
|
34
|
+
"Only Markdown case generation/review may read source facts; pytest generation must not read source/**.",
|
|
35
|
+
"Functional case IDs use BE-<MODULE>-<NNN>; production code/config, skip/xfail, repair and rerun are forbidden."
|
|
37
36
|
],
|
|
38
37
|
"defaults": {
|
|
39
38
|
"executor": "pi",
|
|
@@ -75,11 +74,11 @@
|
|
|
75
74
|
},
|
|
76
75
|
"tasks": [
|
|
77
76
|
{
|
|
78
|
-
"id": "
|
|
77
|
+
"id": "validate-backend-test-environment-shell",
|
|
79
78
|
"depends_on": [],
|
|
80
|
-
"role": "
|
|
81
|
-
"executor": "
|
|
82
|
-
"complexity": "
|
|
79
|
+
"role": "verifier",
|
|
80
|
+
"executor": "shell",
|
|
81
|
+
"complexity": "LOW",
|
|
83
82
|
"writePolicy": "read-only",
|
|
84
83
|
"allowedPaths": [
|
|
85
84
|
"testcase/**",
|
|
@@ -90,54 +89,50 @@
|
|
|
90
89
|
".harness/dag-runs/**",
|
|
91
90
|
"artifacts/**"
|
|
92
91
|
],
|
|
93
|
-
"outputContract": "
|
|
94
|
-
"subtask_prompt": "
|
|
95
|
-
"
|
|
96
|
-
"
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
]
|
|
92
|
+
"outputContract": "Run-owned reports/backend-test-environment.md with PASS/FAIL runtime, bounded project discovery, fixture and HTML-renderer facts; no secret values.",
|
|
93
|
+
"subtask_prompt": "Fail fast before model work when Python/pytest cannot run in the clean shell. Inspect only bounded common config, conftest, test-root and server-entry candidates; never read .env values or credentials.",
|
|
94
|
+
"shell": {
|
|
95
|
+
"commands": [
|
|
96
|
+
"python --version",
|
|
97
|
+
"python -m pytest --version",
|
|
98
|
+
"python -m pytest --help"
|
|
99
|
+
],
|
|
100
|
+
"backendTestPipeline": "markdown-environment",
|
|
101
|
+
"cwd": ".",
|
|
102
|
+
"timeoutMs": 60000,
|
|
103
|
+
"envAllowlist": []
|
|
106
104
|
}
|
|
107
105
|
},
|
|
108
106
|
{
|
|
109
|
-
"id": "
|
|
107
|
+
"id": "generate-backend-md-cases-pi",
|
|
110
108
|
"depends_on": [
|
|
111
|
-
"
|
|
109
|
+
"validate-backend-test-environment-shell"
|
|
110
|
+
],
|
|
111
|
+
"role": "implementer",
|
|
112
|
+
"executor": "pi",
|
|
113
|
+
"toolProfile": "write",
|
|
114
|
+
"complexity": "MED",
|
|
115
|
+
"writePolicy": "exclusive",
|
|
116
|
+
"writeSet": [
|
|
117
|
+
"testcase/md/**"
|
|
112
118
|
],
|
|
113
|
-
"role": "verifier",
|
|
114
|
-
"executor": "shell",
|
|
115
|
-
"complexity": "LOW",
|
|
116
|
-
"writePolicy": "read-only",
|
|
117
119
|
"allowedPaths": [
|
|
118
|
-
"testcase/**"
|
|
119
|
-
"docs/test-reports/**"
|
|
120
|
+
"testcase/md/**"
|
|
120
121
|
],
|
|
121
122
|
"forbiddenPaths": [
|
|
122
123
|
".harness/**",
|
|
123
124
|
".harness/dag-runs/**",
|
|
124
125
|
"artifacts/**"
|
|
125
126
|
],
|
|
126
|
-
"outputContract": "
|
|
127
|
-
"subtask_prompt": "
|
|
128
|
-
"shell": {
|
|
129
|
-
"commands": [],
|
|
130
|
-
"backendTestPipeline": "contracts",
|
|
131
|
-
"cwd": ".",
|
|
132
|
-
"timeoutMs": 60000
|
|
133
|
-
}
|
|
127
|
+
"outputContract": "Write testcase/md/README.md plus module Markdown cases using BE-<MODULE>-<NNN>. Use Chinese for human-readable content while preserving required machine-readable identifiers and section headings; no JSON, pytest execution, production code or config writes.",
|
|
128
|
+
"subtask_prompt": "Read the upstream environment report. Generate a Markdown-first backend test strategy and cases under testcase/md/**.\n\nWrite human-readable content in Simplified Chinese by default: document titles, case titles, strategy explanations, preconditions, test-data descriptions, step descriptions, expected-result descriptions, automation notes, table headers and evidence-gap explanations. Keep English only where it is part of a machine-readable contract or established technical literal, including Case IDs, AC/REQ/BR IDs, exact section headings, HTTP methods, paths, field names, enum values, commands, filenames, code symbols and source citations. Do not add an English translation when Chinese already conveys the meaning.\n\nEvery case heading is `## BE-<MODULE>-<NNN> <中文用例标题>` and contains these exact machine-readable headings: `### Acceptance Criteria`, `### Source References`, `### Preconditions`, `### Test Data`, `### Steps`, `### Expected Results`, and `### Automation Notes`. API cases also contain `### Endpoint` with Method and Path. Under those headings, write descriptions in Chinese while preserving exact IDs, values and protocol literals.\n\nCreate testcase/md/README.md in Chinese. It should concisely explain the test objective, environment/target, isolation and cleanup strategy, module index, traceability summary, assertion principles, evidence gaps and non-goals. Prefer readable Chinese tables and lists over repeated boilerplate.\n\nExpected Results must be concrete, independently assertable Chinese statements. Each result should name the observable HTTP status, response field/value, state transition or membership condition instead of vague phrases such as ‘works correctly’ or ‘符合预期’. Steps must be executable and ordered. Use only environment-supported fixtures/targets/isolation. Record evidence gaps in Chinese instead of inventing behavior or credentials. Do not emit JSON, pytest, or execute commands.\n\n## Derived task contract: 需求.md\n\n# Backend test\n- AC-001 proof\n\n## Authoritative reference index\n\n[]\n\nFor each index entry, use `readPath` for Pi read-tool calls and copy `path` exactly into Markdown Source References. Bound files under .harness/tasks/<taskId>/source/** are read-only inputs: reading them is allowed even though writing .harness/** is forbidden. Never resolve `path` relative to the repository root, search for substitutes, or fall back to docs/** when a bound read fails.\n\nRead only precise indexed references needed for AC/API/field/rule evidence; references remain authoritative over derived text."
|
|
134
129
|
},
|
|
135
130
|
{
|
|
136
|
-
"id": "
|
|
131
|
+
"id": "review-and-revise-backend-md-cases-pi",
|
|
137
132
|
"depends_on": [
|
|
138
|
-
"
|
|
133
|
+
"generate-backend-md-cases-pi"
|
|
139
134
|
],
|
|
140
|
-
"role": "
|
|
135
|
+
"role": "reviewer",
|
|
141
136
|
"executor": "pi",
|
|
142
137
|
"toolProfile": "write",
|
|
143
138
|
"complexity": "MED",
|
|
@@ -153,13 +148,13 @@
|
|
|
153
148
|
".harness/dag-runs/**",
|
|
154
149
|
"artifacts/**"
|
|
155
150
|
],
|
|
156
|
-
"
|
|
157
|
-
"
|
|
151
|
+
"outputContract": "Review source fidelity and directly revise only testcase/md/**; return concise Markdown, never JSON.",
|
|
152
|
+
"subtask_prompt": "Independently review generated Markdown cases against each case Source References and environment evidence. Preserve and improve the Simplified Chinese presentation: human-readable titles, prose, table headers, steps, expected results and notes should be Chinese unless the token is a machine-readable ID, exact required heading, HTTP/API literal, field/enum value, path, filename, command or code symbol.\n\nCheck AC completeness/meaning, endpoint, fields/shape, status/error codes, rules, states, documented boundaries/auth, positive/negative coverage, executable steps and assertable results. Also reject avoidable English prose, duplicated bilingual wording, vague Chinese results such as ‘符合预期’, and literal translations that obscure the observable assertion.\n\nCorrect testcase/md/** directly: add documented omissions, remove unsupported cases, fix mappings/expectations, merge duplicates, improve unclear Chinese wording, or record gaps in Chinese. Do not translate or alter Case IDs, AC/REQ/BR IDs, exact required section headings, HTTP methods, paths, field names, enum values, filenames, code symbols or Source References. Avoid cosmetic rewrites that do not improve correctness or readability.\n\nRead only precise referenced source paths plus requirement sections needed for uncovered ACs. Do not scan the repository, modify source/**, generate pytest, execute tests, or emit JSON.\n\n## Derived task contract: 需求.md\n\n# Backend test\n- AC-001 proof\n\n## Authoritative reference index\n\n[]\n\nFor each index entry, use `readPath` for Pi read-tool calls and keep `path` as the exact Markdown Source References citation. Bound files under .harness/tasks/<taskId>/source/** are read-only inputs: reading them is allowed even though writing .harness/** is forbidden. Never resolve `path` relative to the repository root, search for substitutes, or fall back to docs/** when a bound read fails."
|
|
158
153
|
},
|
|
159
154
|
{
|
|
160
|
-
"id": "backend-
|
|
155
|
+
"id": "validate-backend-md-cases-shell",
|
|
161
156
|
"depends_on": [
|
|
162
|
-
"
|
|
157
|
+
"review-and-revise-backend-md-cases-pi"
|
|
163
158
|
],
|
|
164
159
|
"role": "verifier",
|
|
165
160
|
"executor": "shell",
|
|
@@ -174,60 +169,19 @@
|
|
|
174
169
|
".harness/dag-runs/**",
|
|
175
170
|
"artifacts/**"
|
|
176
171
|
],
|
|
177
|
-
"outputContract": "
|
|
178
|
-
"subtask_prompt": "
|
|
172
|
+
"outputContract": "Run-owned reports/backend-md-case-validation.md proving final Markdown quality and safety.",
|
|
173
|
+
"subtask_prompt": "Fail closed on missing/duplicate IDs, sections, AC coverage, source references, executable steps, assertable results, placeholders or secret-shaped content.",
|
|
179
174
|
"shell": {
|
|
180
175
|
"commands": [],
|
|
181
|
-
"
|
|
182
|
-
"fromNodeId": "generate-backend-cases-and-manifest-pi",
|
|
183
|
-
"schemaId": "backend-test-case-manifest-v1",
|
|
184
|
-
"artifactName": "backend-test-case-manifest.json",
|
|
185
|
-
"outputDir": "contracts"
|
|
186
|
-
},
|
|
176
|
+
"backendTestPipeline": "markdown-cases",
|
|
187
177
|
"cwd": ".",
|
|
188
178
|
"timeoutMs": 60000
|
|
189
179
|
}
|
|
190
180
|
},
|
|
191
|
-
{
|
|
192
|
-
"id": "review-backend-cases-pi",
|
|
193
|
-
"depends_on": [
|
|
194
|
-
"backend-test-case-manifest-shell",
|
|
195
|
-
"validate-backend-test-contracts-shell",
|
|
196
|
-
"generate-backend-pytest-pi"
|
|
197
|
-
],
|
|
198
|
-
"role": "reviewer",
|
|
199
|
-
"executor": "pi",
|
|
200
|
-
"complexity": "HIGH",
|
|
201
|
-
"writePolicy": "read-only",
|
|
202
|
-
"allowedPaths": [
|
|
203
|
-
"testcase/**",
|
|
204
|
-
"docs/test-reports/**"
|
|
205
|
-
],
|
|
206
|
-
"forbiddenPaths": [
|
|
207
|
-
".harness/**",
|
|
208
|
-
".harness/dag-runs/**",
|
|
209
|
-
"artifacts/**"
|
|
210
|
-
],
|
|
211
|
-
"outputContract": "advisory case review evidence whose first non-empty line is VERDICT: pass or VERDICT: request-revision; followed by Findings and Coverage Assessment. No file writes; this review neither authorizes nor blocks pytest generation.",
|
|
212
|
-
"subtask_prompt": "Review the generated backend functional test cases under testcase/md/ and the validated Case Manifest v1.\n\n## Mandatory First Line:\n\nFirst non-empty line must be exactly: VERDICT: pass or VERDICT: request-revision\n\n## Review Checklist:\n\n- ID format: every case uses BE-<MODULE>-<NNN> (full ids only in bodies and matrices)\n\n- Positive coverage: each in-scope acceptance criterion (AC-xxx) has happy-path case\n\n- Negative coverage: error scenarios (invalid input, not found, state violations)\n\n- Traceability: each explicit AC maps to a case ID or an evidenceGap in contracts/backend-test-case-manifest.json\n\n- Case structure: ID, Title, Precondition, Steps, Expected Result\n\n- No duplicate IDs across files\n\n- Manifest consistency (Critical): every AC claimed in MD case bodies/matrices must match manifest caseId→acIds; never accept 'all cases cover AC-xxx' unless every case maps that AC\n\n## Conditional Coverage (check ONLY if mentioned in upstream analysis):\n\n- Boundary coverage: check ONLY if analyze-inputs-pi mentions value ranges, length limits, numeric bounds, or format constraints\n\n- State transition coverage: check ONLY if analyze-inputs-pi mentions state machine\n\n- Authentication coverage: check ONLY if analyze-inputs-pi mentions auth mechanism\n\n- Timeout coverage: check ONLY if analyze-inputs-pi mentions timeout handling\n\n- Concurrency coverage: check ONLY if analyze-inputs-pi mentions concurrency/idempotency rules\n\n- If not mentioned, do NOT flag as missing\n\n## Do NOT treat as Critical alone:\n\n- Missing test_*.py / automation still planned (expected before generate-backend-pytest-pi)\n\n- Out-of-scope ACs already listed in manifest evidenceGaps (Flyway, frontend e2e, mvn test)\n\n## Verdict Rules:\n\n- All Critical checks pass + Important findings ≤ 2 → VERDICT: pass\n\n- Any Critical fails OR Important > 2 → VERDICT: request-revision\n\n- Any request-revision verdict is advisory evidence for canonical context, retrospective, and L-5; it does not authorize or block the pytest writer.\n\n## Output After Verdict:\n\n1. Coverage Assessment table (AC → full BE-* case IDs) using manifest + MD\n\n2. Findings list (Critical/Important/Informational)\n\n3. Statistics (total cases, positive/negative/boundary breakdown)\n\n4. Required follow-up actions (only when request-revision; no in-run writer)\n\n## Constraints:\n\n- Read-only: do not modify files\n\n- Read validated analysis + case manifest artifacts; do not recompute coverage percentages\n\n- Use testcase/md/ files for case review",
|
|
213
|
-
"retryPolicy": {
|
|
214
|
-
"maxAttempts": 3,
|
|
215
|
-
"backoff": "exponential",
|
|
216
|
-
"initialDelayMs": 2000,
|
|
217
|
-
"maxDelayMs": 30000,
|
|
218
|
-
"retryCategories": [
|
|
219
|
-
"timeout",
|
|
220
|
-
"network",
|
|
221
|
-
"rate-limit",
|
|
222
|
-
"unavailable"
|
|
223
|
-
]
|
|
224
|
-
}
|
|
225
|
-
},
|
|
226
181
|
{
|
|
227
182
|
"id": "generate-backend-pytest-pi",
|
|
228
183
|
"depends_on": [
|
|
229
|
-
"backend-
|
|
230
|
-
"validate-backend-test-contracts-shell"
|
|
184
|
+
"validate-backend-md-cases-shell"
|
|
231
185
|
],
|
|
232
186
|
"role": "implementer",
|
|
233
187
|
"executor": "pi",
|
|
@@ -248,15 +202,14 @@
|
|
|
248
202
|
".harness/dag-runs/**",
|
|
249
203
|
"artifacts/**"
|
|
250
204
|
],
|
|
251
|
-
"
|
|
205
|
+
"outputContract": "Convert every final automatable Markdown case one-to-one into pytest assets under the narrow writeSet; no JSON and no pytest execution.",
|
|
206
|
+
"subtask_prompt": "Convert validated testcase/md/** to pytest using upstream environment and validation evidence plus only bounded pytest config/conftest.\n\nEach case maps to one `test_BE_<MODULE>_<NNN>_<description>` function whose first docstring line contains the exact Case ID. Assertions come only from Expected Results; setup comes only from Preconditions/Test Data/Automation Notes.\n\nDo not read source/**, add cases, reassign ACs, modify conftest/config/production code, use skip/xfail, swallow assertions, execute pytest, or emit JSON."
|
|
252
207
|
},
|
|
253
208
|
{
|
|
254
209
|
"id": "backend-test-traceability-gate-shell",
|
|
255
210
|
"depends_on": [
|
|
256
|
-
"generate-backend-pytest-pi"
|
|
257
|
-
"backend-test-case-manifest-shell"
|
|
211
|
+
"generate-backend-pytest-pi"
|
|
258
212
|
],
|
|
259
|
-
"dependsPolicy": "all-or-condition-skip",
|
|
260
213
|
"role": "verifier",
|
|
261
214
|
"executor": "shell",
|
|
262
215
|
"complexity": "LOW",
|
|
@@ -270,21 +223,19 @@
|
|
|
270
223
|
".harness/dag-runs/**",
|
|
271
224
|
"artifacts/**"
|
|
272
225
|
],
|
|
273
|
-
"outputContract": "
|
|
274
|
-
"subtask_prompt": "Fail closed
|
|
226
|
+
"outputContract": "Run-owned reports/backend-test-traceability.md proving Markdown-to-pytest one-to-one mapping.",
|
|
227
|
+
"subtask_prompt": "Fail closed on missing, duplicate or extra Case ID mappings, mismatched docstrings, skip/xfail or swallowed exceptions.",
|
|
275
228
|
"shell": {
|
|
276
|
-
"commands": [
|
|
277
|
-
|
|
278
|
-
],
|
|
229
|
+
"commands": [],
|
|
230
|
+
"backendTestPipeline": "markdown-traceability",
|
|
279
231
|
"cwd": ".",
|
|
280
232
|
"timeoutMs": 60000
|
|
281
233
|
}
|
|
282
234
|
},
|
|
283
235
|
{
|
|
284
|
-
"id": "execute-and-
|
|
236
|
+
"id": "execute-backend-pytest-and-html-report-shell",
|
|
285
237
|
"depends_on": [
|
|
286
|
-
"backend-test-traceability-gate-shell"
|
|
287
|
-
"validate-backend-test-contracts-shell"
|
|
238
|
+
"backend-test-traceability-gate-shell"
|
|
288
239
|
],
|
|
289
240
|
"role": "verifier",
|
|
290
241
|
"executor": "shell",
|
|
@@ -299,95 +250,22 @@
|
|
|
299
250
|
".harness/dag-runs/**",
|
|
300
251
|
"artifacts/**"
|
|
301
252
|
],
|
|
302
|
-
"outputContract": "
|
|
303
|
-
"subtask_prompt": "
|
|
253
|
+
"outputContract": "One pytest execution producing valid JUnit, self-contained HTML and reports/backend-test-facts.md; exit 0/1 with valid evidence continues.",
|
|
254
|
+
"subtask_prompt": "Execute pytest exactly once. Validate JUnit, render self-contained HTML from that JUnit without rerun, and preserve failures as facts.",
|
|
304
255
|
"shell": {
|
|
305
256
|
"commands": [
|
|
306
|
-
"
|
|
257
|
+
"mkdir -p \"${HARNESS_DAG_RUN_DIR}/reports\"; PYTHONUTF8=1 PYTHONIOENCODING=utf-8 PYTHONDONTWRITEBYTECODE=1 python -m pytest testcase/ -v -p no:cacheprovider --junitxml=\"${HARNESS_DAG_RUN_DIR}/reports/backend-test.junit.xml\"; STATUS=$?; printf \"%s\" \"${STATUS}\" > \"${HARNESS_DAG_RUN_DIR}/reports/backend-test-pytest-exit.txt\"; if { [ \"${STATUS}\" -eq 0 ] || [ \"${STATUS}\" -eq 1 ]; } && [ -s \"${HARNESS_DAG_RUN_DIR}/reports/backend-test.junit.xml\" ]; then exit 0; fi; exit \"${STATUS}\""
|
|
307
258
|
],
|
|
308
|
-
"
|
|
309
|
-
"verifyEvidence": {
|
|
310
|
-
"phase": "final",
|
|
311
|
-
"quota": "full",
|
|
312
|
-
"commandSource": "inline",
|
|
313
|
-
"commandCount": 1,
|
|
314
|
-
"commandLabels": [
|
|
315
|
-
"test -n \"${HARNESS_DAG_RUN_DIR:-}\" || { echo \"missing HARNESS_DAG_RUN_DIR for backend pytest preflight\" >&2; exit 2; } && CONTRACT=\"${HARNESS_DAG_RUN_DIR}/contracts/backend-test-execution.json\" && test -f \"${CONTRACT}\" || { echo \"missing backend-test execution contract: ${CONTRACT}\" >&2; exit 2; } && node -e 'const fs=require(\"fs\");const path=require(\"path\");const contractPath=process.argv[1];const contract=JSON.parse(fs.readFileSync(contractPath,\"utf8\"));const expected=\"testcase\";const errors=[];if(contract.framework!==\"pytest\") errors.push(\"framework must be pytest\");const testRoot=String(contract.testRoot||\"\");if(!testRoot||testRoot.includes(\"..\")||path.isAbsolute(testRoot)) errors.push(\"unsafe testRoot\");if(testRoot.replace(/\\/+$/,\"\")!==expected.replace(/\\/+$/,\"\")) errors.push(\"testRoot mismatch vs frozen command: \"+testRoot+\" !== \"+expected);const rootAbs=path.resolve(process.cwd(),testRoot);if(!fs.existsSync(rootAbs)) errors.push(\"testRoot does not exist: \"+testRoot);if(contract.targetMode===\"in-process\"&&!(Array.isArray(contract.existingFixtures)&&contract.existingFixtures.length)) errors.push(\"in-process requires existingFixtures\");for (const name of (contract.requiredEnvNames||[])) { if(!process.env[name]) errors.push(\"required env missing: \"+name); }if(contract.targetMode===\"external-running-service\"){ const n=contract.baseUrlEnvName; if(!n||!process.env[n]) errors.push(\"external base URL env missing: \"+String(n||\"<empty>\")); }if(contract.targetMode===\"managed-command\" && !(contract.managedCommand&&contract.managedCommand.sourceRef)) errors.push(\"managed-command requires sourceRef evidence\");if(errors.length){ console.error(errors.join(\"; \")); process.exit(2);} console.log(\"backend-test preflight ok: framework=pytest testRoot=\"+testRoot+\" targetMode=\"+contract.targetMode);' \"${CONTRACT}\" && { REPORT=\"${HARNESS_DAG_RUN_DIR}/reports/backend-test-initial-junit.xml\"; EXIT_FILE=\"${HARNESS_DAG_RUN_DIR}/reports/backend-test-initial-pytest-exit.txt\"; mkdir -p \"$(dirname \"${REPORT}\")\"; PYTHONUTF8=1 PYTHONIOENCODING=utf-8 PYTHONDONTWRITEBYTECODE=1 python -m pytest testcase/ -v -p no:cacheprovider --junitxml=\"${REPORT}\"; STATUS=$?; printf \"%s\" \"${STATUS}\" > \"${EXIT_FILE}\"; printf \"JUnit report: %s\\n\" \"${REPORT}\"; printf \"pytestExitCode=%s\\n\" \"${STATUS}\"; if { [ \"${STATUS}\" -eq 0 ] || [ \"${STATUS}\" -eq 1 ]; } && [ -s \"${REPORT}\" ]; then exit 0; fi; exit \"${STATUS}\"; }"
|
|
316
|
-
],
|
|
317
|
-
"finalFullRequired": true
|
|
318
|
-
},
|
|
259
|
+
"backendTestPipeline": "markdown-execute-html",
|
|
319
260
|
"cwd": ".",
|
|
320
261
|
"timeoutMs": 300000,
|
|
321
|
-
"
|
|
262
|
+
"envAllowlist": []
|
|
322
263
|
}
|
|
323
264
|
},
|
|
324
265
|
{
|
|
325
|
-
"id": "
|
|
266
|
+
"id": "backend-test-report-and-l5-pi",
|
|
326
267
|
"depends_on": [
|
|
327
|
-
"execute-and-
|
|
328
|
-
],
|
|
329
|
-
"role": "reviewer",
|
|
330
|
-
"executor": "pi",
|
|
331
|
-
"complexity": "MED",
|
|
332
|
-
"writePolicy": "read-only",
|
|
333
|
-
"allowedPaths": [
|
|
334
|
-
"testcase/**",
|
|
335
|
-
"docs/test-reports/**"
|
|
336
|
-
],
|
|
337
|
-
"forbiddenPaths": [
|
|
338
|
-
".harness/**",
|
|
339
|
-
".harness/dag-runs/**",
|
|
340
|
-
"artifacts/**"
|
|
341
|
-
],
|
|
342
|
-
"outputContract": "Pure JSON classification: category in {ProductBug,TestBug,EnvFailure,ContractMismatch,FlakyTest,Unknown}, evidence[], confidence (capped), notes. No file writes.",
|
|
343
|
-
"subtask_prompt": "Read-only classifier for Backend Test Result v1.\n\nReturn exactly one JSON object (prefer pure JSON; single fenced json block tolerated; no trailing prose).\n\nThe object must contain exactly category, evidence, confidence, notes. evidence must be a non-empty array of strings, confidence must be a number from 0 through 1, and notes must be a non-empty string. Do not emit schemaVersion or custom fields.\n\nMinimal shape: {\"category\":\"Unknown\",\"evidence\":[\"outcome=completed-with-failures\"],\"confidence\":0.5,\"notes\":\"Single-run evidence is insufficient for a stronger classification.\"}\n\nRead contracts/backend-test-result-initial.json (run-owned initial Result v1). Do NOT invent pass rates from raw logs.\n\ncategory must be one of: ProductBug, TestBug, EnvFailure, ContractMismatch, FlakyTest, Unknown.\n\nHard constraints:\n\n- Single-run failure MUST NOT use FlakyTest (use Unknown, TestBug, or ProductBug).\n\n- executionStatus/outcome collection-error, command-error, or report-error MUST NOT use ProductBug.\n\n- Prefer EnvFailure/Unknown/TestBug for env, import, collection, and missing-report cases.\n\n- confidence must respect deterministic caps (≤0.75 for assertion failures; ≤0.6 for env/collection).\n\nInclude evidence[] referencing result fields (outcome, failed, failures[].name, executionStatus).\n\nRead-only: do not modify code, docs, artifacts, or repository files.",
|
|
344
|
-
"retryPolicy": {
|
|
345
|
-
"maxAttempts": 3,
|
|
346
|
-
"backoff": "exponential",
|
|
347
|
-
"initialDelayMs": 2000,
|
|
348
|
-
"maxDelayMs": 30000,
|
|
349
|
-
"retryCategories": [
|
|
350
|
-
"timeout",
|
|
351
|
-
"network",
|
|
352
|
-
"rate-limit",
|
|
353
|
-
"unavailable"
|
|
354
|
-
]
|
|
355
|
-
}
|
|
356
|
-
},
|
|
357
|
-
{
|
|
358
|
-
"id": "materialize-classification-and-result-context-shell",
|
|
359
|
-
"depends_on": [
|
|
360
|
-
"classify-backend-test-result-pi",
|
|
361
|
-
"backend-test-case-manifest-shell",
|
|
362
|
-
"review-backend-cases-pi",
|
|
363
|
-
"backend-test-traceability-gate-shell"
|
|
364
|
-
],
|
|
365
|
-
"role": "verifier",
|
|
366
|
-
"executor": "shell",
|
|
367
|
-
"complexity": "LOW",
|
|
368
|
-
"writePolicy": "read-only",
|
|
369
|
-
"allowedPaths": [
|
|
370
|
-
"testcase/**",
|
|
371
|
-
"docs/test-reports/**"
|
|
372
|
-
],
|
|
373
|
-
"forbiddenPaths": [
|
|
374
|
-
".harness/**",
|
|
375
|
-
".harness/dag-runs/**",
|
|
376
|
-
"artifacts/**"
|
|
377
|
-
],
|
|
378
|
-
"outputContract": "Materialize Classification v1, copy the unique initial Result to canonical contracts/backend-test-result.json, and emit Result + Manifest + Classification + advisory case review + traceability context.",
|
|
379
|
-
"subtask_prompt": "Validate classification and materialize canonical single-run result context with auditable case review and traceability evidence, without repair eligibility or rerun.",
|
|
380
|
-
"shell": {
|
|
381
|
-
"commands": [],
|
|
382
|
-
"backendTestPipeline": "classification-result-context",
|
|
383
|
-
"cwd": ".",
|
|
384
|
-
"timeoutMs": 60000
|
|
385
|
-
}
|
|
386
|
-
},
|
|
387
|
-
{
|
|
388
|
-
"id": "test-retrospect-pi",
|
|
389
|
-
"depends_on": [
|
|
390
|
-
"materialize-classification-and-result-context-shell"
|
|
268
|
+
"execute-backend-pytest-and-html-report-shell"
|
|
391
269
|
],
|
|
392
270
|
"role": "closeout",
|
|
393
271
|
"executor": "pi",
|
|
@@ -405,41 +283,8 @@
|
|
|
405
283
|
".harness/dag-runs/**",
|
|
406
284
|
"artifacts/**"
|
|
407
285
|
],
|
|
408
|
-
"outputContract": "
|
|
409
|
-
"subtask_prompt": "
|
|
410
|
-
},
|
|
411
|
-
{
|
|
412
|
-
"id": "l5-metrics-pi",
|
|
413
|
-
"depends_on": [
|
|
414
|
-
"test-retrospect-pi"
|
|
415
|
-
],
|
|
416
|
-
"role": "reviewer",
|
|
417
|
-
"executor": "pi",
|
|
418
|
-
"complexity": "MED",
|
|
419
|
-
"writePolicy": "read-only",
|
|
420
|
-
"allowedPaths": [
|
|
421
|
-
"testcase/**",
|
|
422
|
-
"docs/test-reports/**"
|
|
423
|
-
],
|
|
424
|
-
"forbiddenPaths": [
|
|
425
|
-
".harness/**",
|
|
426
|
-
".harness/dag-runs/**",
|
|
427
|
-
"artifacts/**"
|
|
428
|
-
],
|
|
429
|
-
"outputContract": "Exactly one JSON object with status=ready|not-ready, metrics, and blockingItems; no file writes.",
|
|
430
|
-
"subtask_prompt": "You are the independent L-5 metrics node at the end of the existing backend-test DAG.\n\nThe direct upstream test-retrospect-pi output is the primary report to assess. Read it together with the run-owned Result v1, Case Manifest v1, Code Coverage v1, and Stability Evidence artifacts when present.\n\nDo not create a new DAG, rewrite the retrospective report, change test outcome, or modify any repository file.\n\nReturn exactly one JSON object and no surrounding prose.\n\nRequired shape: {\"status\":\"ready\"|\"not-ready\",\"metrics\":{\"passRate\":metric,\"acCoverage\":metric,\"automationCoverage\":metric,\"stability\":metric,\"lineCoverage\":metric,\"branchCoverage\":metric,\"skipped\":metric,\"criticalRisks\":metric},\"blockingItems\":[string]}.\n\nEach metric must contain numerator, denominator, ratio, threshold, status=pass|fail|unavailable, and reason (null only when passed).\n\nUse only explicit evidence. Missing or invalid required evidence is unavailable, never zero or an estimate.\n\nL-5 ready requires pass rate=100%, AC coverage=100%, automation coverage>=90%, stability>=95% with n>=5, line coverage>=80%, branch coverage>=70%, skipped=0, and zero blocking Critical risks.\n\nFunction/method coverage is display-only and does not gate L-5. Preserve the distinction between L-5 maturity and the Result v1 outcome gate.",
|
|
431
|
-
"retryPolicy": {
|
|
432
|
-
"maxAttempts": 3,
|
|
433
|
-
"backoff": "exponential",
|
|
434
|
-
"initialDelayMs": 2000,
|
|
435
|
-
"maxDelayMs": 30000,
|
|
436
|
-
"retryCategories": [
|
|
437
|
-
"timeout",
|
|
438
|
-
"network",
|
|
439
|
-
"rate-limit",
|
|
440
|
-
"unavailable"
|
|
441
|
-
]
|
|
442
|
-
}
|
|
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, case-validation, traceability, JUnit and HTML evidence. Do not emit JSON.\n\nInclude environment, case quality/review, automation mapping, exact pytest facts, failure classification/analysis, risks, regression recommendations, evidence paths/hashes, coverage/stability availability, and L-5 READY/NOT READY.\n\nNever override Shell/JUnit facts. One run cannot prove FlakyTest. Missing coverage/stability is Unavailable. L-5 requires pass=100%, AC=100%, automation>=90%, stability>=95% n>=5, line>=80%, branch>=70%, skipped=0 and no blocking Critical risk.\n\nWrite only under docs/test-reports/**."
|
|
443
288
|
}
|
|
444
289
|
],
|
|
445
290
|
"sourceBinding": {
|
|
@@ -455,5 +300,15 @@
|
|
|
455
300
|
"requirementIds": [
|
|
456
301
|
"AC-001"
|
|
457
302
|
]
|
|
303
|
+
},
|
|
304
|
+
"taskContractBinding": {
|
|
305
|
+
"schemaVersion": 1,
|
|
306
|
+
"taskId": "backend-test-template",
|
|
307
|
+
"revision": 1,
|
|
308
|
+
"projectionVersion": 1,
|
|
309
|
+
"canonicalizerVersion": 1,
|
|
310
|
+
"taskConfigSchemaVersion": 1,
|
|
311
|
+
"canonicalHash": "752c95f16925ee7711b41e465b8eb3530b99eaa40d17a88d753b3b4fcc7aeb6e",
|
|
312
|
+
"taskConfigSha256": "926c8986ce0b291d26af9ba1be8cf1630e647a06c362dac1d6bbac72e6df7bb0"
|
|
458
313
|
}
|
|
459
314
|
}
|
|
@@ -11,7 +11,7 @@ Mode rationale: `<why this mode is sufficient>`
|
|
|
11
11
|
|
|
12
12
|
## Naming Convention
|
|
13
13
|
|
|
14
|
-
Use `YYYY-MM-DD-origin-<source>-into-<target>-<source-short-sha>.md` under `docs/reports/`. Replace `/` and other path separators in branch names with `-`. The source short SHA distinguishes repeated merges on the same day.
|
|
14
|
+
Use `YYYY-MM-DD-origin-<source>-into-<target>-<source-short-sha>.md` under `docs/reports/merge/`. Replace `/` and other path separators in branch names with `-`. The source short SHA distinguishes repeated merges on the same day.
|
|
15
15
|
|
|
16
16
|
## Pre-merge Inspection
|
|
17
17
|
|
package/package.json
CHANGED
|
@@ -44,7 +44,7 @@ description: 用于 loop-agent 本仓库的初始化能力演化审查,判断
|
|
|
44
44
|
轻量审查可以只在 handoff 中说明。高影响审查应写入:
|
|
45
45
|
|
|
46
46
|
```text
|
|
47
|
-
ai_workspace/loop-agent/reports/YYYY-MM-DD-init-evolution-review.md
|
|
47
|
+
ai_workspace/loop-agent/reports/init-evolution/YYYY-MM-DD-init-evolution-review.md
|
|
48
48
|
```
|
|
49
49
|
|
|
50
50
|
报告保持短小,包含:
|
|
@@ -446,7 +446,7 @@ loop-agent pi-reuse-benchmark \
|
|
|
446
446
|
|
|
447
447
|
```bash
|
|
448
448
|
loop-agent loop-benchmark --markdown
|
|
449
|
-
loop-agent loop-benchmark --markdown --output ai_workspace/loop-agent/reports/2026-06-30-loop-agent-loop-benchmark.md
|
|
449
|
+
loop-agent loop-benchmark --markdown --output ai_workspace/loop-agent/reports/dogfood/2026-06-30-loop-agent-loop-benchmark.md
|
|
450
450
|
```
|
|
451
451
|
|
|
452
452
|
生成 M0 deterministic baseline,对照 `single-repair`、`3-pass-convergence`、`3-pass-convergence+quota`。**不**跑 live Pi/Cursor call、不创建 task、不改 `convergence.enabled` 默认值。live dogfood 证据缺失时输出 `blocked` 并建议保持 opt-in。
|
|
@@ -19,9 +19,9 @@
|
|
|
19
19
|
前端专用链在 `frontend-scout-pi` 后加入只读 `frontend-mock-assess-pi` 和确定性 contract gate,根据接口契约、后端就绪度、生成期能力 seed 与固化验证入口选择 `native|browser-intercept|request-adapter|not-needed|blocked`。策略直接传给 plan、条件 design review、唯一 writer、实现 review 和 closeout;真实请求保持默认,缺少契约、生产隔离、注释真实请求或显式 required 合同不完整时 gate 阻塞。standard/full 拓扑的 initial design pass 直接使用 original plan,只有 request-revision 才运行 plan revision 和 final review;small-risk 拓扑保留 final review 作为对 original plan 的单一审查。已删除 `frontend-first-design-gate-shell`,保留的 final gate 只接受生效 initial/final verdict 的 pass。可选 `frontendMock` 配置声明 `auto|required|disabled`、既有服务目录与专项命令;默认 `auto` 下没有已确认 Mock 能力时跳过 Mock 继续实现并保留真实联调缺口,不安全或不完整的显式 required 合同只生成无 writer 的评估链,有可信命令时才增加 `frontend-mock-verify-shell`。Mock-backed 证据只证明前端状态;跳过 Mock 且未调用后端时 closeout 报告 `Frontend status: locally-validated` 与 `Real integration: pending`。初始验证后的 assessment 输出 JSON,只有 `eligible=true` 才运行 repair/reverify/retrace;绿色路径跳过该分支后仍继续 diff/review/只读 `frontend-closeout-pi`,non-repairable 或 `ERROR` 仍硬阻断。
|
|
20
20
|
|
|
21
21
|
|
|
22
|
-
> Backend-test
|
|
22
|
+
> Backend-test Markdown-first:先由确定性环境 Shell 检查 clean env 中 Python/pytest、常见配置、conftest/fixture、test root、server entry 和 HTML renderer,失败时不消耗模型调用。随后 Pi 生成并独立 Review `testcase/md/**`,Shell 校验 Case ID、AC/source traceability、章节、步骤、可断言预期与 secret 安全;pytest writer 仅转换最终 Markdown,不重读 `source/**`。traceability 是执行前唯一资产硬门;pytest 只运行一次,生成 JUnit,并从同一 JUnit 生成 self-contained HTML 与 Markdown facts。最终 Pi 只解释事实并生成 Markdown 报告和 L-5 结论。active 流程不要求模型生成 backend-test 业务 JSON。
|
|
23
23
|
|
|
24
|
-
显式专用 `taskKind` 保持兼容并优先于任务源分类。`backend-test` 选择固定 **
|
|
24
|
+
显式专用 `taskKind` 保持兼容并优先于任务源分类。`backend-test` 选择固定 **8 个真实顶层节点**的 Markdown-first DAG:环境硬门、Markdown cases、独立 Review/修订、Markdown gate、pytest 转换、确定性 traceability、单次 pytest + JUnit/HTML/facts、最终 Markdown 报告与 L-5。历史 JSON contract/materializer 可继续读取旧 DAG,但新 runtime/template 不再生成模型业务 JSON。`knowledge-sync` 与 `knowledge-graph-bootstrap` 继续通过各自显式 taskKind 选择知识回写/图谱开荒 DAG。治理等级仍由 `minimal|standard|reviewed|supervised` 推断。
|
|
25
25
|
|
|
26
26
|
### DAG workflow 层级
|
|
27
27
|
|