@tea-agent/loop-agent 0.13.0-beta.0 → 0.13.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/AGENTS.md +157 -155
- package/CHANGELOG.md +301 -322
- package/README.md +335 -345
- package/bin/agent-worker.js +22 -22
- package/bin/loop-agent.js +21 -21
- package/dist/commands/cursor-prompt.js +6 -6
- package/dist/commands/init.js +597 -528
- package/dist/commands/loop-benchmark.js +11 -11
- package/dist/commands/pi-reuse-benchmark.js +16 -16
- package/dist/executors/shell-executor.js +200 -21
- package/dist/infrastructure/evaluation/candidate-store.js +5 -1
- package/dist/sidecars/cursor-prompt/executor.js +1 -1
- package/dist/task/runtime.js +27 -27
- package/dist/worker/observe/static/api.js +46 -46
- package/dist/worker/observe/static/app.js +150 -150
- package/dist/worker/observe/static/constants.js +148 -148
- package/dist/worker/observe/static/copy.js +67 -67
- package/dist/worker/observe/static/dag-helpers.js +172 -172
- package/dist/worker/observe/static/dag-layout.d.ts +31 -31
- package/dist/worker/observe/static/dag-layout.js +83 -83
- package/dist/worker/observe/static/dag-model.js +72 -72
- package/dist/worker/observe/static/dom.js +212 -53
- package/dist/worker/observe/static/format-pool.js +67 -67
- package/dist/worker/observe/static/format.js +292 -292
- package/dist/worker/observe/static/index.html +308 -308
- package/dist/worker/observe/static/kpi.js +94 -94
- package/dist/worker/observe/static/relations.js +133 -133
- package/dist/worker/observe/static/router.js +93 -93
- package/dist/worker/observe/static/run-processing.js +148 -148
- package/dist/worker/observe/static/shell-chrome.js +68 -68
- package/dist/worker/observe/static/state.js +267 -253
- package/dist/worker/observe/static/styles.css +1902 -1902
- package/dist/worker/observe/static/views/batch.js +227 -227
- package/dist/worker/observe/static/views/dag-graph.js +172 -172
- package/dist/worker/observe/static/views/dag-inspector.js +627 -607
- package/dist/worker/observe/static/views/dag.js +371 -362
- package/dist/worker/observe/static/views/dashboard.js +509 -252
- package/dist/worker/observe/static/views/failures.js +143 -143
- package/dist/worker/observe/static/views/feature.js +492 -492
- package/dist/worker/observe/static/views/pool.js +350 -350
- package/dist/worker/observe/static/views/run.js +453 -453
- package/dist/worker/observe/static/views/session-timeline.js +219 -205
- package/dist/worker/observe/static/views/shell.js +7 -7
- package/dist/worker/observe/static/views/task.js +314 -314
- package/dist/worker/observe/static/views/timeline.js +163 -163
- package/dist/workflows/dag/backend-test-case-manifest.js +503 -0
- package/dist/workflows/dag/backend-test-execution-contract.js +353 -0
- package/dist/workflows/dag/backend-test-result-contract.js +568 -0
- package/dist/workflows/dag/canvas-observer.js +275 -275
- package/dist/workflows/dag/decision-envelope.js +57 -2
- package/dist/workflows/dag/frontend-implementation-contract.js +240 -0
- package/dist/workflows/dag/frontend-project-capability.js +309 -0
- package/dist/workflows/dag/frontend-repair.js +341 -0
- package/dist/workflows/dag/frontend-risk.js +161 -0
- package/dist/workflows/dag/frontend-verification-trace.js +190 -0
- package/dist/workflows/dag/init-hybrid.js +1020 -125
- package/dist/workflows/dag/repair-artifact.js +43 -3
- package/dist/workflows/dag/skill-instructions.js +4 -2
- package/dist/workflows/dag/types.js +29 -8
- package/docs/README.md +105 -104
- package/docs/agent-dag-recovery-playbook.md +195 -195
- package/docs/agent-dag-runner.md +67 -67
- package/docs/architecture/README.md +26 -26
- package/docs/architecture/dag-execution.md +140 -140
- package/docs/architecture/evolution.md +54 -54
- package/docs/architecture/facts-and-state.md +71 -71
- package/docs/architecture/runtime-boundaries.md +191 -191
- package/docs/architecture/system-overview.md +93 -93
- package/docs/architecture/worker-and-feature.md +85 -85
- package/docs/cursor-prompt-sidecar.md +36 -36
- package/docs/decisions/README.md +18 -18
- package/docs/design/README.md +167 -167
- package/docs/development-principles.md +73 -73
- package/docs/exec-plans/README.md +6 -6
- package/docs/exec-plans/active/README.md +1 -4
- package/docs/exec-plans/completed/README.md +106 -84
- package/docs/feature-workflow.md +414 -389
- package/docs/harness-methodology-debugging.md +153 -153
- package/docs/harness-methodology-tdd.md +130 -130
- package/docs/harness-methodology-verification.md +27 -27
- package/docs/init-surface.manifest.json +307 -289
- package/docs/loop-agent-harness.md +142 -142
- package/docs/production-readiness.md +96 -96
- package/docs/progress/README.md +76 -60
- package/docs/reports/README.md +150 -108
- package/docs/skills/README.md +7 -7
- package/docs/skills/vetted-skill-registry.md +29 -29
- package/docs/templates/adr.md +60 -60
- package/docs/templates/agent-dag-authority-surface-audit.prompt.md +94 -94
- package/docs/templates/agent-dag-decision-envelope.schema.json +213 -213
- package/docs/templates/agent-dag-decision-gate-dogfood-report.md +117 -117
- package/docs/templates/agent-dag-decision-gate.prompt.md +246 -246
- package/docs/templates/agent-dag-process-supervisor.prompt.md +98 -98
- package/docs/templates/agent-dag-report.schema.json +473 -473
- package/docs/templates/agent-dag-review-verdict.prompt.md +68 -68
- package/docs/templates/agent-dag.base.json +190 -190
- package/docs/templates/agent-dag.final-verification.json +185 -185
- package/docs/templates/agent-dag.schema.json +411 -411
- package/docs/templates/agent-dag.supervised-implementation.json +620 -501
- package/docs/templates/backend-test-analysis.schema.json +44 -44
- package/docs/templates/backend-test-case-manifest.schema.json +190 -0
- package/docs/templates/backend-test-dag.classify.prompt.md +75 -0
- package/docs/templates/backend-test-dag.generate-pytest.prompt.md +204 -202
- package/docs/templates/backend-test-dag.json +559 -311
- package/docs/templates/backend-test-dag.retrospect.prompt.md +139 -125
- package/docs/templates/backend-test-dag.review-cases.prompt.md +83 -81
- package/docs/templates/backend-test-execution.schema.json +133 -0
- package/docs/templates/backend-test-result.schema.json +99 -0
- package/docs/templates/branch-merge-report.md +93 -0
- package/docs/templates/exec-plan.md +64 -64
- package/docs/templates/feature-spec.md +53 -53
- package/docs/templates/frontend-design-contract.md +42 -42
- package/docs/templates/frontend-eval/fixtures/failures/01-type-build-error.md +17 -0
- package/docs/templates/frontend-eval/fixtures/failures/02-unit-component-test-fail.md +16 -0
- package/docs/templates/frontend-eval/fixtures/failures/03-fixture-schema-drift.md +16 -0
- package/docs/templates/frontend-eval/fixtures/failures/04-missing-loading-empty-error-state.md +16 -0
- package/docs/templates/frontend-eval/fixtures/failures/05-forbidden-write-writeset-expansion.md +16 -0
- package/docs/templates/frontend-eval/fixtures/failures/06-unapproved-dependency-add.md +16 -0
- package/docs/templates/frontend-eval/fixtures/failures/07-mock-production-on.md +21 -0
- package/docs/templates/frontend-eval/fixtures/functional/01-simple-component-style.md +29 -0
- package/docs/templates/frontend-eval/fixtures/functional/02-form-validation.md +28 -0
- package/docs/templates/frontend-eval/fixtures/functional/03-list-detail-page.md +28 -0
- package/docs/templates/frontend-eval/fixtures/functional/04-api-mock.md +29 -0
- package/docs/templates/frontend-eval/fixtures/functional/05-permission-auth-gated-ui.md +27 -0
- package/docs/templates/frontend-eval/fixtures/functional/06-ssr-server-client-boundary.md +28 -0
- package/docs/templates/frontend-eval/fixtures/functional/07-shared-public-component-api.md +28 -0
- package/docs/templates/frontend-eval/fixtures/functional/08-pure-local-no-remote.md +27 -0
- package/docs/templates/frontend-eval/metrics.md +138 -0
- package/docs/templates/frontend-eval/smoke-targets.md +53 -0
- package/docs/templates/frontend-implementation-contract.schema.json +27 -0
- package/docs/templates/frontend-task-constraints.md +35 -35
- package/docs/templates/frontend-task-requirement.md +70 -70
- package/docs/templates/frontend-test-dag.generate-cases.prompt.md +5 -5
- package/docs/templates/frontend-test-dag.json +23 -23
- package/docs/templates/frontend-test-dag.retrieve-context.prompt.md +3 -3
- package/docs/templates/frontend-test-dag.retrospect.prompt.md +3 -3
- package/docs/templates/frontend-test-dag.review-cases.prompt.md +3 -3
- package/docs/templates/frontend-test-dag.review-execution.prompt.md +3 -3
- package/docs/templates/harness.schema.json +221 -221
- package/docs/templates/hybrid-dag.json +188 -188
- package/docs/templates/init-evolution-review.md +35 -35
- package/docs/templates/interactive-ui-round2-experiment.md +66 -66
- package/docs/templates/knowledge-graph-bootstrap-dag.json +118 -118
- package/docs/templates/knowledge-sync-dag.json +178 -178
- package/docs/templates/knowledge-sync-draft.schema.json +71 -71
- package/docs/templates/product-line/AGENTS.md +8 -8
- package/docs/templates/product-line/README.md +9 -9
- package/docs/templates/product-line/acceptance.yaml +14 -14
- package/docs/templates/product-line/closeout.yaml +9 -9
- package/docs/templates/product-line/design.md +13 -13
- package/docs/templates/product-line/links.md +10 -10
- package/docs/templates/product-line/requirement.md +17 -17
- package/docs/templates/product-line/task-graph.yaml +15 -15
- package/docs/templates/product-line/task.yaml +64 -64
- package/docs/templates/product-line/test-plan.md +7 -7
- package/docs/templates/production-readiness-checklist.md +57 -57
- package/docs/templates/progress-log.md +17 -17
- package/docs/templates/project-start-checklist.md +9 -9
- package/docs/templates/qa-report.md +48 -48
- package/docs/templates/sprint-contract.md +29 -29
- package/docs/templates/worker-dogfood-evidence.md +80 -80
- package/docs/templates/worker-dogfood-setup.md +68 -68
- package/docs/verification-matrix.md +70 -70
- package/examples/decision-gate-agent-dag.json +177 -177
- package/examples/example-dag.json +46 -46
- package/examples/hybrid-loop-agent-dag.json +189 -189
- package/harness.json +66 -66
- package/package.json +52 -88
- package/scripts/check-product-line-docs.sh +29 -29
- package/scripts/check-task-pool-root.sh +32 -32
- package/scripts/kb-bootstrap-init-skeleton.sh +240 -240
- package/scripts/kb-graph-incremental-prepare.mjs +386 -386
- package/scripts/kb-graph-incremental-prepare.sh +5 -5
- package/scripts/kb-graph-materialize.mjs +105 -105
- package/scripts/kb-graph-materialize.sh +4 -4
- package/scripts/kb-graph-promote.mjs +164 -164
- package/scripts/kb-graph-promote.sh +4 -4
- package/scripts/kb-query.mjs +554 -554
- package/scripts/kb-query.sh +5 -5
- package/skills/agent-worker/SKILL.md +39 -39
- package/skills/agent-worker/references/agent-worker-operator.md +60 -60
- package/skills/ai-engineering-context/SKILL.md +48 -48
- package/skills/analyze-product-dependencies/SKILL.md +67 -67
- package/skills/analyze-product-dependencies/agents/openai.yaml +4 -4
- package/skills/analyze-product-dependencies/references/api-documentation-schema.md +30 -30
- package/skills/analyze-product-dependencies/references/dependency-analysis-schema.md +28 -28
- package/skills/analyze-product-dependencies/references/example.md +76 -76
- package/skills/analyze-product-dependencies/references/forward-test-cases.md +35 -35
- package/skills/analyze-product-dependencies/references/input-contract.md +11 -11
- package/skills/analyze-product-dependencies/references/scouting-rules.md +61 -61
- package/skills/analyze-product-dependencies/scripts/test-validators.mjs +267 -267
- package/skills/analyze-product-dependencies/scripts/validate-api-documentation.mjs +101 -101
- package/skills/analyze-product-dependencies/scripts/validate-dependency-analysis.mjs +142 -142
- package/skills/analyze-product-dependencies/scripts/validate-product-requirement-input.mjs +76 -76
- package/skills/analyze-product-dependencies/scripts/validation-helpers.mjs +146 -146
- package/skills/analyze-product-requirements/SKILL.md +90 -90
- package/skills/analyze-product-requirements/agents/openai.yaml +4 -4
- package/skills/analyze-product-requirements/references/acceptance-criteria.md +91 -91
- package/skills/analyze-product-requirements/references/clarification-and-knowledge.md +56 -56
- package/skills/analyze-product-requirements/references/example.md +86 -86
- package/skills/analyze-product-requirements/references/forward-test-cases.md +66 -66
- package/skills/analyze-product-requirements/references/product-analysis-schema.md +32 -32
- package/skills/analyze-product-requirements/references/product-requirement-schema.md +33 -33
- package/skills/analyze-product-requirements/references/requirement-clarification-schema.md +35 -35
- package/skills/analyze-product-requirements/scripts/test-validators.mjs +193 -193
- package/skills/analyze-product-requirements/scripts/validate-product-analysis.mjs +69 -69
- package/skills/analyze-product-requirements/scripts/validate-product-requirement.mjs +97 -97
- package/skills/analyze-product-requirements/scripts/validate-requirement-clarification.mjs +98 -98
- package/skills/analyze-product-requirements/scripts/validation-helpers.mjs +156 -156
- package/skills/browser-tools/SKILL.md +196 -0
- package/skills/browser-tools/browser-content.js +103 -0
- package/skills/browser-tools/browser-cookies.js +35 -0
- package/skills/browser-tools/browser-eval.js +53 -0
- package/skills/browser-tools/browser-hn-scraper.js +108 -0
- package/skills/browser-tools/browser-nav.js +44 -0
- package/skills/browser-tools/browser-pick.js +162 -0
- package/skills/browser-tools/browser-screenshot.js +34 -0
- package/skills/browser-tools/browser-start.js +86 -0
- package/skills/browser-tools/package-lock.json +2556 -0
- package/skills/browser-tools/package.json +19 -0
- package/skills/code-review-core/SKILL.md +20 -20
- package/skills/codebase-scout/SKILL.md +19 -19
- package/skills/frontend-design-review/SKILL.md +66 -66
- package/skills/frontend-design-review/references/review-checklist.md +58 -58
- package/skills/frontend-implementation/SKILL.md +49 -47
- package/skills/frontend-implementation/references/code-standards.md +32 -32
- package/skills/frontend-implementation/references/design-spec.md +46 -46
- package/skills/frontend-implementation/references/node-contracts.md +27 -76
- package/skills/frontend-review/SKILL.md +59 -59
- package/skills/frontend-review/references/review-findings.md +47 -47
- package/skills/frontend-verification/SKILL.md +53 -53
- package/skills/frontend-verification/references/verification-checklist.md +68 -68
- package/skills/grill-me/SKILL.md +10 -10
- package/skills/grill-with-docs/SKILL.md +88 -88
- package/skills/grill-with-docs/adr-format.md +47 -47
- package/skills/grill-with-docs/context-format.md +60 -60
- package/skills/init-capability-evolution/SKILL.md +70 -70
- package/skills/loop-agent/SKILL.md +151 -151
- package/skills/loop-agent/references/README.md +67 -67
- package/skills/loop-agent/references/command-reference.md +527 -505
- package/skills/loop-agent/references/docs-converge.md +126 -126
- package/skills/loop-agent/references/harness-policy.md +263 -263
- package/skills/loop-agent/references/hybrid-dag.md +243 -238
- package/skills/loop-agent/references/learned/README.md +21 -21
- package/skills/loop-agent/references/long-running-loop.md +57 -57
- package/skills/loop-agent/references/model-routing.md +36 -36
- package/skills/loop-agent/references/multi-worktree.md +54 -54
- package/skills/loop-agent/references/one-shot-runs.md +85 -85
- package/skills/loop-agent/references/orchestrator-and-interventions.md +169 -169
- package/skills/loop-agent/references/pi-prompt.md +23 -23
- package/skills/loop-agent/references/pi-subagent-assisted-mode.md +84 -84
- package/skills/loop-agent/references/post-implementation-and-patterns.md +44 -44
- package/skills/loop-agent/references/task-workflow.md +89 -89
- package/skills/loop-agent/references/verification-and-failure-handling.md +141 -139
- package/skills/playwright-cli/SKILL.md +420 -420
- package/skills/playwright-cli/references/element-attributes.md +23 -23
- package/skills/playwright-cli/references/playwright-tests.md +39 -39
- package/skills/playwright-cli/references/request-mocking.md +87 -87
- package/skills/playwright-cli/references/running-code.md +241 -241
- package/skills/playwright-cli/references/session-management.md +225 -225
- package/skills/playwright-cli/references/storage-state.md +275 -275
- package/skills/playwright-cli/references/test-generation.md +433 -433
- package/skills/playwright-cli/references/tracing.md +139 -139
- package/skills/playwright-cli/references/video-recording.md +143 -143
- package/skills/playwright-cli-case-generator/SKILL.md +74 -74
- package/skills/requesting-code-review/SKILL.md +101 -101
- package/skills/requesting-code-review/code-reviewer.md +168 -168
- package/skills/systematic-debugging/CREATION-LOG.md +119 -119
- package/skills/systematic-debugging/SKILL.md +296 -296
- package/skills/systematic-debugging/condition-based-waiting-example.ts +158 -158
- package/skills/systematic-debugging/condition-based-waiting.md +115 -115
- package/skills/systematic-debugging/defense-in-depth.md +122 -122
- package/skills/systematic-debugging/find-polluter.sh +63 -63
- package/skills/systematic-debugging/root-cause-tracing.md +169 -169
- package/skills/systematic-debugging/test-academic.md +14 -14
- package/skills/systematic-debugging/test-pressure-1.md +58 -58
- package/skills/systematic-debugging/test-pressure-2.md +68 -68
- package/skills/systematic-debugging/test-pressure-3.md +69 -69
- package/skills/test-driven-development/SKILL.md +20 -20
- package/skills/using-git-worktrees/SKILL.md +215 -215
- package/skills/verification-before-completion/SKILL.md +154 -154
- package/skills/webapp-testing/SKILL.md +19 -19
|
@@ -1,311 +1,559 @@
|
|
|
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 as Backend Test Analysis v1 JSON → validate analysis contract → generate functional test cases → review cases → generate pytest automation → execute pytest → retrospective
|
|
11
|
-
"successCriteria": [
|
|
12
|
-
"analyze-inputs-pi returns pure Backend Test Analysis v1 JSON (schema docs/templates/backend-test-analysis.schema.json) with no Markdown prose",
|
|
13
|
-
"backend-test-analysis-contract-shell validates schemaId backend-test-analysis-v1 and materializes run-owned contracts/backend-test-analysis.json",
|
|
14
|
-
"
|
|
15
|
-
"
|
|
16
|
-
"
|
|
17
|
-
"
|
|
18
|
-
"
|
|
19
|
-
"test-
|
|
20
|
-
"
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
"
|
|
24
|
-
"
|
|
25
|
-
"
|
|
26
|
-
"
|
|
27
|
-
"
|
|
28
|
-
"
|
|
29
|
-
"
|
|
30
|
-
"
|
|
31
|
-
"
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
"
|
|
35
|
-
"
|
|
36
|
-
"
|
|
37
|
-
"
|
|
38
|
-
"
|
|
39
|
-
"
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
"
|
|
43
|
-
"
|
|
44
|
-
"
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
"
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
"
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
"
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
"
|
|
59
|
-
"
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
"
|
|
73
|
-
"
|
|
74
|
-
"
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
"
|
|
82
|
-
"
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
"
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
"
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
"
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
"
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
"
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
"
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
"
|
|
140
|
-
"
|
|
141
|
-
"
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
"
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
"
|
|
155
|
-
"
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
"
|
|
159
|
-
"
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
"
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
"
|
|
169
|
-
"
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
"
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
"
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
"
|
|
196
|
-
"
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
"
|
|
200
|
-
"
|
|
201
|
-
"
|
|
202
|
-
|
|
203
|
-
"
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
"
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
"
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
"
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
"
|
|
245
|
-
|
|
246
|
-
"
|
|
247
|
-
],
|
|
248
|
-
"
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
"
|
|
253
|
-
"
|
|
254
|
-
"
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
"
|
|
269
|
-
"
|
|
270
|
-
"
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
"
|
|
302
|
-
],
|
|
303
|
-
"
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
"
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
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 as Backend Test Analysis v1 JSON → validate analysis contract → environment scout + execution contract → generate functional test cases → emit+validate Case Manifest v1 → review cases → generate pytest automation → traceability gate → preflight + execute pytest → parse Result v1 → classify failures → retrospective → outcome gate. Covers the full chain from requirement analysis to test maturity assessment with always-run retrospect on assertion failures and deterministic AC→case→symbol traceability.",
|
|
11
|
+
"successCriteria": [
|
|
12
|
+
"analyze-inputs-pi returns pure Backend Test Analysis v1 JSON (schema docs/templates/backend-test-analysis.schema.json) with no Markdown prose",
|
|
13
|
+
"backend-test-analysis-contract-shell validates schemaId backend-test-analysis-v1 and materializes run-owned contracts/backend-test-analysis.json",
|
|
14
|
+
"backend-test-environment-scout-pi returns pure Backend Test Execution Contract v1 JSON (schema docs/templates/backend-test-execution.schema.json)",
|
|
15
|
+
"backend-test-execution-contract-shell validates schemaId backend-test-execution-v1 and materializes run-owned contracts/backend-test-execution.json",
|
|
16
|
+
"generate-backend-functional-cases-pi consumes validated contracts and produces structured test cases with BE-<MODULE>-<NNN> IDs under testcase/md/",
|
|
17
|
+
"emit-backend-case-manifest-pi returns pure Backend Test Case Manifest v1 JSON (schema docs/templates/backend-test-case-manifest.schema.json) with no Markdown prose",
|
|
18
|
+
"backend-test-case-manifest-shell validates schemaId backend-test-case-manifest-v1 and materializes run-owned contracts/backend-test-case-manifest.json with deterministic AC coverage",
|
|
19
|
+
"backend-test-traceability-gate-shell verifies generated file/symbol existence after pytest generation and before execute",
|
|
20
|
+
"test-retrospect-pi uses Case Manifest coverageSummary + Result v1 only for coverage/pass rate inputs (model must not invent percentages)",
|
|
21
|
+
"review-backend-cases-pi returns VERDICT: pass or request-revision with coverage assessment",
|
|
22
|
+
"review-backend-cases-gate-shell blocks pytest generation unless the review verdict is VERDICT: pass",
|
|
23
|
+
"generate-backend-pytest-pi converts reviewed cases into pytest code using verified analysis + execution contracts under testcase/",
|
|
24
|
+
"execute-backend-pytest-shell runs deterministic preflight against the execution contract, then pytest with frozen Adapter testRoot (default testcase/), writing JUnit XML under the current $HARNESS_DAG_RUN_DIR/reports/** only",
|
|
25
|
+
"execute-backend-pytest-shell maps pytest exit 0/1 to node success only when non-empty JUnit exists; raw pytestExitCode is side-channeled under reports/",
|
|
26
|
+
"parse-backend-test-result-shell materializes run-owned contracts/backend-test-result.json (Backend Test Result v1) from JUnit + pytestExitCode",
|
|
27
|
+
"classify-backend-test-result-pi returns structured failure classification JSON (ProductBug|TestBug|EnvFailure|ContractMismatch|FlakyTest|Unknown) without writing files",
|
|
28
|
+
"test-retrospect-pi runs after parse+classify on both pass and assertion-fail paths; stats come from Result v1 only",
|
|
29
|
+
"backend-test-outcome-gate-shell exits non-zero unless result.outcome=passed (shell facts only; retrospective cannot override)",
|
|
30
|
+
"test-retrospect-pi generates retrospective report with A/B/C/D maturity rating under docs/test-reports/",
|
|
31
|
+
"Full traceability from acceptance criteria → functional test case ID → pytest function name"
|
|
32
|
+
],
|
|
33
|
+
"globalConstraints": [
|
|
34
|
+
"Replace every REPLACE/WITH/... placeholder with concrete repo paths before execution; do not leave template placeholders in production DAG JSON.",
|
|
35
|
+
"Do not commit runtime traces under .harness/dag-runs/.",
|
|
36
|
+
"Use only existing executors: pi, shell. Pi writer nodes must set toolProfile=write.",
|
|
37
|
+
"Read-only nodes must not write repository files, including root artifacts/**.",
|
|
38
|
+
"Exclusive writer nodes must stay within declared writeSet.",
|
|
39
|
+
"Every task must explicitly declare executor; defaults.executor is schema-only and not a runtime fallback.",
|
|
40
|
+
"Functional test case IDs must use BE-<MODULE>-<NNN> format.",
|
|
41
|
+
"pytest execution must keep the target worktree read-only and write machine-readable results only under the current HARNESS_DAG_RUN_DIR/reports/** (e.g. JUnit XML).",
|
|
42
|
+
"Backend-test-dag nodes must maintain traceability from requirements to functional cases to pytest automation.",
|
|
43
|
+
"pytest automation scripts must use test_ filename prefix for pytest discovery.",
|
|
44
|
+
"generate-backend-pytest-pi may create only new files under testcase/**/test_*.py, testcase/**/helpers/**, and testcase/**/factories/**; modifying conftest.py, pytest.ini, pyproject.toml, or production code is forbidden.",
|
|
45
|
+
"review-backend-cases-gate-shell must block pytest generation unless the review verdict is exactly VERDICT: pass.",
|
|
46
|
+
"If a target test filename already exists under testcase/, add a numeric suffix (_01, _02, ...); never overwrite or append to existing files.",
|
|
47
|
+
"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.",
|
|
48
|
+
"Prompt templates must not ask main session to write artifacts; node output is the artifact and runner archives it under .harness/dag-runs/.",
|
|
49
|
+
"Actual file operation paths must be macOS/Windows compatible; use / only for stable repo refs, JSON/Markdown evidence refs, and glob conventions.",
|
|
50
|
+
"Same-rank exclusive writeSet entries must be disjoint.",
|
|
51
|
+
"parse-backend-test-result-shell materializes Backend Test Result v1 from JUnit + pytestExitCode; classify/retrospect run on pass and assertion-fail; backend-test-outcome-gate-shell uses result.outcome only.",
|
|
52
|
+
"backend-test-case-manifest-shell validates schemaId backend-test-case-manifest-v1 and materializes contracts/backend-test-case-manifest.json; AC coverage is fail-closed and deterministic.",
|
|
53
|
+
"backend-test-traceability-gate-shell verifies generated file/symbol existence after pytest generation and before execute; models must not invent coverage percentages."
|
|
54
|
+
],
|
|
55
|
+
"defaults": {
|
|
56
|
+
"executor": "pi",
|
|
57
|
+
"contextProfile": "slim",
|
|
58
|
+
"skills": [
|
|
59
|
+
"ai-engineering-context"
|
|
60
|
+
],
|
|
61
|
+
"writePolicy": "read-only"
|
|
62
|
+
},
|
|
63
|
+
"skillsByRole": {
|
|
64
|
+
"planner": [
|
|
65
|
+
"loop-agent"
|
|
66
|
+
],
|
|
67
|
+
"scout": [],
|
|
68
|
+
"implementer": [
|
|
69
|
+
"test-driven-development",
|
|
70
|
+
"verification-before-completion"
|
|
71
|
+
],
|
|
72
|
+
"reviewer": [
|
|
73
|
+
"requesting-code-review",
|
|
74
|
+
"code-review-core"
|
|
75
|
+
],
|
|
76
|
+
"verifier": [
|
|
77
|
+
"verification-before-completion",
|
|
78
|
+
"systematic-debugging"
|
|
79
|
+
],
|
|
80
|
+
"closeout": [
|
|
81
|
+
"loop-agent",
|
|
82
|
+
"verification-before-completion"
|
|
83
|
+
]
|
|
84
|
+
},
|
|
85
|
+
"executorModels": {
|
|
86
|
+
"pi": {
|
|
87
|
+
"LOW": "gpt-5.3-codex-spark",
|
|
88
|
+
"MED": "glm-5.2",
|
|
89
|
+
"HIGH": "gpt-5.5"
|
|
90
|
+
}
|
|
91
|
+
},
|
|
92
|
+
"tasks": [
|
|
93
|
+
{
|
|
94
|
+
"id": "analyze-inputs-pi",
|
|
95
|
+
"depends_on": [],
|
|
96
|
+
"complexity": "MED",
|
|
97
|
+
"executor": "pi",
|
|
98
|
+
"role": "planner",
|
|
99
|
+
"writePolicy": "read-only",
|
|
100
|
+
"allowedPaths": [
|
|
101
|
+
"REPLACE/WITH/SOURCE/PATH/**"
|
|
102
|
+
],
|
|
103
|
+
"forbiddenPaths": [
|
|
104
|
+
".harness/**",
|
|
105
|
+
"artifacts/**"
|
|
106
|
+
],
|
|
107
|
+
"outputContract": "Pure Backend Test Analysis v1 JSON object matching docs/templates/backend-test-analysis.schema.json. No Markdown prose and no file writes.",
|
|
108
|
+
"retryPolicy": {
|
|
109
|
+
"maxAttempts": 3,
|
|
110
|
+
"backoff": "exponential",
|
|
111
|
+
"initialDelayMs": 2000,
|
|
112
|
+
"maxDelayMs": 30000,
|
|
113
|
+
"retryCategories": [
|
|
114
|
+
"timeout",
|
|
115
|
+
"network",
|
|
116
|
+
"rate-limit",
|
|
117
|
+
"unavailable"
|
|
118
|
+
]
|
|
119
|
+
},
|
|
120
|
+
"subtask_prompt": "Read the task source materials and return exactly one JSON object matching Backend Test Analysis v1.\n\nDo not wrap it in explanatory prose. A single fenced json block is tolerated, but pure JSON is preferred.\n\nCopy taskId, requirementPath, requirementSha256, referencePaths, and requirementIds exactly from the DAG source binding shown below.\n\nPreserve existing AC IDs. Do not invent endpoint methods, paths, fields, errors, boundaries, or business rules; record unknowns in evidenceGaps.\n\nUse empty arrays for categories not documented. Never include credentials, tokens, private keys, or secret values.\n\nRequired top-level keys: schemaVersion, sourceBinding, acceptanceCriteria, endpoints, dataModels, businessRules, stateTransitions, boundaryConstraints, externalDependencies, risks, evidenceGaps.\n\nRead-only: do not modify code, docs, artifacts, or repository files."
|
|
121
|
+
},
|
|
122
|
+
{
|
|
123
|
+
"id": "backend-test-analysis-contract-shell",
|
|
124
|
+
"depends_on": [
|
|
125
|
+
"analyze-inputs-pi"
|
|
126
|
+
],
|
|
127
|
+
"complexity": "LOW",
|
|
128
|
+
"executor": "shell",
|
|
129
|
+
"role": "verifier",
|
|
130
|
+
"writePolicy": "read-only",
|
|
131
|
+
"allowedPaths": [
|
|
132
|
+
"REPLACE/WITH/SOURCE/PATH/**"
|
|
133
|
+
],
|
|
134
|
+
"forbiddenPaths": [
|
|
135
|
+
".harness/**",
|
|
136
|
+
"artifacts/**"
|
|
137
|
+
],
|
|
138
|
+
"outputContract": "Validated run-owned Backend Test Analysis v1 artifact pointer, schema ID, and SHA-256.",
|
|
139
|
+
"subtask_prompt": "Materialize and validate the backend-test analysis contract under the current DAG run.",
|
|
140
|
+
"shell": {
|
|
141
|
+
"commands": [],
|
|
142
|
+
"jsonArtifactGate": {
|
|
143
|
+
"fromNodeId": "analyze-inputs-pi",
|
|
144
|
+
"schemaId": "backend-test-analysis-v1",
|
|
145
|
+
"artifactName": "backend-test-analysis.json",
|
|
146
|
+
"outputDir": "contracts"
|
|
147
|
+
},
|
|
148
|
+
"cwd": ".",
|
|
149
|
+
"timeoutMs": 60000
|
|
150
|
+
}
|
|
151
|
+
},
|
|
152
|
+
{
|
|
153
|
+
"id": "backend-test-environment-scout-pi",
|
|
154
|
+
"depends_on": [
|
|
155
|
+
"backend-test-analysis-contract-shell"
|
|
156
|
+
],
|
|
157
|
+
"complexity": "MED",
|
|
158
|
+
"executor": "pi",
|
|
159
|
+
"role": "scout",
|
|
160
|
+
"writePolicy": "read-only",
|
|
161
|
+
"allowedPaths": [
|
|
162
|
+
"REPLACE/WITH/SOURCE/PATH/**"
|
|
163
|
+
],
|
|
164
|
+
"forbiddenPaths": [
|
|
165
|
+
".harness/**",
|
|
166
|
+
"artifacts/**"
|
|
167
|
+
],
|
|
168
|
+
"outputContract": "Pure Backend Test Execution Contract v1 JSON object matching docs/templates/backend-test-execution.schema.json. No Markdown prose and no file writes.",
|
|
169
|
+
"retryPolicy": {
|
|
170
|
+
"maxAttempts": 3,
|
|
171
|
+
"backoff": "exponential",
|
|
172
|
+
"initialDelayMs": 2000,
|
|
173
|
+
"maxDelayMs": 30000,
|
|
174
|
+
"retryCategories": [
|
|
175
|
+
"timeout",
|
|
176
|
+
"network",
|
|
177
|
+
"rate-limit",
|
|
178
|
+
"unavailable"
|
|
179
|
+
]
|
|
180
|
+
},
|
|
181
|
+
"subtask_prompt": "Read-only environment scout for backend-test pytest MVP.\n\nReturn exactly one JSON object matching Backend Test Execution Contract v1 (schema docs/templates/backend-test-execution.schema.json).\n\nPrefer pure JSON; a single fenced json block is tolerated; no trailing prose.\n\nDiscover only non-secret evidence: pytest config files (pytest.ini / pyproject.toml / setup.cfg test paths), candidate test roots, existing fixtures/clients, documented run commands, and env *names* (not values).\n\nDo NOT search the whole repo for secrets, .env values, tokens, private keys, or production credentials.\n\nframework must be \"pytest\". Default targetMode to \"in-process\" unless evidence clearly shows an external service base URL env name or documented managed start/stop with sourceRef.\n\nDo NOT select targetMode \"managed-command\" unless task source documents a safe start/stop command with an explicit sourceRef; otherwise leave managedCommand absent and record the gap in evidenceGaps.\n\ntestRoot and workingDirectory must be repo-relative posix paths without .. or absolute form. Adapter default testRoot is testcase when evidence is incomplete.\n\nrunner must not include secret values. report.format must be junit with a relativeHint under the run (e.g. reports/backend-test-junit.xml).\n\nrequiredEnvNames lists env NAMES only. baseUrlEnvName is required only for external-running-service and must match ^[A-Z_][A-Z0-9_]*$.\n\nRecord incomplete discovery in evidenceGaps. Populate evidenceRefs with repo-relative paths actually read.\n\nRequired top-level keys: schemaVersion, framework, runner, testRoot, workingDirectory, report, targetMode, existingFixtures, authenticationMode, requiredEnvNames, dataIsolation, evidenceGaps, evidenceRefs.\n\nRead-only: do not modify code, docs, artifacts, or repository files."
|
|
182
|
+
},
|
|
183
|
+
{
|
|
184
|
+
"id": "backend-test-execution-contract-shell",
|
|
185
|
+
"depends_on": [
|
|
186
|
+
"backend-test-environment-scout-pi"
|
|
187
|
+
],
|
|
188
|
+
"complexity": "LOW",
|
|
189
|
+
"executor": "shell",
|
|
190
|
+
"role": "verifier",
|
|
191
|
+
"writePolicy": "read-only",
|
|
192
|
+
"allowedPaths": [
|
|
193
|
+
"REPLACE/WITH/SOURCE/PATH/**"
|
|
194
|
+
],
|
|
195
|
+
"forbiddenPaths": [
|
|
196
|
+
".harness/**",
|
|
197
|
+
"artifacts/**"
|
|
198
|
+
],
|
|
199
|
+
"outputContract": "Validated run-owned Backend Test Execution Contract v1 artifact pointer, schema ID, and SHA-256.",
|
|
200
|
+
"subtask_prompt": "Materialize and validate the backend-test execution contract under the current DAG run.",
|
|
201
|
+
"shell": {
|
|
202
|
+
"commands": [],
|
|
203
|
+
"jsonArtifactGate": {
|
|
204
|
+
"fromNodeId": "backend-test-environment-scout-pi",
|
|
205
|
+
"schemaId": "backend-test-execution-v1",
|
|
206
|
+
"artifactName": "backend-test-execution.json",
|
|
207
|
+
"outputDir": "contracts"
|
|
208
|
+
},
|
|
209
|
+
"cwd": ".",
|
|
210
|
+
"timeoutMs": 60000
|
|
211
|
+
}
|
|
212
|
+
},
|
|
213
|
+
{
|
|
214
|
+
"id": "generate-backend-functional-cases-pi",
|
|
215
|
+
"depends_on": [
|
|
216
|
+
"backend-test-execution-contract-shell"
|
|
217
|
+
],
|
|
218
|
+
"complexity": "MED",
|
|
219
|
+
"executor": "pi",
|
|
220
|
+
"role": "implementer",
|
|
221
|
+
"writePolicy": "exclusive",
|
|
222
|
+
"toolProfile": "write",
|
|
223
|
+
"writeSet": [
|
|
224
|
+
"testcase/md/**"
|
|
225
|
+
],
|
|
226
|
+
"allowedPaths": [
|
|
227
|
+
"testcase/md/**"
|
|
228
|
+
],
|
|
229
|
+
"forbiddenPaths": [
|
|
230
|
+
".harness/**",
|
|
231
|
+
"artifacts/**"
|
|
232
|
+
],
|
|
233
|
+
"subtask_prompt": "Read the validated structured artifact pointer from backend-test-analysis-contract-shell and generate cases only from that JSON contract.\n\n\n\n\n\n## Output Steps (do in order):\n\n1. First, output a brief summary: how many modules, how many cases planned per module\n\n2. Then write each test case file under testcase/md/\n\n\n\n## Format Rules:\n\n- Each test case ID: BE-<MODULE>-<NNN> (e.g. BE-ORDER-001)\n\n- Each file covers one module\n\n- Case structure: ID, Title, Precondition, Steps, Expected Result\n\n- Map each case to acceptance criteria (AC-xxx)\n\n\n\n## Coverage Requirements:\n\n- Positive paths: happy path for each acceptance criterion\n\n- Negative paths: error scenarios (invalid input, not found, state violations)\n\n\n\n## Conditional Coverage (include ONLY if mentioned in upstream analysis):\n\n- Boundary conditions: include ONLY if upstream analyze-inputs-pi mentions value ranges, length limits, numeric bounds, or format constraints\n\n- State transitions: include ONLY if upstream analyze-inputs-pi mentions state machine\n\n- Authentication scenarios: include ONLY if upstream analyze-inputs-pi mentions auth mechanism\n\n- Timeout scenarios: include ONLY if upstream analyze-inputs-pi mentions timeout handling\n\n- Concurrency scenarios: include ONLY if upstream analyze-inputs-pi mentions concurrency/idempotency rules\n\n- If not mentioned, do NOT generate these test cases\n\n\n\n## Constraints:\n\n- Stay within writeSet: testcase/md/**\n\n- Do NOT re-read source documents or fall back to free-form analysis — use the validated structured artifact only\n\n\n\n- Do not write root artifacts/**"
|
|
234
|
+
},
|
|
235
|
+
{
|
|
236
|
+
"id": "emit-backend-case-manifest-pi",
|
|
237
|
+
"depends_on": [
|
|
238
|
+
"generate-backend-functional-cases-pi",
|
|
239
|
+
"backend-test-analysis-contract-shell"
|
|
240
|
+
],
|
|
241
|
+
"complexity": "MED",
|
|
242
|
+
"executor": "pi",
|
|
243
|
+
"role": "scout",
|
|
244
|
+
"writePolicy": "read-only",
|
|
245
|
+
"allowedPaths": [
|
|
246
|
+
"**"
|
|
247
|
+
],
|
|
248
|
+
"forbiddenPaths": [
|
|
249
|
+
".harness/**",
|
|
250
|
+
"artifacts/**"
|
|
251
|
+
],
|
|
252
|
+
"outputContract": "Pure Backend Test Case Manifest v1 JSON (schema docs/templates/backend-test-case-manifest.schema.json). No file writes; model must not write .harness/**.",
|
|
253
|
+
"retryPolicy": {
|
|
254
|
+
"maxAttempts": 3,
|
|
255
|
+
"backoff": "exponential",
|
|
256
|
+
"initialDelayMs": 2000,
|
|
257
|
+
"maxDelayMs": 30000,
|
|
258
|
+
"retryCategories": [
|
|
259
|
+
"timeout",
|
|
260
|
+
"network",
|
|
261
|
+
"rate-limit",
|
|
262
|
+
"unavailable"
|
|
263
|
+
]
|
|
264
|
+
},
|
|
265
|
+
"subtask_prompt": "Emit Backend Test Case Manifest v1 as pure JSON (or one fenced json block with no trailing text).\n\nRead-only: use validated contracts/backend-test-analysis.json pointer + testcase/md/** only. Do not write repository files or .harness/**.\n\nsourceBinding must match the analysis contract / DAG source binding exactly (taskId, requirementPath, requirementSha256, referencePaths, requirementIds).\n\nFor each functional case under testcase/md/: caseId BE-<MODULE>-<NNN>, acIds[], title, category, automationStatus.\n\nAfter case generation (pre-pytest), default automationStatus=planned. Use skipped/unsupported only with gapReason. Use generated only when file+symbol already exist.\n\nevidenceGaps: structured gaps for explicit AC-* that cannot be mapped to a case.\n\nDo NOT invent coverage percentages. Optional coverageSummary must match deterministic counts (gate recomputes/validates).\n\nNo secrets or credential-shaped fields."
|
|
266
|
+
},
|
|
267
|
+
{
|
|
268
|
+
"id": "backend-test-case-manifest-shell",
|
|
269
|
+
"depends_on": [
|
|
270
|
+
"emit-backend-case-manifest-pi"
|
|
271
|
+
],
|
|
272
|
+
"complexity": "LOW",
|
|
273
|
+
"executor": "shell",
|
|
274
|
+
"role": "verifier",
|
|
275
|
+
"writePolicy": "read-only",
|
|
276
|
+
"allowedPaths": [
|
|
277
|
+
"**"
|
|
278
|
+
],
|
|
279
|
+
"forbiddenPaths": [
|
|
280
|
+
".harness/**",
|
|
281
|
+
"artifacts/**"
|
|
282
|
+
],
|
|
283
|
+
"outputContract": "Validated run-owned Backend Test Case Manifest v1 at contracts/backend-test-case-manifest.json (schemaId backend-test-case-manifest-v1) with deterministic AC coverage.",
|
|
284
|
+
"subtask_prompt": "Materialize and validate Backend Test Case Manifest v1; fail closed on duplicate IDs, unknown AC, missing AC coverage without gap, or skipped without gapReason.",
|
|
285
|
+
"shell": {
|
|
286
|
+
"commands": [],
|
|
287
|
+
"jsonArtifactGate": {
|
|
288
|
+
"fromNodeId": "emit-backend-case-manifest-pi",
|
|
289
|
+
"schemaId": "backend-test-case-manifest-v1",
|
|
290
|
+
"artifactName": "backend-test-case-manifest.json",
|
|
291
|
+
"outputDir": "contracts"
|
|
292
|
+
},
|
|
293
|
+
"cwd": ".",
|
|
294
|
+
"timeoutMs": 60000
|
|
295
|
+
}
|
|
296
|
+
},
|
|
297
|
+
{
|
|
298
|
+
"id": "review-backend-cases-pi",
|
|
299
|
+
"depends_on": [
|
|
300
|
+
"backend-test-case-manifest-shell",
|
|
301
|
+
"backend-test-analysis-contract-shell"
|
|
302
|
+
],
|
|
303
|
+
"complexity": "HIGH",
|
|
304
|
+
"executor": "pi",
|
|
305
|
+
"role": "reviewer",
|
|
306
|
+
"writePolicy": "read-only",
|
|
307
|
+
"allowedPaths": [
|
|
308
|
+
"**"
|
|
309
|
+
],
|
|
310
|
+
"forbiddenPaths": [
|
|
311
|
+
".harness/**",
|
|
312
|
+
"artifacts/**"
|
|
313
|
+
],
|
|
314
|
+
"outputContract": "Plain Markdown whose first non-empty line is VERDICT: pass or VERDICT: request-revision; followed by Findings and Coverage Assessment. No file writes.",
|
|
315
|
+
"retryPolicy": {
|
|
316
|
+
"maxAttempts": 3,
|
|
317
|
+
"backoff": "exponential",
|
|
318
|
+
"initialDelayMs": 2000,
|
|
319
|
+
"maxDelayMs": 30000,
|
|
320
|
+
"retryCategories": [
|
|
321
|
+
"timeout",
|
|
322
|
+
"network",
|
|
323
|
+
"rate-limit",
|
|
324
|
+
"unavailable"
|
|
325
|
+
]
|
|
326
|
+
},
|
|
327
|
+
"subtask_prompt_markdown": "./backend-test-dag.review-cases.prompt.md"
|
|
328
|
+
},
|
|
329
|
+
{
|
|
330
|
+
"id": "review-backend-cases-gate-shell",
|
|
331
|
+
"depends_on": [
|
|
332
|
+
"review-backend-cases-pi"
|
|
333
|
+
],
|
|
334
|
+
"complexity": "LOW",
|
|
335
|
+
"executor": "shell",
|
|
336
|
+
"role": "verifier",
|
|
337
|
+
"writePolicy": "read-only",
|
|
338
|
+
"allowedPaths": [
|
|
339
|
+
"**"
|
|
340
|
+
],
|
|
341
|
+
"forbiddenPaths": [
|
|
342
|
+
".harness/**",
|
|
343
|
+
"artifacts/**"
|
|
344
|
+
],
|
|
345
|
+
"outputContract": "Deterministic backend case review gate: exit 0 only when review-backend-cases-pi emits VERDICT: pass.",
|
|
346
|
+
"subtask_prompt": "Deterministic gate: block pytest generation unless backend case review emitted VERDICT: pass.",
|
|
347
|
+
"shell": {
|
|
348
|
+
"commands": [],
|
|
349
|
+
"verdictGate": {
|
|
350
|
+
"fromNodeId": "review-backend-cases-pi",
|
|
351
|
+
"accept": [
|
|
352
|
+
"VERDICT: pass"
|
|
353
|
+
],
|
|
354
|
+
"label": "backend case review",
|
|
355
|
+
"lineMode": "first-verdict-line"
|
|
356
|
+
},
|
|
357
|
+
"cwd": ".",
|
|
358
|
+
"timeoutMs": 60000
|
|
359
|
+
}
|
|
360
|
+
},
|
|
361
|
+
{
|
|
362
|
+
"id": "generate-backend-pytest-pi",
|
|
363
|
+
"depends_on": [
|
|
364
|
+
"review-backend-cases-gate-shell",
|
|
365
|
+
"backend-test-execution-contract-shell"
|
|
366
|
+
],
|
|
367
|
+
"complexity": "HIGH",
|
|
368
|
+
"executor": "pi",
|
|
369
|
+
"role": "implementer",
|
|
370
|
+
"writePolicy": "exclusive",
|
|
371
|
+
"toolProfile": "write",
|
|
372
|
+
"writeSet": [
|
|
373
|
+
"testcase/**/test_*.py",
|
|
374
|
+
"testcase/**/helpers/**",
|
|
375
|
+
"testcase/**/factories/**"
|
|
376
|
+
],
|
|
377
|
+
"allowedPaths": [
|
|
378
|
+
"testcase/**",
|
|
379
|
+
"**"
|
|
380
|
+
],
|
|
381
|
+
"forbiddenPaths": [
|
|
382
|
+
".harness/**",
|
|
383
|
+
"artifacts/**"
|
|
384
|
+
],
|
|
385
|
+
"subtask_prompt_markdown": "./backend-test-dag.generate-pytest.prompt.md"
|
|
386
|
+
},
|
|
387
|
+
{
|
|
388
|
+
"id": "backend-test-traceability-gate-shell",
|
|
389
|
+
"depends_on": [
|
|
390
|
+
"generate-backend-pytest-pi",
|
|
391
|
+
"backend-test-case-manifest-shell"
|
|
392
|
+
],
|
|
393
|
+
"complexity": "LOW",
|
|
394
|
+
"executor": "shell",
|
|
395
|
+
"role": "verifier",
|
|
396
|
+
"writePolicy": "read-only",
|
|
397
|
+
"allowedPaths": [
|
|
398
|
+
"**"
|
|
399
|
+
],
|
|
400
|
+
"forbiddenPaths": [
|
|
401
|
+
".harness/**",
|
|
402
|
+
"artifacts/**"
|
|
403
|
+
],
|
|
404
|
+
"outputContract": "Deterministic traceability: generated cases have real file/symbol; skipped/unsupported have gapReason; convention symbols scanned under testcase/**/test_*.py.",
|
|
405
|
+
"subtask_prompt": "Fail closed when generated automation claims do not resolve to workspace pytest symbols, or skip/unsupported lacks gapReason.",
|
|
406
|
+
"shell": {
|
|
407
|
+
"commands": [
|
|
408
|
+
"backend-test-traceability-gate"
|
|
409
|
+
],
|
|
410
|
+
"cwd": ".",
|
|
411
|
+
"timeoutMs": 60000
|
|
412
|
+
}
|
|
413
|
+
},
|
|
414
|
+
{
|
|
415
|
+
"id": "execute-backend-pytest-shell",
|
|
416
|
+
"depends_on": [
|
|
417
|
+
"backend-test-traceability-gate-shell",
|
|
418
|
+
"backend-test-execution-contract-shell"
|
|
419
|
+
],
|
|
420
|
+
"complexity": "LOW",
|
|
421
|
+
"executor": "shell",
|
|
422
|
+
"role": "verifier",
|
|
423
|
+
"writePolicy": "read-only",
|
|
424
|
+
"allowedPaths": [
|
|
425
|
+
"**"
|
|
426
|
+
],
|
|
427
|
+
"forbiddenPaths": [
|
|
428
|
+
".harness/**",
|
|
429
|
+
"artifacts/**"
|
|
430
|
+
],
|
|
431
|
+
"outputContract": "Archived pytest stdout/stderr; raw pytestExitCode side-channel + JUnit at $HARNESS_DAG_RUN_DIR/reports/**. Exit 0/1 with non-empty JUnit finishes the node so parse/classify/retrospect can run; assertion failures remain recorded in exit file.",
|
|
432
|
+
"subtask_prompt": "Run pytest for the backend test suite; write JUnit + pytestExitCode evidence only under the current HARNESS_DAG_RUN_DIR/reports/.",
|
|
433
|
+
"shell": {
|
|
434
|
+
"commands": [
|
|
435
|
+
"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(Array.isArray(contract.evidenceGaps)&&contract.evidenceGaps.length) errors.push(\"evidenceGaps present: \"+contract.evidenceGaps.length);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-junit.xml\"; EXIT_FILE=\"${HARNESS_DAG_RUN_DIR}/reports/backend-test-pytest-exit.txt\"; mkdir -p \"$(dirname \"${REPORT}\")\"; 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}\""
|
|
436
|
+
],
|
|
437
|
+
"verifyEvidence": {
|
|
438
|
+
"phase": "final",
|
|
439
|
+
"quota": "full",
|
|
440
|
+
"commandSource": "inline",
|
|
441
|
+
"commandCount": 1,
|
|
442
|
+
"commandLabels": [
|
|
443
|
+
"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(Array.isArray(contract.evidenceGaps)&&contract.evidenceGaps.length) errors.push(\"evidenceGaps present: \"+contract.evidenceGaps.length);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-junit.xml\"; EXIT_FILE=\"${HARNESS_DAG_RUN_DIR}/reports/backend-test-pytest-exit.txt\"; mkdir -p \"$(dirname \"${REPORT}\")\"; 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}\""
|
|
444
|
+
],
|
|
445
|
+
"finalFullRequired": true
|
|
446
|
+
},
|
|
447
|
+
"cwd": ".",
|
|
448
|
+
"timeoutMs": 300000
|
|
449
|
+
}
|
|
450
|
+
},
|
|
451
|
+
{
|
|
452
|
+
"id": "parse-backend-test-result-shell",
|
|
453
|
+
"depends_on": [
|
|
454
|
+
"execute-backend-pytest-shell"
|
|
455
|
+
],
|
|
456
|
+
"complexity": "LOW",
|
|
457
|
+
"executor": "shell",
|
|
458
|
+
"role": "verifier",
|
|
459
|
+
"writePolicy": "read-only",
|
|
460
|
+
"allowedPaths": [
|
|
461
|
+
"**"
|
|
462
|
+
],
|
|
463
|
+
"forbiddenPaths": [
|
|
464
|
+
".harness/**",
|
|
465
|
+
"artifacts/**"
|
|
466
|
+
],
|
|
467
|
+
"outputContract": "Validated run-owned Backend Test Result v1 at contracts/backend-test-result.json (schemaId backend-test-result-v1) with outcome/counts/failures from deterministic JUnit parse.",
|
|
468
|
+
"subtask_prompt": "Materialize Backend Test Result v1 from JUnit + pytestExitCode under the current DAG run (fail-closed on missing/corrupt report).",
|
|
469
|
+
"shell": {
|
|
470
|
+
"commands": [],
|
|
471
|
+
"jsonArtifactGate": {
|
|
472
|
+
"fromNodeId": "execute-backend-pytest-shell",
|
|
473
|
+
"schemaId": "backend-test-result-v1",
|
|
474
|
+
"artifactName": "backend-test-result.json",
|
|
475
|
+
"outputDir": "contracts"
|
|
476
|
+
},
|
|
477
|
+
"cwd": ".",
|
|
478
|
+
"timeoutMs": 60000
|
|
479
|
+
}
|
|
480
|
+
},
|
|
481
|
+
{
|
|
482
|
+
"id": "classify-backend-test-result-pi",
|
|
483
|
+
"depends_on": [
|
|
484
|
+
"parse-backend-test-result-shell"
|
|
485
|
+
],
|
|
486
|
+
"complexity": "MED",
|
|
487
|
+
"executor": "pi",
|
|
488
|
+
"role": "reviewer",
|
|
489
|
+
"writePolicy": "read-only",
|
|
490
|
+
"allowedPaths": [
|
|
491
|
+
"**"
|
|
492
|
+
],
|
|
493
|
+
"forbiddenPaths": [
|
|
494
|
+
".harness/**",
|
|
495
|
+
"artifacts/**"
|
|
496
|
+
],
|
|
497
|
+
"outputContract": "Pure JSON classification: category in {ProductBug,TestBug,EnvFailure,ContractMismatch,FlakyTest,Unknown}, evidence[], confidence (capped), notes. No file writes.",
|
|
498
|
+
"subtask_prompt_markdown": "./backend-test-dag.classify.prompt.md"
|
|
499
|
+
},
|
|
500
|
+
{
|
|
501
|
+
"id": "test-retrospect-pi",
|
|
502
|
+
"depends_on": [
|
|
503
|
+
"classify-backend-test-result-pi"
|
|
504
|
+
],
|
|
505
|
+
"complexity": "MED",
|
|
506
|
+
"executor": "pi",
|
|
507
|
+
"role": "closeout",
|
|
508
|
+
"writePolicy": "exclusive",
|
|
509
|
+
"toolProfile": "write",
|
|
510
|
+
"writeSet": [
|
|
511
|
+
"docs/test-reports/**"
|
|
512
|
+
],
|
|
513
|
+
"allowedPaths": [
|
|
514
|
+
"docs/test-reports/**"
|
|
515
|
+
],
|
|
516
|
+
"forbiddenPaths": [
|
|
517
|
+
".harness/**",
|
|
518
|
+
"artifacts/**"
|
|
519
|
+
],
|
|
520
|
+
"subtask_prompt_markdown": "./backend-test-dag.retrospect.prompt.md"
|
|
521
|
+
},
|
|
522
|
+
{
|
|
523
|
+
"id": "backend-test-outcome-gate-shell",
|
|
524
|
+
"depends_on": [
|
|
525
|
+
"test-retrospect-pi"
|
|
526
|
+
],
|
|
527
|
+
"complexity": "LOW",
|
|
528
|
+
"executor": "shell",
|
|
529
|
+
"role": "verifier",
|
|
530
|
+
"writePolicy": "read-only",
|
|
531
|
+
"allowedPaths": [
|
|
532
|
+
"**"
|
|
533
|
+
],
|
|
534
|
+
"forbiddenPaths": [
|
|
535
|
+
".harness/**",
|
|
536
|
+
"artifacts/**"
|
|
537
|
+
],
|
|
538
|
+
"outputContract": "Shell exit 0 only when Result v1 outcome=passed with failed=0 and error=0; non-zero otherwise. Ignores retrospective Markdown.",
|
|
539
|
+
"subtask_prompt": "Gate the backend-test DAG on run-owned Result v1 shell facts only (not retrospective prose).",
|
|
540
|
+
"shell": {
|
|
541
|
+
"commands": [
|
|
542
|
+
"test -n \"${HARNESS_DAG_RUN_DIR:-}\" || { echo \"missing HARNESS_DAG_RUN_DIR for backend-test outcome gate\" >&2; exit 2; }; RESULT=\"${HARNESS_DAG_RUN_DIR}/contracts/backend-test-result.json\"; test -f \"${RESULT}\" || { echo \"missing backend-test result: ${RESULT}\" >&2; exit 2; }; node -e 'const fs=require(\"fs\");const r=JSON.parse(fs.readFileSync(process.argv[1],\"utf8\"));const outcome=String(r.outcome||\"\");const ok=outcome===\"passed\"&&Number(r.failed||0)===0&&Number(r.error||0)===0;console.log(\"backend-test outcome=\"+outcome+\" passed=\"+r.passed+\" failed=\"+r.failed+\" error=\"+r.error+\" executionStatus=\"+r.executionStatus);if(!ok){process.exit(1);}' \"${RESULT}\""
|
|
543
|
+
],
|
|
544
|
+
"verifyEvidence": {
|
|
545
|
+
"phase": "final",
|
|
546
|
+
"quota": "full",
|
|
547
|
+
"commandSource": "inline",
|
|
548
|
+
"commandCount": 1,
|
|
549
|
+
"commandLabels": [
|
|
550
|
+
"test -n \"${HARNESS_DAG_RUN_DIR:-}\" || { echo \"missing HARNESS_DAG_RUN_DIR for backend-test outcome gate\" >&2; exit 2; }; RESULT=\"${HARNESS_DAG_RUN_DIR}/contracts/backend-test-result.json\"; test -f \"${RESULT}\" || { echo \"missing backend-test result: ${RESULT}\" >&2; exit 2; }; node -e 'const fs=require(\"fs\");const r=JSON.parse(fs.readFileSync(process.argv[1],\"utf8\"));const outcome=String(r.outcome||\"\");const ok=outcome===\"passed\"&&Number(r.failed||0)===0&&Number(r.error||0)===0;console.log(\"backend-test outcome=\"+outcome+\" passed=\"+r.passed+\" failed=\"+r.failed+\" error=\"+r.error+\" executionStatus=\"+r.executionStatus);if(!ok){process.exit(1);}' \"${RESULT}\""
|
|
551
|
+
],
|
|
552
|
+
"finalFullRequired": true
|
|
553
|
+
},
|
|
554
|
+
"cwd": ".",
|
|
555
|
+
"timeoutMs": 60000
|
|
556
|
+
}
|
|
557
|
+
}
|
|
558
|
+
]
|
|
559
|
+
}
|