@chenmk/superflow 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (198) hide show
  1. package/INSTALL.en.md +106 -0
  2. package/INSTALL.md +664 -0
  3. package/LICENSE +21 -0
  4. package/README.md +142 -0
  5. package/README.zh-CN.md +117 -0
  6. package/assets/context-templates/business-rules.md +98 -0
  7. package/assets/context-templates/decisions.md +153 -0
  8. package/assets/context-templates/external-systems.md +166 -0
  9. package/assets/context-templates/incidents.md +89 -0
  10. package/assets/manifest.json +53 -0
  11. package/assets/prompts/superflow-archive.md +9 -0
  12. package/assets/prompts/superflow-clarify.md +10 -0
  13. package/assets/prompts/superflow-design.md +10 -0
  14. package/assets/prompts/superflow-docs.md +10 -0
  15. package/assets/prompts/superflow-implement.md +10 -0
  16. package/assets/prompts/superflow-pipeline.md +13 -0
  17. package/assets/prompts/superflow-verify.md +10 -0
  18. package/assets/rules/superflow-phase-guard.md +50 -0
  19. package/assets/scripts/claude-auto-backup-hook.sh +313 -0
  20. package/assets/scripts/codex-auto-backup-hook.sh +361 -0
  21. package/assets/scripts/install-sql-pre-commit.sh +44 -0
  22. package/assets/scripts/superflow-contract-hooks.sh +744 -0
  23. package/assets/scripts/superflow-delivery-check.sh +315 -0
  24. package/assets/scripts/superflow-dependency-update-hook.sh +161 -0
  25. package/assets/scripts/superflow-enforce-hook.sh +70 -0
  26. package/assets/scripts/superflow-hook-guard.sh +132 -0
  27. package/assets/scripts/superflow-integration-evidence-hook.sh +80 -0
  28. package/assets/scripts/superflow-sql-sync-hook.py +950 -0
  29. package/assets/scripts/superflow-test-report-lint.py +433 -0
  30. package/assets/scripts/superflow-verify-integration.sh +90 -0
  31. package/assets/scripts/sync-settings-json.py +52 -0
  32. package/assets/skills/api-doc-changelog/SKILL.md +193 -0
  33. package/assets/skills/openspec-apply-change/SKILL.md +156 -0
  34. package/assets/skills/openspec-archive-change/SKILL.md +114 -0
  35. package/assets/skills/openspec-explore/SKILL.md +288 -0
  36. package/assets/skills/openspec-propose/SKILL.md +110 -0
  37. package/assets/skills/superflow-archive/SKILL.md +61 -0
  38. package/assets/skills/superflow-clarify/SKILL.md +146 -0
  39. package/assets/skills/superflow-clarify/agents/openai.yaml +4 -0
  40. package/assets/skills/superflow-design/SKILL.md +83 -0
  41. package/assets/skills/superflow-design/agents/openai.yaml +4 -0
  42. package/assets/skills/superflow-docs/SKILL.md +316 -0
  43. package/assets/skills/superflow-docs/agents/openai.yaml +4 -0
  44. package/assets/skills/superflow-hotfix/SKILL.md +48 -0
  45. package/assets/skills/superflow-implement/SKILL.md +461 -0
  46. package/assets/skills/superflow-implement/agents/openai.yaml +4 -0
  47. package/assets/skills/superflow-pipeline/SKILL.md +844 -0
  48. package/assets/skills/superflow-pipeline/agents/openai.yaml +4 -0
  49. package/assets/skills/superflow-pipeline/references/api-design-template.md +431 -0
  50. package/assets/skills/superflow-pipeline/references/architecture-design-template.md +119 -0
  51. package/assets/skills/superflow-pipeline/references/batch-prompt-template.md +536 -0
  52. package/assets/skills/superflow-pipeline/references/batch-split-guide.md +140 -0
  53. package/assets/skills/superflow-pipeline/references/decision-point.md +30 -0
  54. package/assets/skills/superflow-pipeline/references/dirty-worktree.md +35 -0
  55. package/assets/skills/superflow-pipeline/references/document-templates.md +123 -0
  56. package/assets/skills/superflow-pipeline/references/feature-gated-workflow.md +124 -0
  57. package/assets/skills/superflow-pipeline/references/implementation-prompt-template.md +1056 -0
  58. package/assets/skills/superflow-pipeline/references/mock-strategy-guide.md +86 -0
  59. package/assets/skills/superflow-pipeline/references/openspec-format.md +57 -0
  60. package/assets/skills/superflow-pipeline/references/orchestration.md +639 -0
  61. package/assets/skills/superflow-pipeline/references/p0-baseline-template.md +174 -0
  62. package/assets/skills/superflow-pipeline/references/project-config.md +40 -0
  63. package/assets/skills/superflow-pipeline/references/prompt-usage-template.md +152 -0
  64. package/assets/skills/superflow-pipeline/references/quality-gate.md +299 -0
  65. package/assets/skills/superflow-pipeline/references/quality-standards.md +190 -0
  66. package/assets/skills/superflow-pipeline/references/reviewer-checklist.md +154 -0
  67. package/assets/skills/superflow-pipeline/references/sql-risk-review-checklist.md +323 -0
  68. package/assets/skills/superflow-pipeline/references/subagent-progress.md +90 -0
  69. package/assets/skills/superflow-pipeline/references/superpower-technical-design-template.md +125 -0
  70. package/assets/skills/superflow-pipeline/references/test-execution-template.md +220 -0
  71. package/assets/skills/superflow-pipeline/references/test-guide.md +30 -0
  72. package/assets/skills/superflow-pipeline/references/traceability-matrix.md +106 -0
  73. package/assets/skills/superflow-pipeline/references/validation-integrity.md +134 -0
  74. package/assets/skills/superflow-pipeline/scripts/superflow-archive.sh +178 -0
  75. package/assets/skills/superflow-pipeline/scripts/superflow-env.sh +118 -0
  76. package/assets/skills/superflow-pipeline/scripts/superflow-guard.sh +428 -0
  77. package/assets/skills/superflow-pipeline/scripts/superflow-handoff.sh +296 -0
  78. package/assets/skills/superflow-pipeline/scripts/superflow-state.sh +574 -0
  79. package/assets/skills/superflow-pipeline/scripts/superflow-status.sh +172 -0
  80. package/assets/skills/superflow-pipeline/scripts/superflow-yaml-validate.sh +138 -0
  81. package/assets/skills/superflow-table-impact-analysis/SKILL.md +77 -0
  82. package/assets/skills/superflow-tweak/SKILL.md +46 -0
  83. package/assets/skills/superflow-verify/SKILL.md +112 -0
  84. package/assets/skills-en/api-doc-changelog/SKILL.md +193 -0
  85. package/assets/skills-en/openspec-apply-change/SKILL.md +156 -0
  86. package/assets/skills-en/openspec-archive-change/SKILL.md +114 -0
  87. package/assets/skills-en/openspec-explore/SKILL.md +288 -0
  88. package/assets/skills-en/openspec-propose/SKILL.md +110 -0
  89. package/assets/skills-en/superflow-archive/SKILL.md +61 -0
  90. package/assets/skills-en/superflow-clarify/SKILL.md +146 -0
  91. package/assets/skills-en/superflow-clarify/agents/openai.yaml +4 -0
  92. package/assets/skills-en/superflow-design/SKILL.md +83 -0
  93. package/assets/skills-en/superflow-design/agents/openai.yaml +4 -0
  94. package/assets/skills-en/superflow-docs/SKILL.md +316 -0
  95. package/assets/skills-en/superflow-docs/agents/openai.yaml +4 -0
  96. package/assets/skills-en/superflow-hotfix/SKILL.md +48 -0
  97. package/assets/skills-en/superflow-implement/SKILL.md +461 -0
  98. package/assets/skills-en/superflow-implement/agents/openai.yaml +4 -0
  99. package/assets/skills-en/superflow-pipeline/SKILL.md +844 -0
  100. package/assets/skills-en/superflow-pipeline/agents/openai.yaml +4 -0
  101. package/assets/skills-en/superflow-pipeline/references/api-design-template.md +431 -0
  102. package/assets/skills-en/superflow-pipeline/references/architecture-design-template.md +119 -0
  103. package/assets/skills-en/superflow-pipeline/references/batch-prompt-template.md +536 -0
  104. package/assets/skills-en/superflow-pipeline/references/batch-split-guide.md +140 -0
  105. package/assets/skills-en/superflow-pipeline/references/decision-point.md +30 -0
  106. package/assets/skills-en/superflow-pipeline/references/dirty-worktree.md +35 -0
  107. package/assets/skills-en/superflow-pipeline/references/document-templates.md +123 -0
  108. package/assets/skills-en/superflow-pipeline/references/feature-gated-workflow.md +124 -0
  109. package/assets/skills-en/superflow-pipeline/references/implementation-prompt-template.md +1056 -0
  110. package/assets/skills-en/superflow-pipeline/references/mock-strategy-guide.md +86 -0
  111. package/assets/skills-en/superflow-pipeline/references/openspec-format.md +57 -0
  112. package/assets/skills-en/superflow-pipeline/references/orchestration.md +639 -0
  113. package/assets/skills-en/superflow-pipeline/references/p0-baseline-template.md +174 -0
  114. package/assets/skills-en/superflow-pipeline/references/project-config.md +40 -0
  115. package/assets/skills-en/superflow-pipeline/references/prompt-usage-template.md +152 -0
  116. package/assets/skills-en/superflow-pipeline/references/quality-gate.md +299 -0
  117. package/assets/skills-en/superflow-pipeline/references/quality-standards.md +190 -0
  118. package/assets/skills-en/superflow-pipeline/references/reviewer-checklist.md +154 -0
  119. package/assets/skills-en/superflow-pipeline/references/sql-risk-review-checklist.md +323 -0
  120. package/assets/skills-en/superflow-pipeline/references/subagent-progress.md +90 -0
  121. package/assets/skills-en/superflow-pipeline/references/superpower-technical-design-template.md +125 -0
  122. package/assets/skills-en/superflow-pipeline/references/test-execution-template.md +220 -0
  123. package/assets/skills-en/superflow-pipeline/references/test-guide.md +30 -0
  124. package/assets/skills-en/superflow-pipeline/references/traceability-matrix.md +106 -0
  125. package/assets/skills-en/superflow-pipeline/references/validation-integrity.md +134 -0
  126. package/assets/skills-en/superflow-pipeline/scripts/superflow-archive.sh +178 -0
  127. package/assets/skills-en/superflow-pipeline/scripts/superflow-env.sh +118 -0
  128. package/assets/skills-en/superflow-pipeline/scripts/superflow-guard.sh +428 -0
  129. package/assets/skills-en/superflow-pipeline/scripts/superflow-handoff.sh +296 -0
  130. package/assets/skills-en/superflow-pipeline/scripts/superflow-state.sh +574 -0
  131. package/assets/skills-en/superflow-pipeline/scripts/superflow-status.sh +172 -0
  132. package/assets/skills-en/superflow-pipeline/scripts/superflow-yaml-validate.sh +138 -0
  133. package/assets/skills-en/superflow-table-impact-analysis/SKILL.md +77 -0
  134. package/assets/skills-en/superflow-tweak/SKILL.md +46 -0
  135. package/assets/skills-en/superflow-verify/SKILL.md +112 -0
  136. package/dist/cli/index.js +186 -0
  137. package/dist/cli/index.js.map +1 -0
  138. package/dist/commands/archive.js +6 -0
  139. package/dist/commands/archive.js.map +1 -0
  140. package/dist/commands/clarify.js +6 -0
  141. package/dist/commands/clarify.js.map +1 -0
  142. package/dist/commands/design.js +6 -0
  143. package/dist/commands/design.js.map +1 -0
  144. package/dist/commands/docs.js +6 -0
  145. package/dist/commands/docs.js.map +1 -0
  146. package/dist/commands/doctor.js +473 -0
  147. package/dist/commands/doctor.js.map +1 -0
  148. package/dist/commands/implement.js +6 -0
  149. package/dist/commands/implement.js.map +1 -0
  150. package/dist/commands/init.js +471 -0
  151. package/dist/commands/init.js.map +1 -0
  152. package/dist/commands/pipeline.js +6 -0
  153. package/dist/commands/pipeline.js.map +1 -0
  154. package/dist/commands/scan.js +59 -0
  155. package/dist/commands/scan.js.map +1 -0
  156. package/dist/commands/status.js +173 -0
  157. package/dist/commands/status.js.map +1 -0
  158. package/dist/commands/uninstall.js +213 -0
  159. package/dist/commands/uninstall.js.map +1 -0
  160. package/dist/commands/update.js +187 -0
  161. package/dist/commands/update.js.map +1 -0
  162. package/dist/commands/verify.js +6 -0
  163. package/dist/commands/verify.js.map +1 -0
  164. package/dist/core/assets.js +27 -0
  165. package/dist/core/assets.js.map +1 -0
  166. package/dist/core/context.js +100 -0
  167. package/dist/core/context.js.map +1 -0
  168. package/dist/core/dependencies.js +146 -0
  169. package/dist/core/dependencies.js.map +1 -0
  170. package/dist/core/detect.js +71 -0
  171. package/dist/core/detect.js.map +1 -0
  172. package/dist/core/i18n.js +103 -0
  173. package/dist/core/i18n.js.map +1 -0
  174. package/dist/core/integrity.js +46 -0
  175. package/dist/core/integrity.js.map +1 -0
  176. package/dist/core/manifest.js +18 -0
  177. package/dist/core/manifest.js.map +1 -0
  178. package/dist/core/prompts.js +20 -0
  179. package/dist/core/prompts.js.map +1 -0
  180. package/dist/core/registry.js +134 -0
  181. package/dist/core/registry.js.map +1 -0
  182. package/dist/core/rules.js +17 -0
  183. package/dist/core/rules.js.map +1 -0
  184. package/dist/core/scripts.js +40 -0
  185. package/dist/core/scripts.js.map +1 -0
  186. package/dist/core/skill-check.js +31 -0
  187. package/dist/core/skill-check.js.map +1 -0
  188. package/dist/core/skills.js +56 -0
  189. package/dist/core/skills.js.map +1 -0
  190. package/dist/core/state.js +43 -0
  191. package/dist/core/state.js.map +1 -0
  192. package/dist/types.js +2 -0
  193. package/dist/types.js.map +1 -0
  194. package/dist/utils/path.js +11 -0
  195. package/dist/utils/path.js.map +1 -0
  196. package/dist/utils/shell.js +29 -0
  197. package/dist/utils/shell.js.map +1 -0
  198. package/package.json +60 -0
@@ -0,0 +1,428 @@
1
+ #!/usr/bin/env bash
2
+ set -euo pipefail
3
+
4
+ usage() {
5
+ cat <<'USAGE'
6
+ Usage:
7
+ superflow-guard.sh <change-dir> docs|design|implement|verify|archive [--apply]
8
+
9
+ Validate SDD phase readiness. With --apply, update .sdd/state.yaml through
10
+ superflow-state transition events.
11
+ USAGE
12
+ }
13
+
14
+ die() {
15
+ printf 'superflow-guard: %s\n' "$*" >&2
16
+ exit 1
17
+ }
18
+
19
+ SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
20
+ STATE="$SCRIPT_DIR/superflow-state.sh"
21
+ HANDOFF="$SCRIPT_DIR/superflow-handoff.sh"
22
+ VALIDATE="$SCRIPT_DIR/superflow-yaml-validate.sh"
23
+
24
+ CHANGE_DIR="${1:-}"
25
+ PHASE="${2:-}"
26
+ MODE="${3:-}"
27
+
28
+ [[ -n "$CHANGE_DIR" && -n "$PHASE" ]] || {
29
+ usage
30
+ exit 1
31
+ }
32
+ [[ -d "$CHANGE_DIR" ]] || die "change dir not found: $CHANGE_DIR"
33
+ [[ -z "$MODE" || "$MODE" == "--apply" ]] || die "unknown option: $MODE"
34
+
35
+ CHANGE_DIR="$(cd "$CHANGE_DIR" && pwd)"
36
+ issues=()
37
+
38
+ require_file() {
39
+ local path="$1"
40
+ [[ -f "$CHANGE_DIR/$path" ]] || issues+=("missing file: $path")
41
+ }
42
+
43
+ require_grep() {
44
+ local pattern="$1"
45
+ local path="$2"
46
+ local label="$3"
47
+ local target="$CHANGE_DIR/$path"
48
+ [[ -f "$path" ]] && target="$path"
49
+ if [[ ! -f "$target" ]]; then
50
+ issues+=("missing file for check: $path")
51
+ elif ! grep -Eiq "$pattern" "$target"; then
52
+ issues+=("$label not found in $path")
53
+ fi
54
+ }
55
+
56
+ project_root_for_change() {
57
+ if git -C "$CHANGE_DIR" rev-parse --show-toplevel >/dev/null 2>&1; then
58
+ git -C "$CHANGE_DIR" rev-parse --show-toplevel
59
+ return
60
+ fi
61
+ if [[ "$CHANGE_DIR" == */openspec/changes/* ]]; then
62
+ dirname "$(dirname "$(dirname "$CHANGE_DIR")")"
63
+ return
64
+ fi
65
+ dirname "$(dirname "$CHANGE_DIR")"
66
+ }
67
+
68
+ require_test_report_lint() {
69
+ local report="$CHANGE_DIR/test-report.md"
70
+ local root lint output
71
+ root="$(project_root_for_change)"
72
+
73
+ for lint in \
74
+ "$root/.codex/hooks/superflow-test-report-lint.py" \
75
+ "$HOME/.codex/hooks/superflow-test-report-lint.py"; do
76
+ if [[ -x "$lint" ]]; then
77
+ output="$(mktemp)"
78
+ if ! "$lint" --tests "$CHANGE_DIR/tests.md" "$report" >"$output" 2>&1; then
79
+ issues+=("superflow-test-report-lint failed: $(tr '\n' ' ' < "$output" | sed -E 's/[[:space:]]+/ /g')")
80
+ fi
81
+ rm -f "$output"
82
+ return
83
+ fi
84
+ done
85
+
86
+ issues+=("superflow-test-report-lint.py not found for verify guard")
87
+ }
88
+
89
+ require_markdown_links_valid() {
90
+ local output
91
+ output="$(mktemp)"
92
+ if ! python3 - "$CHANGE_DIR" >"$output" 2>&1 <<'PY'
93
+ import os
94
+ import re
95
+ import sys
96
+ from pathlib import Path
97
+
98
+ change_dir = Path(sys.argv[1]).resolve()
99
+ files = [
100
+ p for p in change_dir.rglob("*.md")
101
+ if ".sdd" not in p.relative_to(change_dir).parts
102
+ ]
103
+ state = change_dir / ".sdd" / "state.yaml"
104
+ if state.exists():
105
+ for line in state.read_text(errors="ignore").splitlines():
106
+ if line.startswith("technical_design:") or line.startswith("design_doc:"):
107
+ value = line.split(":", 1)[1].strip()
108
+ if value and value != "null":
109
+ candidate = (change_dir / value).resolve()
110
+ if candidate.exists() and candidate.suffix == ".md":
111
+ files.append(candidate)
112
+
113
+ link_re = re.compile(r"\[[^\]]+\]\(([^)]+\.md(?:#[^)]+)?)\)")
114
+ bad = []
115
+ seen = set()
116
+ for file in files:
117
+ if file in seen or not file.exists():
118
+ continue
119
+ seen.add(file)
120
+ try:
121
+ display_file = str(file.relative_to(change_dir))
122
+ except ValueError:
123
+ display_file = os.path.relpath(file, change_dir)
124
+ text = file.read_text(errors="ignore")
125
+ for match in link_re.finditer(text):
126
+ target = match.group(1).strip()
127
+ if (
128
+ target.startswith("#")
129
+ or re.match(r"^[a-zA-Z][a-zA-Z0-9+.-]*:", target)
130
+ or target.startswith("/")
131
+ ):
132
+ continue
133
+ target_path = target.split("#", 1)[0]
134
+ resolved = (file.parent / target_path).resolve()
135
+ if not resolved.exists():
136
+ bad.append(
137
+ f"{display_file} -> {target} "
138
+ f"(resolved: {os.path.relpath(resolved, change_dir)})"
139
+ )
140
+
141
+ if bad:
142
+ print("; ".join(bad))
143
+ sys.exit(1)
144
+ PY
145
+ then
146
+ issues+=("broken markdown links: $(tr '\n' ' ' < "$output" | sed -E 's/[[:space:]]+/ /g')")
147
+ fi
148
+ rm -f "$output"
149
+ }
150
+
151
+ state_get() {
152
+ "$STATE" get "$CHANGE_DIR" "$1" 2>/dev/null || true
153
+ }
154
+
155
+ require_state_value() {
156
+ local key="$1"
157
+ local label="$2"
158
+ local value
159
+ value="$(state_get "$key")"
160
+ [[ -n "$value" && "$value" != "null" ]] || issues+=("$label is not set in .sdd/state.yaml")
161
+ }
162
+
163
+ require_optional_state_path() {
164
+ local key="$1"
165
+ local label="$2"
166
+ local value
167
+ value="$(state_get "$key")"
168
+ [[ -n "$value" && "$value" != "null" ]] || {
169
+ issues+=("$label is not set in .sdd/state.yaml")
170
+ return 0
171
+ }
172
+ [[ -f "$CHANGE_DIR/$value" || -f "$value" ]] || {
173
+ issues+=("$label path does not exist: $value")
174
+ }
175
+ }
176
+
177
+ require_state_file() {
178
+ require_file .sdd/state.yaml
179
+ }
180
+
181
+ require_spec_doc() {
182
+ if [[ -f "$CHANGE_DIR/spec.md" ]]; then
183
+ return
184
+ fi
185
+ if find "$CHANGE_DIR/specs" -path '*/spec.md' -type f 2>/dev/null | grep -q .; then
186
+ return
187
+ fi
188
+ issues+=("missing spec document: spec.md or specs/<capability>/spec.md")
189
+ }
190
+
191
+ require_handoff() {
192
+ require_file .sdd/handoff/sdd-context.md
193
+ require_file .sdd/handoff/sdd-context.json
194
+ require_file .sdd/handoff/sdd-context.sha256
195
+ require_state_value handoff_context "handoff_context"
196
+ require_state_value handoff_hash "handoff_hash"
197
+ }
198
+
199
+ require_handoff_current() {
200
+ local hash_file="$CHANGE_DIR/.sdd/handoff/sdd-context.sha256"
201
+ local recorded actual
202
+ [[ -f "$hash_file" ]] || return 0
203
+ recorded="$(tr -d '[:space:]' < "$hash_file")"
204
+ actual="$("$HANDOFF" "$CHANGE_DIR" --hash-only 2>/dev/null || true)"
205
+ [[ -n "$actual" ]] || {
206
+ issues+=("could not compute current handoff hash")
207
+ return 0
208
+ }
209
+ [[ "$recorded" == "$actual" ]] || {
210
+ issues+=("handoff hash is stale: recorded=$recorded actual=$actual")
211
+ }
212
+ }
213
+
214
+ require_beta_handoff_structure() {
215
+ local mode json
216
+ mode="$(state_get context_compression)"
217
+ [[ "$mode" == "beta" ]] || return 0
218
+ json="$CHANGE_DIR/.sdd/handoff/sdd-context.json"
219
+ [[ -s "$json" ]] || {
220
+ issues+=("beta handoff json missing or empty")
221
+ return 0
222
+ }
223
+ grep -q '"contextCompression": "beta"' "$json" || issues+=("beta handoff json missing contextCompression=beta")
224
+ grep -q '"role": "api"' "$json" || issues+=("beta handoff json missing api role")
225
+ grep -Eq '"role": "(spec|test)"' "$json" || issues+=("beta handoff json missing spec/test role")
226
+ grep -q '"projected": true' "$json" || issues+=("beta handoff json missing projected=true sources")
227
+ }
228
+
229
+ require_hash_recorded() {
230
+ local hash_file="$CHANGE_DIR/.sdd/handoff/sdd-context.sha256"
231
+ [[ -f "$hash_file" ]] || return 0
232
+ local hash
233
+ hash="$(tr -d '[:space:]' < "$hash_file")"
234
+ [[ -n "$hash" ]] || {
235
+ issues+=("handoff hash file is empty")
236
+ return 0
237
+ }
238
+ if ! grep -Riq "$hash" \
239
+ "$CHANGE_DIR/design.md" "$CHANGE_DIR/sdd-quality-gate.md" \
240
+ "$CHANGE_DIR/test-report.md" "$CHANGE_DIR/prompt" 2>/dev/null; then
241
+ issues+=("handoff hash is not recorded in design, quality gate, prompt, or test-report")
242
+ fi
243
+ }
244
+
245
+ change_has_field_status_risk() {
246
+ grep -RIEiq \
247
+ '字段值|状态|枚举|online|offline|上线|下线|删除|恢复|同步标记|sync marker|payment|refund|支付|退款|第三方状态|running_status|offline_time' \
248
+ "$CHANGE_DIR"/*.md "$CHANGE_DIR"/**/*.md 2>/dev/null
249
+ }
250
+
251
+ change_has_architecture_boundary_risk() {
252
+ grep -RIEiq \
253
+ '跨仓|跨服务|sibling|SDK|MQ|topic|consumer|scheduler|定时|device|设备|callback|回调|third[- ]party|第三方|mini[- ]program|小程序|gateway|网关|adapter|适配|protocol|协议|interconnect|互联互通|调用链|入口|出口' \
254
+ "$CHANGE_DIR"/*.md "$CHANGE_DIR"/**/*.md 2>/dev/null
255
+ }
256
+
257
+ first_prompt_rel() {
258
+ find "$CHANGE_DIR" -path '*/prompt/*.md' -type f | head -n 1 | sed "s#^$CHANGE_DIR/##"
259
+ }
260
+
261
+ require_any_prompt() {
262
+ if ! find "$CHANGE_DIR" -path '*/prompt/*.md' -type f | grep -q .; then
263
+ issues+=("missing implementation prompt under prompt/*.md")
264
+ fi
265
+ }
266
+
267
+ require_prompt_set() {
268
+ local task_count prompt_count non_index_prompt_count
269
+ require_file prompt/implementation.md
270
+ task_count="$(grep -E '^[[:space:]]*-[[:space:]]+\[[ xX]\]' "$CHANGE_DIR/tasks.md" 2>/dev/null | wc -l | tr -d ' ')"
271
+ prompt_count="$(find "$CHANGE_DIR/prompt" -maxdepth 1 -type f -name '*.md' 2>/dev/null | wc -l | tr -d ' ')"
272
+ non_index_prompt_count="$(find "$CHANGE_DIR/prompt" -maxdepth 1 -type f -name '*.md' ! -name 'implementation.md' 2>/dev/null | wc -l | tr -d ' ')"
273
+ if [[ "$task_count" -gt 0 && "$non_index_prompt_count" -eq 0 ]]; then
274
+ issues+=("missing task prompt under prompt/<task-name>.md; prompt/implementation.md alone is not enough")
275
+ fi
276
+ if [[ "$prompt_count" -eq 0 ]]; then
277
+ issues+=("missing prompt/*.md files")
278
+ fi
279
+ if [[ -f "$CHANGE_DIR/tasks.md" ]] && ! grep -Riq 'prompt/.*\.md' "$CHANGE_DIR/tasks.md" "$CHANGE_DIR/traceability-matrix.md" "$CHANGE_DIR/sdd-quality-gate.md" "$CHANGE_DIR/test-report.md" 2>/dev/null; then
280
+ issues+=("prompt files are not cross-linked from tasks/traceability/quality gate/test-report")
281
+ fi
282
+ }
283
+
284
+ transition_event=""
285
+
286
+ if [[ -x "$VALIDATE" && -f "$CHANGE_DIR/.sdd/state.yaml" ]]; then
287
+ "$VALIDATE" "$CHANGE_DIR" >/dev/null
288
+ fi
289
+
290
+ case "$PHASE" in
291
+ docs)
292
+ require_state_file
293
+ require_file proposal.md
294
+ require_file api.md
295
+ require_spec_doc
296
+ require_file design.md
297
+ require_file tasks.md
298
+ require_file tests.md
299
+ require_file traceability-matrix.md
300
+ require_file review-checklist.md
301
+ require_file sdd-quality-gate.md
302
+ require_file test-report.md
303
+ require_handoff
304
+ require_handoff_current
305
+ require_beta_handoff_structure
306
+ require_hash_recorded
307
+ require_grep 'Superpowers Technical Design Handoff|Superpower 技术详设|technical_design|源码级 HOW' design.md "Superpowers technical design handoff"
308
+ require_grep 'OpenSpec/SDD|WHAT|合同|API|DB|tests|验收' design.md "OpenSpec/SDD contract boundary"
309
+ require_grep '文档完整性|完整文档|proposal.md|api.md|design.md|tasks.md|tests.md' sdd-quality-gate.md "document completeness gate"
310
+ require_grep 'RED|红绿|GREEN' tests.md "RED/GREEN test contract"
311
+ require_grep 'curl|Postman|Newman|pytest|RestAssured|自动化命令' tests.md "interface automation command"
312
+ require_grep 'handoff_hash|sdd-context|上下文包|防漂移' sdd-quality-gate.md "handoff/context-drift gate"
313
+ require_markdown_links_valid
314
+ transition_event="docs-complete"
315
+ ;;
316
+ design)
317
+ require_state_file
318
+ require_file proposal.md
319
+ require_file api.md
320
+ require_spec_doc
321
+ require_file design.md
322
+ require_file tasks.md
323
+ require_file tests.md
324
+ require_file traceability-matrix.md
325
+ require_file review-checklist.md
326
+ require_file sdd-quality-gate.md
327
+ require_file test-report.md
328
+ require_handoff
329
+ require_handoff_current
330
+ require_beta_handoff_structure
331
+ require_hash_recorded
332
+ workflow="$(state_get workflow)"
333
+ if [[ "$workflow" == "full" ]]; then
334
+ require_optional_state_path technical_design "technical_design"
335
+ technical_design_rel="$(state_get technical_design)"
336
+ if [[ -n "${technical_design_rel:-}" && "$technical_design_rel" != "null" ]]; then
337
+ require_grep 'Superpowers Technical Design|Superpower 技术详设|Technical Design|源码级 HOW' "$technical_design_rel" "Superpowers technical design"
338
+ require_grep 'OpenSpec/SDD|canonical|事实源|不得覆盖|不能覆盖' "$technical_design_rel" "technical design canonical boundary"
339
+ if change_has_architecture_boundary_risk; then
340
+ require_grep 'Architecture Boundary And Call Direction|架构边界与调用方向|模块职责.*调用方向|owner.*入口.*出口|禁止绕路' "$technical_design_rel" "architecture boundary and call direction matrix"
341
+ fi
342
+ if change_has_field_status_risk; then
343
+ require_grep 'Field And Status Reverse Impact|字段/状态反向影响面|写入点.*读取|读取/过滤点|派生/同步点' "$technical_design_rel" "field/status reverse impact matrix"
344
+ fi
345
+ fi
346
+ fi
347
+ require_grep 'Superpowers Technical Design Handoff|Superpower 技术详设|technical_design|源码级 HOW' design.md "Superpowers technical design handoff"
348
+ require_grep 'technical_design|Superpowers 技术详设|源码级 HOW' sdd-quality-gate.md "technical design quality gate"
349
+ require_markdown_links_valid
350
+ transition_event="design-complete"
351
+ ;;
352
+ implement)
353
+ require_state_file
354
+ require_handoff
355
+ require_handoff_current
356
+ require_beta_handoff_structure
357
+ require_hash_recorded
358
+ require_any_prompt
359
+ require_prompt_set
360
+ require_grep 'OpenSpec/SDD|设计事实源|canonical|事实源' design.md "canonical source boundary"
361
+ prompt_rel="$(first_prompt_rel)"
362
+ if [[ -n "${prompt_rel:-}" ]]; then
363
+ require_grep 'Superpower 技术详设继承|Superpower 执行策略继承|technical_design|源码级 HOW' "$prompt_rel" "prompt Superpower strategy inheritance"
364
+ technical_design_rel="$(state_get technical_design)"
365
+ if [[ -n "${technical_design_rel:-}" && "$technical_design_rel" != "null" ]]; then
366
+ require_grep 'Superpower 技术详设继承|technical_design|源码级 HOW|Technical Design' "$prompt_rel" "prompt Superpowers technical design inheritance"
367
+ if change_has_field_status_risk; then
368
+ require_grep '字段/状态反向影响面|Field And Status Reverse Impact|读取/过滤点|派生/同步点' "$prompt_rel" "prompt field/status reverse impact inheritance"
369
+ fi
370
+ fi
371
+ require_grep '上下文防漂移|handoff_hash|sdd-context' "$prompt_rel" "prompt context drift inheritance"
372
+ fi
373
+ require_state_value build_mode "build_mode"
374
+ require_state_value isolation "isolation"
375
+ require_state_value tdd_mode "tdd_mode"
376
+ workflow="$(state_get workflow)"
377
+ review_mode="$(state_get review_mode)"
378
+ if [[ "$workflow" == "full" ]]; then
379
+ case "$review_mode" in
380
+ off|standard|thorough) ;;
381
+ *) issues+=("review_mode must be off, standard, or thorough before leaving implement") ;;
382
+ esac
383
+ fi
384
+ require_markdown_links_valid
385
+ transition_event="implement-complete"
386
+ ;;
387
+ verify)
388
+ require_state_file
389
+ require_file test-report.md
390
+ require_grep 'RED|失败证据' test-report.md "RED evidence"
391
+ require_grep 'GREEN|通过证据' test-report.md "GREEN evidence"
392
+ require_grep '接口自动化|curl|Postman|Newman|pytest|RestAssured' test-report.md "interface automation evidence"
393
+ require_grep 'DB|数据库|SELECT|SHOW CREATE' test-report.md "DB evidence"
394
+ require_grep 'superflow-verify-integration|superflow-delivery-check|superflow-test-report-lint' test-report.md "SuperBridge Flow hook/script evidence"
395
+ require_test_report_lint
396
+ require_markdown_links_valid
397
+ if [[ "$(state_get verification_report)" == "" || "$(state_get verification_report)" == "null" ]]; then
398
+ "$STATE" set "$CHANGE_DIR" verification_report test-report.md
399
+ fi
400
+ transition_event="verify-pass"
401
+ ;;
402
+ archive)
403
+ require_state_file
404
+ verify_result="$(state_get verify_result)"
405
+ [[ "$verify_result" == "pass" ]] || issues+=("verify_result must be pass before archive")
406
+ archived="$(state_get archived)"
407
+ [[ "$archived" != "true" ]] || issues+=("archived is already true")
408
+ require_state_value verification_report "verification_report"
409
+ transition_event="archived"
410
+ ;;
411
+ *)
412
+ usage
413
+ exit 1
414
+ ;;
415
+ esac
416
+
417
+ if [[ "${#issues[@]}" -gt 0 ]]; then
418
+ printf 'SDD guard failed for phase %s:\n' "$PHASE" >&2
419
+ printf -- '- %s\n' "${issues[@]}" >&2
420
+ exit 1
421
+ fi
422
+
423
+ printf 'SDD guard passed for phase %s\n' "$PHASE"
424
+
425
+ if [[ "$MODE" == "--apply" ]]; then
426
+ "$STATE" transition "$CHANGE_DIR" "$transition_event"
427
+ "$STATE" next "$CHANGE_DIR"
428
+ fi