@chenmk/superflow 0.5.11 → 0.5.13

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 (101) hide show
  1. package/README.md +26 -0
  2. package/README.zh-CN.md +8 -0
  3. package/assets/manifest.json +33 -7
  4. package/assets/review-rules.json +24 -0
  5. package/assets/scripts/superflow-archive-command-hook.sh +4 -0
  6. package/assets/scripts/superflow-contract-hooks.sh +4 -0
  7. package/assets/scripts/superflow-delivery-check.sh +4 -0
  8. package/assets/scripts/superflow-dependency-update-hook.sh +29 -0
  9. package/assets/scripts/superflow-doc-placement-hook.py +38 -0
  10. package/assets/scripts/superflow-enforce-hook.sh +4 -0
  11. package/assets/scripts/superflow-hook-guard.sh +4 -0
  12. package/assets/scripts/superflow-integration-evidence-hook.sh +4 -0
  13. package/assets/scripts/superflow-java-build-hook.py +178 -0
  14. package/assets/scripts/superflow-java-stop-hook.sh +3 -0
  15. package/assets/scripts/superflow-loop-end-hook.sh +3 -0
  16. package/assets/scripts/superflow-loop-failure-hook.sh +3 -0
  17. package/assets/scripts/superflow-loop-observer.py +149 -0
  18. package/assets/scripts/superflow-managed-work-guard.sh +4 -0
  19. package/assets/scripts/superflow-sql-sync-hook.py +151 -3
  20. package/assets/skill-registry.json +229 -0
  21. package/assets/skills/openspec-propose/SKILL.md +14 -0
  22. package/assets/skills/superflow-clarify/SKILL.md +23 -1
  23. package/assets/skills/superflow-design/SKILL.md +6 -1
  24. package/assets/skills/superflow-docs/SKILL.md +12 -0
  25. package/assets/skills/superflow-implement/SKILL.md +8 -0
  26. package/assets/skills/superflow-pipeline/SKILL.md +28 -1
  27. package/assets/skills/superflow-pipeline/references/superpower-technical-design-template.md +17 -0
  28. package/assets/skills/superflow-quick-dev/SKILL.md +44 -0
  29. package/assets/skills/superflow-verify/SKILL.md +41 -0
  30. package/assets/skills-en/openspec-propose/SKILL.md +14 -0
  31. package/assets/skills-en/superflow-clarify/SKILL.md +23 -1
  32. package/assets/skills-en/superflow-design/SKILL.md +6 -1
  33. package/assets/skills-en/superflow-docs/SKILL.md +12 -0
  34. package/assets/skills-en/superflow-implement/SKILL.md +9 -0
  35. package/assets/skills-en/superflow-pipeline/SKILL.md +30 -0
  36. package/assets/skills-en/superflow-quick-dev/SKILL.md +43 -0
  37. package/assets/skills-en/superflow-verify/SKILL.md +46 -0
  38. package/dist/app/cli.js +98 -0
  39. package/dist/app/cli.js.map +1 -1
  40. package/dist/app/commands/check.js +7 -3
  41. package/dist/app/commands/check.js.map +1 -1
  42. package/dist/app/commands/cleanup-audit.js +13 -0
  43. package/dist/app/commands/cleanup-audit.js.map +1 -0
  44. package/dist/app/commands/context-audit.js +43 -0
  45. package/dist/app/commands/context-audit.js.map +1 -0
  46. package/dist/app/commands/docs-audit.js +11 -0
  47. package/dist/app/commands/docs-audit.js.map +1 -0
  48. package/dist/app/commands/doctor.js +10 -0
  49. package/dist/app/commands/doctor.js.map +1 -1
  50. package/dist/app/commands/hook-migrate.js +25 -0
  51. package/dist/app/commands/hook-migrate.js.map +1 -0
  52. package/dist/app/commands/init.js +25 -18
  53. package/dist/app/commands/init.js.map +1 -1
  54. package/dist/app/commands/map-audit.js +10 -0
  55. package/dist/app/commands/map-audit.js.map +1 -0
  56. package/dist/app/commands/pipeline.js +13 -1
  57. package/dist/app/commands/pipeline.js.map +1 -1
  58. package/dist/app/commands/quick.js +136 -0
  59. package/dist/app/commands/quick.js.map +1 -0
  60. package/dist/app/commands/review-coverage.js +84 -0
  61. package/dist/app/commands/review-coverage.js.map +1 -0
  62. package/dist/app/commands/skill-audit.js +36 -0
  63. package/dist/app/commands/skill-audit.js.map +1 -0
  64. package/dist/app/commands/status.js +108 -7
  65. package/dist/app/commands/status.js.map +1 -1
  66. package/dist/app/commands/uninstall.js +119 -25
  67. package/dist/app/commands/uninstall.js.map +1 -1
  68. package/dist/app/commands/update.js +62 -25
  69. package/dist/app/commands/update.js.map +1 -1
  70. package/dist/domains/cleanup-audit.js +38 -0
  71. package/dist/domains/cleanup-audit.js.map +1 -0
  72. package/dist/domains/config/cli-help.js +14 -0
  73. package/dist/domains/config/cli-help.js.map +1 -1
  74. package/dist/domains/config/context.js +13 -10
  75. package/dist/domains/config/context.js.map +1 -1
  76. package/dist/domains/context-audit.js +39 -0
  77. package/dist/domains/context-audit.js.map +1 -0
  78. package/dist/domains/deps.js +18 -8
  79. package/dist/domains/deps.js.map +1 -1
  80. package/dist/domains/docs-audit.js +34 -0
  81. package/dist/domains/docs-audit.js.map +1 -0
  82. package/dist/domains/hook-migration.js +127 -0
  83. package/dist/domains/hook-migration.js.map +1 -0
  84. package/dist/domains/hook.js +76 -2
  85. package/dist/domains/hook.js.map +1 -1
  86. package/dist/domains/managed-work/control.js +56 -2
  87. package/dist/domains/managed-work/control.js.map +1 -1
  88. package/dist/domains/map-audit.js +23 -0
  89. package/dist/domains/map-audit.js.map +1 -0
  90. package/dist/domains/quick-dev/gate.js +91 -0
  91. package/dist/domains/quick-dev/gate.js.map +1 -0
  92. package/dist/domains/review/coverage.js +119 -0
  93. package/dist/domains/review/coverage.js.map +1 -0
  94. package/dist/domains/review/report.js +62 -0
  95. package/dist/domains/review/report.js.map +1 -0
  96. package/dist/domains/skill/registry.js +87 -0
  97. package/dist/domains/skill/registry.js.map +1 -0
  98. package/dist/domains/state.js +64 -0
  99. package/dist/domains/state.js.map +1 -1
  100. package/package.json +1 -1
  101. package/scripts/check-design-principles.mjs +4 -0
@@ -5,6 +5,11 @@ SDD SQL sync hook.
5
5
  Warns when database-backed Java/XML changes are made without a version-level
6
6
  summary SQL change. Blocks forbidden migration SQL style before commit.
7
7
 
8
+ Hook registration note: this hook is intentionally registered twice
9
+ (default matcher + Bash matcher override). The default matcher covers SQL
10
+ file edits; the Bash matcher covers git commit paths. Both trigger surfaces
11
+ need the SQL sync check -- do not "fix" this as a duplicate registration.
12
+
8
13
  Forbidden (B1-B8, blocks commit):
9
14
  - B1 ALTER TABLE ADD COLUMN IF NOT EXISTS
10
15
  - B2 CREATE [UNIQUE] INDEX IF NOT EXISTS
@@ -59,12 +64,27 @@ per finding for the developer to apply):
59
64
  import json
60
65
  import os
61
66
  import re
67
+ import shlex
62
68
  import subprocess
63
69
  import sys
64
70
  from pathlib import Path
65
71
 
72
+ # Defensive short-circuit: run SDD gates only in SDD projects
73
+ # (openspec/, .sdd/, .sdd-enforced); zero-cost exit elsewhere.
74
+ if not (os.path.isdir('openspec') or os.path.isdir('.sdd') or os.path.isfile('.sdd-enforced')):
75
+ raise SystemExit(0)
76
+
66
77
 
67
78
  DB_CODE_FILE = re.compile(r"\.(java|xml)$", re.I)
79
+ MYBATIS_SAFE_EXPRESSIONS = frozenset({
80
+ "ew.sqlSegment", "ew.customSqlSegment", "ew.sqlSet", "ew.sqlComment",
81
+ })
82
+ MYBATIS_INTERPOLATION = re.compile(r"\$\{([^}]+)\}")
83
+ SECRET_PATTERNS = (
84
+ re.compile(r"\bAKIA[0-9A-Z]{16}\b"),
85
+ re.compile(r"\b(?:api[_-]?key|api[_-]?secret)\s*[:=]\s*['\"][^'\"]{8,}", re.I),
86
+ re.compile(r"\b[a-z_][a-z0-9_]*_(?:secret|token)\s*[:=]\s*['\"][^'\"]{16,}['\"]", re.I),
87
+ )
68
88
  SQL_SUMMARY_FILE = re.compile(r"(^|/)sql/.*\.sql$", re.I)
69
89
  NO_SQL_ACK_FILE = re.compile(
70
90
  r"(^|/)(openspec/.*\.(md|yaml|yml)|ReleaseNotes\.md)$",
@@ -504,10 +524,113 @@ def warn(message, block=False):
504
524
  print(f"[SDD SQL 收口{prefix}] {message}", file=sys.stderr)
505
525
 
506
526
 
527
+ def mapper_interpolations(file_path, content):
528
+ normalized = file_path.replace("\\", "/")
529
+ if not normalized.lower().endswith(".xml"):
530
+ return []
531
+ mapper_path = re.search(r"(?:^|/)(?:mapper|dao)/", normalized, re.I)
532
+ mapper_name = re.search(r"(?:Mapper|Dao)\.xml$", normalized)
533
+ mapper_body = re.search(r"<mapper\b|<!DOCTYPE\s+mapper", content, re.I)
534
+ if not (mapper_path or mapper_name or mapper_body):
535
+ return []
536
+ return [match.group(1).strip() for match in MYBATIS_INTERPOLATION.finditer(content)
537
+ if match.group(1).strip() not in MYBATIS_SAFE_EXPRESSIONS]
538
+
539
+
540
+ def git_segment_args(segment):
541
+ tokens = shlex.split(segment)
542
+ git_at = next((i for i, token in enumerate(tokens)
543
+ if token == "git" or token.endswith("/git")), -1)
544
+ if git_at < 0:
545
+ return None
546
+ return tokens[:git_at], tokens[git_at + 1:]
547
+
548
+
549
+ def git_subcommand_index(args):
550
+ index = 0
551
+ while index < len(args) and args[index].startswith("-"):
552
+ index += 2 if args[index] in ("-c", "-C") else 1
553
+ return index
554
+
555
+
556
+ def check_git_bypass(command):
557
+ for segment in re.split(r"\|\||&&|[;|\n]", command):
558
+ try:
559
+ parsed = git_segment_args(segment)
560
+ except ValueError:
561
+ if "git" in segment and ("--no-verify" in segment or "core.hooksPath" in segment):
562
+ return "Git 命令无法解析且包含 Hook 绕过参数"
563
+ continue
564
+ if parsed is None:
565
+ continue
566
+ prefix, args = parsed
567
+ config_override = any(
568
+ arg.startswith("core.hooksPath=") for arg in args
569
+ ) or any(token.startswith("GIT_CONFIG_") and "core.hooksPath" in token
570
+ for token in prefix)
571
+ if config_override or "--no-verify" in args:
572
+ return "禁止使用 --no-verify 或 core.hooksPath 绕过 Git Hook"
573
+ index = git_subcommand_index(args)
574
+ if index < len(args) and args[index] == "commit":
575
+ flags = []
576
+ skip_value = False
577
+ for arg in args[index + 1:]:
578
+ if skip_value:
579
+ skip_value = False
580
+ continue
581
+ if arg in ("-m", "--message", "-F", "--file"):
582
+ skip_value = True
583
+ continue
584
+ flags.append(arg)
585
+ if any(re.fullmatch(r"-[a-zA-Z]*n[a-zA-Z]*", arg)
586
+ for arg in flags):
587
+ return "禁止使用 git commit -n 绕过 Git Hook"
588
+ return None
589
+
590
+
591
+ def is_git_commit(command):
592
+ for segment in re.split(r"\|\||&&|[;|\n]", command):
593
+ try:
594
+ parsed = git_segment_args(segment)
595
+ except ValueError:
596
+ continue
597
+ if parsed is None:
598
+ continue
599
+ _, args = parsed
600
+ index = git_subcommand_index(args)
601
+ if index < len(args) and args[index] == "commit":
602
+ return True
603
+ return False
604
+
605
+
606
+ def check_staged_secrets(root):
607
+ result = run(["git", "diff", "--cached", "--unified=0", "--no-ext-diff"], cwd=root)
608
+ if result.returncode != 0:
609
+ return []
610
+ findings = []
611
+ current_path = ""
612
+ for line in result.stdout.splitlines():
613
+ if line.startswith("+++ b/"):
614
+ current_path = line[6:]
615
+ elif line.startswith("+") and not line.startswith("+++"):
616
+ if any(pattern.search(line[1:]) for pattern in SECRET_PATTERNS):
617
+ findings.append(current_path)
618
+ return sorted(set(findings))
619
+
620
+
507
621
  def handle_commit(command, root):
508
- if not re.search(r"\bgit\s+commit\b", command):
622
+ bypass = check_git_bypass(command)
623
+ if bypass:
624
+ warn(bypass, block=True)
625
+ return 2
626
+ if not is_git_commit(command):
509
627
  return 0
510
628
 
629
+ secrets = check_staged_secrets(root)
630
+ if secrets:
631
+ warn("暂存差异包含疑似硬编码密钥:" + ", ".join(secrets), block=True)
632
+ return 2
633
+
511
634
  files = staged_files(root)
512
635
  if not files:
513
636
  return 0
@@ -585,6 +708,11 @@ def handle_commit(command, root):
585
708
  def handle_edit(file_path, edit_content):
586
709
  if not file_path:
587
710
  return 0
711
+ unsafe = mapper_interpolations(file_path, edit_content)
712
+ if unsafe:
713
+ warn("Mapper XML 使用危险 ${} 插值:" + ", ".join(unsafe[:3])
714
+ + ";请使用 #{},动态标识符须在 Java 侧白名单校验。", block=True)
715
+ return 2
588
716
  if SQL_SUMMARY_FILE.search(file_path):
589
717
  sql_style_issues = lint_sql_style(file_path, edit_content)
590
718
  if sql_style_issues:
@@ -934,7 +1062,9 @@ def main():
934
1062
 
935
1063
  start = Path.cwd()
936
1064
  if file_path:
937
- start = Path(file_path).expanduser().resolve().parent
1065
+ candidate = Path(file_path).expanduser().resolve().parent
1066
+ if candidate.exists():
1067
+ start = candidate
938
1068
  root = repo_root(start)
939
1069
  if root is None:
940
1070
  return 0
@@ -942,7 +1072,25 @@ def main():
942
1072
  if command:
943
1073
  return handle_commit(command, root)
944
1074
 
945
- edit_content = tool_input.get("new_string") or tool_input.get("content") or ""
1075
+ patch = tool_input.get("patch") or ""
1076
+ if patch:
1077
+ sections = re.split(r"(?=^\*\*\* (?:Add|Update) File: )", patch, flags=re.M)
1078
+ for section in sections:
1079
+ target = re.search(r"^\*\*\* (?:Add|Update) File: (.+)$", section, re.M)
1080
+ if not target:
1081
+ continue
1082
+ added = "\n".join(line[1:] for line in section.splitlines()
1083
+ if line.startswith("+") and not line.startswith("+++"))
1084
+ if handle_edit(target.group(1), added) == 2:
1085
+ return 2
1086
+ return 0
1087
+
1088
+ edits = tool_input.get("edits")
1089
+ if isinstance(edits, list):
1090
+ edit_content = "\n".join(str(edit.get("new_string") or "")
1091
+ for edit in edits if isinstance(edit, dict))
1092
+ else:
1093
+ edit_content = tool_input.get("new_string") or tool_input.get("content") or ""
946
1094
  return handle_edit(file_path, edit_content)
947
1095
 
948
1096
 
@@ -0,0 +1,229 @@
1
+ {
2
+ "version": "1.0.0",
3
+ "contracts": [
4
+ {
5
+ "name": "openspec-apply-change",
6
+ "owner": "implement",
7
+ "triggers": [
8
+ "implement approved change"
9
+ ],
10
+ "excludes": [],
11
+ "outputs": [
12
+ "tasks.md progress"
13
+ ],
14
+ "neighbors": []
15
+ },
16
+ {
17
+ "name": "openspec-archive-change",
18
+ "owner": "archive",
19
+ "triggers": [
20
+ "archive completed change"
21
+ ],
22
+ "excludes": [],
23
+ "outputs": [
24
+ "archive result"
25
+ ],
26
+ "neighbors": []
27
+ },
28
+ {
29
+ "name": "openspec-explore",
30
+ "owner": "explore",
31
+ "triggers": [
32
+ "explore requirements"
33
+ ],
34
+ "excludes": [],
35
+ "outputs": [
36
+ "alignment.md"
37
+ ],
38
+ "neighbors": [
39
+ "openspec-propose"
40
+ ]
41
+ },
42
+ {
43
+ "name": "openspec-propose",
44
+ "owner": "propose",
45
+ "triggers": [
46
+ "generate OpenSpec proposal"
47
+ ],
48
+ "excludes": [],
49
+ "outputs": [
50
+ "proposal.md specs design.md tasks.md"
51
+ ],
52
+ "neighbors": [
53
+ "superflow-clarify",
54
+ "superflow-design",
55
+ "superflow-implement"
56
+ ]
57
+ },
58
+ {
59
+ "name": "superflow-archive",
60
+ "owner": "archive",
61
+ "triggers": [
62
+ "archive SDD change"
63
+ ],
64
+ "excludes": [],
65
+ "outputs": [
66
+ "archive report"
67
+ ],
68
+ "neighbors": [
69
+ "superflow-verify"
70
+ ]
71
+ },
72
+ {
73
+ "name": "superflow-clarify",
74
+ "owner": "clarify",
75
+ "triggers": [
76
+ "clarify requirements"
77
+ ],
78
+ "excludes": [],
79
+ "outputs": [
80
+ "source-code-audit.md feature-gates.md brainstorm-summary.md"
81
+ ],
82
+ "neighbors": [
83
+ "openspec-propose",
84
+ "superflow-docs"
85
+ ]
86
+ },
87
+ {
88
+ "name": "superflow-design",
89
+ "owner": "design",
90
+ "triggers": [
91
+ "technical design"
92
+ ],
93
+ "excludes": [],
94
+ "outputs": [
95
+ "technical_design"
96
+ ],
97
+ "neighbors": [
98
+ "superflow-docs",
99
+ "superflow-implement"
100
+ ]
101
+ },
102
+ {
103
+ "name": "superflow-docs",
104
+ "owner": "docs",
105
+ "triggers": [
106
+ "SDD contract documents"
107
+ ],
108
+ "excludes": [],
109
+ "outputs": [
110
+ "api.md tests.md sdd-quality-gate.md"
111
+ ],
112
+ "neighbors": [
113
+ "superflow-clarify",
114
+ "superflow-design",
115
+ "superflow-implement"
116
+ ]
117
+ },
118
+ {
119
+ "name": "superflow-hotfix",
120
+ "owner": "pipeline",
121
+ "triggers": [
122
+ "urgent small fix"
123
+ ],
124
+ "excludes": [],
125
+ "outputs": [
126
+ "bug-fix-plan.md"
127
+ ],
128
+ "neighbors": []
129
+ },
130
+ {
131
+ "name": "superflow-implement",
132
+ "owner": "implement",
133
+ "triggers": [
134
+ "generate implementation prompts"
135
+ ],
136
+ "excludes": [],
137
+ "outputs": [
138
+ "prompt/ test-report.md"
139
+ ],
140
+ "neighbors": [
141
+ "superflow-design",
142
+ "superflow-verify"
143
+ ]
144
+ },
145
+ {
146
+ "name": "superflow-pipeline",
147
+ "owner": "pipeline",
148
+ "triggers": [
149
+ "Superflow SDD pipeline"
150
+ ],
151
+ "excludes": [],
152
+ "outputs": [
153
+ "state.yaml handoff"
154
+ ],
155
+ "neighbors": []
156
+ },
157
+ {
158
+ "name": "superflow-requirement-review",
159
+ "owner": "review",
160
+ "triggers": [
161
+ "review requirements"
162
+ ],
163
+ "excludes": [],
164
+ "outputs": [
165
+ "requirement-review.md"
166
+ ],
167
+ "neighbors": []
168
+ },
169
+ {
170
+ "name": "superflow-table-impact-analysis",
171
+ "owner": "docs",
172
+ "triggers": [
173
+ "table impact analysis"
174
+ ],
175
+ "excludes": [],
176
+ "outputs": [
177
+ "impact analysis"
178
+ ],
179
+ "neighbors": []
180
+ },
181
+ {
182
+ "name": "superflow-tweak",
183
+ "owner": "pipeline",
184
+ "triggers": [
185
+ "small wording tweak"
186
+ ],
187
+ "excludes": [],
188
+ "outputs": [
189
+ "tweak result"
190
+ ],
191
+ "neighbors": []
192
+ },
193
+ {
194
+ "name": "superflow-quick-dev",
195
+ "owner": "quick",
196
+ "triggers": [
197
+ "small code task",
198
+ "quick development"
199
+ ],
200
+ "excludes": [
201
+ "public API or database change",
202
+ "cross-module change"
203
+ ],
204
+ "outputs": [
205
+ ".sdd/tasks/<date>-<slug>/spec.md",
206
+ "quick evidence"
207
+ ],
208
+ "neighbors": [
209
+ "superflow-clarify",
210
+ "superflow-verify"
211
+ ]
212
+ },
213
+ {
214
+ "name": "superflow-verify",
215
+ "owner": "verify",
216
+ "triggers": [
217
+ "verify implementation"
218
+ ],
219
+ "excludes": [],
220
+ "outputs": [
221
+ "verification report"
222
+ ],
223
+ "neighbors": [
224
+ "superflow-implement",
225
+ "superflow-archive"
226
+ ]
227
+ }
228
+ ]
229
+ }
@@ -22,6 +22,14 @@ When ready to implement, run /opsx:apply
22
22
 
23
23
  **Input**: The user's request should include a change name (kebab-case) OR a description of what they want to build.
24
24
 
25
+ When this skill follows `superflow-clarify`, read the confirmed change-level
26
+ Consensus Summary and its source evidence before creating artifacts. Put the
27
+ goal, scope, material owner decisions, rejected alternatives, migration risks,
28
+ and non-blocking reopen triggers in canonical `proposal.md`; cite the existing
29
+ source audit rather than copying it. A pending owner decision that changes the
30
+ solution blocks downstream spec/design/tasks. An explicit decision in the
31
+ user's original request needs no second confirmation.
32
+
25
33
  ### OpenSpec canonical change 目录(阻塞级)
26
34
 
27
35
  - change 必须只有一个实体目录:`openspec/changes/<name>/`。
@@ -108,6 +116,12 @@ After completing all artifacts, summarize:
108
116
  - Follow the `instruction` field from `openspec instructions` for each artifact type
109
117
  - The schema defines what each artifact should contain - follow it
110
118
  - Read dependency artifacts for context before creating new ones
119
+ - For a Superflow change, keep ordinary OpenSpec checkbox task syntax. For each
120
+ independently verifiable task, state its observable delivery and acceptance
121
+ signal; record real predecessor task IDs as `Blocked by` and link the relevant
122
+ requirement/scenario or traceability row. A free-text blocker does not change
123
+ Superflow's `[local_required]` / `[environment_required]` /
124
+ `[release_required]` machine classification. Do not invent dependencies.
111
125
  - Use `template` as the structure for your output file - fill in its sections
112
126
  - **IMPORTANT**: `context` and `rules` are constraints for YOU, not content for the file
113
127
  - Do NOT copy `<context>`, `<rules>`, `<project_context>` blocks into the artifact
@@ -13,7 +13,7 @@ any full SDD document or implementation prompt is generated.
13
13
 
14
14
  - Before freezing any new requirement or bug fix, perform platform-level impact
15
15
  discovery. Prefer understand-anything artifacts when present, such as
16
- `.understand-anything/`, `understand-anything.md`, `understand anything.md`,
16
+ `.ua/`, `.understand-anything/`, `understand-anything.md`, `understand anything.md`,
17
17
  or the project-specific graph output, but treat them only as locator evidence.
18
18
  If artifacts are missing, stale, incomplete, or unavailable, degrade to `rg`,
19
19
  source reading, Mapper/XML, configuration, database table names, log
@@ -171,6 +171,28 @@ Use the detailed workflow in:
171
171
  indexed feature. Do not batch-confirm multiple features from memory or a
172
172
  compressed chat summary.
173
173
 
174
+ ### Change-level alignment before OpenSpec artifacts
175
+
176
+ After all in-scope features are frozen, present one concise change-level
177
+ `Consensus Summary` covering the goal, in/out scope, verified source facts,
178
+ owner decisions with rejected alternatives, production and migration risks,
179
+ and remaining non-blocking questions with owner and reopen trigger. Derive it
180
+ from `source-code-audit.md`, `feature-gates.md`, and the confirmed decisions in
181
+ `.sdd/handoff/brainstorm-summary.md`; the summary is a handoff view, not a
182
+ second source of requirements. Record unresolved decisions as blockers and
183
+ ask only the next owner decision. Do not ask the user to reconfirm facts or
184
+ choices already explicit in the original request.
185
+
186
+ When a material owner choice was made during clarification, show the current
187
+ summary before generating OpenSpec artifacts. Reuse an explicit confirmation
188
+ already given for that exact choice and summary; ask once only if the summary
189
+ introduces a new choice or changes its consequence. The later `proposal.md`
190
+ must carry the confirmed change-level
191
+ decisions and cite their evidence. If a later finding changes a confirmed
192
+ choice, return to that decision, update affected canonical documents, refresh
193
+ the handoff hash and repeat document review and Coding Ready. Task checkbox
194
+ progress alone does not change the agreed contract.
195
+
174
196
  ## Handoff
175
197
 
176
198
  When the feature is frozen, tell the user to continue with `$openspec-propose`
@@ -64,7 +64,12 @@ Superpowers own source-level HOW without weakening OpenSpec/SDD contracts.
64
64
  5. Write:
65
65
  `docs/superpowers/specs/YYYY-MM-DD-<change-id>-technical-design.md`
66
66
  using `../superflow-pipeline/references/superpower-technical-design-template.md`.
67
- 6. Complete `复杂度减法评审` before expanding source-level HOW. For every new
67
+ 6. For each new or changed module interface, add a `Design-It-Twice` card to
68
+ the technical design: two materially different interfaces, seam and adapter
69
+ ownership, the real test surface, reuse evidence, caller consequences, and
70
+ an explicit choice. Renaming the same interface does not count as two
71
+ options; revisit it. This card is advisory and does not add a state gate.
72
+ 7. Complete `复杂度减法评审` before expanding source-level HOW. For every new
68
73
  table, field, API, Service/component, abstraction, cache, async/MQ/event
69
74
  flow, scheduled job, or compatibility layer, prove existing reuse options,
70
75
  necessity, and why the simplest direct implementation is insufficient.
@@ -37,6 +37,12 @@ Do not invent new fields or requirements.
37
37
 
38
38
  For complex requirements, verify these before writing docs:
39
39
 
40
+ - `proposal.md` carries the confirmed change-level Consensus Summary from
41
+ clarification: goal, scope, owner choices and rejected alternatives,
42
+ production/migration risks, and non-blocking reopen triggers. Check it
43
+ against original sources and `source-code-audit.md`; do not treat the
44
+ handoff summary as a second authority. If a material choice remains open,
45
+ return to `$superflow-clarify` before finalizing design or tasks.
40
46
  - `source-ingestion.md`, `feature-inventory.md`, and `feature-gates.md` prove
41
47
  that the original PRD/Lark/Feishu/screenshots were processed section by
42
48
  section, not summarized into tasks in one whole-document pass. Each feature
@@ -240,6 +246,12 @@ applicable:
240
246
  - `tasks.md` 每个 checkbox 必须带且只带一个机器分类:`[local_required]`、
241
247
  `[environment_required]` 或 `[release_required]`。能够在本地完成的编码、测试、启动和浏览器
242
248
  验证必须是 local_required;不得用自由文本 Blocker/owner 代替分类。
249
+ - For each implementation task, review observable delivery, acceptance signal,
250
+ requirement/scenario coverage, and actual predecessors. Show the currently
251
+ executable tasks whose predecessors are complete. Reuse
252
+ `traceability-matrix.md` for detailed coverage; do not create another task
253
+ state file. `Blocked by` expresses execution order and never changes the
254
+ machine task classification above.
243
255
  - `tests.md`
244
256
  - `test-report.md` skeleton
245
257
  - `sdd-quality-gate.md`
@@ -83,6 +83,14 @@ Before implementation phase can exit:
83
83
  ## Prompt Splitting Rules
84
84
 
85
85
  - Split by independently verifiable feature closure, not by a giant backend module.
86
+ - Read `tasks.md` predecessor links before splitting or dispatching. A batch is
87
+ executable only when its real predecessors are complete; independent batches
88
+ may run in parallel. Keep the existing checkbox and machine category as the
89
+ progress authority. An implementation discovery that changes a confirmed
90
+ owner decision or task acceptance requires canonical document repair,
91
+ handoff refresh, document review, and a new Coding Ready receipt before the
92
+ affected batch resumes. A free-text `Blocked by` note cannot downgrade a
93
+ locally executable task to an external category.
86
94
  - Use P0 for baseline only: worktree, branch, compile, SQL/entity/mapper/DTO consistency.
87
95
  - Keep business prompts small and explicit.
88
96
  - Every implementation prompt must begin with the mandatory superpower/team
@@ -7,6 +7,16 @@ description: SDD 总入口和路由技能。Use when the user says sdd, SDD 流
7
7
 
8
8
  This is the lightweight SDD router. Do not load the whole SDD process when a smaller phase skill is enough.
9
9
 
10
+ ## 角色 owner 与互斥边界
11
+
12
+ | 角色 | 唯一 owner | 可以做 | 不可以做 |
13
+ |---|---|---|---|
14
+ | Host | 目标、澄清、监督、语义评审 | 选择路由、判断代码/架构风险、决定是否接受反馈 | 代替 Executor 写业务代码;启动嵌套 Supervisor |
15
+ | Executor | 源码实现、测试、启动、整改 | 在冻结合同内修改工作区并提交证据 | 改合同/状态;自行降低验收等级;自动提交发布 |
16
+ | Runner | 状态、哈希、退出码、证据持久化 | 调度、等待、恢复、确定性门禁 | 猜业务语义;重新设计 API/DB;代替 Host 评审 |
17
+
18
+ 菜单或 persona 只改变入口表达,不创建第二套状态机;发现 owner 冲突时回到 Host 澄清。
19
+
10
20
  维护 Superflow CLI 自身时,必须先读取仓库根目录
11
21
  `docs/superflow-cli-design-principles.md` 和
12
22
  `docs/superflow-cli-evaluation-framework.md`;涉及托管时再读取托管专项宪章与协议。
@@ -86,6 +96,12 @@ JSON,再用 `--resume-task <task-id> --submit-host-review <json>` 恢复。监
86
96
 
87
97
  ## Choose The Right SDD Skill
88
98
 
99
+ - Use `$superflow-quick-dev` for one clear, low-blast-radius code change along
100
+ an existing test seam. Run its narrow gate before editing; API, DB, security,
101
+ transactions, concurrency, payments, cross-module work, a related active SDD
102
+ change, or uncertain ownership goes to `$superflow-clarify` instead. Reuse
103
+ the current quick managed profile after the Quick Spec is approved; do not
104
+ create a second managed-task state machine.
89
105
  - Use `$openspec-explore` when the user is still thinking through a requirement,
90
106
  wants to compare options, or needs codebase investigation before a change.
91
107
  - Route to `$superflow-clarify` in embedded deep-clarification mode when the
@@ -163,6 +179,12 @@ When the router selects embedded deep clarification, follow these rules inside
163
179
  - Exit deep clarification once only repository-verifiable facts remain and the
164
180
  user confirms the current feature understanding. Continue through the existing
165
181
  clarify workflow without invoking an external skill dependency.
182
+ - After all relevant features are frozen, show the change-level Consensus
183
+ Summary from `superflow-clarify` before OpenSpec artifact generation. Carry
184
+ confirmed choices into canonical `proposal.md`; do not create a parallel
185
+ alignment fact source or add approval prompts for decisions already explicit
186
+ in the user's request. A changed owner choice requires affected documents,
187
+ handoff, review, and Coding Ready to be refreshed before execution.
166
188
 
167
189
  ## Non-Negotiable Rules
168
190
 
@@ -326,6 +348,11 @@ context_compression | created_at | verified_at | updated_at`
326
348
 
327
349
  - 设计范围、API/DB 合同、执行模式、验证边界、archive closeout 需要用户取舍时,
328
350
  使用 `references/decision-point.md` 的格式记录,不用聊天记忆代替。
351
+
352
+ 仓库级术语或持久架构决定可运行 `superflow context-audit --path <project>`
353
+ 做只读检查。业务术语放入 `CONTEXT.md`;只有难逆转且存在有意义备选方案时才写 ADR。
354
+ 审计是 advisory:缺少 ADR 只提醒,ADR 字段不全或术语混入实现细节才报告修复项,
355
+ 不新增审批门禁,也不替代 `design.md`。
329
356
  - 脏工作区、并行 worktree 或跨会话接力前,使用 `references/dirty-worktree.md`
330
357
  的检查项,避免覆盖用户改动或拿旧 handoff 继续。
331
358
  - `build_mode: subagent-driven-development` 时,维护
@@ -431,7 +458,7 @@ Mapper/XML、数据库样例、接口契约和真实消费入口验证。
431
458
  **影响面发现方式(优先但可降级):**
432
459
 
433
460
  - 优先检查当前仓库是否存在 understand-anything 相关索引/产物,例如
434
- `.understand-anything/`、`understand-anything.md`、`understand anything.md`、
461
+ `.ua/`、`.understand-anything/`、`understand-anything.md`、`understand anything.md`、
435
462
  或项目约定的 understand-anything 图谱文件。
436
463
  - 如果索引存在,可以用它快速定位整个平台相关代码,包括当前仓库、同平台
437
464
  sibling repo、共享 SDK、公共 DTO、数据库表消费方、定时任务、回调入口、外部平台
@@ -20,6 +20,23 @@ canonical_sources:
20
20
 
21
21
  # Superpowers Technical Design: <change title>
22
22
 
23
+ ## Design-It-Twice:接口与 seam 选择
24
+
25
+ 仅在新增或改变模块接口时填写;纯实现内重构可写“无接口变化”。
26
+
27
+ | 项目 | 方案 A | 方案 B |
28
+ |---|---|---|
29
+ | 接口与调用方约束 | | |
30
+ | seam 与 adapter owner | | |
31
+ | 真实测试面 | | |
32
+ | 复用证据(文件/符号) | | |
33
+ | 爆炸半径与后果 | | |
34
+
35
+ - 选择:A / B
36
+ - 选择理由:
37
+ - 被拒绝方案的具体代价:
38
+ - 两种方案不能只是改名或换参数顺序。
39
+
23
40
  ## Boundary
24
41
 
25
42
  - This document owns source-level HOW only.