speccrew 0.6.69 → 0.7.1
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/.speccrew/agents/speccrew-task-worker.md +1 -1
- package/.speccrew/agents/speccrew-team-leader.md +336 -189
- package/.speccrew/skills/speccrew-agentflow-manager/SKILL.md +161 -0
- package/.speccrew/skills/speccrew-agentflow-manager/workflow.agentflow.xml +347 -0
- package/.speccrew/skills/speccrew-deploy-build/SKILL.md +3 -56
- package/.speccrew/skills/speccrew-deploy-build/workflow.agentflow.xml +125 -0
- package/.speccrew/skills/speccrew-deploy-migrate/SKILL.md +3 -64
- package/.speccrew/skills/speccrew-deploy-migrate/workflow.agentflow.xml +135 -0
- package/.speccrew/skills/speccrew-deploy-smoke-test/SKILL.md +4 -156
- package/.speccrew/skills/speccrew-deploy-smoke-test/workflow.agentflow.xml +178 -0
- package/.speccrew/skills/speccrew-deploy-startup/SKILL.md +3 -135
- package/.speccrew/skills/speccrew-deploy-startup/workflow.agentflow.xml +223 -0
- package/.speccrew/skills/speccrew-dev-backend/SKILL.md +10 -2
- package/.speccrew/skills/speccrew-dev-backend/workflow.agentflow.xml +254 -0
- package/.speccrew/skills/speccrew-dev-desktop-electron/SKILL.md +10 -2
- package/.speccrew/skills/speccrew-dev-desktop-electron/workflow.agentflow.xml +259 -0
- package/.speccrew/skills/speccrew-dev-desktop-tauri/SKILL.md +10 -2
- package/.speccrew/skills/speccrew-dev-desktop-tauri/workflow.agentflow.xml +245 -0
- package/.speccrew/skills/speccrew-dev-frontend/SKILL.md +10 -2
- package/.speccrew/skills/speccrew-dev-frontend/workflow.agentflow.xml +262 -0
- package/.speccrew/skills/speccrew-dev-mobile/SKILL.md +10 -2
- package/.speccrew/skills/speccrew-dev-mobile/workflow.agentflow.xml +244 -0
- package/.speccrew/skills/speccrew-dev-review-backend/SKILL.md +10 -2
- package/.speccrew/skills/speccrew-dev-review-backend/workflow.agentflow.xml +251 -0
- package/.speccrew/skills/speccrew-dev-review-desktop/SKILL.md +10 -2
- package/.speccrew/skills/speccrew-dev-review-desktop/workflow.agentflow.xml +214 -0
- package/.speccrew/skills/speccrew-dev-review-frontend/SKILL.md +10 -2
- package/.speccrew/skills/speccrew-dev-review-frontend/workflow.agentflow.xml +213 -0
- package/.speccrew/skills/speccrew-dev-review-mobile/SKILL.md +10 -2
- package/.speccrew/skills/speccrew-dev-review-mobile/workflow.agentflow.xml +214 -0
- package/.speccrew/skills/speccrew-fd-api-contract/SKILL.md +7 -1
- package/.speccrew/skills/speccrew-fd-api-contract/workflow.agentflow.xml +222 -0
- package/.speccrew/skills/speccrew-fd-feature-analyze/SKILL.md +7 -1
- package/.speccrew/skills/speccrew-fd-feature-analyze/workflow.agentflow.xml +223 -0
- package/.speccrew/skills/speccrew-fd-feature-design/SKILL.md +7 -1
- package/.speccrew/skills/speccrew-fd-feature-design/workflow.agentflow.xml +322 -0
- package/.speccrew/skills/speccrew-get-timestamp/SKILL.md +3 -39
- package/.speccrew/skills/speccrew-get-timestamp/workflow.agentflow.xml +43 -0
- package/.speccrew/skills/speccrew-knowledge-bizs-api-analyze/SKILL.md +57 -508
- package/.speccrew/skills/{speccrew-knowledge-bizs-api-analyze-xml/SKILL.md → speccrew-knowledge-bizs-api-analyze/workflow.agentflow.xml} +1 -154
- package/.speccrew/skills/speccrew-knowledge-bizs-api-graph/SKILL.md +73 -283
- package/.speccrew/skills/{speccrew-knowledge-bizs-api-graph-xml/SKILL.md → speccrew-knowledge-bizs-api-graph/workflow.agentflow.xml} +0 -298
- package/.speccrew/skills/speccrew-knowledge-bizs-dispatch/SKILL.md +931 -801
- package/.speccrew/skills/{speccrew-knowledge-bizs-dispatch-xml/SKILL.md → speccrew-knowledge-bizs-dispatch/workflow.agentflow.xml} +42 -272
- package/.speccrew/skills/speccrew-knowledge-bizs-identify-entries/SKILL.md +263 -71
- package/.speccrew/skills/{speccrew-knowledge-bizs-identify-entries-xml/SKILL.md → speccrew-knowledge-bizs-identify-entries/workflow.agentflow.xml} +8 -184
- package/.speccrew/skills/speccrew-knowledge-bizs-init-features/SKILL.md +200 -181
- package/.speccrew/skills/{speccrew-knowledge-bizs-init-features-xml/SKILL.md → speccrew-knowledge-bizs-init-features/workflow.agentflow.xml} +7 -134
- package/.speccrew/skills/speccrew-knowledge-bizs-module-classify/SKILL.md +5 -89
- package/.speccrew/skills/speccrew-knowledge-bizs-module-classify/workflow.agentflow.xml +129 -0
- package/.speccrew/skills/speccrew-knowledge-bizs-ui-analyze/SKILL.md +454 -326
- package/.speccrew/skills/{speccrew-knowledge-bizs-ui-analyze-xml/SKILL.md → speccrew-knowledge-bizs-ui-analyze/workflow.agentflow.xml} +8 -128
- package/.speccrew/skills/speccrew-knowledge-bizs-ui-graph/SKILL.md +302 -247
- package/.speccrew/skills/{speccrew-knowledge-bizs-ui-graph-xml/SKILL.md → speccrew-knowledge-bizs-ui-graph/workflow.agentflow.xml} +7 -199
- package/.speccrew/skills/speccrew-knowledge-bizs-ui-style-extract/SKILL.md +267 -156
- package/.speccrew/skills/{speccrew-knowledge-bizs-ui-style-extract-xml/SKILL.md → speccrew-knowledge-bizs-ui-style-extract/workflow.agentflow.xml} +7 -151
- package/.speccrew/skills/speccrew-knowledge-graph-query/SKILL.md +3 -122
- package/.speccrew/skills/speccrew-knowledge-graph-query/workflow.agentflow.xml +106 -0
- package/.speccrew/skills/speccrew-knowledge-graph-write/SKILL.md +3 -80
- package/.speccrew/skills/speccrew-knowledge-graph-write/workflow.agentflow.xml +152 -0
- package/.speccrew/skills/speccrew-knowledge-module-summarize/SKILL.md +371 -265
- package/.speccrew/skills/{speccrew-knowledge-module-summarize-xml/SKILL.md → speccrew-knowledge-module-summarize/workflow.agentflow.xml} +7 -197
- package/.speccrew/skills/speccrew-knowledge-system-summarize/SKILL.md +45 -333
- package/.speccrew/skills/{speccrew-knowledge-system-summarize-xml/SKILL.md → speccrew-knowledge-system-summarize/workflow.agentflow.xml} +0 -177
- package/.speccrew/skills/speccrew-knowledge-techs-dispatch/SKILL.md +174 -727
- package/.speccrew/skills/{speccrew-knowledge-techs-dispatch-xml/SKILL.md → speccrew-knowledge-techs-dispatch/workflow.agentflow.xml} +10 -351
- package/.speccrew/skills/speccrew-knowledge-techs-generate/SKILL.md +20 -150
- package/.speccrew/skills/{speccrew-knowledge-techs-generate-xml/SKILL.md → speccrew-knowledge-techs-generate/workflow.agentflow.xml} +0 -169
- package/.speccrew/skills/speccrew-knowledge-techs-generate-conventions/SKILL.md +75 -587
- package/.speccrew/skills/{speccrew-knowledge-techs-generate-conventions-xml/SKILL.md → speccrew-knowledge-techs-generate-conventions/workflow.agentflow.xml} +0 -153
- package/.speccrew/skills/speccrew-knowledge-techs-generate-quality/SKILL.md +463 -297
- package/.speccrew/skills/{speccrew-knowledge-techs-generate-quality-xml/SKILL.md → speccrew-knowledge-techs-generate-quality/workflow.agentflow.xml} +0 -164
- package/.speccrew/skills/speccrew-knowledge-techs-generate-ui-style/SKILL.md +57 -292
- package/.speccrew/skills/{speccrew-knowledge-techs-generate-ui-style-xml/SKILL.md → speccrew-knowledge-techs-generate-ui-style/workflow.agentflow.xml} +2 -193
- package/.speccrew/skills/speccrew-knowledge-techs-index/SKILL.md +49 -335
- package/.speccrew/skills/{speccrew-knowledge-techs-index-xml/SKILL.md → speccrew-knowledge-techs-index/workflow.agentflow.xml} +0 -167
- package/.speccrew/skills/speccrew-knowledge-techs-init/SKILL.md +28 -109
- package/.speccrew/skills/{speccrew-knowledge-techs-init-xml/SKILL.md → speccrew-knowledge-techs-init/workflow.agentflow.xml} +0 -189
- package/.speccrew/skills/speccrew-knowledge-techs-ui-analyze/SKILL.md +3 -487
- package/.speccrew/skills/speccrew-knowledge-techs-ui-analyze/workflow.agentflow.xml +278 -0
- package/.speccrew/skills/speccrew-pm-knowledge-detector/SKILL.md +3 -71
- package/.speccrew/skills/speccrew-pm-knowledge-detector/workflow.agentflow.xml +108 -0
- package/.speccrew/skills/speccrew-pm-module-initializer/SKILL.md +3 -107
- package/.speccrew/skills/speccrew-pm-module-initializer/workflow.agentflow.xml +139 -0
- package/.speccrew/skills/speccrew-pm-module-matcher/SKILL.md +3 -115
- package/.speccrew/skills/speccrew-pm-module-matcher/workflow.agentflow.xml +146 -0
- package/.speccrew/skills/speccrew-pm-requirement-analysis/SKILL.md +3 -343
- package/.speccrew/skills/speccrew-pm-requirement-analysis/workflow.agentflow.xml +174 -0
- package/.speccrew/skills/speccrew-pm-requirement-assess/SKILL.md +3 -91
- package/.speccrew/skills/speccrew-pm-requirement-assess/workflow.agentflow.xml +173 -0
- package/.speccrew/skills/speccrew-pm-requirement-clarify/SKILL.md +3 -224
- package/.speccrew/skills/speccrew-pm-requirement-clarify/workflow.agentflow.xml +159 -0
- package/.speccrew/skills/speccrew-pm-requirement-model/SKILL.md +3 -275
- package/.speccrew/skills/speccrew-pm-requirement-model/workflow.agentflow.xml +210 -0
- package/.speccrew/skills/speccrew-pm-requirement-simple/SKILL.md +3 -76
- package/.speccrew/skills/speccrew-pm-requirement-simple/workflow.agentflow.xml +120 -0
- package/.speccrew/skills/speccrew-pm-sub-prd-generate/SKILL.md +7 -1
- package/.speccrew/skills/speccrew-pm-sub-prd-generate/workflow.agentflow.xml +218 -0
- package/.speccrew/skills/speccrew-sd-backend/SKILL.md +7 -1
- package/.speccrew/skills/speccrew-sd-backend/workflow.agentflow.xml +264 -0
- package/.speccrew/skills/speccrew-sd-desktop/SKILL.md +7 -1
- package/.speccrew/skills/speccrew-sd-desktop/workflow.agentflow.xml +288 -0
- package/.speccrew/skills/speccrew-sd-framework-evaluate/SKILL.md +7 -1
- package/.speccrew/skills/speccrew-sd-framework-evaluate/workflow.agentflow.xml +235 -0
- package/.speccrew/skills/speccrew-sd-frontend/SKILL.md +7 -1
- package/.speccrew/skills/speccrew-sd-frontend/workflow.agentflow.xml +299 -0
- package/.speccrew/skills/speccrew-sd-mobile/SKILL.md +7 -1
- package/.speccrew/skills/speccrew-sd-mobile/workflow.agentflow.xml +301 -0
- package/.speccrew/skills/speccrew-test-case-design/SKILL.md +165 -284
- package/.speccrew/skills/speccrew-test-case-design/workflow.agentflow.xml +210 -0
- package/.speccrew/skills/speccrew-test-code-gen/SKILL.md +204 -324
- package/.speccrew/skills/speccrew-test-code-gen/workflow.agentflow.xml +265 -0
- package/.speccrew/skills/speccrew-test-reporter/SKILL.md +205 -184
- package/.speccrew/skills/speccrew-test-reporter/workflow.agentflow.xml +284 -0
- package/.speccrew/skills/speccrew-test-runner/SKILL.md +242 -241
- package/.speccrew/skills/speccrew-test-runner/workflow.agentflow.xml +314 -0
- package/bin/cli.js +8 -1
- package/lib/commands/init.js +11 -3
- package/lib/commands/update.js +11 -3
- package/lib/commands/validate.js +565 -0
- package/lib/utils.js +43 -0
- package/package.json +1 -1
- package/workspace-template/docs/rules/{xml-workflow-spec.md → agentflow-spec.md} +5 -5
- package/workspace-template/scripts/validate-agentflow.js +637 -0
- package/.speccrew/agents/speccrew-team-leader-xml.md +0 -480
- package/.speccrew/skills/speccrew-knowledge-bizs-dispatch/STATUS-FORMATS.md +0 -99
- package/.speccrew/skills/speccrew-knowledge-bizs-dispatch/scripts/batch-orchestrator.js +0 -176
- package/.speccrew/skills/speccrew-knowledge-bizs-dispatch/scripts/get-next-batch.js +0 -150
- package/.speccrew/skills/speccrew-knowledge-bizs-dispatch/scripts/get-pending-features.js +0 -106
- package/.speccrew/skills/speccrew-knowledge-bizs-dispatch/scripts/mark-stale.js +0 -249
- package/.speccrew/skills/speccrew-knowledge-bizs-dispatch/scripts/merge-features.js +0 -300
- package/.speccrew/skills/speccrew-knowledge-bizs-dispatch/scripts/process-batch-results.js +0 -915
- package/.speccrew/skills/speccrew-knowledge-bizs-dispatch/scripts/update-feature-status.js +0 -226
- package/.speccrew/skills/speccrew-knowledge-bizs-init-features/examples/features.json +0 -34
- package/.speccrew/skills/speccrew-knowledge-bizs-init-features/scripts/generate-inventory.js +0 -1087
- package/.speccrew/skills/speccrew-knowledge-bizs-init-features/scripts/test-inventory.js +0 -26
- package/.speccrew/skills/speccrew-knowledge-techs-dispatch/STATUS-FORMATS.md +0 -550
|
@@ -0,0 +1,178 @@
|
|
|
1
|
+
<?xml version="1.0" encoding="UTF-8"?>
|
|
2
|
+
<workflow id="deploy-smoke-test" status="pending" version="1.0" desc="Perform lightweight smoke testing against running application">
|
|
3
|
+
|
|
4
|
+
<!-- ============================================================
|
|
5
|
+
Input Parameters Definition
|
|
6
|
+
============================================================ -->
|
|
7
|
+
<block type="input" id="I1" desc="Workflow input parameters">
|
|
8
|
+
<field name="platform_id" required="true" type="string" desc="Platform identifier"/>
|
|
9
|
+
<field name="base_url" required="false" type="string" desc="Application base URL (e.g., http://localhost:8080). Required for http mode."/>
|
|
10
|
+
<field name="api_contract_paths" required="false" type="string" desc="Comma-separated paths to API Contract documents. Required for http mode."/>
|
|
11
|
+
<field name="iteration_path" required="true" type="string" desc="Current iteration directory path"/>
|
|
12
|
+
<field name="test_mode" required="false" type="string" default="http" desc="Test method: http (default), process, log"/>
|
|
13
|
+
<field name="expected_exit_code" required="false" type="string" default="0" desc="Expected process exit code for process mode"/>
|
|
14
|
+
<field name="log_file" required="false" type="string" desc="Log file path for log mode verification"/>
|
|
15
|
+
<field name="expected_log_patterns" required="false" type="string" desc="Comma-separated regex patterns expected in log for log mode"/>
|
|
16
|
+
<field name="process_name" required="false" type="string" desc="Process name or pattern to check for process mode"/>
|
|
17
|
+
</block>
|
|
18
|
+
|
|
19
|
+
<!-- ============================================================
|
|
20
|
+
Global Constraints
|
|
21
|
+
============================================================ -->
|
|
22
|
+
<block type="rule" id="R1" level="mandatory" desc="Smoke test constraints">
|
|
23
|
+
<field name="text">Smoke test is NOT integration testing — only verify HTTP status codes</field>
|
|
24
|
+
<field name="text">Pass rate threshold — If pass rate less than 80% then FAILED</field>
|
|
25
|
+
<field name="text">Critical GET endpoints — If any critical GET endpoint returns 404 then FAILED</field>
|
|
26
|
+
<field name="text">No business logic testing — Smoke test does not validate request/response bodies</field>
|
|
27
|
+
</block>
|
|
28
|
+
|
|
29
|
+
<!-- ============================================================
|
|
30
|
+
Test Mode Selection Gateway
|
|
31
|
+
============================================================ -->
|
|
32
|
+
<block type="gateway" id="G0" mode="exclusive" desc="Select test mode execution path">
|
|
33
|
+
|
|
34
|
+
<!-- HTTP Mode (default) -->
|
|
35
|
+
<branch test="${test_mode} == 'http' OR ${test_mode} == null" name="HTTP Mode">
|
|
36
|
+
|
|
37
|
+
<!-- Step 1: Parse API Contracts -->
|
|
38
|
+
<block type="task" id="B1" action="analyze" desc="Parse API Contract paths">
|
|
39
|
+
<field name="input">${api_contract_paths}</field>
|
|
40
|
+
<field name="split_by">,</field>
|
|
41
|
+
<field name="output" var="contract_path_list"/>
|
|
42
|
+
</block>
|
|
43
|
+
|
|
44
|
+
<block type="loop" id="L1" over="${contract_path_list}" as="contract_path" desc="Read each API Contract document">
|
|
45
|
+
<block type="task" action="read-file" desc="Read API Contract">
|
|
46
|
+
<field name="path">${contract_path}</field>
|
|
47
|
+
<field name="output" var="contract_content"/>
|
|
48
|
+
</block>
|
|
49
|
+
</block>
|
|
50
|
+
|
|
51
|
+
<block type="task" id="B2" action="analyze" desc="Extract endpoint list from contracts">
|
|
52
|
+
<field name="rules">
|
|
53
|
+
- Parse endpoints from contract:
|
|
54
|
+
- Method: GET, POST, PUT, DELETE, etc.
|
|
55
|
+
- Path: endpoint path (e.g., /api/users)
|
|
56
|
+
- Expected status code: from contract definition
|
|
57
|
+
- Filter for core endpoints only
|
|
58
|
+
- For GET endpoints: test directly with full validation
|
|
59
|
+
- For POST/PUT/DELETE: only verify endpoint exists (expect 400/401/405 is acceptable, NOT 404)
|
|
60
|
+
</field>
|
|
61
|
+
<field name="output" var="endpoint_list"/>
|
|
62
|
+
</block>
|
|
63
|
+
|
|
64
|
+
<!-- Step 2: Execute Smoke Tests -->
|
|
65
|
+
<block type="loop" id="L2" over="${endpoint_list}" as="endpoint" desc="Test each endpoint">
|
|
66
|
+
<block type="task" action="run-script" desc="Execute curl for endpoint">
|
|
67
|
+
<field name="command">curl -s -o /dev/null -w "%{http_code}" -X ${endpoint.method} ${base_url}${endpoint.path}</field>
|
|
68
|
+
<field name="output" var="endpoint.http_status"/>
|
|
69
|
+
</block>
|
|
70
|
+
</block>
|
|
71
|
+
|
|
72
|
+
<!-- Step 3: Evaluate Results -->
|
|
73
|
+
<block type="task" id="B3" action="analyze" desc="Apply pass criteria">
|
|
74
|
+
<field name="rules">
|
|
75
|
+
- GET endpoints: Pass if HTTP 200 or 301/302 (redirect)
|
|
76
|
+
- POST/PUT/DELETE endpoints: Pass if NOT 404 (any other status acceptable)
|
|
77
|
+
- Health endpoint: Pass if HTTP 200
|
|
78
|
+
- Calculate pass_rate = (passed_count / total_count) * 100
|
|
79
|
+
</field>
|
|
80
|
+
<field name="output" var="evaluation_result"/>
|
|
81
|
+
</block>
|
|
82
|
+
|
|
83
|
+
<block type="gateway" id="G1" mode="guard" desc="Check pass rate threshold"
|
|
84
|
+
test="${evaluation_result.pass_rate} >= 80"
|
|
85
|
+
fail-action="stop">
|
|
86
|
+
<field name="message">Smoke test failed with pass rate ${evaluation_result.pass_rate}% (threshold: 80%)</field>
|
|
87
|
+
</block>
|
|
88
|
+
|
|
89
|
+
</branch>
|
|
90
|
+
|
|
91
|
+
<!-- Process Mode -->
|
|
92
|
+
<branch test="${test_mode} == 'process'" name="Process Mode">
|
|
93
|
+
|
|
94
|
+
<block type="task" id="B4" action="run-script" desc="Check process is running">
|
|
95
|
+
<field name="command">
|
|
96
|
+
Windows: tasklist /FI "IMAGENAME eq ${process_name}" | findstr /I "${process_name}"
|
|
97
|
+
Unix/Mac: pgrep -f "${process_name}"
|
|
98
|
+
</field>
|
|
99
|
+
<field name="output" var="process_check_result"/>
|
|
100
|
+
</block>
|
|
101
|
+
|
|
102
|
+
<block type="task" id="B5" action="analyze" desc="Verify process stability">
|
|
103
|
+
<field name="rules">
|
|
104
|
+
- Record process start time
|
|
105
|
+
- Wait 10 seconds
|
|
106
|
+
- Check if process is still running (not crashed)
|
|
107
|
+
- If process has exited: get exit code and compare with expected_exit_code (default: 0)
|
|
108
|
+
</field>
|
|
109
|
+
<field name="output" var="process_stability_result"/>
|
|
110
|
+
</block>
|
|
111
|
+
|
|
112
|
+
<block type="gateway" id="G2" mode="guard" desc="Verify process running"
|
|
113
|
+
test="${process_stability_result.status} == 'RUNNING' OR ${process_stability_result.exit_code} == ${expected_exit_code}"
|
|
114
|
+
fail-action="stop">
|
|
115
|
+
<field name="message">Process verification failed. Process not running or exit code mismatch.</field>
|
|
116
|
+
</block>
|
|
117
|
+
|
|
118
|
+
</branch>
|
|
119
|
+
|
|
120
|
+
<!-- Log Mode -->
|
|
121
|
+
<branch test="${test_mode} == 'log'" name="Log Mode">
|
|
122
|
+
|
|
123
|
+
<block type="task" id="B6" action="read-file" desc="Read log file content">
|
|
124
|
+
<field name="path">${log_file}</field>
|
|
125
|
+
<field name="on_fail">STOP - log file not found</field>
|
|
126
|
+
<field name="output" var="log_content"/>
|
|
127
|
+
</block>
|
|
128
|
+
|
|
129
|
+
<block type="task" id="B7" action="analyze" desc="Parse expected patterns">
|
|
130
|
+
<field name="input">${expected_log_patterns}</field>
|
|
131
|
+
<field name="split_by">,</field>
|
|
132
|
+
<field name="output" var="pattern_list"/>
|
|
133
|
+
</block>
|
|
134
|
+
|
|
135
|
+
<block type="loop" id="L3" over="${pattern_list}" as="pattern" desc="Check each pattern in log">
|
|
136
|
+
<block type="task" action="run-script" desc="Check pattern in log">
|
|
137
|
+
<field name="command">
|
|
138
|
+
Windows: Select-String -Path "${log_file}" -Pattern "${pattern}"
|
|
139
|
+
Unix/Mac: grep -E "${pattern}" "${log_file}"
|
|
140
|
+
</field>
|
|
141
|
+
<field name="output" var="pattern.found"/>
|
|
142
|
+
</block>
|
|
143
|
+
</block>
|
|
144
|
+
|
|
145
|
+
<block type="task" id="B8" action="analyze" desc="Evaluate log patterns">
|
|
146
|
+
<field name="rules">
|
|
147
|
+
- Pass criteria: ALL expected patterns found in log
|
|
148
|
+
- Fail: Any pattern missing → report which patterns were not found
|
|
149
|
+
</field>
|
|
150
|
+
<field name="output" var="log_verification_result"/>
|
|
151
|
+
</block>
|
|
152
|
+
|
|
153
|
+
<block type="gateway" id="G3" mode="guard" desc="Verify all patterns found"
|
|
154
|
+
test="${log_verification_result.all_patterns_found} == true"
|
|
155
|
+
fail-action="stop">
|
|
156
|
+
<field name="message">Log verification failed. Missing patterns: ${log_verification_result.missing_patterns}</field>
|
|
157
|
+
</block>
|
|
158
|
+
|
|
159
|
+
</branch>
|
|
160
|
+
|
|
161
|
+
</block>
|
|
162
|
+
|
|
163
|
+
<!-- ============================================================
|
|
164
|
+
Output Results
|
|
165
|
+
============================================================ -->
|
|
166
|
+
<block type="output" id="O1" desc="Workflow output results">
|
|
167
|
+
<field name="status" value="SUCCESS" type="string" desc="Test status"/>
|
|
168
|
+
<field name="platform_id" from="${platform_id}" type="string" desc="Platform identifier"/>
|
|
169
|
+
<field name="base_url" from="${base_url}" type="string" desc="Base URL tested"/>
|
|
170
|
+
<field name="test_mode" from="${test_mode}" type="string" desc="Test mode used"/>
|
|
171
|
+
<field name="endpoints_tested" from="${endpoint_list.length}" type="number" desc="Number of endpoints tested"/>
|
|
172
|
+
<field name="pass_rate" from="${evaluation_result.pass_rate}" type="number" desc="Pass rate percentage"/>
|
|
173
|
+
<field name="passed_count" from="${evaluation_result.passed_count}" type="number" desc="Number of passed tests"/>
|
|
174
|
+
<field name="failed_count" from="${evaluation_result.failed_count}" type="number" desc="Number of failed tests"/>
|
|
175
|
+
<field name="test_results" from="${evaluation_result.results}" type="array" desc="Detailed test results"/>
|
|
176
|
+
</block>
|
|
177
|
+
|
|
178
|
+
</workflow>
|
|
@@ -25,143 +25,11 @@ tools: Read, Bash
|
|
|
25
25
|
| `log_file` | No | string | Path to application log file (for `log` mode) |
|
|
26
26
|
| `success_pattern` | No | string | Regex pattern in log that indicates successful startup (for `log` mode, e.g., `"Application started"` or `"Ready"`) |
|
|
27
27
|
|
|
28
|
-
|
|
28
|
+
## AgentFlow Definition
|
|
29
29
|
|
|
30
|
-
|
|
30
|
+
<!-- @agentflow: workflow.agentflow.xml -->
|
|
31
31
|
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
1. **Execute start_cmd in background via Bash**
|
|
35
|
-
- Working directory: `project_root`
|
|
36
|
-
- Command: `start_cmd`
|
|
37
|
-
- Use background execution (e.g., `nohup {start_cmd} > app.log 2>&1 &` on Unix)
|
|
38
|
-
- Capture the process PID
|
|
39
|
-
|
|
40
|
-
2. **Record PID for cleanup**
|
|
41
|
-
- Store PID for later reference
|
|
42
|
-
- Log: "Application started with PID {pid}"
|
|
43
|
-
|
|
44
|
-
3. **Wait for initial startup**
|
|
45
|
-
- Wait 5 seconds for application initialization
|
|
46
|
-
- Log: "Waiting for application to initialize..."
|
|
47
|
-
|
|
48
|
-
## Step 2: Verification (Based on Mode)
|
|
49
|
-
|
|
50
|
-
### Verification Strategy
|
|
51
|
-
|
|
52
|
-
Based on `verification_mode` parameter:
|
|
53
|
-
|
|
54
|
-
**Mode: `http`** (default — for server/web applications)
|
|
55
|
-
- Poll `health_url` every 5 seconds using curl
|
|
56
|
-
- Success: HTTP 200 response
|
|
57
|
-
- Timeout: `health_timeout` seconds
|
|
58
|
-
|
|
59
|
-
**Mode: `process`** (for desktop/mobile/client applications)
|
|
60
|
-
- Check if process `process_name` is running
|
|
61
|
-
- On Windows: `tasklist /FI "IMAGENAME eq {process_name}" | findstr /I "{process_name}"`
|
|
62
|
-
- On Unix/Mac: `pgrep -f "{process_name}"`
|
|
63
|
-
- Success: Process found and running
|
|
64
|
-
- Timeout: `health_timeout` seconds (default 30s)
|
|
65
|
-
|
|
66
|
-
**Mode: `log`** (for applications with log-based startup confirmation)
|
|
67
|
-
- Monitor `log_file` for `success_pattern`
|
|
68
|
-
- On Windows: `Select-String -Path "{log_file}" -Pattern "{success_pattern}"`
|
|
69
|
-
- On Unix/Mac: `grep -m 1 "{success_pattern}" "{log_file}"`
|
|
70
|
-
- Poll every 3 seconds
|
|
71
|
-
- Success: Pattern found in log
|
|
72
|
-
- Timeout: `health_timeout` seconds (default 60s)
|
|
73
|
-
|
|
74
|
-
### Execution by Mode
|
|
75
|
-
|
|
76
|
-
#### HTTP Mode (default)
|
|
77
|
-
|
|
78
|
-
Poll health endpoint until success or timeout:
|
|
79
|
-
|
|
80
|
-
1. **Calculate max attempts**
|
|
81
|
-
- timeout_seconds = parseInt(health_timeout) || 60
|
|
82
|
-
- max_attempts = timeout_seconds / 5
|
|
83
|
-
- attempt = 0
|
|
84
|
-
|
|
85
|
-
2. **Poll health_url**
|
|
86
|
-
```bash
|
|
87
|
-
curl -s -o /dev/null -w "%{http_code}" {health_url}
|
|
88
|
-
```
|
|
89
|
-
|
|
90
|
-
3. **Check response**
|
|
91
|
-
- HTTP 200 → Health check passed, continue to Step 3
|
|
92
|
-
- Other codes → Increment attempt, wait 5 seconds, retry
|
|
93
|
-
|
|
94
|
-
4. **Timeout handling**
|
|
95
|
-
- If attempt >= max_attempts → FAILED with Error Category: RUNTIME_ERROR
|
|
96
|
-
- Report: "Health check timed out after {timeout_seconds}s"
|
|
97
|
-
|
|
98
|
-
#### Process Mode (for client apps)
|
|
99
|
-
|
|
100
|
-
Verify process is running:
|
|
101
|
-
|
|
102
|
-
1. **Calculate max attempts**
|
|
103
|
-
- timeout_seconds = parseInt(health_timeout) || 30
|
|
104
|
-
- max_attempts = timeout_seconds / 3
|
|
105
|
-
- attempt = 0
|
|
106
|
-
|
|
107
|
-
2. **Check process existence**
|
|
108
|
-
- **Windows**:
|
|
109
|
-
```powershell
|
|
110
|
-
tasklist /FI "IMAGENAME eq {process_name}" | findstr /I "{process_name}"
|
|
111
|
-
```
|
|
112
|
-
- **Unix/Mac**:
|
|
113
|
-
```bash
|
|
114
|
-
pgrep -f "{process_name}"
|
|
115
|
-
```
|
|
116
|
-
|
|
117
|
-
3. **Check result**
|
|
118
|
-
- Process found → Verification passed, continue to Step 3
|
|
119
|
-
- Process not found → Increment attempt, wait 3 seconds, retry
|
|
120
|
-
|
|
121
|
-
4. **Timeout handling**
|
|
122
|
-
- If attempt >= max_attempts → FAILED with Error Category: RUNTIME_ERROR
|
|
123
|
-
- Report: "Process verification timed out after {timeout_seconds}s - process {process_name} not found"
|
|
124
|
-
|
|
125
|
-
#### Log Mode (for log-based verification)
|
|
126
|
-
|
|
127
|
-
Monitor log file for success pattern:
|
|
128
|
-
|
|
129
|
-
1. **Calculate max attempts**
|
|
130
|
-
- timeout_seconds = parseInt(health_timeout) || 60
|
|
131
|
-
- max_attempts = timeout_seconds / 3
|
|
132
|
-
- attempt = 0
|
|
133
|
-
|
|
134
|
-
2. **Check log file for success_pattern**
|
|
135
|
-
- **Windows**:
|
|
136
|
-
```powershell
|
|
137
|
-
Select-String -Path "{log_file}" -Pattern "{success_pattern}"
|
|
138
|
-
```
|
|
139
|
-
- **Unix/Mac**:
|
|
140
|
-
```bash
|
|
141
|
-
grep -m 1 "{success_pattern}" "{log_file}"
|
|
142
|
-
```
|
|
143
|
-
|
|
144
|
-
3. **Check result**
|
|
145
|
-
- Pattern found → Verification passed, continue to Step 3
|
|
146
|
-
- Pattern not found → Increment attempt, wait 3 seconds, retry
|
|
147
|
-
|
|
148
|
-
4. **Timeout handling**
|
|
149
|
-
- If attempt >= max_attempts → FAILED with Error Category: RUNTIME_ERROR
|
|
150
|
-
- Report: "Log verification timed out after {timeout_seconds}s - pattern '{success_pattern}' not found in {log_file}"
|
|
151
|
-
|
|
152
|
-
## Step 3: Report Startup Status
|
|
153
|
-
|
|
154
|
-
Compile and report startup results:
|
|
155
|
-
|
|
156
|
-
1. **Record service information**
|
|
157
|
-
- Service URL: derived from `health_url` (remove `/actuator/health` if present)
|
|
158
|
-
- Health status: UP / DOWN
|
|
159
|
-
- Startup duration: time from start to health success
|
|
160
|
-
- PID: process ID for cleanup
|
|
161
|
-
|
|
162
|
-
2. **Verify application is still running**
|
|
163
|
-
- Check if process with recorded PID exists
|
|
164
|
-
- If not running → FAILED with Error Category: RUNTIME_ERROR
|
|
32
|
+
> **REQUIRED**: Before executing this workflow, read the XML workflow specification: `speccrew-workspace/docs/rules/agentflow-spec.md`
|
|
165
33
|
|
|
166
34
|
# Task Completion Report
|
|
167
35
|
|
|
@@ -0,0 +1,223 @@
|
|
|
1
|
+
<?xml version="1.0" encoding="UTF-8"?>
|
|
2
|
+
<workflow id="deploy-startup" status="pending" version="1.0" desc="Start application and perform health check verification">
|
|
3
|
+
|
|
4
|
+
<!-- ============================================================
|
|
5
|
+
Input Parameters Definition
|
|
6
|
+
============================================================ -->
|
|
7
|
+
<block type="input" id="I1" desc="Workflow input parameters">
|
|
8
|
+
<field name="platform_id" required="true" type="string" desc="Platform identifier"/>
|
|
9
|
+
<field name="start_cmd" required="true" type="string" desc="Application start command from conventions-data (e.g., java -jar target/app.jar)"/>
|
|
10
|
+
<field name="health_url" required="false" type="string" desc="Health check URL. Required for http mode."/>
|
|
11
|
+
<field name="health_timeout" required="false" type="string" default="60" desc="Health check timeout in seconds, default 60"/>
|
|
12
|
+
<field name="project_root" required="true" type="string" desc="Absolute path to the project root directory"/>
|
|
13
|
+
<field name="iteration_path" required="true" type="string" desc="Current iteration directory path"/>
|
|
14
|
+
<field name="verification_mode" required="false" type="string" default="http" desc="Verification method: http (default), process, log"/>
|
|
15
|
+
<field name="process_name" required="false" type="string" desc="Process name or pattern to check for process mode"/>
|
|
16
|
+
<field name="log_file" required="false" type="string" desc="Path to application log file for log mode"/>
|
|
17
|
+
<field name="success_pattern" required="false" type="string" desc="Regex pattern in log indicating successful startup for log mode"/>
|
|
18
|
+
</block>
|
|
19
|
+
|
|
20
|
+
<!-- ============================================================
|
|
21
|
+
Global Constraints
|
|
22
|
+
============================================================ -->
|
|
23
|
+
<block type="rule" id="R1" level="mandatory" desc="Startup execution constraints">
|
|
24
|
+
<field name="text">Application must start in background and continue running</field>
|
|
25
|
+
<field name="text">Always record and report the process PID</field>
|
|
26
|
+
<field name="text">Poll health endpoint every 5 seconds until success or timeout</field>
|
|
27
|
+
<field name="text">Timeout is configurable via health_timeout parameter</field>
|
|
28
|
+
<field name="text">Verify application process is still running after health check</field>
|
|
29
|
+
</block>
|
|
30
|
+
|
|
31
|
+
<!-- ============================================================
|
|
32
|
+
Main Processing Sequence
|
|
33
|
+
============================================================ -->
|
|
34
|
+
<sequence id="S1" name="Application Startup" status="pending" desc="Start application, verify health, report status">
|
|
35
|
+
|
|
36
|
+
<!-- Step 1: Start Application -->
|
|
37
|
+
<block type="task" id="B1" action="run-script" desc="Execute start command in background">
|
|
38
|
+
<field name="command">${start_cmd}</field>
|
|
39
|
+
<field name="working_directory">${project_root}</field>
|
|
40
|
+
<field name="background">true</field>
|
|
41
|
+
<field name="note">On Unix: nohup {start_cmd} > app.log 2>&1 &</field>
|
|
42
|
+
<field name="output" var="start_result"/>
|
|
43
|
+
</block>
|
|
44
|
+
|
|
45
|
+
<block type="task" id="B2" action="analyze" desc="Record PID for cleanup">
|
|
46
|
+
<field name="rules">Extract PID from start_result and store for later reference</field>
|
|
47
|
+
<field name="output" var="pid"/>
|
|
48
|
+
</block>
|
|
49
|
+
|
|
50
|
+
<block type="event" id="E1" action="log" level="info" desc="Log application started">
|
|
51
|
+
<field name="message">Application started with PID ${pid}</field>
|
|
52
|
+
</block>
|
|
53
|
+
|
|
54
|
+
<block type="event" id="E2" action="log" level="info" desc="Wait for initialization">
|
|
55
|
+
<field name="message">Waiting for application to initialize...</field>
|
|
56
|
+
<field name="wait_seconds">5</field>
|
|
57
|
+
</block>
|
|
58
|
+
|
|
59
|
+
<!-- Step 2: Verification (Based on Mode) -->
|
|
60
|
+
<block type="gateway" id="G0" mode="exclusive" desc="Select verification mode">
|
|
61
|
+
|
|
62
|
+
<!-- HTTP Mode (default) -->
|
|
63
|
+
<branch test="${verification_mode} == 'http' OR ${verification_mode} == null" name="HTTP Verification">
|
|
64
|
+
|
|
65
|
+
<block type="task" id="B3" action="analyze" desc="Calculate max attempts">
|
|
66
|
+
<field name="rules">
|
|
67
|
+
- timeout_seconds = parseInt(health_timeout) || 60
|
|
68
|
+
- max_attempts = timeout_seconds / 5
|
|
69
|
+
</field>
|
|
70
|
+
<field name="output" var="http_verification_config"/>
|
|
71
|
+
</block>
|
|
72
|
+
|
|
73
|
+
<block type="loop" id="L1" over="${range(1, ${http_verification_config.max_attempts})}" as="attempt" desc="Poll health URL">
|
|
74
|
+
<block type="task" action="run-script" desc="Check health endpoint">
|
|
75
|
+
<field name="command">curl -s -o /dev/null -w "%{http_code}" ${health_url}</field>
|
|
76
|
+
<field name="output" var="http_status"/>
|
|
77
|
+
</block>
|
|
78
|
+
|
|
79
|
+
<block type="gateway" mode="guard" desc="Check HTTP status">
|
|
80
|
+
<branch test="${http_status} == 200">
|
|
81
|
+
<block type="event" action="log" level="info" desc="Health check passed">
|
|
82
|
+
<field name="message">Health check passed with HTTP 200</field>
|
|
83
|
+
<field name="output" var="health_status" value="UP"/>
|
|
84
|
+
</block>
|
|
85
|
+
</branch>
|
|
86
|
+
</block>
|
|
87
|
+
|
|
88
|
+
<block type="event" action="log" level="debug" desc="Wait before retry">
|
|
89
|
+
<field name="message">Attempt ${attempt}: HTTP ${http_status}, waiting 5 seconds...</field>
|
|
90
|
+
<field name="wait_seconds">5</field>
|
|
91
|
+
</block>
|
|
92
|
+
</block>
|
|
93
|
+
|
|
94
|
+
<block type="gateway" id="G1" mode="guard" desc="Check health check timeout"
|
|
95
|
+
test="${health_status} == 'UP'"
|
|
96
|
+
fail-action="stop">
|
|
97
|
+
<field name="message">Health check timed out after ${health_timeout}s</field>
|
|
98
|
+
</block>
|
|
99
|
+
|
|
100
|
+
</branch>
|
|
101
|
+
|
|
102
|
+
<!-- Process Mode -->
|
|
103
|
+
<branch test="${verification_mode} == 'process'" name="Process Verification">
|
|
104
|
+
|
|
105
|
+
<block type="task" id="B4" action="analyze" desc="Calculate max attempts for process mode">
|
|
106
|
+
<field name="rules">
|
|
107
|
+
- timeout_seconds = parseInt(health_timeout) || 30
|
|
108
|
+
- max_attempts = timeout_seconds / 3
|
|
109
|
+
</field>
|
|
110
|
+
<field name="output" var="process_verification_config"/>
|
|
111
|
+
</block>
|
|
112
|
+
|
|
113
|
+
<block type="loop" id="L2" over="${range(1, ${process_verification_config.max_attempts})}" as="attempt" desc="Check process existence">
|
|
114
|
+
<block type="task" action="run-script" desc="Check process running">
|
|
115
|
+
<field name="command">
|
|
116
|
+
Windows: tasklist /FI "IMAGENAME eq ${process_name}" | findstr /I "${process_name}"
|
|
117
|
+
Unix/Mac: pgrep -f "${process_name}"
|
|
118
|
+
</field>
|
|
119
|
+
<field name="output" var="process_found"/>
|
|
120
|
+
</block>
|
|
121
|
+
|
|
122
|
+
<block type="gateway" mode="guard" desc="Check process found">
|
|
123
|
+
<branch test="${process_found} == true">
|
|
124
|
+
<block type="event" action="log" level="info" desc="Process verification passed">
|
|
125
|
+
<field name="message">Process ${process_name} is running</field>
|
|
126
|
+
<field name="output" var="health_status" value="UP"/>
|
|
127
|
+
</block>
|
|
128
|
+
</branch>
|
|
129
|
+
</block>
|
|
130
|
+
|
|
131
|
+
<block type="event" action="log" level="debug" desc="Wait before retry">
|
|
132
|
+
<field name="message">Attempt ${attempt}: Process not found, waiting 3 seconds...</field>
|
|
133
|
+
<field name="wait_seconds">3</field>
|
|
134
|
+
</block>
|
|
135
|
+
</block>
|
|
136
|
+
|
|
137
|
+
<block type="gateway" id="G2" mode="guard" desc="Check process verification timeout"
|
|
138
|
+
test="${health_status} == 'UP'"
|
|
139
|
+
fail-action="stop">
|
|
140
|
+
<field name="message">Process verification timed out after ${health_timeout}s - process ${process_name} not found</field>
|
|
141
|
+
</block>
|
|
142
|
+
|
|
143
|
+
</branch>
|
|
144
|
+
|
|
145
|
+
<!-- Log Mode -->
|
|
146
|
+
<branch test="${verification_mode} == 'log'" name="Log Verification">
|
|
147
|
+
|
|
148
|
+
<block type="task" id="B5" action="analyze" desc="Calculate max attempts for log mode">
|
|
149
|
+
<field name="rules">
|
|
150
|
+
- timeout_seconds = parseInt(health_timeout) || 60
|
|
151
|
+
- max_attempts = timeout_seconds / 3
|
|
152
|
+
</field>
|
|
153
|
+
<field name="output" var="log_verification_config"/>
|
|
154
|
+
</block>
|
|
155
|
+
|
|
156
|
+
<block type="loop" id="L3" over="${range(1, ${log_verification_config.max_attempts})}" as="attempt" desc="Monitor log for success pattern">
|
|
157
|
+
<block type="task" action="run-script" desc="Check log for success pattern">
|
|
158
|
+
<field name="command">
|
|
159
|
+
Windows: Select-String -Path "${log_file}" -Pattern "${success_pattern}"
|
|
160
|
+
Unix/Mac: grep -m 1 "${success_pattern}" "${log_file}"
|
|
161
|
+
</field>
|
|
162
|
+
<field name="output" var="pattern_found"/>
|
|
163
|
+
</block>
|
|
164
|
+
|
|
165
|
+
<block type="gateway" mode="guard" desc="Check pattern found">
|
|
166
|
+
<branch test="${pattern_found} == true">
|
|
167
|
+
<block type="event" action="log" level="info" desc="Log verification passed">
|
|
168
|
+
<field name="message">Success pattern '${success_pattern}' found in log</field>
|
|
169
|
+
<field name="output" var="health_status" value="UP"/>
|
|
170
|
+
</block>
|
|
171
|
+
</branch>
|
|
172
|
+
</block>
|
|
173
|
+
|
|
174
|
+
<block type="event" action="log" level="debug" desc="Wait before retry">
|
|
175
|
+
<field name="message">Attempt ${attempt}: Pattern not found, waiting 3 seconds...</field>
|
|
176
|
+
<field name="wait_seconds">3</field>
|
|
177
|
+
</block>
|
|
178
|
+
</block>
|
|
179
|
+
|
|
180
|
+
<block type="gateway" id="G3" mode="guard" desc="Check log verification timeout"
|
|
181
|
+
test="${health_status} == 'UP'"
|
|
182
|
+
fail-action="stop">
|
|
183
|
+
<field name="message">Log verification timed out after ${health_timeout}s - pattern '${success_pattern}' not found in ${log_file}</field>
|
|
184
|
+
</block>
|
|
185
|
+
|
|
186
|
+
</branch>
|
|
187
|
+
|
|
188
|
+
</block>
|
|
189
|
+
|
|
190
|
+
<!-- Step 3: Report Startup Status -->
|
|
191
|
+
<block type="task" id="B6" action="analyze" desc="Derive service URL from health URL">
|
|
192
|
+
<field name="rules">Remove /actuator/health from health_url if present to get service URL</field>
|
|
193
|
+
<field name="output" var="service_url"/>
|
|
194
|
+
</block>
|
|
195
|
+
|
|
196
|
+
<block type="task" id="B7" action="run-script" desc="Verify process still running">
|
|
197
|
+
<field name="command">Check if process with PID ${pid} still exists</field>
|
|
198
|
+
<field name="output" var="process_running"/>
|
|
199
|
+
</block>
|
|
200
|
+
|
|
201
|
+
<block type="gateway" id="G4" mode="guard" desc="Verify process still running"
|
|
202
|
+
test="${process_running} == true"
|
|
203
|
+
fail-action="stop">
|
|
204
|
+
<field name="message">Process with PID ${pid} is no longer running. Error Category: RUNTIME_ERROR</field>
|
|
205
|
+
</block>
|
|
206
|
+
|
|
207
|
+
</sequence>
|
|
208
|
+
|
|
209
|
+
<!-- ============================================================
|
|
210
|
+
Output Results
|
|
211
|
+
============================================================ -->
|
|
212
|
+
<block type="output" id="O1" desc="Workflow output results">
|
|
213
|
+
<field name="status" value="SUCCESS" type="string" desc="Startup status"/>
|
|
214
|
+
<field name="platform_id" from="${platform_id}" type="string" desc="Platform identifier"/>
|
|
215
|
+
<field name="project_root" from="${project_root}" type="string" desc="Project root path"/>
|
|
216
|
+
<field name="service_url" from="${service_url}" type="string" desc="Service URL"/>
|
|
217
|
+
<field name="health_url" from="${health_url}" type="string" desc="Health check URL"/>
|
|
218
|
+
<field name="health_status" from="${health_status}" type="string" desc="Health status UP/DOWN"/>
|
|
219
|
+
<field name="pid" from="${pid}" type="number" desc="Process ID for cleanup"/>
|
|
220
|
+
<field name="start_command" from="${start_cmd}" type="string" desc="Start command executed"/>
|
|
221
|
+
</block>
|
|
222
|
+
|
|
223
|
+
</workflow>
|
|
@@ -20,9 +20,17 @@ tools: Bash, Edit, Write, Glob, Grep, Read
|
|
|
20
20
|
| `iteration_id` | No | string | Current iteration identifier for progress messages |
|
|
21
21
|
| `output_dir` | No | string | Output directory for task record (default: auto-derived from iteration path) |
|
|
22
22
|
|
|
23
|
-
|
|
23
|
+
## AgentFlow Definition
|
|
24
24
|
|
|
25
|
-
|
|
25
|
+
<!-- @agentflow: workflow.agentflow.xml -->
|
|
26
|
+
|
|
27
|
+
> **REQUIRED**: Before executing this workflow, read the XML workflow specification: `speccrew-workspace/docs/rules/agentflow-spec.md`
|
|
28
|
+
|
|
29
|
+
---
|
|
30
|
+
|
|
31
|
+
## Workflow
|
|
32
|
+
|
|
33
|
+
### Absolute Constraints
|
|
26
34
|
|
|
27
35
|
> **These rules apply to Task Record document generation. Violation = task failure.**
|
|
28
36
|
|