@chenmk/superflow 0.3.0 → 0.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +20 -1
- package/README.zh-CN.md +16 -1
- package/assets/manifest.json +5 -4
- package/assets/prompts/superflow-design.md +3 -0
- package/assets/prompts/superflow-docs.md +4 -1
- package/assets/scripts/superflow-dependency-update-hook.sh +1 -1
- package/assets/scripts/superflow-managed-work-check.mjs +194 -0
- package/assets/scripts/superflow-managed-work-guard.sh +103 -0
- package/assets/skills/openspec-propose/SKILL.md +11 -0
- package/assets/skills/superflow-design/SKILL.md +18 -9
- package/assets/skills/superflow-docs/SKILL.md +16 -0
- package/assets/skills/superflow-pipeline/SKILL.md +46 -0
- package/assets/skills/superflow-pipeline/references/document-templates.md +8 -0
- package/assets/skills/superflow-pipeline/references/managed-work.md +58 -0
- package/assets/skills/superflow-pipeline/references/quality-gate.md +1 -0
- package/assets/skills/superflow-pipeline/references/superpower-technical-design-template.md +10 -0
- package/assets/skills/superflow-pipeline/scripts/superflow-archive.sh +1 -1
- package/assets/skills/superflow-pipeline/scripts/superflow-guard.sh +79 -9
- package/assets/skills-en/openspec-propose/SKILL.md +14 -0
- package/assets/skills-en/superflow-design/SKILL.md +18 -8
- package/assets/skills-en/superflow-docs/SKILL.md +16 -0
- package/assets/skills-en/superflow-pipeline/SKILL.md +48 -0
- package/assets/skills-en/superflow-pipeline/references/document-templates.md +5 -0
- package/assets/skills-en/superflow-pipeline/references/managed-work.md +34 -0
- package/assets/skills-en/superflow-pipeline/references/quality-gate.md +8 -0
- package/assets/skills-en/superflow-pipeline/references/superpower-technical-design-template.md +11 -0
- package/assets/skills-en/superflow-pipeline/scripts/superflow-archive.sh +1 -1
- package/assets/skills-en/superflow-pipeline/scripts/superflow-guard.sh +78 -9
- package/dist/app/cli.js +120 -102
- package/dist/app/cli.js.map +1 -1
- package/dist/app/commands/init.js +6 -2
- package/dist/app/commands/init.js.map +1 -1
- package/dist/app/commands/managed-service.js +5 -0
- package/dist/app/commands/managed-service.js.map +1 -0
- package/dist/app/commands/pipeline.js +123 -3
- package/dist/app/commands/pipeline.js.map +1 -1
- package/dist/app/commands/status.js +199 -77
- package/dist/app/commands/status.js.map +1 -1
- package/dist/app/commands/uninstall.js +5 -2
- package/dist/app/commands/uninstall.js.map +1 -1
- package/dist/app/commands/update.js +31 -6
- package/dist/app/commands/update.js.map +1 -1
- package/dist/domains/config/cli-help.js +103 -73
- package/dist/domains/config/cli-help.js.map +1 -1
- package/dist/domains/deps.js +2 -1
- package/dist/domains/deps.js.map +1 -1
- package/dist/domains/hook.js +71 -38
- package/dist/domains/hook.js.map +1 -1
- package/dist/domains/managed-work/contract.js +218 -0
- package/dist/domains/managed-work/contract.js.map +1 -0
- package/dist/domains/managed-work/i18n.js +12 -0
- package/dist/domains/managed-work/i18n.js.map +1 -0
- package/dist/domains/managed-work/input.js +111 -0
- package/dist/domains/managed-work/input.js.map +1 -0
- package/dist/domains/managed-work/journal.js +122 -0
- package/dist/domains/managed-work/journal.js.map +1 -0
- package/dist/domains/managed-work/lock.js +40 -0
- package/dist/domains/managed-work/lock.js.map +1 -0
- package/dist/domains/managed-work/notifications.js +53 -0
- package/dist/domains/managed-work/notifications.js.map +1 -0
- package/dist/domains/managed-work/paths.js +18 -0
- package/dist/domains/managed-work/paths.js.map +1 -0
- package/dist/domains/managed-work/prompts.js +218 -0
- package/dist/domains/managed-work/prompts.js.map +1 -0
- package/dist/domains/managed-work/runner.js +626 -0
- package/dist/domains/managed-work/runner.js.map +1 -0
- package/dist/domains/managed-work/schemas.js +85 -0
- package/dist/domains/managed-work/schemas.js.map +1 -0
- package/dist/domains/managed-work/service.js +121 -0
- package/dist/domains/managed-work/service.js.map +1 -0
- package/dist/domains/managed-work/state.js +90 -0
- package/dist/domains/managed-work/state.js.map +1 -0
- package/dist/domains/managed-work/storage.js +181 -0
- package/dist/domains/managed-work/storage.js.map +1 -0
- package/dist/domains/managed-work/types.js +16 -0
- package/dist/domains/managed-work/types.js.map +1 -0
- package/dist/domains/managed-work/wait.js +40 -0
- package/dist/domains/managed-work/wait.js.map +1 -0
- package/dist/platform/agent-process.js +308 -0
- package/dist/platform/agent-process.js.map +1 -0
- package/dist/platform/process-liveness.js +10 -0
- package/dist/platform/process-liveness.js.map +1 -0
- package/dist/platform/version-check.js +30 -9
- package/dist/platform/version-check.js.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -48,6 +48,11 @@ state, and dependency guards for Claude Code, Codex, and OpenCode.
|
|
|
48
48
|
|
|
49
49
|
## Highlights
|
|
50
50
|
|
|
51
|
+
- **Dual-Agent managed delivery.** The current Agent supervises while the peer
|
|
52
|
+
Agent develops, starts, and verifies through a non-interactive CLI. Repair
|
|
53
|
+
rounds resume exact sessions and are capped at 5 reviews, 7 executor calls,
|
|
54
|
+
and 12 total calls. Durable journals allow recovery after terminal or network
|
|
55
|
+
interruption, and passing work stops for explicit Git approval.
|
|
51
56
|
- **9 catalogued failure modes, blocked at the gate.** Nine real ways AI breaks
|
|
52
57
|
in production — swallowing the whole PRD then forgetting details, editing
|
|
53
58
|
only the setter while missing consumers, SQL drift across dev/test/DB
|
|
@@ -141,12 +146,25 @@ superflow --language en --help
|
|
|
141
146
|
SUPERFLOW_LANG=en superflow init
|
|
142
147
|
```
|
|
143
148
|
|
|
149
|
+
Manage an implementation prompt, OpenSpec change, or direct development task:
|
|
150
|
+
|
|
151
|
+
```bash
|
|
152
|
+
superflow pipeline "<prompt path, change directory, or task>" --managed \
|
|
153
|
+
--project "<project root>"
|
|
154
|
+
```
|
|
155
|
+
|
|
156
|
+
The selected language is frozen into the task contract and reused by Agent
|
|
157
|
+
prompts, reviews, journals, reports, notifications, and resumed rounds.
|
|
158
|
+
|
|
144
159
|
## What Init Installs
|
|
145
160
|
|
|
146
161
|
`superflow init` installs and configures:
|
|
147
162
|
|
|
148
163
|
- OpenSpec CLI, then runs `openspec init <project> --tools ...`
|
|
149
|
-
- Superpowers for the selected agent tools
|
|
164
|
+
- Superpowers for the selected agent tools. Codex uses the official
|
|
165
|
+
`superpowers@openai-api-curated` plugin, including
|
|
166
|
+
`verification-before-completion`, `requesting-code-review`, and
|
|
167
|
+
`finishing-a-development-branch`.
|
|
150
168
|
- SuperBridge Flow/OpenSpec skills
|
|
151
169
|
- hooks, scripts, and anti-drift rules
|
|
152
170
|
- Codex prompt aliases
|
|
@@ -170,6 +188,7 @@ best-effort and does not block initialization.
|
|
|
170
188
|
| `superflow --language en --help` | Show English CLI help |
|
|
171
189
|
| `superflow scan --language en` | Regenerate project context templates in English |
|
|
172
190
|
| `superflow pipeline` | Check pipeline skill deployment |
|
|
191
|
+
| `superflow pipeline "<task>" --managed --project <path>` | Run Dual-Agent managed development to a terminal delivery state |
|
|
173
192
|
| `superflow docs` | Check docs-phase skill deployment |
|
|
174
193
|
| `superflow design` | Check design-phase skill deployment |
|
|
175
194
|
| `superflow implement` | Check implement-phase skill deployment |
|
package/README.zh-CN.md
CHANGED
|
@@ -43,6 +43,9 @@ CLI 会把 SuperBridge Flow 技能、配套 hook/command 脚本整合为单一 n
|
|
|
43
43
|
|
|
44
44
|
## 亮点
|
|
45
45
|
|
|
46
|
+
- **双 Agent 托管到真实交付。** 当前 Agent 负责监督,另一个 Agent 通过无交互 CLI
|
|
47
|
+
持续开发、启动和验证;评审整改复用原会话,最多 5 轮评审、7 次执行、12 次总调用。
|
|
48
|
+
状态和证据全部落盘,终端或网络中断后可恢复,最终停在等待 Git 批准。
|
|
46
49
|
- **9 类翻车场景,沉淀成门禁。** 我们见过的 AI 翻车——需求一次吞、字段漏查消费者、SQL 漂移、mock-only 报告、跨服务只看到"能调"……9 种典型形态都被固化成 guard,AI 想跳过都不行。
|
|
47
50
|
- **跨服务代码必须先答架构 6 问。** 涉及跨仓、跨服务、SDK、MQ、设备、回调、网关的改动,技术详设里必须先回答:owner 是谁、调用方向、新入口是否允许、禁止路径、证据锚点——答不全不让进入实现。
|
|
48
51
|
- **改字段之前先填"字段与状态反向影响"矩阵。** 任何 schema、状态、枚举的改动,必须枚举写入点、读取点、过滤点、派生 / 同步点、跨模块消费者、测试覆盖,还要列反向恢复场景(下线后重上线、旧值不可用但上游没传字段、历史脏数据被新过滤条件消费)。
|
|
@@ -115,6 +118,15 @@ export SUPERFLOW_LANG=en
|
|
|
115
118
|
superflow init
|
|
116
119
|
```
|
|
117
120
|
|
|
121
|
+
托管一个 implementation prompt、OpenSpec change 或简单开发任务:
|
|
122
|
+
|
|
123
|
+
```bash
|
|
124
|
+
superflow pipeline "<prompt 路径、change 目录或任务>" --managed \
|
|
125
|
+
--project "<项目根目录>"
|
|
126
|
+
```
|
|
127
|
+
|
|
128
|
+
语言会冻结进任务合同;执行 Prompt、评审、账本、报告、通知和恢复轮次保持一致。
|
|
129
|
+
|
|
118
130
|
## SDD 分工
|
|
119
131
|
|
|
120
132
|
- OpenSpec/SDD 负责 WHAT 和合同:需求、API、DB、SQL、字段语义、tests、真实入口验收和质量门禁。
|
|
@@ -145,6 +157,7 @@ superflow init
|
|
|
145
157
|
| `superflow design [change]` | 校验 SuperBridge Flow design 阶段技能部署 |
|
|
146
158
|
| `superflow implement [task]` | 校验 SuperBridge Flow implement 阶段技能部署 |
|
|
147
159
|
| `superflow pipeline` | 校验 SuperBridge Flow pipeline 阶段技能部署 |
|
|
160
|
+
| `superflow pipeline "<任务>" --managed --project <目录>` | 双 Agent 托管开发并等待交付终态 |
|
|
148
161
|
| `superflow check <change>` | 对照 13 项必备文件清单检查文档完整性 |
|
|
149
162
|
| `superflow config <change> --review-mode <mode>` | 设置代码审查强度(off/standard/thorough) |
|
|
150
163
|
| `superflow config <change> --auto-transition <bool>` | 控制阶段自动流转(true/false) |
|
|
@@ -163,7 +176,9 @@ superflow init
|
|
|
163
176
|
- Claude Code、Codex 或 OpenCode(按 `--agent` 选择)
|
|
164
177
|
- 第三方(`superflow init` 自动装):
|
|
165
178
|
- openspec CLI(硬依赖,npm 全局)并在当前项目执行 `openspec init --tools ...`
|
|
166
|
-
- superpowers(Claude Code / Codex 为硬依赖;
|
|
179
|
+
- superpowers(Claude Code / Codex 为硬依赖;Codex 自动安装官方
|
|
180
|
+
`superpowers@openai-api-curated`,确保包含验证、代码评审和分支收尾三个强制技能;
|
|
181
|
+
OpenCode 侧通过已部署 skills/commands 使用流程)
|
|
167
182
|
- understand-anything(尽力安装,失败只警告)
|
|
168
183
|
- api-doc-changelog(辅助 skill,复制到目标 agent skills 目录)
|
|
169
184
|
|
package/assets/manifest.json
CHANGED
|
@@ -17,9 +17,7 @@
|
|
|
17
17
|
"superflow-tweak",
|
|
18
18
|
"superflow-verify"
|
|
19
19
|
],
|
|
20
|
-
"rules": [
|
|
21
|
-
"superflow-phase-guard.md"
|
|
22
|
-
],
|
|
20
|
+
"rules": ["superflow-phase-guard.md"],
|
|
23
21
|
"scripts": [
|
|
24
22
|
"superflow-verify-integration.sh",
|
|
25
23
|
"superflow-delivery-check.sh",
|
|
@@ -31,6 +29,8 @@
|
|
|
31
29
|
"superflow-integration-evidence-hook.sh",
|
|
32
30
|
"superflow-archive-command-hook.sh",
|
|
33
31
|
"superflow-test-report-lint.py",
|
|
32
|
+
"superflow-managed-work-check.mjs",
|
|
33
|
+
"superflow-managed-work-guard.sh",
|
|
34
34
|
"install-sql-pre-commit.sh",
|
|
35
35
|
"sync-settings-json.py"
|
|
36
36
|
],
|
|
@@ -47,7 +47,8 @@
|
|
|
47
47
|
"superflow-sql-sync-hook.py",
|
|
48
48
|
"superflow-delivery-check.sh",
|
|
49
49
|
"superflow-integration-evidence-hook.sh",
|
|
50
|
-
"superflow-archive-command-hook.sh"
|
|
50
|
+
"superflow-archive-command-hook.sh",
|
|
51
|
+
"superflow-managed-work-guard.sh"
|
|
51
52
|
],
|
|
52
53
|
"agentHooks": {
|
|
53
54
|
"claude": ["claude-auto-backup-hook.sh"],
|
|
@@ -8,3 +8,6 @@ Use the `superflow-design` skill for this request.
|
|
|
8
8
|
Let Superpowers handle source-level HOW: inspect real code, reverse impact,
|
|
9
9
|
field references, TDD strategy, worker split, worktree and port planning. Do not
|
|
10
10
|
rewrite OpenSpec contracts unless a conflict is found and returned to docs.
|
|
11
|
+
Complete the source-level Minimal Design Review before implementation planning:
|
|
12
|
+
prove reuse and necessity, choose the simplest implementation, and explicitly
|
|
13
|
+
remove or reject unsupported complexity.
|
|
@@ -7,4 +7,7 @@ Use the `superflow-docs` skill for this request.
|
|
|
7
7
|
|
|
8
8
|
Keep OpenSpec as the source of WHAT and contracts. Ensure API, DB, tests,
|
|
9
9
|
traceability, quality gates, and handoff files are complete before technical
|
|
10
|
-
design starts.
|
|
10
|
+
design starts. For full workflows, require a Minimal Design Review in
|
|
11
|
+
`design.md` and a PASS/BLOCKED verdict in `sdd-quality-gate.md`; prefer reuse
|
|
12
|
+
and remove unsupported tables, fields, APIs, services, caches, async flows,
|
|
13
|
+
jobs, and compatibility layers.
|
|
@@ -143,7 +143,7 @@ if [ "$MODE" = "apply" ]; then
|
|
|
143
143
|
fi
|
|
144
144
|
|
|
145
145
|
if command -v codex >/dev/null 2>&1; then
|
|
146
|
-
run_logged codex plugin add superpowers@openai-curated || true
|
|
146
|
+
run_logged codex plugin add superpowers@openai-api-curated || true
|
|
147
147
|
fi
|
|
148
148
|
else
|
|
149
149
|
STATUS_FILE="$STATE_DIR/dependency-update-status.txt"
|
|
@@ -0,0 +1,194 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import crypto from 'crypto';
|
|
3
|
+
import fs from 'fs';
|
|
4
|
+
import path from 'path';
|
|
5
|
+
|
|
6
|
+
const [projectArg = '.', taskId, mode] = process.argv.slice(2);
|
|
7
|
+
const beforeReadyEvent = mode === '--before-ready-event';
|
|
8
|
+
if (!taskId) {
|
|
9
|
+
console.error('用法: superflow-managed-work-check.mjs <project-root> <task-id>');
|
|
10
|
+
process.exit(2);
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
const projectRoot = path.resolve(projectArg);
|
|
14
|
+
const taskDir = path.join(projectRoot, '.superflow', 'tasks', taskId);
|
|
15
|
+
const taskFile = path.join(taskDir, 'task.json');
|
|
16
|
+
if (!fs.existsSync(taskFile)) fail(`缺少任务状态: ${taskFile}`);
|
|
17
|
+
const task = JSON.parse(fs.readFileSync(taskFile, 'utf8'));
|
|
18
|
+
verifyContract(task);
|
|
19
|
+
const runsDir = path.join(taskDir, 'runs');
|
|
20
|
+
const runs = fs.existsSync(runsDir)
|
|
21
|
+
? fs.readdirSync(runsDir).filter((entry) => fs.statSync(path.join(runsDir, entry)).isDirectory())
|
|
22
|
+
: [];
|
|
23
|
+
if (runs.length !== 1) fail(`首版要求一个活动 run,实际 ${runs.length}`);
|
|
24
|
+
|
|
25
|
+
const runDir = path.join(runsDir, runs[0]);
|
|
26
|
+
const stateFile = path.join(runDir, 'run-state.json');
|
|
27
|
+
const journalFile = path.join(runDir, 'progress.jsonl');
|
|
28
|
+
const reportFile = path.join(runDir, 'task-report.md');
|
|
29
|
+
for (const file of [stateFile, journalFile, reportFile]) {
|
|
30
|
+
if (!fs.existsSync(file)) fail(`缺少必备运行产物: ${file}`);
|
|
31
|
+
}
|
|
32
|
+
const state = JSON.parse(fs.readFileSync(stateFile, 'utf8'));
|
|
33
|
+
|
|
34
|
+
assertMax('reviewRound', state.reviewRound, 5);
|
|
35
|
+
assertMax('executorInvocations', state.executorInvocations, 7);
|
|
36
|
+
assertMax('totalAgentInvocations', state.totalAgentInvocations, 12);
|
|
37
|
+
assertMax('reviewInvocations', state.reviewInvocations, 5);
|
|
38
|
+
if (state.contractHash !== task.contractHash) fail('任务合同哈希与运行状态不一致');
|
|
39
|
+
if (state.status !== task.status) fail('任务合同状态与运行状态不一致');
|
|
40
|
+
if (state.executorInvocations > 0 && !state.executorSession?.sessionId) {
|
|
41
|
+
fail('已有执行调用但缺少执行会话编号');
|
|
42
|
+
}
|
|
43
|
+
if (state.reviewInvocations > 0 && !state.supervisorSession?.sessionId) {
|
|
44
|
+
fail('已有正式检查但缺少监督会话编号');
|
|
45
|
+
}
|
|
46
|
+
const events = verifyJournal(journalFile);
|
|
47
|
+
|
|
48
|
+
if (state.status === 'awaiting_git_approval') {
|
|
49
|
+
if (!state.lastExecutorResult || !fs.existsSync(state.lastExecutorResult)) {
|
|
50
|
+
fail('等待 Git 批准状态缺少最终执行结果');
|
|
51
|
+
}
|
|
52
|
+
if (!state.lastReviewResult || !fs.existsSync(state.lastReviewResult)) {
|
|
53
|
+
fail('等待 Git 批准状态缺少最终检查结果');
|
|
54
|
+
}
|
|
55
|
+
assertInsideRun(state.lastExecutorResult, runDir, '最终执行结果');
|
|
56
|
+
assertInsideRun(state.lastReviewResult, runDir, '最终检查结果');
|
|
57
|
+
const executor = JSON.parse(fs.readFileSync(state.lastExecutorResult, 'utf8'));
|
|
58
|
+
verifyExecutorEvidence(task, executor);
|
|
59
|
+
const review = JSON.parse(fs.readFileSync(state.lastReviewResult, 'utf8'));
|
|
60
|
+
if (review.result !== 'pass' || review.findings?.some((item) => item.blocking)) {
|
|
61
|
+
fail('等待 Git 批准状态与最终检查结论不一致');
|
|
62
|
+
}
|
|
63
|
+
const readyEvents = events.filter((event) => event.eventType === 'run.delivery_ready');
|
|
64
|
+
const expectedReadyEvents = beforeReadyEvent ? 0 : 1;
|
|
65
|
+
if (readyEvents.length !== expectedReadyEvents) {
|
|
66
|
+
fail(`交付就绪事件数量应为 ${expectedReadyEvents},实际 ${readyEvents.length}`);
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
console.log(`OK 托管任务状态完整: ${taskId} (${state.status})`);
|
|
71
|
+
|
|
72
|
+
function assertMax(name, value, max) {
|
|
73
|
+
if (!Number.isInteger(value) || value < 0 || value > max) {
|
|
74
|
+
fail(`${name}=${value} 超出范围 0..${max}`);
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
function verifyContract(contract) {
|
|
79
|
+
const budgets = contract.budgets ?? {};
|
|
80
|
+
assertPositiveMax('maxReviewRounds', budgets.maxReviewRounds, 5, true);
|
|
81
|
+
assertPositiveMax('maxExecutorInvocations', budgets.maxExecutorInvocations, 7, true);
|
|
82
|
+
assertPositiveMax('maxTotalAgentInvocations', budgets.maxTotalAgentInvocations, 12, true);
|
|
83
|
+
assertPositiveMax('maxActiveRunHours', budgets.maxActiveRunHours, 24, false);
|
|
84
|
+
assertPositiveMax('maxSingleInvocationHours', budgets.maxSingleInvocationHours, 3, false);
|
|
85
|
+
if (contract.supervisorAgent === contract.executorAgent) {
|
|
86
|
+
fail('监督 Agent 和执行 Agent 不能相同');
|
|
87
|
+
}
|
|
88
|
+
const permissions = contract.permissions ?? {};
|
|
89
|
+
for (const key of ['gitCommit', 'gitPush', 'productionWrites', 'bypassSandbox']) {
|
|
90
|
+
if (permissions[key] !== false) fail(`不可覆盖的权限边界被放宽: ${key}`);
|
|
91
|
+
}
|
|
92
|
+
if (contract.taskPrompt) {
|
|
93
|
+
const expectedSnapshot = path.join(
|
|
94
|
+
path.resolve(contract.projectRoot),
|
|
95
|
+
'.superflow',
|
|
96
|
+
'tasks',
|
|
97
|
+
contract.taskId,
|
|
98
|
+
'source-prompt.md',
|
|
99
|
+
);
|
|
100
|
+
if (path.resolve(contract.taskPrompt.snapshotPath) !== expectedSnapshot) {
|
|
101
|
+
fail('冻结 Prompt 快照路径不属于当前托管任务');
|
|
102
|
+
}
|
|
103
|
+
if (!fs.existsSync(expectedSnapshot)) fail('冻结 Prompt 快照不存在');
|
|
104
|
+
const promptHash = crypto.createHash('sha256')
|
|
105
|
+
.update(fs.readFileSync(expectedSnapshot, 'utf8'))
|
|
106
|
+
.digest('hex');
|
|
107
|
+
if (promptHash !== contract.taskPrompt.sha256) fail('冻结 Prompt 快照哈希不一致');
|
|
108
|
+
}
|
|
109
|
+
const immutable = {
|
|
110
|
+
schemaVersion: contract.schemaVersion,
|
|
111
|
+
taskId: contract.taskId,
|
|
112
|
+
request: contract.request,
|
|
113
|
+
source: contract.source,
|
|
114
|
+
projectRoot: path.resolve(contract.projectRoot),
|
|
115
|
+
relatedProjectRoots: contract.relatedProjectRoots.map((root) => path.resolve(root)),
|
|
116
|
+
profile: contract.profile,
|
|
117
|
+
...(contract.language ? { language: contract.language } : {}),
|
|
118
|
+
objective: contract.objective,
|
|
119
|
+
doneCriteria: contract.doneCriteria,
|
|
120
|
+
taskPrompt: contract.taskPrompt,
|
|
121
|
+
supervisorAgent: contract.supervisorAgent,
|
|
122
|
+
executorAgent: contract.executorAgent,
|
|
123
|
+
permissions: contract.permissions,
|
|
124
|
+
budgets: contract.budgets,
|
|
125
|
+
};
|
|
126
|
+
const actual = crypto.createHash('sha256').update(JSON.stringify(immutable)).digest('hex');
|
|
127
|
+
if (actual !== contract.contractHash) fail('任务合同内容与冻结哈希不一致');
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
function assertPositiveMax(name, value, max, integer) {
|
|
131
|
+
if (!Number.isFinite(value) || value <= 0 || value > max || (integer && !Number.isInteger(value))) {
|
|
132
|
+
fail(`${name}=${value} 超出硬上限或格式非法`);
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
function verifyExecutorEvidence(task, result) {
|
|
137
|
+
if (result.status !== 'ready_for_review') fail('最终执行结果不是可检查状态');
|
|
138
|
+
if (!Array.isArray(result.commands) || result.commands.some((item) => item.exitCode !== 0)) {
|
|
139
|
+
fail('最终执行结果缺少成功命令证据或仍含失败命令');
|
|
140
|
+
}
|
|
141
|
+
if (Array.isArray(result.blockers) && result.blockers.length > 0) {
|
|
142
|
+
fail('最终执行结果仍含阻塞项');
|
|
143
|
+
}
|
|
144
|
+
if (task.profile === 'engineering' || task.profile === 'sdd') {
|
|
145
|
+
const categories = new Set(result.commands.flatMap((item) => verificationCategories(item.command)));
|
|
146
|
+
if (categories.size < 2) fail('工程任务缺少至少两类成功验证证据');
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
function verificationCategories(command = '') {
|
|
151
|
+
const value = command.toLowerCase();
|
|
152
|
+
const categories = [];
|
|
153
|
+
if (/(^|\s)(test|vitest|jest|pytest|phpunit|go\s+test|cargo\s+test)(\s|$)/.test(value)
|
|
154
|
+
|| /(?:npm|pnpm|yarn)\s+(?:run\s+)?test/.test(value)
|
|
155
|
+
|| /mvn(?:\s+[^\s]+)*\s+test/.test(value)
|
|
156
|
+
|| /gradle\w*\s+test/.test(value)) categories.push('test');
|
|
157
|
+
if (/(?:npm|pnpm|yarn)\s+(?:run\s+)?build/.test(value)
|
|
158
|
+
|| /(^|\s)(tsc|make|cmake|compile)(\s|$)/.test(value)
|
|
159
|
+
|| /mvn(?:\s+[^\s]+)*\s+(?:compile|package|verify)/.test(value)
|
|
160
|
+
|| /gradle\w*\s+(?:build|assemble)/.test(value)
|
|
161
|
+
|| /cargo\s+build|go\s+build/.test(value)) categories.push('build');
|
|
162
|
+
if (/(?:npm|pnpm|yarn)\s+(?:run\s+)?(?:start|dev|serve)/.test(value)
|
|
163
|
+
|| /spring-boot:run|docker\s+compose\s+up|(^|\s)(curl|wget)(\s|$)/.test(value)
|
|
164
|
+
|| /health(?:check)?|integration|e2e/.test(value)) categories.push('runtime');
|
|
165
|
+
return categories;
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
function assertInsideRun(file, runDir, label) {
|
|
169
|
+
const relative = path.relative(path.resolve(runDir), path.resolve(file));
|
|
170
|
+
if (relative.startsWith('..') || path.isAbsolute(relative)) {
|
|
171
|
+
fail(`${label}不在当前运行目录内`);
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
function verifyJournal(file) {
|
|
176
|
+
const lines = fs.readFileSync(file, 'utf8').split(/\r?\n/).filter(Boolean);
|
|
177
|
+
let previous = null;
|
|
178
|
+
const events = lines.map((line, index) => {
|
|
179
|
+
const event = JSON.parse(line);
|
|
180
|
+
const { eventHash, ...base } = event;
|
|
181
|
+
const expected = crypto.createHash('sha256').update(JSON.stringify(base)).digest('hex');
|
|
182
|
+
if (event.sequence !== index + 1) fail(`事件序号断裂: ${event.sequence}`);
|
|
183
|
+
if (event.previousEventHash !== previous) fail(`事件前序哈希不一致: ${event.sequence}`);
|
|
184
|
+
if (eventHash !== expected) fail(`事件哈希不一致: ${event.sequence}`);
|
|
185
|
+
previous = eventHash;
|
|
186
|
+
return event;
|
|
187
|
+
});
|
|
188
|
+
return events;
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
function fail(message) {
|
|
192
|
+
console.error(`FAIL ${message}`);
|
|
193
|
+
process.exit(1);
|
|
194
|
+
}
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
# Managed-work role guard. Active only inside a Superflow managed Agent process.
|
|
3
|
+
|
|
4
|
+
set -u
|
|
5
|
+
|
|
6
|
+
ROLE="${SUPERFLOW_MANAGED_ROLE:-}"
|
|
7
|
+
[ -n "$ROLE" ] || exit 0
|
|
8
|
+
|
|
9
|
+
block() {
|
|
10
|
+
echo "[Superflow 托管任务门禁] $1" >&2
|
|
11
|
+
exit 2
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
case "$ROLE" in
|
|
15
|
+
supervisor|executor) ;;
|
|
16
|
+
*) block "检测到非法托管角色,按失败关闭。" ;;
|
|
17
|
+
esac
|
|
18
|
+
|
|
19
|
+
INPUT=""
|
|
20
|
+
if [ ! -t 0 ]; then
|
|
21
|
+
INPUT=$(cat 2>/dev/null || true)
|
|
22
|
+
fi
|
|
23
|
+
[ -n "$INPUT" ] || block "Hook 没有收到工具调用数据,按失败关闭。"
|
|
24
|
+
|
|
25
|
+
VALID_JSON=$(printf '%s' "$INPUT" | python3 -c "
|
|
26
|
+
import json, sys
|
|
27
|
+
try:
|
|
28
|
+
value = json.load(sys.stdin)
|
|
29
|
+
print('yes' if isinstance(value, dict) else 'no')
|
|
30
|
+
except Exception:
|
|
31
|
+
print('no')
|
|
32
|
+
" 2>/dev/null)
|
|
33
|
+
[ "$VALID_JSON" = "yes" ] || block "Hook 输入不是有效 JSON,按失败关闭。"
|
|
34
|
+
|
|
35
|
+
read_field() {
|
|
36
|
+
local field="$1"
|
|
37
|
+
printf '%s' "$INPUT" | python3 -c "
|
|
38
|
+
import json, sys
|
|
39
|
+
try:
|
|
40
|
+
data = json.load(sys.stdin)
|
|
41
|
+
except Exception:
|
|
42
|
+
print('')
|
|
43
|
+
raise SystemExit
|
|
44
|
+
tool_input = data.get('tool_input', {})
|
|
45
|
+
print(tool_input.get('$field') or '')
|
|
46
|
+
" 2>/dev/null
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
TOOL_NAME=$(printf '%s' "$INPUT" | python3 -c "
|
|
50
|
+
import json, sys
|
|
51
|
+
try:
|
|
52
|
+
data = json.load(sys.stdin)
|
|
53
|
+
except Exception:
|
|
54
|
+
print('')
|
|
55
|
+
raise SystemExit
|
|
56
|
+
print(data.get('tool_name') or data.get('tool') or '')
|
|
57
|
+
" 2>/dev/null)
|
|
58
|
+
FILE_PATH=$(read_field file_path)
|
|
59
|
+
[ -n "$FILE_PATH" ] || FILE_PATH=$(read_field path)
|
|
60
|
+
[ -n "$FILE_PATH" ] || FILE_PATH=$(read_field file)
|
|
61
|
+
COMMAND=$(read_field command)
|
|
62
|
+
[ -n "$COMMAND" ] || COMMAND=$(read_field cmd)
|
|
63
|
+
|
|
64
|
+
normalize() {
|
|
65
|
+
printf '%s' "$1" | sed 's|\\|/|g'
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
FILE_PATH=$(normalize "$FILE_PATH")
|
|
69
|
+
COMMAND=$(printf '%s' "$COMMAND" | tr '\n' ' ')
|
|
70
|
+
|
|
71
|
+
if [ "$ROLE" = "supervisor" ]; then
|
|
72
|
+
case "$TOOL_NAME" in
|
|
73
|
+
Edit|Write|MultiEdit|NotebookEdit|apply_patch)
|
|
74
|
+
block "监督角色只允许检查,禁止修改目标文件。"
|
|
75
|
+
;;
|
|
76
|
+
esac
|
|
77
|
+
if [ -n "$COMMAND" ] && printf '%s' "$COMMAND" | grep -Eiq \
|
|
78
|
+
'(^|[[:space:]])(rm|mv|cp|mkdir|touch|chmod|chown)([[:space:]]|$)|git[[:space:]]+(add|commit|push|tag|reset|checkout|restore)|npm[[:space:]]+publish|apply_patch|sed[[:space:]]+-i|(^|[^>])>[>|[:space:]]|tee[[:space:]]'; then
|
|
79
|
+
block "监督角色的 Bash 仅允许只读检查,检测到可能写入的命令。"
|
|
80
|
+
fi
|
|
81
|
+
fi
|
|
82
|
+
|
|
83
|
+
if [ "$ROLE" = "executor" ]; then
|
|
84
|
+
case "$TOOL_NAME" in
|
|
85
|
+
Edit|Write|MultiEdit|NotebookEdit|apply_patch)
|
|
86
|
+
[ -n "$FILE_PATH" ] || block "写入工具缺少目标路径,按失败关闭。"
|
|
87
|
+
;;
|
|
88
|
+
esac
|
|
89
|
+
if [ -n "$FILE_PATH" ] && printf '%s' "$FILE_PATH" | grep -Eq \
|
|
90
|
+
'(^|/)\.superflow/tasks/'; then
|
|
91
|
+
block "执行角色禁止修改托管状态、事件、Prompt 和过程报告。"
|
|
92
|
+
fi
|
|
93
|
+
if [ -n "$COMMAND" ] && printf '%s' "$COMMAND" | grep -Eq \
|
|
94
|
+
'\.superflow/tasks/'; then
|
|
95
|
+
block "执行角色的 Bash 禁止直接访问托管运行目录,请使用提示词中提供的只读证据。"
|
|
96
|
+
fi
|
|
97
|
+
if [ -n "$COMMAND" ] && printf '%s' "$COMMAND" | grep -Eiq \
|
|
98
|
+
'git[[:space:]]+(add|commit|push|tag)|npm[[:space:]]+publish|dangerously-(bypass|skip)|kubectl[[:space:]]+(apply|delete)|helm[[:space:]]+(install|upgrade)|DROP[[:space:]]+(DATABASE|TABLE)|TRUNCATE[[:space:]]+TABLE'; then
|
|
99
|
+
block "执行角色禁止自动 Git 提交/推送、发布、部署、绕过沙箱或高破坏数据库操作。"
|
|
100
|
+
fi
|
|
101
|
+
fi
|
|
102
|
+
|
|
103
|
+
exit 0
|
|
@@ -22,6 +22,17 @@ 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
|
+
### OpenSpec canonical change 目录(阻塞级)
|
|
26
|
+
|
|
27
|
+
- change 必须只有一个实体目录:`openspec/changes/<name>/`。
|
|
28
|
+
- 版本归属必须编码进 `<name>`,例如版本 `v1.1.1` 的账号权限需求使用
|
|
29
|
+
`v1-1-1-account-permission-optimization`。
|
|
30
|
+
- 禁止创建 `openspec/changes/v1.1.1/<feature>/` 这类嵌套版本目录。
|
|
31
|
+
- 禁止为了兼容 OpenSpec CLI 再创建扁平软链接、目录副本或第二套 canonical 文档。
|
|
32
|
+
- 创建、查询、校验和后续 apply 必须始终使用同一个 `<name>`:
|
|
33
|
+
`openspec new change`、`openspec status --change`、
|
|
34
|
+
`openspec validate <name> --strict` 的名称必须一致。
|
|
35
|
+
|
|
25
36
|
**Steps**
|
|
26
37
|
|
|
27
38
|
1. **If no clear input provided, ask what they want to build**
|
|
@@ -46,7 +46,16 @@ Superpowers own source-level HOW without weakening OpenSpec/SDD contracts.
|
|
|
46
46
|
4. Write:
|
|
47
47
|
`docs/superpowers/specs/YYYY-MM-DD-<change-id>-technical-design.md`
|
|
48
48
|
using `../superflow-pipeline/references/superpower-technical-design-template.md`.
|
|
49
|
-
5.
|
|
49
|
+
5. Complete `复杂度减法评审` before expanding source-level HOW. For every new
|
|
50
|
+
table, field, API, Service/component, abstraction, cache, async/MQ/event
|
|
51
|
+
flow, scheduled job, or compatibility layer, prove existing reuse options,
|
|
52
|
+
necessity, and why the simplest direct implementation is insufficient.
|
|
53
|
+
Prefer one owner, one write path, one transaction, and set-based operations
|
|
54
|
+
when they satisfy the contract. Remove speculative extension points,
|
|
55
|
+
duplicate DTO/API layers, derivable persistence, premature caches, and
|
|
56
|
+
async compensation without measured need. Record the retained and removed
|
|
57
|
+
counts; unresolved simpler alternatives keep the design blocked.
|
|
58
|
+
6. For cross-repository, service-to-service, SDK, MQ, scheduler, device,
|
|
50
59
|
callback, third-party, mini-program, gateway, or adapter changes, include
|
|
51
60
|
`Architecture Boundary And Call Direction`. Prove owner module, call
|
|
52
61
|
direction, existing entry/exit points, proposed entry/exit points, evidence
|
|
@@ -54,7 +63,7 @@ Superpowers own source-level HOW without weakening OpenSpec/SDD contracts.
|
|
|
54
63
|
adapter/protocol translator/device gateway into a business-entry
|
|
55
64
|
orchestrator, stop and return to `$superflow-docs` unless the OpenSpec/SDD
|
|
56
65
|
contract explicitly grants that ownership with approval evidence.
|
|
57
|
-
|
|
66
|
+
7. For third-party platforms/tools, SDKs, MQ/Kafka, callbacks, payment
|
|
58
67
|
gateways, cloud services, or other external integrations, include
|
|
59
68
|
`External Integration Configuration And Deployment Contract`. Inventory
|
|
60
69
|
every endpoint, app/tenant/project ID, Topic, Tag, Consumer Group,
|
|
@@ -66,7 +75,7 @@ Superpowers own source-level HOW without weakening OpenSpec/SDD contracts.
|
|
|
66
75
|
auto-creation or pre-existing resources must not be treated as proof that
|
|
67
76
|
production will provision them. Missing production provisioning evidence
|
|
68
77
|
blocks design completion.
|
|
69
|
-
|
|
78
|
+
8. For concurrent requests, batch issue/activation/renewal, duplicate callbacks,
|
|
70
79
|
duplicate consumption, or repeated external delivery, include
|
|
71
80
|
`Concurrency And Idempotency Ownership`. Use a stable business idempotency
|
|
72
81
|
key and an application-layer atomic claim in a short transaction; persist
|
|
@@ -76,17 +85,17 @@ Superpowers own source-level HOW without weakening OpenSpec/SDD contracts.
|
|
|
76
85
|
optional fallback with proven natural uniqueness, historical cleanup,
|
|
77
86
|
NULL/soft-delete semantics, and a conflict contract. Check-then-insert,
|
|
78
87
|
process-local locks, and random IDs alone are blocked.
|
|
79
|
-
|
|
88
|
+
9. For field/status/enum/sync changes, include `Field And Status Reverse
|
|
80
89
|
Impact` and prove writers, readers, filters, derived sync paths, consumers,
|
|
81
90
|
and tests. Direct setter-only design is blocked.
|
|
82
|
-
|
|
91
|
+
10. For third-party, SDK, BEM/parking, payment/refund, financial display,
|
|
83
92
|
source/origin, status sync, or external dictionary fields, include
|
|
84
93
|
`External Enum Binding`. Prove local source fields/enums, external fields,
|
|
85
94
|
external enum values, display/business/financial meaning, source evidence,
|
|
86
95
|
owner confirmation, unresolved handling, and test evidence. A request
|
|
87
96
|
succeeding or a field being non-null is not enough; unconfirmed values are
|
|
88
97
|
blockers and must be returned to `$superflow-docs` or the user.
|
|
89
|
-
|
|
98
|
+
11. For amount, fee, discount, deduction, refund, sharing, payment, invoice,
|
|
90
99
|
balance, electricity fee, service fee, package settlement, proration,
|
|
91
100
|
allocation, reconciliation, or financial display changes,
|
|
92
101
|
include `Money Precision Boundary`. Prove calculation-state fields,
|
|
@@ -105,12 +114,12 @@ Impact` and prove writers, readers, filters, derived sync paths, consumers,
|
|
|
105
114
|
level and policy source, deterministic residual strategy with stable
|
|
106
115
|
tie-breaker, and positive/zero/negative evidence. For FX changes, freeze the
|
|
107
116
|
directional rate metadata and one canonical conversion path.
|
|
108
|
-
|
|
117
|
+
12. Record state:
|
|
109
118
|
```bash
|
|
110
119
|
../superflow-pipeline/scripts/superflow-state.sh set <change-dir> technical_design docs/superpowers/specs/YYYY-MM-DD-<change-id>-technical-design.md
|
|
111
120
|
../superflow-pipeline/scripts/superflow-state.sh set <change-dir> design_doc design.md
|
|
112
121
|
```
|
|
113
|
-
|
|
122
|
+
13. Update `design.md` with `Superpowers Technical Design Handoff`, update
|
|
114
123
|
`sdd-quality-gate.md` with the technical design path and hash, then run
|
|
115
124
|
`../superflow-pipeline/scripts/superflow-handoff.sh <change-dir> --refresh`.
|
|
116
125
|
If the guard reports a stale or missing hash, record the printed hash in
|
|
@@ -118,7 +127,7 @@ Impact` and prove writers, readers, filters, derived sync paths, consumers,
|
|
|
118
127
|
`--refresh` again. Do not set `design_doc` to the Superpowers document;
|
|
119
128
|
`design_doc` is the OpenSpec/SDD contract design, while `technical_design`
|
|
120
129
|
is the Superpowers HOW document.
|
|
121
|
-
|
|
130
|
+
14. Run:
|
|
122
131
|
|
|
123
132
|
```bash
|
|
124
133
|
../superflow-pipeline/scripts/superflow-yaml-validate.sh <change-dir>
|
|
@@ -112,6 +112,17 @@ Binding` with:
|
|
|
112
112
|
chain, no-fallback/no-guessing boundary, and pre-coding agent self-check. If
|
|
113
113
|
any gate is missing from `design.md`, `tests.md`, or quality gate, stop and
|
|
114
114
|
complete the docs first.
|
|
115
|
+
- For full workflow changes, `design.md` must include `复杂度减法评审` before
|
|
116
|
+
docs freeze. Inventory every proposed table, field, API, Service/component,
|
|
117
|
+
cache, async/MQ/event flow, scheduled job, compatibility layer, and new
|
|
118
|
+
abstraction. For each item, record existing reuse evidence, necessity, the
|
|
119
|
+
simplest implementation, removed/rejected complexity, and blockers.
|
|
120
|
+
Prefer extending current modules and synchronous transactions. Do not retain
|
|
121
|
+
a new layer merely for future flexibility; without evidence, remove it.
|
|
122
|
+
- `sdd-quality-gate.md` must record the complexity review verdict as
|
|
123
|
+
`PASS` or `BLOCKED`; only `PASS` may leave docs/design. Missing reuse evidence, unexplained parallel APIs/models,
|
|
124
|
+
redundant persisted fields, speculative cache/async/compensation, or an
|
|
125
|
+
unresolved simpler option blocks docs completion.
|
|
115
126
|
- `design.md` stays the OpenSpec/SDD design contract: requirement mapping,
|
|
116
127
|
API/DB/field semantics, source facts, real-entry call chain, no-fallback
|
|
117
128
|
boundary, risks, and acceptance hooks. It must not try to own all source-level
|
|
@@ -260,6 +271,11 @@ Use references only as needed:
|
|
|
260
271
|
the relationship judgment as `确定/部分确定/不确定` when a bug fix hinges on
|
|
261
272
|
existing data or call-chain behavior.
|
|
262
273
|
- `design.md` must reference the frozen `api.md` fields and errors.
|
|
274
|
+
- `design.md` must include `复杂度减法评审` with:
|
|
275
|
+
`设计项 | 现有能力/复用证据 | 是否必要 | 最简实现 | 删除/拒绝项 | 证据/阻塞`.
|
|
276
|
+
It must also count new tables, fields, APIs, services/components, caches,
|
|
277
|
+
async flows, jobs, and compatibility layers. A zero count is valid and
|
|
278
|
+
preferable when existing capabilities close the contract.
|
|
263
279
|
- `design.md` must include a "字段语义合同" table for every risky field:
|
|
264
280
|
`字段 | 来源表/DTO/事件 | 真实语义 | 目标字段 | 目标语义 | 是否可等价 |
|
|
265
281
|
证据锚点 | 禁止用法 | 不确定项/owner`.
|
|
@@ -7,6 +7,39 @@ 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
|
+
## 托管任务与双 Agent 闭环
|
|
11
|
+
|
|
12
|
+
当用户说“用 Superflow 托管完成”并给出 implementation prompt、change 目录或一个简单
|
|
13
|
+
任务时,直接使用内建托管模式。不要要求用户说出 `superflow-pipeline`、角色参数或底层
|
|
14
|
+
CLI 命令:
|
|
15
|
+
|
|
16
|
+
```bash
|
|
17
|
+
superflow pipeline "<implementation-prompt 路径、change 目录或简单任务>" --managed --project "<项目根目录>" \
|
|
18
|
+
--supervisor codex --executor claude --language zh
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
当前入口是 Claude 时交换两个角色。命令默认由独立后台服务执行,同时监听本地任务账本
|
|
22
|
+
直到终态,再由当前 Agent 读取报告并在同一会话汇总。监听中断不影响后台任务。执行前
|
|
23
|
+
必须阅读 `references/managed-work.md`,不得直接手工递归启动 peer CLI。
|
|
24
|
+
|
|
25
|
+
硬规则:
|
|
26
|
+
|
|
27
|
+
- 每个任务固定监督会话和执行会话,后续轮次按明确 session ID 恢复。
|
|
28
|
+
- 任务合同、事件账本、检查结果和证据文件是事实源,不依赖聊天上下文。
|
|
29
|
+
- 正式检查最多 5 轮、执行最多 7 次、Agent 总调用最多 12 次。
|
|
30
|
+
- 每次启动和恢复都校验冻结合同与硬上限;工程任务只有一类验证证据时不得进入检查。
|
|
31
|
+
- 输入是 change 目录时必须从 `.sdd/state.yaml` 解析 `implementation_prompt`;输入是
|
|
32
|
+
`tasks.md` 时必须阻塞。执行前冻结 Prompt 快照和 SHA-256,两个 Agent 使用同一快照。
|
|
33
|
+
- 监督角色只读,执行角色禁止修改 `.superflow/tasks` 和自动 Git 提交/推送/发布。
|
|
34
|
+
- 最终通过后状态必须停在 `awaiting_git_approval`,当前主 Agent 汇总并获得用户批准后
|
|
35
|
+
才能提交 Git。
|
|
36
|
+
- 使用 `superflow status <project-root>` 查看状态;不得通过模型轮询询问进度。
|
|
37
|
+
- 运行产物完整性必须通过 `superflow-managed-work-check.mjs`。
|
|
38
|
+
- 只有完整性脚本先通过,状态机才能记录唯一的交付就绪事件。
|
|
39
|
+
- 托管命令返回终态后,当前 Agent 必须读取任务报告并向用户汇总;不能只报告任务编号。
|
|
40
|
+
- 语言必须冻结进任务合同;执行 Prompt、恢复轮次、进度账本、任务报告、通知和错误提示
|
|
41
|
+
必须继承合同语言,不能在中途切换。
|
|
42
|
+
|
|
10
43
|
## Choose The Right SDD Skill
|
|
11
44
|
|
|
12
45
|
- Use `$openspec-explore` when the user is still thinking through a requirement,
|
|
@@ -80,6 +113,19 @@ When the router selects embedded deep clarification, follow these rules inside
|
|
|
80
113
|
|
|
81
114
|
## Non-Negotiable Rules
|
|
82
115
|
|
|
116
|
+
### OpenSpec change 目录唯一性(阻塞级)
|
|
117
|
+
|
|
118
|
+
- Superflow 必须遵守 OpenSpec CLI 的单层目录规范:
|
|
119
|
+
`openspec/changes/<change-name>/`。
|
|
120
|
+
- 版本号属于 change name,不属于中间目录。`v1.1.1` 必须编码为
|
|
121
|
+
`v1-1-1-<feature-slug>`,不得生成 `changes/v1.1.1/<feature-slug>/`。
|
|
122
|
+
- 同一 change 只能保留一个实体目录;禁止生成兼容软链接、目录副本或第二套
|
|
123
|
+
canonical 文档。
|
|
124
|
+
- 生成文档前必须先执行 `openspec new change <change-name>`,后续 status、
|
|
125
|
+
instructions、validate、Superflow state/handoff/guard 全部复用该实体目录。
|
|
126
|
+
- 发现嵌套版本目录或软链接 change 时,停止文档生成并迁移为唯一的扁平实体目录,
|
|
127
|
+
再运行 `openspec validate <change-name> --strict`。
|
|
128
|
+
|
|
83
129
|
### 上下文防漂移与状态门禁(阻塞级)
|
|
84
130
|
|
|
85
131
|
SDD 的核心价值是可追溯事实链、接口验证、hook 质量监控、任务 prompt
|
|
@@ -43,6 +43,14 @@
|
|
|
43
43
|
| Requirement | 修改文件 | 修改方法 | 变更类型 |
|
|
44
44
|
|---|---|---|---|
|
|
45
45
|
|
|
46
|
+
## 复杂度减法评审
|
|
47
|
+
| 设计项 | 现有能力/复用证据 | 是否必要 | 最简实现 | 删除/拒绝项 | 证据/阻塞 |
|
|
48
|
+
|---|---|---|---|---|---|
|
|
49
|
+
| <表/API/Service/组件/同步机制> | <源码、接口、表或依赖锚点> | <保留/删除/阻塞> | <能够闭环的最小方案> | <不新增的抽象、字段、缓存、异步、兼容层> | <证据或待确认项> |
|
|
50
|
+
|
|
51
|
+
新增项统计:表 0;字段 0;API 0;Service/组件 0;缓存 0;MQ/事件 0;定时任务 0;兼容层 0。按实际设计替换数量,不适用时保留 0。
|
|
52
|
+
能够复用、推导或同步完成的能力不得另建平行实现;没有证据证明需要时默认删除。
|
|
53
|
+
|
|
46
54
|
## Detailed Design
|
|
47
55
|
详细设计
|
|
48
56
|
|