openone-workflow-kit 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +21 -0
- package/CODE_OF_CONDUCT.md +25 -0
- package/CONTRIBUTING.md +51 -0
- package/INIT.md +81 -0
- package/LICENSE +201 -0
- package/NOTICE +6 -0
- package/README.md +195 -0
- package/SECURITY.md +39 -0
- package/bin/check-contract.cjs +137 -0
- package/bin/check-sanitized.cjs +93 -0
- package/bin/init-workspace.cjs +966 -0
- package/docs/assets/PROVENANCE.md +20 -0
- package/docs/assets/architecture.svg +112 -0
- package/docs/assets/hero.svg +83 -0
- package/docs/assets/quick-demo.svg +74 -0
- package/docs/assets/social-preview.svg +57 -0
- package/docs/assets/visual-manifest.json +52 -0
- package/docs/definition-of-done.md +80 -0
- package/docs/dual-track-workflow.md +90 -0
- package/docs/local-merge-notes.md +21 -0
- package/docs/maintainer-handoff.md +150 -0
- package/docs/manual-publish.md +119 -0
- package/docs/private-denylist.example.txt +11 -0
- package/docs/publication-decisions.md +36 -0
- package/docs/release-checklist.md +72 -0
- package/docs/releases/v0.1.0.md +70 -0
- package/docs/shareable-install.md +51 -0
- package/docs/tool-install-recipes.md +103 -0
- package/examples/ecommerce/team-profile.example.yaml +141 -0
- package/examples/education/team-profile.example.yaml +143 -0
- package/examples/saas-to-b/team-profile.example.yaml +130 -0
- package/examples/team-profile.example.yaml +69 -0
- package/install.sh +27 -0
- package/package.json +65 -0
- package/scripts/build-release.cjs +141 -0
- package/scripts/release-source-state.cjs +38 -0
- package/templates/AGENTS.template.md +26 -0
- package/test/release-readiness.cjs +214 -0
- package/test/smoke.cjs +272 -0
- package/workflow/adapters/README.md +16 -0
- package/workflow/core/README.md +38 -0
- package/workflow/core/capabilities/README.md +61 -0
- package/workflow/core/capabilities/acceptance-oracle-tracker.md +45 -0
- package/workflow/core/capabilities/branch-gatekeeper.md +57 -0
- package/workflow/core/capabilities/channel-experiment-tracker.md +32 -0
- package/workflow/core/capabilities/ci-cd-automation-governor.md +123 -0
- package/workflow/core/capabilities/contract-tracer.md +53 -0
- package/workflow/core/capabilities/data-change-safety-checker.md +52 -0
- package/workflow/core/capabilities/definition-lint.md +81 -0
- package/workflow/core/capabilities/deployment-readiness-checker.md +57 -0
- package/workflow/core/capabilities/impact-scope-analyzer.md +50 -0
- package/workflow/core/capabilities/knowledge-capture-maintainer.md +32 -0
- package/workflow/core/capabilities/market-evidence-grader.md +33 -0
- package/workflow/core/capabilities/memory-curator.md +48 -0
- package/workflow/core/capabilities/personal-git-operator.md +41 -0
- package/workflow/core/capabilities/personal-release-checklist.md +49 -0
- package/workflow/core/capabilities/prd-code-diff-checker.md +53 -0
- package/workflow/core/capabilities/protocol-state-machine-checker.md +57 -0
- package/workflow/core/capabilities/release-safety-checker.md +61 -0
- package/workflow/core/capabilities/repo-baseline-scanner.md +48 -0
- package/workflow/core/capabilities/rule-extractor.md +48 -0
- package/workflow/core/capabilities/runtime-evidence-triage.md +53 -0
- package/workflow/core/capabilities/security-reviewer.md +48 -0
- package/workflow/core/capabilities/test-evidence-reviewer.md +50 -0
- package/workflow/core/capabilities/ui-baseline-reviewer.md +50 -0
- package/workflow/core/capabilities/verify-app.md +51 -0
- package/workflow/core/capabilities/worktree-isolator.md +53 -0
- package/workflow/core/commands/01-/351/234/200/346/261/202/350/256/250/350/256/272.md +36 -0
- package/workflow/core/commands/02-/344/272/247/345/223/201/346/226/207/346/241/243.md +35 -0
- package/workflow/core/commands/02B-UI/350/256/276/350/256/241.md +75 -0
- package/workflow/core/commands/03-06-/347/240/224/345/217/221/345/207/206/345/244/207.md +30 -0
- package/workflow/core/commands/03-/346/212/200/346/234/257/346/236/266/346/236/204.md +32 -0
- package/workflow/core/commands/04-/344/273/243/347/240/201/345/256/236/347/216/260.md +32 -0
- package/workflow/core/commands/04A-/345/211/215/347/253/257/344/273/243/347/240/201/345/256/236/347/216/260.md +36 -0
- package/workflow/core/commands/04B-/345/220/216/347/253/257/344/273/243/347/240/201/345/256/236/347/216/260.md +31 -0
- package/workflow/core/commands/05-/344/273/243/347/240/201/345/256/241/346/237/245.md +31 -0
- package/workflow/core/commands/06-/346/265/213/350/257/225/347/224/250/344/276/213.md +34 -0
- package/workflow/core/commands/07-/346/265/213/350/257/225/346/211/247/350/241/214.md +33 -0
- package/workflow/core/commands/08-/345/217/221/345/270/203/345/207/206/345/244/207.md +44 -0
- package/workflow/core/commands/09-/345/217/221/345/270/203/346/211/247/350/241/214.md +39 -0
- package/workflow/core/commands/10-/345/244/215/347/233/230/346/200/273/347/273/223.md +41 -0
- package/workflow/core/commands/B1-B8-/345/225/206/344/270/232/345/214/226/345/207/206/345/244/207.md +30 -0
- package/workflow/core/commands/B1-/344/270/232/345/212/241/345/256/232/344/275/215.md +38 -0
- package/workflow/core/commands/B2-/345/225/206/344/270/232/346/250/241/345/274/217.md +38 -0
- package/workflow/core/commands/B3-PMF/344/270/216/345/256/242/346/210/267/347/224/273/345/203/217.md +39 -0
- package/workflow/core/commands/B4-/345/234/272/346/231/257/344/270/216/350/264/255/344/271/260/346/227/205/347/250/213.md +37 -0
- package/workflow/core/commands/B5-/346/270/240/351/201/223/346/274/217/346/226/227/346/230/240/345/260/204.md +39 -0
- package/workflow/core/commands/B6-/350/220/245/351/224/200/350/216/267/345/256/242/347/255/226/347/225/245.md +38 -0
- package/workflow/core/commands/B7-/350/220/245/351/224/200/351/242/204/347/256/227.md +36 -0
- package/workflow/core/commands/B8-/346/270/240/351/201/223/346/211/247/350/241/214/347/255/226/347/225/245.md +39 -0
- package/workflow/core/commands/B9-/347/255/226/347/225/245/345/244/215/347/233/230.md +38 -0
- package/workflow/core/commands/README.md +56 -0
- package/workflow/core/commands/init-workspace.md +29 -0
- package/workflow/core/commands/new-feature.md +33 -0
- package/workflow/core/commands/new-product.md +28 -0
- package/workflow/core/commands/workflow-status.md +30 -0
- package/workflow/core/commands//344/270/200/350/207/264/346/200/247/346/243/200/346/237/245.md +35 -0
- package/workflow/core/commands//344/272/244/344/273/230/350/207/263/345/256/214/346/210/220.md +40 -0
- package/workflow/core/commands//345/256/232/344/271/211/345/256/214/346/210/220.md +41 -0
- package/workflow/core/commands//346/276/204/346/270/205.md +31 -0
- package/workflow/core/templates/00-business-status.md +43 -0
- package/workflow/core/templates/00-workflow-status.md +50 -0
- package/workflow/core/templates/README.md +12 -0
- package/workflow/core/templates/business-stage-document.md +49 -0
- package/workflow/core/templates/completion-contract.md +114 -0
- package/workflow/core/templates/constitution.template.md +50 -0
- package/workflow/core/templates/living-spec.md +35 -0
- package/workflow/core/templates/stage-document.md +42 -0
- package/workflow/core/templates/team-profile.template.yaml +104 -0
package/test/smoke.cjs
ADDED
|
@@ -0,0 +1,272 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
const fs = require('fs');
|
|
3
|
+
const os = require('os');
|
|
4
|
+
const path = require('path');
|
|
5
|
+
const { spawnSync } = require('child_process');
|
|
6
|
+
|
|
7
|
+
const root = path.resolve(__dirname, '..');
|
|
8
|
+
const init = path.join(root, 'bin', 'init-workspace.cjs');
|
|
9
|
+
const { toPortablePath } = require(init);
|
|
10
|
+
const tmp = fs.mkdtempSync(path.join(os.tmpdir(), 'agent-workflow-smoke-'));
|
|
11
|
+
|
|
12
|
+
// Windows path.relative() emits backslashes. Generated team-profile paths are
|
|
13
|
+
// portable identifiers and must always use POSIX separators.
|
|
14
|
+
const windowsRepoPath = path.win32.relative('C:\\workspace', 'C:\\workspace\\apps\\web');
|
|
15
|
+
if (toPortablePath(windowsRepoPath) !== 'apps/web') {
|
|
16
|
+
throw new Error(`Windows relative path was not normalized: ${windowsRepoPath}`);
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
function mkdir(rel) {
|
|
20
|
+
fs.mkdirSync(path.join(tmp, rel), { recursive: true });
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
function write(rel, content) {
|
|
24
|
+
const file = path.join(tmp, rel);
|
|
25
|
+
fs.mkdirSync(path.dirname(file), { recursive: true });
|
|
26
|
+
fs.writeFileSync(file, content);
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
function run(args, options = {}) {
|
|
30
|
+
const result = spawnSync(process.execPath, [init, ...args], {
|
|
31
|
+
cwd: tmp,
|
|
32
|
+
encoding: 'utf8',
|
|
33
|
+
...options
|
|
34
|
+
});
|
|
35
|
+
if (result.status !== 0) {
|
|
36
|
+
throw new Error(`命令执行失败: ${result.stderr || result.stdout}`);
|
|
37
|
+
}
|
|
38
|
+
return result;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
function assertFile(rel) {
|
|
42
|
+
const file = path.join(tmp, rel);
|
|
43
|
+
if (!fs.existsSync(file)) throw new Error(`missing file: ${rel}`);
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
function assertContains(rel, text) {
|
|
47
|
+
const file = path.join(tmp, rel);
|
|
48
|
+
const content = fs.readFileSync(file, 'utf8');
|
|
49
|
+
if (!content.includes(text)) throw new Error(`${rel} does not contain ${text}`);
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
mkdir('docs/product');
|
|
53
|
+
write('docs/business-overview.md', '# Business overview\n');
|
|
54
|
+
write('docs/frontend-rules.md', '# Frontend rules\n');
|
|
55
|
+
write('apps/web/package.json', JSON.stringify({
|
|
56
|
+
dependencies: { vue: 'latest', vite: 'latest', typescript: 'latest' }
|
|
57
|
+
}, null, 2));
|
|
58
|
+
write('services/api/pom.xml', '<project></project>\n');
|
|
59
|
+
|
|
60
|
+
run([
|
|
61
|
+
'--target', tmp,
|
|
62
|
+
'--tools', 'codex,claude,cursor,copilot,codebuddy,kiro,trea',
|
|
63
|
+
'--yes'
|
|
64
|
+
]);
|
|
65
|
+
|
|
66
|
+
for (const rel of [
|
|
67
|
+
'AGENTS.md',
|
|
68
|
+
'CLAUDE.md',
|
|
69
|
+
'.codex/prompts/init-workspace.md',
|
|
70
|
+
'.codex/prompts/04-代码实现.md',
|
|
71
|
+
'.codex/prompts/05-代码审查.md',
|
|
72
|
+
'.codex/prompts/10-复盘总结.md',
|
|
73
|
+
'.codex/prompts/new-product.md',
|
|
74
|
+
'.codex/prompts/B1-业务定位.md',
|
|
75
|
+
'.claude/commands/04-代码实现.md',
|
|
76
|
+
'.claude/commands/B1-业务定位.md',
|
|
77
|
+
'.claude/commands/B9-策略复盘.md',
|
|
78
|
+
'.cursor/rules/agent-workflow-core.mdc',
|
|
79
|
+
'.github/copilot-instructions.md',
|
|
80
|
+
'.codebuddy/instructions.md',
|
|
81
|
+
'.kiro/instructions.md',
|
|
82
|
+
'.trae/instructions.md',
|
|
83
|
+
'workflow/team-profile.yaml',
|
|
84
|
+
'workflow/INITIALIZATION_QUESTIONS.md',
|
|
85
|
+
'workflow/core/commands/init-workspace.md',
|
|
86
|
+
'workflow/core/commands/04-代码实现.md',
|
|
87
|
+
'workflow/core/commands/定义完成.md',
|
|
88
|
+
'workflow/core/commands/交付至完成.md',
|
|
89
|
+
'workflow/core/commands/澄清.md',
|
|
90
|
+
'workflow/core/commands/一致性检查.md',
|
|
91
|
+
'workflow/core/templates/completion-contract.md',
|
|
92
|
+
'workflow/core/templates/constitution.template.md',
|
|
93
|
+
'workflow/core/templates/living-spec.md',
|
|
94
|
+
'workflow/core/capabilities/definition-lint.md',
|
|
95
|
+
'workflow/core/capabilities/acceptance-oracle-tracker.md',
|
|
96
|
+
'workflow/constitution.md',
|
|
97
|
+
'workflow/standards/README.md',
|
|
98
|
+
'specs/README.md',
|
|
99
|
+
'.claude/commands/定义完成.md',
|
|
100
|
+
'.claude/commands/交付至完成.md',
|
|
101
|
+
'workflow/core/commands/new-product.md',
|
|
102
|
+
'workflow/core/commands/B1-业务定位.md',
|
|
103
|
+
'workflow/core/commands/B1-B8-商业化准备.md',
|
|
104
|
+
'workflow/core/commands/B5-渠道漏斗映射.md',
|
|
105
|
+
'workflow/core/commands/B9-策略复盘.md',
|
|
106
|
+
'workflow/core/templates/00-business-status.md',
|
|
107
|
+
'workflow/core/templates/business-stage-document.md',
|
|
108
|
+
'workflow/core/capabilities/market-evidence-grader.md',
|
|
109
|
+
'workflow/core/capabilities/channel-experiment-tracker.md',
|
|
110
|
+
'workflow/core/capabilities/branch-gatekeeper.md',
|
|
111
|
+
'workflow/core/capabilities/release-safety-checker.md',
|
|
112
|
+
'workflow/core/capabilities/prd-code-diff-checker.md',
|
|
113
|
+
'workflow/core/capabilities/contract-tracer.md',
|
|
114
|
+
'workflow/core/capabilities/deployment-readiness-checker.md',
|
|
115
|
+
'workflow/core/capabilities/runtime-evidence-triage.md',
|
|
116
|
+
'workflow/core/capabilities/data-change-safety-checker.md',
|
|
117
|
+
'workflow/core/capabilities/protocol-state-machine-checker.md'
|
|
118
|
+
]) {
|
|
119
|
+
assertFile(rel);
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
assertContains('workflow/team-profile.yaml', '- trae');
|
|
123
|
+
assertContains('workflow/team-profile.yaml', 'apps/web');
|
|
124
|
+
assertContains('workflow/team-profile.yaml', 'services/api');
|
|
125
|
+
assertContains('workflow/INSTALL_REPORT.md', '初始化器没有执行远程 Git 命令');
|
|
126
|
+
assertContains('workflow/team-profile.yaml', 'agent-allowed-after-scope-check');
|
|
127
|
+
|
|
128
|
+
// AGENTS.md must contain the comprehensive usage guide, not just hard gates.
|
|
129
|
+
assertContains('AGENTS.md', '## 快速开始');
|
|
130
|
+
assertContains('AGENTS.md', '## 工作流命令');
|
|
131
|
+
assertContains('AGENTS.md', '## 任务描述模板');
|
|
132
|
+
assertContains('AGENTS.md', '## 工具使用方式');
|
|
133
|
+
assertContains('AGENTS.md', '### Cursor');
|
|
134
|
+
assertContains('AGENTS.md', '/04-代码实现');
|
|
135
|
+
// The command table must list every stage.
|
|
136
|
+
assertContains('AGENTS.md', '/08-发布准备');
|
|
137
|
+
assertContains('AGENTS.md', '/09-发布执行');
|
|
138
|
+
assertContains('AGENTS.md', '/10-复盘总结');
|
|
139
|
+
// The business track must be wired into the guide, profile, and adapters.
|
|
140
|
+
assertContains('AGENTS.md', '/new-product');
|
|
141
|
+
assertContains('AGENTS.md', '/B1-业务定位');
|
|
142
|
+
assertContains('AGENTS.md', '/B9-策略复盘');
|
|
143
|
+
assertContains('workflow/team-profile.yaml', 'business_dir');
|
|
144
|
+
assertContains('workflow/team-profile.yaml', 'outbound_marketing_actions');
|
|
145
|
+
assertContains('workflow/team-profile.yaml', 'market_research');
|
|
146
|
+
assertContains('.cursor/commands/B1-业务定位.md', 'workflow/core/commands/B1-业务定位.md');
|
|
147
|
+
assertContains('.cursor/rules/agent-workflow-core.mdc', 'B9-策略复盘');
|
|
148
|
+
// Definition-of-done mechanics must be wired through guide, profile, and adapters.
|
|
149
|
+
assertContains('AGENTS.md', '/定义完成');
|
|
150
|
+
assertContains('AGENTS.md', '/交付至完成');
|
|
151
|
+
assertContains('AGENTS.md', '完成合同');
|
|
152
|
+
assertContains('workflow/team-profile.yaml', 'specs_dir');
|
|
153
|
+
assertContains('workflow/team-profile.yaml', 'done_verdict');
|
|
154
|
+
assertContains('.cursor/rules/agent-workflow-core.mdc', '定义完成');
|
|
155
|
+
assertContains('.cursor/commands/定义完成.md', 'workflow/core/commands/定义完成.md');
|
|
156
|
+
|
|
157
|
+
// Contract checker: a well-formed frozen contract passes, a broken one fails.
|
|
158
|
+
const checker = path.join(root, 'bin', 'check-contract.cjs');
|
|
159
|
+
const goodContract = `# 完成合同:demo
|
|
160
|
+
|
|
161
|
+
## 合同状态
|
|
162
|
+
|
|
163
|
+
| 项 | 内容 |
|
|
164
|
+
| --- | --- |
|
|
165
|
+
| 需求名称 | demo |
|
|
166
|
+
| 复杂度档位 | S |
|
|
167
|
+
| 状态 | 已冻结 |
|
|
168
|
+
| 冻结时间 | 2026-01-01 |
|
|
169
|
+
| 冻结确认 | 用户于会话中确认 |
|
|
170
|
+
| Definition Lint | 通过 |
|
|
171
|
+
|
|
172
|
+
## ★ 目标与非目标
|
|
173
|
+
|
|
174
|
+
- WHEN 用户提交空表单 THE SYSTEM SHALL 阻止提交
|
|
175
|
+
|
|
176
|
+
## ★ 术语表
|
|
177
|
+
|
|
178
|
+
| 术语 | 本合同内的精确定义 | 被替代的模糊说法 |
|
|
179
|
+
| --- | --- | --- |
|
|
180
|
+
| 提交成功 | 服务端返回 201 且列表可见 | 提交成功 |
|
|
181
|
+
|
|
182
|
+
## ★ 验收 Oracle
|
|
183
|
+
|
|
184
|
+
| ID | 验收标准 | 验证方法 | 类型 | blocking | 状态 | 证据 | 更新时间 |
|
|
185
|
+
| --- | --- | --- | --- | --- | --- | --- | --- |
|
|
186
|
+
| O-001 | WHEN 提交空表单 THE SYSTEM SHALL 阻止并提示 | npm test -- form.spec | auto | 是 | PASS | 输出片段 | 2026-01-01 |
|
|
187
|
+
|
|
188
|
+
## ★ 待澄清项
|
|
189
|
+
|
|
190
|
+
- 无
|
|
191
|
+
|
|
192
|
+
## 修订记录
|
|
193
|
+
|
|
194
|
+
| 时间 | 修订内容 | 原因 | 用户确认 |
|
|
195
|
+
| --- | --- | --- | --- |
|
|
196
|
+
`;
|
|
197
|
+
write('features/demo/00-完成合同.md', goodContract);
|
|
198
|
+
const goodRun = spawnSync(process.execPath, [checker, path.join(tmp, 'features/demo/00-完成合同.md')], { encoding: 'utf8' });
|
|
199
|
+
if (goodRun.status !== 0) {
|
|
200
|
+
throw new Error(`check-contract should pass a valid contract: ${goodRun.stdout} ${goodRun.stderr}`);
|
|
201
|
+
}
|
|
202
|
+
const badContract = goodContract
|
|
203
|
+
.replace('| Definition Lint | 通过 |', '| Definition Lint | 未运行 |')
|
|
204
|
+
.replace('npm test -- form.spec', '待填写');
|
|
205
|
+
write('features/demo-bad/00-完成合同.md', badContract);
|
|
206
|
+
const badRun = spawnSync(process.execPath, [checker, path.join(tmp, 'features/demo-bad/00-完成合同.md')], { encoding: 'utf8' });
|
|
207
|
+
if (badRun.status === 0) {
|
|
208
|
+
throw new Error('check-contract should fail a frozen contract without lint pass and verification method');
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
// The Cursor rule must explain how to run a stage via Cursor custom commands.
|
|
212
|
+
assertContains('.cursor/rules/agent-workflow-core.mdc', '.cursor/commands/');
|
|
213
|
+
assertContains('.cursor/rules/agent-workflow-core.mdc', 'workflow/core/commands/04-代码实现.md');
|
|
214
|
+
// Cursor custom slash command adapters must be generated for every stage.
|
|
215
|
+
assertFile('.cursor/commands/04-代码实现.md');
|
|
216
|
+
assertFile('.cursor/commands/10-复盘总结.md');
|
|
217
|
+
assertContains('.cursor/commands/04-代码实现.md', 'workflow/core/commands/04-代码实现.md');
|
|
218
|
+
|
|
219
|
+
run(['--target', tmp, '--tools', 'codex', '--yes']);
|
|
220
|
+
assertFile('workflow/team-profile.yaml.agent-workflow-new');
|
|
221
|
+
|
|
222
|
+
const beforeDryRun = fs.readdirSync(tmp).sort().join('\n');
|
|
223
|
+
run(['--target', tmp, '--tools', 'codex', '--dry-run']);
|
|
224
|
+
const afterDryRun = fs.readdirSync(tmp).sort().join('\n');
|
|
225
|
+
if (beforeDryRun !== afterDryRun) {
|
|
226
|
+
throw new Error('dry-run changed top-level files');
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
// Upgrade path: --upgrade --force should overwrite in place without writing new
|
|
230
|
+
// .agent-workflow-new files. Clean up stale .agent-workflow-new files left by
|
|
231
|
+
// previous non-force runs before measuring.
|
|
232
|
+
for (const stale of fs.readdirSync(path.join(tmp, 'workflow'))) {
|
|
233
|
+
if (stale.endsWith('.agent-workflow-new')) {
|
|
234
|
+
fs.unlinkSync(path.join(tmp, 'workflow', stale));
|
|
235
|
+
}
|
|
236
|
+
}
|
|
237
|
+
const profileBefore = fs.readFileSync(path.join(tmp, 'workflow/team-profile.yaml'), 'utf8');
|
|
238
|
+
fs.writeFileSync(path.join(tmp, 'workflow/team-profile.yaml'), profileBefore + '\n# user note\n');
|
|
239
|
+
run(['--target', tmp, '--tools', 'codex,claude,cursor', '--upgrade', '--force', '--yes']);
|
|
240
|
+
const profileAfter = fs.readFileSync(path.join(tmp, 'workflow/team-profile.yaml'), 'utf8');
|
|
241
|
+
if (profileAfter.includes('# user note')) {
|
|
242
|
+
throw new Error('upgrade --force did not overwrite team-profile.yaml');
|
|
243
|
+
}
|
|
244
|
+
const upgradeStrayFiles = fs
|
|
245
|
+
.readdirSync(path.join(tmp, 'workflow'))
|
|
246
|
+
.filter((name) => name.endsWith('.agent-workflow-new'));
|
|
247
|
+
if (upgradeStrayFiles.length) {
|
|
248
|
+
throw new Error(`upgrade --force should not produce new .agent-workflow-new files, found: ${upgradeStrayFiles.join(',')}`);
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
// Cursor-only install must still generate AGENTS.md (the tool-neutral usage guide),
|
|
252
|
+
// even though codex is not selected.
|
|
253
|
+
const cursorTmp = fs.mkdtempSync(path.join(os.tmpdir(), 'agent-workflow-cursor-'));
|
|
254
|
+
spawnSync(process.execPath, [init, '--target', cursorTmp, '--tools', 'cursor', '--yes'], {
|
|
255
|
+
cwd: cursorTmp,
|
|
256
|
+
encoding: 'utf8'
|
|
257
|
+
});
|
|
258
|
+
for (const rel of [
|
|
259
|
+
'AGENTS.md',
|
|
260
|
+
'.cursor/rules/agent-workflow-core.mdc',
|
|
261
|
+
'.cursor/commands/04-代码实现.md'
|
|
262
|
+
]) {
|
|
263
|
+
if (!fs.existsSync(path.join(cursorTmp, rel))) {
|
|
264
|
+
throw new Error(`cursor-only install missing file: ${rel}`);
|
|
265
|
+
}
|
|
266
|
+
}
|
|
267
|
+
const cursorAgents = fs.readFileSync(path.join(cursorTmp, 'AGENTS.md'), 'utf8');
|
|
268
|
+
if (!cursorAgents.includes('### Cursor')) {
|
|
269
|
+
throw new Error('cursor-only AGENTS.md missing the Cursor usage section');
|
|
270
|
+
}
|
|
271
|
+
|
|
272
|
+
console.log('Smoke test passed.');
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
# Adapters
|
|
2
|
+
|
|
3
|
+
Adapters 是从同一套 workflow core 和 `team-profile.yaml` 生成的工具特定薄入口。
|
|
4
|
+
|
|
5
|
+
它们的职责:
|
|
6
|
+
|
|
7
|
+
- 帮当前工具找到 `AGENTS.md`、`workflow/core/` 和 `workflow/team-profile.yaml`。
|
|
8
|
+
- 按当前工具能力暴露 slash commands、prompts、rules 或 instructions。
|
|
9
|
+
- 保持工具入口轻量,不复制或改写 core 规则。
|
|
10
|
+
|
|
11
|
+
它们不能:
|
|
12
|
+
|
|
13
|
+
- 削弱 `workflow/core` 的硬闸门。
|
|
14
|
+
- 调用另一个工具的私有能力。
|
|
15
|
+
- 承诺所有工具体验完全一致。
|
|
16
|
+
- 写入凭证、真实客户数据、私有 URL 或生产配置。
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
# Workflow Core
|
|
2
|
+
|
|
3
|
+
`workflow/core` 是工具无关的工作流层,定义阶段、闸门、模板和可复用检查能力。它不得包含公司特定业务事实、内部仓库名、私有 URL、凭证、客户数据或某个工具的私有能力。
|
|
4
|
+
|
|
5
|
+
工作流分两条轨道:研发轨(`/new-feature`、`/01` 到 `/10`,加上 `/澄清`、`/定义完成`、`/一致性检查`、`/交付至完成`,产物在 `features/{feature}/`)和商业化轨(`/new-product`、`/B1` 到 `/B9`,产物在 `business/{product}/`)。两轨共享同一套授权口径:本地文档和本地 git 动作可由 agent 执行,对外动作必须用户授权。
|
|
6
|
+
|
|
7
|
+
研发轨的判定核心是《完成合同》:`/定义完成` 把前序结论编译为合同(目标/非目标、数据流、失败路径、质量预算、验收 Oracle、术语表、影响边界),Definition Lint 通过并经用户确认后冻结;宣布完成 = blocking Oracle 全 PASS。`workflow/constitution.md` 存放跨需求不可协商原则,`workflow/standards/` 存放个人代码规范,工作区级 `specs/` 存放已实现行为的 living specs。
|
|
8
|
+
|
|
9
|
+
## Core 规则
|
|
10
|
+
|
|
11
|
+
- 同一套 core,多个工具 adapter 分层增强。
|
|
12
|
+
- 不承诺所有工具体验完全一致。
|
|
13
|
+
- 业务代码修改必须通过功能分支闸门和实现阶段闸门。
|
|
14
|
+
- 个人项目允许 agent 在范围明确且工作树已检查后执行本地分支命名、创建、commit、tag 和本地 merge。
|
|
15
|
+
- 远程 Git、push、GitHub release、商店提交、部署、数据库写入和生产配置写入必须获得用户明确授权。
|
|
16
|
+
- 同仓多需求进入实现阶段后必须使用独立 worktree。
|
|
17
|
+
- adapter 可以增强或降级体验,但不能削弱 core 闸门。
|
|
18
|
+
- 商业化轨只产出文档和清单:对外发布内容、投放广告、cold outreach、联系合作方必须用户明确授权或自行执行;营销工程需求通过 `/new-feature` 回流研发轨,不在 B 阶段直接改代码。
|
|
19
|
+
- 商业化结论必须做证据分级(一手/二手/推断),不得编造市场数据、用户评价或竞品价格。
|
|
20
|
+
- M/L 档需求进入实现前,完成合同必须已冻结且 Definition Lint 通过;S 档必须有 ★ 必填节完整的迷你合同。
|
|
21
|
+
- 合同冻结后不得静默修改标准、阈值或 blocking 标记;变更走修订记录并经用户确认。
|
|
22
|
+
- Oracle 状态只能由 `/交付至完成` 或 `/07-测试执行` 翻转且必须附证据;blocking Oracle 存在 NOT_RUN/FAIL/STALE 时不得宣布完成或进入发布执行。
|
|
23
|
+
- constitution 与需求冲突时先修订宪法(经用户确认),不得绕过。
|
|
24
|
+
|
|
25
|
+
## 目录地图
|
|
26
|
+
|
|
27
|
+
- `commands/`: 每个阶段的契约。
|
|
28
|
+
- `templates/`: 通用文档模板。
|
|
29
|
+
- `capabilities/`: 可复用检查能力。
|
|
30
|
+
|
|
31
|
+
## 项目特化
|
|
32
|
+
|
|
33
|
+
不要为了加入单个项目事实而修改 core 文件。项目特化内容应放在:
|
|
34
|
+
|
|
35
|
+
- `workflow/team-profile.yaml`
|
|
36
|
+
- `features/{feature}/`
|
|
37
|
+
- 目标项目自己的规范和本地资料
|
|
38
|
+
- 工具 adapter 的薄入口
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
# Capabilities
|
|
2
|
+
|
|
3
|
+
Capabilities 是可复用检查能力。不同工具可以把它们实现成 prompt、规则、hooks、checklist 或 subagent;实现形态可以不同,但核心阻断规则不能被削弱。
|
|
4
|
+
|
|
5
|
+
## 能力等级
|
|
6
|
+
|
|
7
|
+
| 等级 | 含义 | 常见实现 |
|
|
8
|
+
| --- | --- | --- |
|
|
9
|
+
| L0 | 文档规则 | `AGENTS.md`、core 文档 |
|
|
10
|
+
| L1 | Prompt 或 checklist | prompts、命令模板 |
|
|
11
|
+
| L2 | 工具原生规则 | slash commands、editor rules |
|
|
12
|
+
| L3 | Hooks 或前置检查 | 本地 validator |
|
|
13
|
+
| L4 | 多 agent 路由 | 支持 subagent 的工具 |
|
|
14
|
+
|
|
15
|
+
## 分层定义
|
|
16
|
+
|
|
17
|
+
| 分层 | 含义 |
|
|
18
|
+
| --- | --- |
|
|
19
|
+
| essential | 首批必须接入;直接保护实现闸门和核心交付风险。 |
|
|
20
|
+
| recommended | 第二批接入;补齐范围扫描、运行验证、数据变更和发布准备。 |
|
|
21
|
+
| optional | 多项目规模或高风险场景需要时再接入。 |
|
|
22
|
+
|
|
23
|
+
## 最小能力集
|
|
24
|
+
|
|
25
|
+
| 分层 | Capability | 用途 | 阶段 |
|
|
26
|
+
| --- | --- | --- | --- |
|
|
27
|
+
| essential | [definition-lint](./definition-lint.md) | 冻结前按八维度检查完成合同,配按项目类型的定义面试题库 | `/定义完成` |
|
|
28
|
+
| essential | [acceptance-oracle-tracker](./acceptance-oracle-tracker.md) | 验收 Oracle 状态机:绑定验证方法、证据与 STALE 复验,完成=blocking 全绿 | `/定义完成`, `/07`, `/交付至完成`, `/08` |
|
|
29
|
+
| essential | [branch-gatekeeper](./branch-gatekeeper.md) | 阻止在错误分支或错误阶段修改业务代码 | `/04` |
|
|
30
|
+
| essential | [release-safety-checker](./release-safety-checker.md) | 对比发布候选与生产基线,防止范围漂移 | `/05`, `/07`, `/08`, `/09` |
|
|
31
|
+
| essential | [prd-code-diff-checker](./prd-code-diff-checker.md) | 对比产品意图、技术方案与真实 diff | `/05` |
|
|
32
|
+
| essential | [contract-tracer](./contract-tracer.md) | 追踪跨服务、跨层或前后端契约变更 | `/03`, `/05` |
|
|
33
|
+
| recommended | [worktree-isolator](./worktree-isolator.md) | 同仓多需求进入实现后强制 worktree 隔离 | `/04` |
|
|
34
|
+
| recommended | [repo-baseline-scanner](./repo-baseline-scanner.md) | 记录分支、dirty 状态和事实来源降级 | `/03` |
|
|
35
|
+
| recommended | [impact-scope-analyzer](./impact-scope-analyzer.md) | 扫描仓库、API、UI、数据、配置和测试影响面 | `/03` |
|
|
36
|
+
| recommended | [security-reviewer](./security-reviewer.md) | 审查凭证、鉴权、隐私、ACL、配置和审计风险 | `/05` |
|
|
37
|
+
| recommended | [verify-app](./verify-app.md) | 记录真实执行的构建、单测、集成、浏览器或人工验证 | `/04`, `/07` |
|
|
38
|
+
| recommended | [deployment-readiness-checker](./deployment-readiness-checker.md) | 区分构建成功、启动成功、部署生效和路由可达 | `/07`, `/08`, `/09` |
|
|
39
|
+
| recommended | [runtime-evidence-triage](./runtime-evidence-triage.md) | 用运行态证据替代静态猜测,定位部署、路由、配置和日志问题 | `/03`, `/05`, `/07` |
|
|
40
|
+
| recommended | [data-change-safety-checker](./data-change-safety-checker.md) | 管理 DDL/DML/数据修复的交付位置、预检查、后检查和回滚口径 | `/03`, `/05`, `/07` |
|
|
41
|
+
| recommended | [protocol-state-machine-checker](./protocol-state-machine-checker.md) | 让多步外部协议按状态机建模,明确终态、幂等和失败语义 | `/03`, `/05`, `/07` |
|
|
42
|
+
| recommended | [personal-git-operator](./personal-git-operator.md) | 允许个人项目中的本地分支、commit、tag 和本地 merge 自动化 | `/04`, `/08`, `/09` |
|
|
43
|
+
| recommended | [personal-release-checklist](./personal-release-checklist.md) | 迁移独立开发者发布 SOP:双分支、tag、artifact、渠道清单和回滚 | `/08`, `/09` |
|
|
44
|
+
| recommended | [knowledge-capture-maintainer](./knowledge-capture-maintainer.md) | 把复盘经验沉淀到 Markdown 知识层并保持索引/日志 | `/10` |
|
|
45
|
+
| optional | [test-evidence-reviewer](./test-evidence-reviewer.md) | 检查测试是否真的证明需求行为 | `/06`, `/07` |
|
|
46
|
+
| optional | [ui-baseline-reviewer](./ui-baseline-reviewer.md) | 检查 UI 实现是否符合设计和前端规范 | `/02`, `/04A`, `/05` |
|
|
47
|
+
| optional | [memory-curator](./memory-curator.md) | 把复盘中的可复用经验脱敏沉淀为结构化记忆 | `/10` |
|
|
48
|
+
| optional | [rule-extractor](./rule-extractor.md) | 从复盘中提炼可进入 workflow core 的通用规则候选 | `/10` |
|
|
49
|
+
|
|
50
|
+
## 商业化跑道能力
|
|
51
|
+
|
|
52
|
+
商业化跑道(`/new-product`、`/B1` 到 `/B9`)复用上面的能力分级口径。首批接入下面两个能力,保护“市场结论不编造、渠道投放不失控”这两条商业化最容易翻车的边界。
|
|
53
|
+
|
|
54
|
+
| 分层 | Capability | 用途 | 阶段 |
|
|
55
|
+
| --- | --- | --- | --- |
|
|
56
|
+
| essential | [market-evidence-grader](./market-evidence-grader.md) | 给市场、竞品和客户结论做一手/二手/推断证据分级,禁止编造数据 | `/B1`-`/B5`, `/B9` |
|
|
57
|
+
| essential | [channel-experiment-tracker](./channel-experiment-tracker.md) | 把每个渠道当实验管理:假设、双预算上限、周期和事前判定标准 | `/B5`-`/B9` |
|
|
58
|
+
|
|
59
|
+
## 接入建议
|
|
60
|
+
|
|
61
|
+
先接入四个 essential 能力,保护“分支 / 阶段 / 发布范围 / PRD-diff / 契约追踪”这些最容易造成严重返工的边界。稳定后再接入 recommended 能力,补齐部署有效性、运行态证据、数据变更和多步协议风险。optional 能力适合多项目进入规模化使用后逐步增强。启用商业化跑道时,market-evidence-grader 和 channel-experiment-tracker 与 B 阶段同批接入。
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
# Acceptance Oracle Tracker
|
|
2
|
+
|
|
3
|
+
## Purpose
|
|
4
|
+
|
|
5
|
+
Make "done" a machine-checkable verdict instead of a feeling: every acceptance criterion is an oracle bound to a reproducible verification method, tracked through an explicit state machine. Declaring completion means all blocking oracles are PASS (or user-confirmed WAIVED) — nothing else counts.
|
|
6
|
+
|
|
7
|
+
## Sources
|
|
8
|
+
|
|
9
|
+
- `features/{feature}/00-完成合同.md` oracle table
|
|
10
|
+
- `features/{feature}/交付至完成.md` or `07-测试执行.md` execution evidence
|
|
11
|
+
- Local test/build/browser/manual-check outputs
|
|
12
|
+
|
|
13
|
+
## Oracle Format
|
|
14
|
+
|
|
15
|
+
| 字段 | 要求 |
|
|
16
|
+
| --- | --- |
|
|
17
|
+
| ID | `O-###`,稳定不复用 |
|
|
18
|
+
| 验收标准 | EARS(WHEN/WHILE/IF…THEN/WHERE + SHALL)或 Given/When/Then;绑定数字或可观察行为 |
|
|
19
|
+
| 验证方法 | auto:可复现命令/脚本/测试名;manual:编号步骤 + 明确判定标准 |
|
|
20
|
+
| 类型 | auto / manual(auto 优先;manual 用于体验直觉与无法自动化的检查) |
|
|
21
|
+
| blocking | 是/否;发布准入只看 blocking 集合 |
|
|
22
|
+
| 状态 | NOT_RUN / PASS / FAIL / STALE / WAIVED |
|
|
23
|
+
| 证据 | 命令输出、退出码、截图路径、日志片段;manual 附执行人与时间 |
|
|
24
|
+
|
|
25
|
+
## State Machine
|
|
26
|
+
|
|
27
|
+
- 初始一律 `NOT_RUN`;只有真实执行过验证方法才能进入 `PASS` 或 `FAIL`。
|
|
28
|
+
- `PASS` 之后,其覆盖的代码或配置再次变更 → 立即置 `STALE`,必须复验;`STALE` 不等于 `PASS`。
|
|
29
|
+
- `WAIVED` 只能由用户书面确认产生,必须记录理由与风险;agent 不得自我豁免。
|
|
30
|
+
- 状态只能由 `/交付至完成` 或 `/07-测试执行` 翻转,且逐次附证据;其他阶段只读。
|
|
31
|
+
- 冻结后不得修改标准、阈值、blocking 标记或删除 Oracle;确需变更走合同修订记录 + 用户确认。
|
|
32
|
+
|
|
33
|
+
## Verdict Rules
|
|
34
|
+
|
|
35
|
+
- 宣布完成 = blocking 全部 `PASS` 或 `WAIVED`(带确认);存在 `NOT_RUN`/`FAIL`/`STALE` 的 blocking 项时,任何"基本完成/差不多了"表述都是违规。
|
|
36
|
+
- 非 blocking 项不阻塞发布,但终态汇总必须如实列出其状态。
|
|
37
|
+
- 无法执行的验证方法(缺环境/凭据)记为 `NOT_RUN` + 精确阻塞说明,不得凭推测标 `PASS`。
|
|
38
|
+
|
|
39
|
+
## Failure Modes
|
|
40
|
+
|
|
41
|
+
- 把"代码写完了"当成 PASS 的证据。
|
|
42
|
+
- 复用旧运行结果糊弄复验(证据必须对应当前 commit)。
|
|
43
|
+
- 修改测试或阈值使其通过,而不是修复实现。
|
|
44
|
+
- manual Oracle 没有步骤和判定标准,执行时临场发挥。
|
|
45
|
+
- STALE 项在发布前被悄悄当作 PASS 统计。
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
# Capability: branch-gatekeeper
|
|
2
|
+
|
|
3
|
+
- **Tier**: essential
|
|
4
|
+
- **Stage**: `/04`, `/04A`, `/04B`
|
|
5
|
+
- **Purpose**: 在业务代码写入前确认功能分支闸门和实现阶段闸门,防止代码落到错误基线。
|
|
6
|
+
|
|
7
|
+
## 为什么需要
|
|
8
|
+
|
|
9
|
+
分支漂移和阶段漂移是代码管理失控的高频来源。实现必须同时满足:当前请求已进入实现阶段,且每个受影响仓库都在本需求功能分支或登记 worktree 中。
|
|
10
|
+
|
|
11
|
+
## 输入
|
|
12
|
+
|
|
13
|
+
- `workflow/team-profile.yaml#branch_model`
|
|
14
|
+
- 每个受影响仓库的当前分支
|
|
15
|
+
- 用户请求和 `features/{feature}/00-工作流状态.md` 中的当前阶段
|
|
16
|
+
- 功能名称和前序阶段文档
|
|
17
|
+
|
|
18
|
+
## 输出
|
|
19
|
+
|
|
20
|
+
```yaml
|
|
21
|
+
result: PASS | WARN | BLOCK
|
|
22
|
+
checks:
|
|
23
|
+
- name: stage_gate
|
|
24
|
+
status: pass | block
|
|
25
|
+
detail: "..."
|
|
26
|
+
- name: branch_gate_per_repo
|
|
27
|
+
status: pass | block
|
|
28
|
+
repos:
|
|
29
|
+
- path: "<repo>"
|
|
30
|
+
branch: "<current branch>"
|
|
31
|
+
verdict: pass | block
|
|
32
|
+
reason: "..."
|
|
33
|
+
blocked_reason: "..."
|
|
34
|
+
recommended_action: "请按 team-profile 中的分支规则准备功能分支。"
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
## 阻断规则
|
|
38
|
+
|
|
39
|
+
- 当前不是 `/04`、`/04A`、`/04B`,但 agent 将要修改业务源码、配置、SQL、迁移或部署文件时阻断。
|
|
40
|
+
- 任一受影响仓库位于生产、集成、历史、不明或无关分支时阻断。
|
|
41
|
+
- 功能分支不符合 `branch_model.feature_branch_rule` 时阻断。
|
|
42
|
+
- 无 Git 元数据时降级为 WARN,并要求用户明确确认本地快照风险后才能继续。
|
|
43
|
+
|
|
44
|
+
## Adapter 示例
|
|
45
|
+
|
|
46
|
+
- **L0**: 在 `AGENTS.md` 中写明闸门规则。
|
|
47
|
+
- **L1**: prompt 要求用户粘贴当前分支输出。
|
|
48
|
+
- **L2**: slash command 运行仓级分支检查并输出结论。
|
|
49
|
+
- **L3**: 写入前 hook 发现分支不合规时中断。
|
|
50
|
+
- **L4**: 独立 subagent 负责执行准入检查并返回结构化结果。
|
|
51
|
+
|
|
52
|
+
## 反模式
|
|
53
|
+
|
|
54
|
+
- 因为目录名看起来正确就跳过分支检查。
|
|
55
|
+
- 认为“小改动”可以绕过 04 阶段。
|
|
56
|
+
- 在 `main`、`prod`、`test` 或 integration 分支上直接修代码。
|
|
57
|
+
- 两个需求混用同一个功能分支。
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
# Channel Experiment Tracker
|
|
2
|
+
|
|
3
|
+
## Purpose
|
|
4
|
+
|
|
5
|
+
Run every marketing channel as an explicit experiment with a hypothesis, budget cap, time box, and predefined kill criteria, so solo developers avoid open-ended spend of money and attention.
|
|
6
|
+
|
|
7
|
+
## Sources
|
|
8
|
+
|
|
9
|
+
- `business/{product}/B5-渠道漏斗映射.md`, `B6-营销获客策略.md`, `B7-营销预算.md`, `B8-渠道执行策略.md`
|
|
10
|
+
- Channel analytics, spend records, and time logs kept by the user
|
|
11
|
+
- `business/{product}/B9-策略复盘.md` history
|
|
12
|
+
|
|
13
|
+
## Rules
|
|
14
|
+
|
|
15
|
+
- Each experiment records: channel, funnel position, hypothesis, action cadence, money cap, time cap, time box, primary metric, decision threshold, and notes.
|
|
16
|
+
- Define kill / keep / scale criteria before the experiment starts, not after seeing results.
|
|
17
|
+
- Time cost counts: hours-heavy channels are not "free" just because no cash was spent.
|
|
18
|
+
- Results use real numbers with date ranges; missing data is recorded as a collection gap, never silently estimated.
|
|
19
|
+
- Every experiment ends with an explicit verdict — validated / invalidated / inconclusive — feeding `/B9-策略复盘`.
|
|
20
|
+
- Outbound actions inside an experiment (posting, sending, spending) still require explicit user authorization or user execution.
|
|
21
|
+
|
|
22
|
+
## Suggested Outputs
|
|
23
|
+
|
|
24
|
+
- An experiment ledger table in `B8-渠道执行策略.md`, one row per experiment per cycle.
|
|
25
|
+
- Per-cycle verdicts and channel disposal recommendations (scale / keep / reduce / kill) for `/B9-策略复盘`.
|
|
26
|
+
|
|
27
|
+
## Failure Modes
|
|
28
|
+
|
|
29
|
+
- Running a channel "to see how it goes" with no metric or end date.
|
|
30
|
+
- Moving the decision threshold after results arrive.
|
|
31
|
+
- Running several overlapping experiments that share one primary metric window, making attribution impossible.
|
|
32
|
+
- Letting an inconclusive experiment run indefinitely instead of re-scoping or ending it.
|
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
# Capability: ci-cd-automation-governor
|
|
2
|
+
|
|
3
|
+
- **Tier**: recommended
|
|
4
|
+
- **Stage**: `/03`, `/04`, `/07`, `/08`, `/09`; revisit in `/10`
|
|
5
|
+
- **Purpose**: Introduce CI/CD and deployment automation in controlled stages, so automation improves repeatability without silently releasing unreviewed or untested changes.
|
|
6
|
+
|
|
7
|
+
## Why
|
|
8
|
+
|
|
9
|
+
Personal projects still need disciplined release flow. The risk is not "too much process"; the risk is automation publishing the wrong branch, leaking secrets, skipping App Store/release requirements, or deploying code whose tests do not match the feature scope. CI should start early because it is read-only verification. CD should start manual-gated, then become progressively automated only after the first stable production release and rollback path exist.
|
|
10
|
+
|
|
11
|
+
## Automation Maturity Model
|
|
12
|
+
|
|
13
|
+
```yaml
|
|
14
|
+
level_0_manual:
|
|
15
|
+
when: "before first production release or when repo has no stable build"
|
|
16
|
+
allowed:
|
|
17
|
+
- local validation commands
|
|
18
|
+
- documented manual deployment checklist
|
|
19
|
+
blocked:
|
|
20
|
+
- automatic deployment
|
|
21
|
+
- production secret writes
|
|
22
|
+
|
|
23
|
+
level_1_ci_only:
|
|
24
|
+
when: "repo has repeatable build/test commands"
|
|
25
|
+
allowed:
|
|
26
|
+
- branch and pull-request CI checks
|
|
27
|
+
- lint, unit tests, type checks, build checks
|
|
28
|
+
- artifact creation without deployment
|
|
29
|
+
blocked:
|
|
30
|
+
- automatic production deployment
|
|
31
|
+
|
|
32
|
+
level_2_manual_cd:
|
|
33
|
+
when: "first prod release exists and rollback is documented"
|
|
34
|
+
allowed:
|
|
35
|
+
- manually approved deployment job
|
|
36
|
+
- deployment from main to prod after tests pass
|
|
37
|
+
- tagged release artifacts
|
|
38
|
+
blocked:
|
|
39
|
+
- unattended production deployment
|
|
40
|
+
|
|
41
|
+
level_3_guarded_auto_cd:
|
|
42
|
+
when: "several stable releases have passed with reliable CI and rollback"
|
|
43
|
+
allowed:
|
|
44
|
+
- automatic non-production preview deployment
|
|
45
|
+
- optional automatic production deployment from prod tags or protected prod branch
|
|
46
|
+
required:
|
|
47
|
+
- branch protection
|
|
48
|
+
- required CI checks
|
|
49
|
+
- environment protection or equivalent manual approval for high-risk changes
|
|
50
|
+
- rollback runbook tested at least once
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
## Branch Flow Contract
|
|
54
|
+
|
|
55
|
+
Automation must respect the workspace branch model:
|
|
56
|
+
|
|
57
|
+
- Development branches are created from `prod`.
|
|
58
|
+
- CI runs on development branches and on `main`.
|
|
59
|
+
- `main` is the testing/integration branch.
|
|
60
|
+
- Release promotion goes from `main` to `prod`.
|
|
61
|
+
- No separate `test` branch is created for personal projects.
|
|
62
|
+
- Production deployment must be tied to `prod` or a release tag produced from `prod`.
|
|
63
|
+
|
|
64
|
+
## Inputs
|
|
65
|
+
|
|
66
|
+
- `workflow/team-profile.yaml#branch_model`
|
|
67
|
+
- `workflow/team-profile.yaml#risk_policy`
|
|
68
|
+
- Target repository package/build/test scripts
|
|
69
|
+
- Runtime and deployment provider docs for the target project
|
|
70
|
+
- Secret inventory and environment variable list
|
|
71
|
+
- Workspace-level `features/{feature}/03-技术架构.md`
|
|
72
|
+
- Workspace-level `features/{feature}/07-测试执行.md`
|
|
73
|
+
- Workspace-level `features/{feature}/08-发布准备.md`
|
|
74
|
+
- Workspace-level `features/{feature}/09-发布执行.md`
|
|
75
|
+
|
|
76
|
+
## Outputs
|
|
77
|
+
|
|
78
|
+
```yaml
|
|
79
|
+
result: PASS | WARN | BLOCK
|
|
80
|
+
automation_level: 0 | 1 | 2 | 3
|
|
81
|
+
ci:
|
|
82
|
+
required_checks:
|
|
83
|
+
- "<command or workflow>"
|
|
84
|
+
evidence:
|
|
85
|
+
- "<log, URL, or local command output>"
|
|
86
|
+
cd:
|
|
87
|
+
deployment_mode: "none" | "manual-gated" | "guarded-auto"
|
|
88
|
+
source_branch: "main" | "prod" | "<tag>"
|
|
89
|
+
target_environment: "preview" | "production"
|
|
90
|
+
rollback_plan: "<path or summary>"
|
|
91
|
+
secrets:
|
|
92
|
+
location: "platform secret store only"
|
|
93
|
+
repo_committed_secrets: false
|
|
94
|
+
blocked_reason: "..."
|
|
95
|
+
recommended_action: "..."
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
## Blocking Rules
|
|
99
|
+
|
|
100
|
+
- Block automatic production deployment before the first manual production release succeeds.
|
|
101
|
+
- Block any deployment automation that can deploy from a development branch directly to production.
|
|
102
|
+
- Block production deployment if required CI checks are missing, failing, or not clearly tied to the release commit.
|
|
103
|
+
- Block automation that stores secrets in source code, workflow documents, `.env` committed files, logs, screenshots, or prompt transcripts.
|
|
104
|
+
- Block deployment from `main` to `prod` unless the release scope has passed `/07-测试执行`, `/08-发布准备` records the rollback plan, and `/09-发布执行` has explicit user authorization for remote or production actions.
|
|
105
|
+
- Block creating a `test` branch as a deployment environment for personal projects; use `main` for testing/integration and provider preview environments for previews.
|
|
106
|
+
- Downgrade to WARN when the project has no code yet; require a CI/CD plan document but do not create workflows until implementation begins.
|
|
107
|
+
|
|
108
|
+
## Adapter Examples
|
|
109
|
+
|
|
110
|
+
- **L0**: A checklist in `/03`, `/08`, and `/09` stating the automation level, CI commands, deployment trigger, secret storage, authorization, and rollback path.
|
|
111
|
+
- **L1**: A prompt that asks for package scripts and deployment provider, then drafts a CI/CD plan.
|
|
112
|
+
- **L2**: A slash command that validates workflow files against branch and secret rules.
|
|
113
|
+
- **L3**: A pre-push or CI policy check that blocks deployment workflow changes without required checks and rollback notes.
|
|
114
|
+
- **L4**: A deployment-safety subagent that reviews workflow YAML, provider configuration, release notes, and evidence before promotion.
|
|
115
|
+
|
|
116
|
+
## Anti-Patterns
|
|
117
|
+
|
|
118
|
+
- Treating "personal project" as permission to deploy from a laptop without repeatable checks.
|
|
119
|
+
- Enabling auto-deploy before the first manual production release proves the runbook.
|
|
120
|
+
- Using `main` as both development and production.
|
|
121
|
+
- Creating a `test` branch when provider preview environments or `main` integration are enough.
|
|
122
|
+
- Committing platform secrets, API keys, provisioning profiles, or App Store credentials.
|
|
123
|
+
- Letting CI pass on a different commit than the one promoted to `prod`.
|