@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.
- package/README.md +26 -0
- package/README.zh-CN.md +8 -0
- package/assets/manifest.json +33 -7
- package/assets/review-rules.json +24 -0
- package/assets/scripts/superflow-archive-command-hook.sh +4 -0
- package/assets/scripts/superflow-contract-hooks.sh +4 -0
- package/assets/scripts/superflow-delivery-check.sh +4 -0
- package/assets/scripts/superflow-dependency-update-hook.sh +29 -0
- package/assets/scripts/superflow-doc-placement-hook.py +38 -0
- package/assets/scripts/superflow-enforce-hook.sh +4 -0
- package/assets/scripts/superflow-hook-guard.sh +4 -0
- package/assets/scripts/superflow-integration-evidence-hook.sh +4 -0
- package/assets/scripts/superflow-java-build-hook.py +178 -0
- package/assets/scripts/superflow-java-stop-hook.sh +3 -0
- package/assets/scripts/superflow-loop-end-hook.sh +3 -0
- package/assets/scripts/superflow-loop-failure-hook.sh +3 -0
- package/assets/scripts/superflow-loop-observer.py +149 -0
- package/assets/scripts/superflow-managed-work-guard.sh +4 -0
- package/assets/scripts/superflow-sql-sync-hook.py +151 -3
- package/assets/skill-registry.json +229 -0
- package/assets/skills/openspec-propose/SKILL.md +14 -0
- package/assets/skills/superflow-clarify/SKILL.md +23 -1
- package/assets/skills/superflow-design/SKILL.md +6 -1
- package/assets/skills/superflow-docs/SKILL.md +12 -0
- package/assets/skills/superflow-implement/SKILL.md +8 -0
- package/assets/skills/superflow-pipeline/SKILL.md +28 -1
- package/assets/skills/superflow-pipeline/references/superpower-technical-design-template.md +17 -0
- package/assets/skills/superflow-quick-dev/SKILL.md +44 -0
- package/assets/skills/superflow-verify/SKILL.md +41 -0
- package/assets/skills-en/openspec-propose/SKILL.md +14 -0
- package/assets/skills-en/superflow-clarify/SKILL.md +23 -1
- package/assets/skills-en/superflow-design/SKILL.md +6 -1
- package/assets/skills-en/superflow-docs/SKILL.md +12 -0
- package/assets/skills-en/superflow-implement/SKILL.md +9 -0
- package/assets/skills-en/superflow-pipeline/SKILL.md +30 -0
- package/assets/skills-en/superflow-quick-dev/SKILL.md +43 -0
- package/assets/skills-en/superflow-verify/SKILL.md +46 -0
- package/dist/app/cli.js +98 -0
- package/dist/app/cli.js.map +1 -1
- package/dist/app/commands/check.js +7 -3
- package/dist/app/commands/check.js.map +1 -1
- package/dist/app/commands/cleanup-audit.js +13 -0
- package/dist/app/commands/cleanup-audit.js.map +1 -0
- package/dist/app/commands/context-audit.js +43 -0
- package/dist/app/commands/context-audit.js.map +1 -0
- package/dist/app/commands/docs-audit.js +11 -0
- package/dist/app/commands/docs-audit.js.map +1 -0
- package/dist/app/commands/doctor.js +10 -0
- package/dist/app/commands/doctor.js.map +1 -1
- package/dist/app/commands/hook-migrate.js +25 -0
- package/dist/app/commands/hook-migrate.js.map +1 -0
- package/dist/app/commands/init.js +25 -18
- package/dist/app/commands/init.js.map +1 -1
- package/dist/app/commands/map-audit.js +10 -0
- package/dist/app/commands/map-audit.js.map +1 -0
- package/dist/app/commands/pipeline.js +13 -1
- package/dist/app/commands/pipeline.js.map +1 -1
- package/dist/app/commands/quick.js +136 -0
- package/dist/app/commands/quick.js.map +1 -0
- package/dist/app/commands/review-coverage.js +84 -0
- package/dist/app/commands/review-coverage.js.map +1 -0
- package/dist/app/commands/skill-audit.js +36 -0
- package/dist/app/commands/skill-audit.js.map +1 -0
- package/dist/app/commands/status.js +108 -7
- package/dist/app/commands/status.js.map +1 -1
- package/dist/app/commands/uninstall.js +119 -25
- package/dist/app/commands/uninstall.js.map +1 -1
- package/dist/app/commands/update.js +62 -25
- package/dist/app/commands/update.js.map +1 -1
- package/dist/domains/cleanup-audit.js +38 -0
- package/dist/domains/cleanup-audit.js.map +1 -0
- package/dist/domains/config/cli-help.js +14 -0
- package/dist/domains/config/cli-help.js.map +1 -1
- package/dist/domains/config/context.js +13 -10
- package/dist/domains/config/context.js.map +1 -1
- package/dist/domains/context-audit.js +39 -0
- package/dist/domains/context-audit.js.map +1 -0
- package/dist/domains/deps.js +18 -8
- package/dist/domains/deps.js.map +1 -1
- package/dist/domains/docs-audit.js +34 -0
- package/dist/domains/docs-audit.js.map +1 -0
- package/dist/domains/hook-migration.js +127 -0
- package/dist/domains/hook-migration.js.map +1 -0
- package/dist/domains/hook.js +76 -2
- package/dist/domains/hook.js.map +1 -1
- package/dist/domains/managed-work/control.js +56 -2
- package/dist/domains/managed-work/control.js.map +1 -1
- package/dist/domains/map-audit.js +23 -0
- package/dist/domains/map-audit.js.map +1 -0
- package/dist/domains/quick-dev/gate.js +91 -0
- package/dist/domains/quick-dev/gate.js.map +1 -0
- package/dist/domains/review/coverage.js +119 -0
- package/dist/domains/review/coverage.js.map +1 -0
- package/dist/domains/review/report.js +62 -0
- package/dist/domains/review/report.js.map +1 -0
- package/dist/domains/skill/registry.js +87 -0
- package/dist/domains/skill/registry.js.map +1 -0
- package/dist/domains/state.js +64 -0
- package/dist/domains/state.js.map +1 -1
- package/package.json +1 -1
- 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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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.
|
|
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.
|