@xulthekl/team-flow 0.35.0 → 0.36.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/.claude/always/phase-guard.md +1 -1
- package/.claude-plugin/marketplace.json +1 -1
- package/.claude-plugin/plugin.json +1 -1
- package/.codex-plugin/plugin.json +1 -1
- package/.cursor-plugin/marketplace.json +1 -1
- package/.cursor-plugin/plugin.json +1 -1
- package/.github/plugin/marketplace.json +2 -2
- package/CHANGELOG.md +27 -0
- package/GEMINI.md +1 -1
- package/INSTALL.md +1 -1
- package/README.md +1 -1
- package/agents/architecture-reviewer.md +12 -0
- package/docs/README_en.md +1 -1
- package/gemini-extension.json +1 -1
- package/hooks/session-start +2 -2
- package/llms.txt +1 -1
- package/package.json +1 -1
- package/plugin.json +1 -1
- package/scripts/guard/checks/arch-gate-exemptions.mjs +68 -0
- package/scripts/guard/checks/arch-readiness.mjs +36 -0
- package/scripts/guard/checks/arch-snapshot.mjs +35 -0
- package/scripts/guard/guard.mjs +10 -2
- package/scripts/lib/arch-merge.mjs +405 -316
- package/scripts/lib/arch-parse.mjs +162 -0
- package/scripts/lib/cmd-arch.mjs +84 -0
- package/scripts/team-flow.mjs +4 -0
- package/skills/architecture-design/SKILL.md +22 -1
- package/skills/architecture-design/chapters/ch06-integration.md +4 -4
- package/skills/architecture-design/references/s3.5-architecture-template.md +164 -0
- package/skills/architecture-design/references/s3.5-loading-protocol.md +40 -0
- package/skills/architecture-design/references/s3.5-product-architecture.md +76 -0
- package/skills/session-handoff/references/handoff-template.md +2 -2
- package/skills/spec-writer/SKILL.md +1 -0
- package/skills/workflow-bootstrap/references/agents/arch-reverse-analyst.md +60 -0
- package/skills/workflow-orchestrator/references/feedback-loops.md +2 -0
- package/skills/workflow-orchestrator/references/s1-path-router.md +1 -1
- package/skills/workflow-orchestrator/references/s3-plan-pipeline.md +2 -1
- package/skills/workflow-orchestrator/references/s4-split-validate.md +11 -1
- package/skills/workflow-orchestrator/references/state-model.md +52 -0
|
@@ -0,0 +1,162 @@
|
|
|
1
|
+
// scripts/lib/arch-parse.mjs — 结构化解析 change 架构产物(v0.35.0,v0.14 §62.2)
|
|
2
|
+
//
|
|
3
|
+
// P2 机器管结构:从 markdown 表格 / schema SQL 提取机器可读数据,替代正则扫 markdown。
|
|
4
|
+
// 背景(红队评估实证):旧实现正则硬编码(`## 2. To-Be`、`/api/` 前缀、反引号表名)
|
|
5
|
+
// 在 LLM 文档标题漂移/格式变化时静默失败(match 失配返回空串、流程继续、返回 merged:true)。
|
|
6
|
+
// 本模块用通用表格解析(按 `|` split + 去反引号)与格式容错匹配,抽取失配由调用方 abort。
|
|
7
|
+
|
|
8
|
+
/** 解析一行 markdown 表格为单元格数组(去反引号/去 code 包裹/trim)。非表格行返回 null。 */
|
|
9
|
+
export function parseTableRow(line) {
|
|
10
|
+
const trimmed = line.trim();
|
|
11
|
+
if (!trimmed.startsWith('|') || !trimmed.endsWith('|')) return null;
|
|
12
|
+
return trimmed
|
|
13
|
+
.slice(1, -1)
|
|
14
|
+
.split('|')
|
|
15
|
+
.map(cell => cell.trim().replace(/`/g, '').trim());
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* 在内容中定位某个标题(headingRe),解析其后的第一个表格为行数组。
|
|
20
|
+
* 标题匹配容错:不依赖序号/中英文(如 `/^#{2,3}\s*\d*\.?\s*(聚合注册表|Aggregate Registry)/i`)。
|
|
21
|
+
* 返回行数组(每行 = 单元格数组);找不到标题或表格返回 []。
|
|
22
|
+
*/
|
|
23
|
+
export function parseTableAfter(content, headingRe) {
|
|
24
|
+
const lines = content.split('\n');
|
|
25
|
+
let i = 0;
|
|
26
|
+
for (; i < lines.length; i++) {
|
|
27
|
+
if (headingRe.test(lines[i])) break;
|
|
28
|
+
}
|
|
29
|
+
if (i >= lines.length) return [];
|
|
30
|
+
for (; i < lines.length; i++) {
|
|
31
|
+
if (lines[i].trim().startsWith('|')) break;
|
|
32
|
+
}
|
|
33
|
+
if (i >= lines.length) return [];
|
|
34
|
+
const rows = [];
|
|
35
|
+
for (; i < lines.length; i++) {
|
|
36
|
+
const line = lines[i];
|
|
37
|
+
if (!line.trim().startsWith('|')) break;
|
|
38
|
+
if (/^\s*\|[\s:|-]+\|\s*$/.test(line)) continue;
|
|
39
|
+
const cells = parseTableRow(line);
|
|
40
|
+
if (cells && cells.length > 0) rows.push(cells);
|
|
41
|
+
}
|
|
42
|
+
return rows;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
/**
|
|
46
|
+
* 从 api.md 提取端点(Command/Read/Query 三段表格)。
|
|
47
|
+
* 容错:匹配路径单元格(`/xxx/{id}`)与方法单元格(GET/POST/PUT/DELETE/PATCH),
|
|
48
|
+
* 不依赖 `/api/` 前缀硬编码(企业系统可能是 /v1/、/gateway/oms/ 等)。
|
|
49
|
+
*/
|
|
50
|
+
export function extractEndpoints(apiMd) {
|
|
51
|
+
const endpoints = [];
|
|
52
|
+
const lines = apiMd.split('\n');
|
|
53
|
+
let currentKind = 'unknown';
|
|
54
|
+
for (const line of lines) {
|
|
55
|
+
if (/^#{2,3}\s*.*(Command|命令)/i.test(line)) currentKind = 'Command';
|
|
56
|
+
else if (/^#{2,3}\s*.*(Read|读取)/i.test(line)) currentKind = 'Read';
|
|
57
|
+
else if (/^#{2,3}\s*.*(Query|查询)/i.test(line)) currentKind = 'Query';
|
|
58
|
+
if (!line.trim().startsWith('|')) continue;
|
|
59
|
+
const cells = parseTableRow(line);
|
|
60
|
+
if (!cells || cells.length === 0) continue;
|
|
61
|
+
const pathCell = cells.find(c => /^\/[\w\-/{}.]+$/.test(c));
|
|
62
|
+
if (!pathCell) continue;
|
|
63
|
+
const methodCell = cells.find(c => /^(GET|POST|PUT|DELETE|PATCH)$/i.test(c));
|
|
64
|
+
// kind:章节标题优先;若无章节标题(如 API-INDEX 生成格式),从表格分流列取
|
|
65
|
+
const kindCell = cells.find(c => /^(Command|Read|Query)$/i.test(c));
|
|
66
|
+
const kind = currentKind !== 'unknown' ? currentKind : (kindCell || 'unknown');
|
|
67
|
+
endpoints.push({ path: pathCell, method: methodCell ? methodCell.toUpperCase() : '', kind });
|
|
68
|
+
}
|
|
69
|
+
return endpoints;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
/**
|
|
73
|
+
* 从 architecture.md 提取聚合清单。聚合 id 格式 `context:Aggregate`。
|
|
74
|
+
* 兼容两种模板:
|
|
75
|
+
* - 产品级「聚合注册表」:`| 聚合ID | 上下文 | 根实体 | ... |`(列1=上下文,列2=根,列5=不变量)
|
|
76
|
+
* - change 级「To-Be 增量设计 §2.1 聚合变更」:`| 聚合名称 | 操作 | 聚合根 | ... | 所属 BC |`(列1=操作,列5=所属 BC)
|
|
77
|
+
*/
|
|
78
|
+
export function extractAggregates(archMd) {
|
|
79
|
+
let rows = parseTableAfter(archMd, /^#{2,3}\s*\d*\.?\s*(聚合注册表|Aggregate Registry)/i);
|
|
80
|
+
if (rows.length === 0) {
|
|
81
|
+
rows = parseTableAfter(archMd, /^#{3,4}\s*\d*\.?\s*(聚合变更|Aggregate Changes)/i);
|
|
82
|
+
}
|
|
83
|
+
if (rows.length === 0) {
|
|
84
|
+
rows = parseTableAfter(archMd, /^#{2,3}\s*\d*\.?\s*To-Be/i);
|
|
85
|
+
}
|
|
86
|
+
const aggregates = [];
|
|
87
|
+
for (const row of rows) {
|
|
88
|
+
const id = row[0]?.trim();
|
|
89
|
+
if (!id || id === '聚合ID' || id === '聚合名称' || id === 'Aggregate') continue;
|
|
90
|
+
if (!/^[\w]+:[\w]+$/.test(id)) continue;
|
|
91
|
+
const col1 = row[1]?.trim() || '';
|
|
92
|
+
const isChange = /^(新增|修改|New|Update)/i.test(col1);
|
|
93
|
+
// source:产品级全局格式(buildCurrentStateSection 生成)列3=来源 changeName;change 级无来源列 → ''
|
|
94
|
+
const source = /^change:/.test(row[3]?.trim() || '') ? row[3].trim() : '';
|
|
95
|
+
aggregates.push({
|
|
96
|
+
id,
|
|
97
|
+
context: isChange ? (row[5]?.trim() || '') : col1,
|
|
98
|
+
root: row[2]?.trim() || '',
|
|
99
|
+
invariants: isChange ? '' : (row[5]?.trim() || ''),
|
|
100
|
+
source,
|
|
101
|
+
});
|
|
102
|
+
}
|
|
103
|
+
return aggregates;
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
/** 从 schema-baseline.sql 提取 CREATE TABLE 表名(容错:IF NOT EXISTS / 反引号 / schema 前缀)。 */
|
|
107
|
+
export function extractTablesFromSql(sql) {
|
|
108
|
+
const tables = [];
|
|
109
|
+
const re = /CREATE\s+TABLE(?:\s+IF\s+NOT\s+EXISTS)?\s+`?([\w.]+)`?\s*(?:\(|;)/gi;
|
|
110
|
+
let m;
|
|
111
|
+
while ((m = re.exec(sql))) {
|
|
112
|
+
tables.push(m[1].replace(/`/g, ''));
|
|
113
|
+
}
|
|
114
|
+
return [...new Set(tables)];
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
/**
|
|
118
|
+
* 从演进日志段提取条目。返回 `{ key, content }[]`,key 用 changeName 唯一锚
|
|
119
|
+
*(`### change:<name>` 或 `### <name>`),替代按版本号去重(不同 change 可能同版本号)。
|
|
120
|
+
*/
|
|
121
|
+
export function extractEvolutionLogEntries(archMd, changeName) {
|
|
122
|
+
const logStart = archMd.search(/^#{2,3}\s*\d*\.?\s*(演进日志|Evolution Log)/m);
|
|
123
|
+
if (logStart < 0) return [];
|
|
124
|
+
const logSection = archMd.slice(logStart);
|
|
125
|
+
const entries = [];
|
|
126
|
+
const blockRe = /(###\s+.+)([\s\S]*?)(?=###\s|##\s|\n#\s|$)/g;
|
|
127
|
+
let m;
|
|
128
|
+
while ((m = blockRe.exec(logSection))) {
|
|
129
|
+
const title = m[1].trim();
|
|
130
|
+
const body = m[2].trim();
|
|
131
|
+
if (!title || !body) continue;
|
|
132
|
+
entries.push({ key: changeName, title, body });
|
|
133
|
+
}
|
|
134
|
+
return entries;
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
/** 从 database.md 的 Schema 变更详情段(§3)提取受影响的表。 */
|
|
138
|
+
export function extractTablesFromDatabaseMd(dbMd) {
|
|
139
|
+
const tables = new Set();
|
|
140
|
+
// 匹配表格行中的 CREATE/ALTER TABLE 操作列
|
|
141
|
+
const re = /(?:CREATE|ALTER)\s+TABLE(?:\s+IF\s+NOT\s+EXISTS)?\s+`?([\w.]+)`?/gi;
|
|
142
|
+
let m;
|
|
143
|
+
while ((m = re.exec(dbMd))) {
|
|
144
|
+
tables.add(m[1].replace(/`/g, ''));
|
|
145
|
+
}
|
|
146
|
+
// 兜底:匹配形如 `t_xxx` 的表名行
|
|
147
|
+
const tableRe = /\b(t_[a-z_0-9]+)\b/g;
|
|
148
|
+
while ((m = tableRe.exec(dbMd))) tables.add(m[1]);
|
|
149
|
+
return [...tables];
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
/** 从 markdown 中提取所有 frontmatter 字段(简单正则,与 state-loader 兼容)。 */
|
|
153
|
+
export function readFrontmatter(content) {
|
|
154
|
+
const match = content.match(/^---\n([\s\S]*?)\n---/);
|
|
155
|
+
if (!match) return {};
|
|
156
|
+
const fm = {};
|
|
157
|
+
for (const line of match[1].split('\n')) {
|
|
158
|
+
const m = line.match(/^(\w+):\s*(.*)$/);
|
|
159
|
+
if (m) fm[m[1]] = m[2].trim();
|
|
160
|
+
}
|
|
161
|
+
return fm;
|
|
162
|
+
}
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
// scripts/lib/cmd-arch.mjs — tf arch init/show:项目级架构基线打戳(v0.35.0,v0.14 §59.4/§63.1)
|
|
2
|
+
//
|
|
3
|
+
// arch_baseline 完全复刻 v0.13 §48.1 schema_version 防污染模式:
|
|
4
|
+
// 仅 `tf arch init` 打戳(项目级 .team-flow/arch-state.json),缺失 = 存量信号。
|
|
5
|
+
// 防污染:已打戳则拒绝重复 init(不覆盖);rebuild/doctor/set 一律不追加。
|
|
6
|
+
import fs from 'node:fs';
|
|
7
|
+
import path from 'node:path';
|
|
8
|
+
import { parseArgs } from 'node:util';
|
|
9
|
+
|
|
10
|
+
const ARCH_STATE_FILE = '.team-flow/arch-state.json';
|
|
11
|
+
|
|
12
|
+
export async function run(args) {
|
|
13
|
+
const { positionals, values } = parseArgs({
|
|
14
|
+
args,
|
|
15
|
+
options: {
|
|
16
|
+
'project-root': { type: 'string' },
|
|
17
|
+
mode: { type: 'string', default: 'reconstruction' },
|
|
18
|
+
'baseline-ref': { type: 'string', default: 'prd/vN/' },
|
|
19
|
+
},
|
|
20
|
+
allowPositionals: true,
|
|
21
|
+
});
|
|
22
|
+
|
|
23
|
+
const sub = positionals[0];
|
|
24
|
+
if (sub === 'init') return init(values);
|
|
25
|
+
if (sub === 'show') return show(values);
|
|
26
|
+
console.error('Usage: tf arch init [--mode reconstruction|design] [--baseline-ref <prd/vN/>] | tf arch show');
|
|
27
|
+
process.exit(2);
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
function findRoot(rootOpt) {
|
|
31
|
+
if (rootOpt) return path.resolve(rootOpt);
|
|
32
|
+
let dir = process.cwd();
|
|
33
|
+
while (dir !== path.dirname(dir)) {
|
|
34
|
+
if (fs.existsSync(path.join(dir, '.team-flow'))) return dir;
|
|
35
|
+
dir = path.dirname(dir);
|
|
36
|
+
}
|
|
37
|
+
return dir;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
function readState(root) {
|
|
41
|
+
const target = path.join(root, ARCH_STATE_FILE);
|
|
42
|
+
if (!fs.existsSync(target)) return null;
|
|
43
|
+
try { return JSON.parse(fs.readFileSync(target, 'utf-8')); }
|
|
44
|
+
catch { return null; }
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
function init(values) {
|
|
48
|
+
const root = findRoot(values['project-root']);
|
|
49
|
+
const target = path.join(root, ARCH_STATE_FILE);
|
|
50
|
+
const mode = values.mode === 'design' ? 'design' : 'reconstruction';
|
|
51
|
+
|
|
52
|
+
const existing = readState(root);
|
|
53
|
+
if (existing?.arch_baseline) {
|
|
54
|
+
console.error(
|
|
55
|
+
`arch-state.json already established (arch_baseline=${existing.arch_baseline}, mode=${existing.mode})`
|
|
56
|
+
+ ' — 防污染规则:不重复打戳。如需重建,先手工处理旧标记。'
|
|
57
|
+
);
|
|
58
|
+
process.exit(1);
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
const state = {
|
|
62
|
+
arch_baseline: 'v0',
|
|
63
|
+
established_at: new Date().toISOString(),
|
|
64
|
+
mode,
|
|
65
|
+
snapshot_root: 'iterations/',
|
|
66
|
+
baseline_prd_ref: values['baseline-ref'],
|
|
67
|
+
};
|
|
68
|
+
|
|
69
|
+
fs.mkdirSync(path.dirname(target), { recursive: true });
|
|
70
|
+
fs.writeFileSync(target, JSON.stringify(state, null, 2) + '\n');
|
|
71
|
+
console.log(`arch-state.json written: ${target}`);
|
|
72
|
+
console.log(JSON.stringify(state, null, 2));
|
|
73
|
+
console.log('项目架构基线已打戳,进入 design 模式。重建快照位于 docs/architecture/iterations/v0/。');
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
function show(values) {
|
|
77
|
+
const root = findRoot(values['project-root']);
|
|
78
|
+
const state = readState(root);
|
|
79
|
+
if (!state) {
|
|
80
|
+
console.log('arch_baseline: <unset>(存量/未建立,S3.5 reconstruction pending)');
|
|
81
|
+
return;
|
|
82
|
+
}
|
|
83
|
+
console.log(JSON.stringify(state, null, 2));
|
|
84
|
+
}
|
package/scripts/team-flow.mjs
CHANGED
|
@@ -35,6 +35,7 @@ const COMMANDS = {
|
|
|
35
35
|
'install-zcode': () => import('./lib/cmd-install-zcode.mjs'),
|
|
36
36
|
'prototype-sync': () => import('./lib/prototype-sync.mjs'),
|
|
37
37
|
'arch-merge': () => import('./lib/arch-merge.mjs'),
|
|
38
|
+
arch: () => import('./lib/cmd-arch.mjs'),
|
|
38
39
|
'test-merge': () => import('./lib/test-merge.mjs'),
|
|
39
40
|
'test-matrix-export': () => import('./lib/test-matrix-export.mjs'),
|
|
40
41
|
test: () => import('./lib/test-record.mjs'),
|
|
@@ -52,6 +53,9 @@ Commands:
|
|
|
52
53
|
sync <change-dir> Merge delta specs into main specs
|
|
53
54
|
prototype-sync <change-dir> [--source <path>] [--prototype-dir <path>]
|
|
54
55
|
Merge UX delta into global prototype/ + design-system.md
|
|
56
|
+
arch init [--mode reconstruction|design] [--baseline-ref <prd/vN/>]
|
|
57
|
+
Stamp project-level arch_baseline into .team-flow/arch-state.json (v0.35.0 §59.4)
|
|
58
|
+
arch show Show current project architecture baseline state
|
|
55
59
|
arch-merge <change-dir> [--project-root <path>] [--dry-run]
|
|
56
60
|
Merge architecture delta into global docs/architecture/
|
|
57
61
|
test-merge <change-dir> [--project-root <path>] [--dry-run]
|
|
@@ -67,8 +67,9 @@ description: 基于 4A 企业架构 + DDD 领域驱动设计的架构/API/DB 设
|
|
|
67
67
|
|
|
68
68
|
- `change-brief.md`(scope / AC / 技术方向)
|
|
69
69
|
- `prd/vN/plan.md` 高阶技术设计段(模块边界/技术选型/数据流/关键聚合划分)
|
|
70
|
+
- `docs/architecture/iterations/vN/architecture.md`(产品级架构快照,**主输入**,v0.35.0)——BC 边界/聚合所有权/全局契约的唯一事实源
|
|
71
|
+
- 全局 `docs/architecture/`(As-Is 实际态基线,已落地部分)
|
|
70
72
|
- 现有 `specs/`(若有)
|
|
71
|
-
- 全局 `docs/architecture/`(As-Is 基线)
|
|
72
73
|
|
|
73
74
|
### 五项检查(架构变更判定)
|
|
74
75
|
|
|
@@ -80,6 +81,15 @@ description: 基于 4A 企业架构 + DDD 领域驱动设计的架构/API/DB 设
|
|
|
80
81
|
4. **API 变更**:是否涉及 API 新增/变更(端点、方法签名、请求响应 schema)
|
|
81
82
|
5. **DB schema 变更**:是否涉及数据库表结构、字段、索引变更
|
|
82
83
|
|
|
84
|
+
### 路由分流(v0.35.0 新增)
|
|
85
|
+
|
|
86
|
+
当产品级架构快照存在时(已建档项目),判定结果再按"产品级决策 vs change 内实现细节"分流:
|
|
87
|
+
|
|
88
|
+
- 触及**产品级决策**(BC 边界变更 / 聚合所有权变更 / 全局契约变更)→ 引用快照 + 走**架构修订决策门**(不硬阻断,显式确认 + 登记 deviation,P3)
|
|
89
|
+
- 仅 **change 内实现细节**(字段 / 端点 / 状态增量)→ 增量设计,不触发产品级变更
|
|
90
|
+
|
|
91
|
+
变更级聚合动作限三类:`extend`(既有聚合加字段/指令/事件/状态)、`new`(新增聚合,flag 登记待产品级晋升)、`refactor`(需决策门)。聚合 id 一律引用产品级注册表,不重定义(防重发明,v0.14 §61.3)。
|
|
92
|
+
|
|
83
93
|
### 执行流程
|
|
84
94
|
|
|
85
95
|
```
|
|
@@ -149,6 +159,15 @@ changes/<name>/
|
|
|
149
159
|
|
|
150
160
|
change 进入 closing 阶段时,由 release-archivist 调用 `tf arch-merge` CLI 命令,将 `changes/<name>/architecture/` 下的增量制品合并回全局 `docs/architecture/`,完成 As-Is → To-Be 基线更新。architecture-design 本身不执行合并,只负责产出增量制品。
|
|
151
161
|
|
|
162
|
+
### 调用模式(v0.35.0:变更级 / 产品级)
|
|
163
|
+
|
|
164
|
+
| 模式 | 编排入口 | 判定 | 产出 | owner |
|
|
165
|
+
|------|---------|------|------|-------|
|
|
166
|
+
| 变更级(默认) | workflow-start(exploring→specifying) | 五项检查 | `changes/<name>/architecture/` 三件套 + sql/ | architecture-design 子代理 |
|
|
167
|
+
| 产品级(product 模式) | workflow-orchestrator S3.5(architecture 阶段) | 8 步全系统结构级设计(无五项检查) | `docs/architecture/iterations/vN/architecture.md`(6 产物快照) | architecture-design product 模式子代理(唯一 owner) |
|
|
168
|
+
|
|
169
|
+
**产品级模式执行**:按 `references/s3.5-product-architecture.md` SOP(8 步),模板用 `references/s3.5-architecture-template.md`,加载协议用 `references/s3.5-loading-protocol.md`。产出经 architecture-reviewer product 视角评审(`review_mode: product`)PASS 才进 S4。时序遵守 P1:只写快照不写全局。
|
|
170
|
+
|
|
152
171
|
### 独立调用
|
|
153
172
|
|
|
154
173
|
除 workflow-start 编排调用外,本 skill 仍支持用户显式独立调用(`/team-flow:architecture-design`),此时不走五项检查判定门,直接执行完整 4A+DDD 设计。
|
|
@@ -182,6 +201,8 @@ architecture-design 执行时的上下文组装:
|
|
|
182
201
|
|
|
183
202
|
**上下文预算**:单次执行 ~2K tokens(L1 INDEX + 1-2 个 L2 域段 + L3 变更层)
|
|
184
203
|
|
|
204
|
+
**产品级三段式加载(v0.35.0,有产品级快照时)**:按 `references/s3.5-loading-protocol.md` 三段式——① 索引层(INDEX + ARCHITECTURE §1-2 厚锚点)② 按域加载(change 触及的 `domains/<bc>.md`)③ 变更增量。迭代中读 `iterations/vN/` 快照(in-flight),迭代收尾读全局当前态(P1)。
|
|
205
|
+
|
|
185
206
|
## Scope & Limits
|
|
186
207
|
本 skill 覆盖 4A+DDD 架构设计方法及其与 team-flow/compound-engineering 的衔接。落地实现结合项目具体工具;超出本范围见相关 skill 或直接问 agent。
|
|
187
208
|
|
|
@@ -28,10 +28,10 @@ changes/<name>/ # change 容器
|
|
|
28
28
|
|
|
29
29
|
> **语义分离**:架构产出独立 `architecture/` 目录,不混入 `specs/`(行为规格)。目录存在 = 有架构产出,目录不存在 = 判定为不需要。下游消费方(spec-writer / release-archivist)显式读取此目录。
|
|
30
30
|
|
|
31
|
-
## 每变更增量设计(SOP
|
|
32
|
-
1. (LLM) 读全局 ARCHITECTURE.md
|
|
33
|
-
2. (LLM) 出 To-Be
|
|
34
|
-
3. **As-Is
|
|
31
|
+
## 每变更增量设计(SOP 步骤,v0.35.0 更新:产品级快照为输入)
|
|
32
|
+
1. (LLM) 读全局 ARCHITECTURE.md **+ 产品级快照 `iterations/vN/architecture.md`**(v0.35.0,BC 边界/聚合注册表唯一事实源)作 grounding;识别本 change 触及的 BC → 按 `references/s3.5-loading-protocol.md` 三段式装载对应域;用活动对象矩阵识别限界上下文/聚合(变更级只引用产品级注册表,不重定义)。
|
|
33
|
+
2. (LLM) 出 To-Be:**本 change 增量**(extend/new/refactor 三类动作)——新增/调整聚合、Context Map 关系、CQRS 读写模型、4A 跨域对齐;触及产品级决策走架构修订决策门。
|
|
34
|
+
3. **As-Is 冻结**(核心修正):复制产品级快照/全局相关章节**当前原文** + 记版本锚点(`iterations/vN/architecture.md@<change_id>#<章节>`),变更内不可变——杜绝活引用漂移。
|
|
35
35
|
4. (脚本) 填 frontmatter 并校验:`cap_id/date/change_type/bounded_contexts/aggregates_affected/cqrs`。
|
|
36
36
|
5. (LLM) 写 ADR 理由;API 标 Command/Read/Query + 阻断测试归属。
|
|
37
37
|
6. (脚本) 回写全局 + 生成 API 索引。
|
|
@@ -0,0 +1,164 @@
|
|
|
1
|
+
# S3.5 产品级架构文档模板(v0.35.0,v0.14 §60)
|
|
2
|
+
|
|
3
|
+
> 产品级架构设计(architecture 阶段)产出的权威文档模板。基于 4A + DDD 方法论,覆盖 6 类产物。
|
|
4
|
+
> 位置:`docs/architecture/iterations/vN/architecture.md`(预测态快照,P1:不写全局当前态)。
|
|
5
|
+
> 产出后须经产品级评审门(architecture-reviewer product 视角)PASS 才进 S4。
|
|
6
|
+
|
|
7
|
+
## 文档骨架
|
|
8
|
+
|
|
9
|
+
````markdown
|
|
10
|
+
---
|
|
11
|
+
iteration_version: v1 # 迭代版本号
|
|
12
|
+
provenance: forward-designed # forward-designed | reverse-engineered | mixed
|
|
13
|
+
established_at: <ISO 8601> # 快照冻结时间
|
|
14
|
+
snapshot_status: in-flight # in-flight | superseded | archived
|
|
15
|
+
superseded_by: null # 下一版快照路径(退役时填)
|
|
16
|
+
---
|
|
17
|
+
# 产品级架构设计 · 迭代 vN
|
|
18
|
+
|
|
19
|
+
## 1 限界上下文(Context Map) <a id="bc"></a>
|
|
20
|
+
|
|
21
|
+
| 上下文 | 职责(一句话) | 依赖 | 关系类型 | 语言边界/关键术语 |
|
|
22
|
+
|--------|------------|------|---------|-----------------|
|
|
23
|
+
| order | 订单生命周期与履约 | payment, stock | Customer-Supplier | 客户=下单人 |
|
|
24
|
+
| payment| 收款与对账 | order | Open Host Service | 客户=付款人(同词异义) |
|
|
25
|
+
|
|
26
|
+
> mermaid:上下文关系图
|
|
27
|
+
```mermaid
|
|
28
|
+
flowchart LR
|
|
29
|
+
order -->|C-S| payment
|
|
30
|
+
order -->|C-S| stock
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
**关系类型枚举(6 种)**:Shared Kernel / Customer-Supplier / Conformist / Anti-Corruption Layer / Open Host Service / Separate Ways。
|
|
34
|
+
|
|
35
|
+
## 2 聚合注册表 <a id="aggregates"></a>
|
|
36
|
+
|
|
37
|
+
| 聚合ID | 上下文 | 根实体 | 值对象 | 核心行为 | 关键不变量 | 事务边界 | 状态机锚点 |
|
|
38
|
+
|--------|--------|--------|--------|---------|-----------|---------|-----------|
|
|
39
|
+
| order:Order | order | Order | OrderItem, Address, OrderStatus | PlaceOrder/MarkPaid/Ship/Complete | 总金额=明细和;状态流转有序 | 订单事务 | §4.1 |
|
|
40
|
+
|
|
41
|
+
### 2.2 聚合→表映射
|
|
42
|
+
| 聚合 | 表集合 | 读模型 |
|
|
43
|
+
|------|--------|--------|
|
|
44
|
+
| order:Order | t_order, t_order_item, t_order_status_history | v_order_summary |
|
|
45
|
+
|
|
46
|
+
### 2.3 聚合大小自检
|
|
47
|
+
- [ ] 每聚合实体数 ≤5(超过提示拆分)
|
|
48
|
+
- [ ] 事务边界无合并迹象
|
|
49
|
+
- [ ] 并发写冲突高发区已识别
|
|
50
|
+
|
|
51
|
+
> **唯一事实源**:本注册表是 BC 边界/聚合所有权的产品级权威;变更级(change 内)只引用本表 id,不重定义。
|
|
52
|
+
|
|
53
|
+
## 3 指令与事件识别 <a id="commands-events"></a>
|
|
54
|
+
|
|
55
|
+
### 3.1 指令表
|
|
56
|
+
| 指令 | 触发方 | 目标聚合 | Command/Read/Query | 结果事件 |
|
|
57
|
+
|------|--------|---------|-------------------|---------|
|
|
58
|
+
| PlaceOrder | Client | order:Order | Command | OrderPlaced |
|
|
59
|
+
| MarkPaid | PaymentCaptured 集成 | order:Order | Command | OrderPaid |
|
|
60
|
+
|
|
61
|
+
### 3.2 事件表
|
|
62
|
+
| 事件 | 类型(领域/集成/外部) | 源聚合/上下文 | 触发 | 携带数据 | 消费方 | 投影读模型 |
|
|
63
|
+
|------|--------------------|--------------|------|---------|--------|-----------|
|
|
64
|
+
| OrderPlaced | 领域 | order:Order | PlaceOrder | orderId, items | payment, stock | order-summary-view |
|
|
65
|
+
| PaymentCaptured | 集成 | payment:Payment | 支付回调 | orderId, paymentId | order:Order | order-summary-view |
|
|
66
|
+
|
|
67
|
+
### 3.3 事件流图
|
|
68
|
+
> mermaid:事件→指令级联链(覆盖 saga/process manager 跨聚合长流程一致性)
|
|
69
|
+
|
|
70
|
+
### 3.4 读模型投影清单
|
|
71
|
+
| 读模型 | 投影来源事件 | 更新方式(同步/异步) |
|
|
72
|
+
|--------|-------------|-------------------|
|
|
73
|
+
| order-summary-view | OrderPlaced, PaymentCaptured | 异步 |
|
|
74
|
+
|
|
75
|
+
> 显式声明:事件用于**变更通知与投影驱动,不引入事件溯源持久化**。事件命名规范 `OrderPlaced`(名词+过去式动词),全系统一致。
|
|
76
|
+
|
|
77
|
+
## 4 聚合状态迁移 <a id="state-machines"></a>
|
|
78
|
+
|
|
79
|
+
### 4.1 {order:Order} 状态机
|
|
80
|
+
> mermaid stateDiagram-v2
|
|
81
|
+
|
|
82
|
+
### 4.2 状态表
|
|
83
|
+
| 状态 | 触发(Command/Event) | 触发源上下文 | 目标状态 | guard 不变量 |
|
|
84
|
+
|------|--------------------|------------|---------|-------------|
|
|
85
|
+
| 创建 | PlaceOrder | order | 已支付 | 总金额>0 |
|
|
86
|
+
| 已支付 | Ship | order | 已发货 | 已收款 |
|
|
87
|
+
|
|
88
|
+
> 区分**聚合状态机**(本表,聚合事务边界内)与**跨聚合流程状态机**(入 saga,不在聚合状态机内表达)。
|
|
89
|
+
|
|
90
|
+
## 5 数据模型 / ER(概念级) <a id="erd"></a>
|
|
91
|
+
|
|
92
|
+
### 5.1 聚合边界 ER
|
|
93
|
+
> mermaid erDiagram:同聚合表圈在一起标注聚合根表;跨聚合外键标"引用关系(非事务内)"。
|
|
94
|
+
|
|
95
|
+
### 5.2 实体表
|
|
96
|
+
| 实体 | 关键字段 | 所属聚合 | 写/读模型 |
|
|
97
|
+
|------|---------|---------|----------|
|
|
98
|
+
| Order | id, status, total | order:Order | 写 |
|
|
99
|
+
|
|
100
|
+
> **派生纪律**:ER 从聚合注册表 + 状态图映射而来,**禁止先画 ER 再定聚合**(DB 表 ≠ 聚合)。
|
|
101
|
+
|
|
102
|
+
## 6 应用时序(关键用例) <a id="sequences"></a>
|
|
103
|
+
|
|
104
|
+
### 6.1 用例索引
|
|
105
|
+
| 用例 | 图文件 | 涉及聚合/上下文 |
|
|
106
|
+
|------|--------|---------------|
|
|
107
|
+
| 下单履约 | diagrams/sequences/order-place.md | order, payment, stock |
|
|
108
|
+
|
|
109
|
+
### 6.2 {用例} 时序图
|
|
110
|
+
> mermaid sequenceDiagram:跨聚合/跨上下文关键流程 Top-N。
|
|
111
|
+
|
|
112
|
+
## 7 跨域一致性检查 <a id="consistency"></a>
|
|
113
|
+
|
|
114
|
+
### 7.1 AA ↔ IA 双对齐(F2 门禁)
|
|
115
|
+
| AA 功能 | IA 实体 | 对齐状态 | 说明 |
|
|
116
|
+
|---------|---------|---------|------|
|
|
117
|
+
| PlaceOrder | Order | ✅ | |
|
|
118
|
+
|
|
119
|
+
- [ ] 每个 AA 功能 ≥1 个 IA 实体支撑
|
|
120
|
+
- [ ] 每个 IA 实体 ≥1 个 AA 功能消费(无孤立节点)
|
|
121
|
+
|
|
122
|
+
### 7.2 语义一致性
|
|
123
|
+
| 概念 | 上下文 A 命名 | 上下文 B 命名 | 一致性 |
|
|
124
|
+
|------|-------------|-------------|--------|
|
|
125
|
+
| 客户 | 下单人(order) | 付款人(payment) | ✅ 显式映射 |
|
|
126
|
+
|
|
127
|
+
### 7.3 变更分叉级联(F3)
|
|
128
|
+
直接依赖 / 间接依赖 / 隐式依赖 三层次分析。
|
|
129
|
+
|
|
130
|
+
## 8 DDD 反模式自检 <a id="antipatterns"></a>
|
|
131
|
+
|
|
132
|
+
- [ ] 贫血模型(聚合只有 getter/setter,行为全在 Service)
|
|
133
|
+
- [ ] 聚合过大(实体 >5 或事务边界膨胀)
|
|
134
|
+
- [ ] 实体滥用(ER 每张表被当实体)
|
|
135
|
+
- [ ] 表驱动聚合(表=聚合=Repository)
|
|
136
|
+
- [ ] 事件命名不一致(大小写/时态混用)
|
|
137
|
+
|
|
138
|
+
## 演进日志 <a id="evolution-log"></a>
|
|
139
|
+
|
|
140
|
+
| 版本 | 日期 | 变更摘要 |
|
|
141
|
+
|------|------|---------|
|
|
142
|
+
| v1 | <date> | 初始设计 |
|
|
143
|
+
|
|
144
|
+
<!-- arch:current-state:begin -->
|
|
145
|
+
<!-- 此 marker 区由 arch-merge 代码独占写(迭代收尾/change 合并时覆盖),禁止手改 -->
|
|
146
|
+
<!-- arch:current-state:end -->
|
|
147
|
+
````
|
|
148
|
+
|
|
149
|
+
## 结构约束
|
|
150
|
+
|
|
151
|
+
- **厚锚点**:§1-2 每行一句话,不展开细节;细节全部下沉 `domains/<bc>.md` 按域详细页与 `diagrams/`。
|
|
152
|
+
- **marker 区**:`<!-- arch:current-state:begin/end -->` 是 arch-merge 覆盖写的替换边界,**只由代码写,不由 LLM 写**。
|
|
153
|
+
- **按域详细页** `domains/<bc>.md`:职责与依赖 / 聚合明细 / 指令与事件(本域)/ 状态迁移图 / 数据片段(ER 局部)/ 应用时序(本域用例)/ 对外契约。单文件 ≤1500 token。
|
|
154
|
+
- **结构级详设边界**:BC/聚合/关键事件/状态机/概念 ER/关键时序做全;**每 API schema、每表全字段留给 change 落地时涌现**。
|
|
155
|
+
|
|
156
|
+
## 正反向设计差异(旧项目首轮)
|
|
157
|
+
|
|
158
|
+
| 维度 | 正向设计(全新/已建档) | 逆向重建(旧项目首轮) |
|
|
159
|
+
|------|------------------------|----------------------|
|
|
160
|
+
| 输入 | PRD/plan/原型(预测) | 既有代码/DDL/文档(事实) |
|
|
161
|
+
| 推导方向 | 业务能力→BC→聚合→... | 代码结构→候选 BC→聚合根候选→... |
|
|
162
|
+
| 工具 | 方法论 + LLM | recon-probe.sh + codebase-recon-analyst + arch-reverse-analyst |
|
|
163
|
+
| provenance | forward-designed | reverse-engineered + 置信度(high/medium/low) |
|
|
164
|
+
| 深度 | L0 骨架 + 触及域深化 | 同(首轮强制 L0 骨架) |
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
# S3.5 产品级架构按域加载协议(v0.35.0,v0.14 §60.4)
|
|
2
|
+
|
|
3
|
+
> 产品级架构文档(iterations/vN/architecture.md + domains/)供变更级 architecture-design 子代理加载。
|
|
4
|
+
> 硬约束:单次上下文装载 ≤ **~2K token**(设计增强方案 v0.10 §29.1 三层策略)。本协议是 architecture-design SKILL.md「上下文加载协议」的产品级扩展。
|
|
5
|
+
|
|
6
|
+
## 三段式加载
|
|
7
|
+
|
|
8
|
+
| 段 | 内容 | 预算 |
|
|
9
|
+
|----|------|------|
|
|
10
|
+
| ① 索引层 | `docs/architecture/INDEX.md`(统计摘要)+ ARCHITECTURE.md §1-2(厚锚点:BC 表 + 聚合注册表) | ~400-600 |
|
|
11
|
+
| ② 按域加载(按需) | change 触及的 `domains/<bc>.md`(+ 相关 sequence/erd 片段) | ~800-1400 |
|
|
12
|
+
| ③ 变更增量 | `changes/<id>/architecture/` 增量 + 相关 changelog | ~200-400 |
|
|
13
|
+
|
|
14
|
+
## 加载规则
|
|
15
|
+
|
|
16
|
+
1. **先索引、后按域**:子代理先读 ① 索引层做路由(识别 change 触及哪些 BC),再按需加载 ② 该域的详细页。
|
|
17
|
+
2. **单域单次**:跨多域时一次只装载一个域文件,逐域分步处理(与 ch06 增量 SOP 对齐)。
|
|
18
|
+
3. **引用非复制**:只读不改;产品级聚合注册表是唯一事实源,change 内设计**引用**注册表 id,不重定义。
|
|
19
|
+
4. **迭代状态判定**(P1):读快照还是读全局由迭代状态决定——
|
|
20
|
+
- 迭代中(`snapshot_status: in-flight`)→ 读 `iterations/vN/` 快照(产品级决策权威)
|
|
21
|
+
- 迭代收尾(`snapshot_status: superseded/archived`)→ 读全局当前态(唯一权威)
|
|
22
|
+
|
|
23
|
+
## 跨域降级(横向 change)
|
|
24
|
+
|
|
25
|
+
横向 change(跨 ≥3 个 BC 的公共组件改造)会突破单次预算。降级路径:
|
|
26
|
+
|
|
27
|
+
1. 只加载 ① 索引层 + 各域聚合注册表行(不加载详细页)。
|
|
28
|
+
2. 触及域按"受影响优先级"逐域分步处理(每步 ≤1 域)。
|
|
29
|
+
3. 加载前做 token 估算,超预算 → 告警 + 降级,而非硬约束失败。
|
|
30
|
+
|
|
31
|
+
## token 预算自动化校验
|
|
32
|
+
|
|
33
|
+
- 锚点(§1-2)与域页 token 预算加**自动化校验**(镜像 frontmatter-lint 模式,进 npm test)——不靠 LLM 自律。
|
|
34
|
+
- S3.5 产物自检 + S4 审计抽查:`iterations/vN/architecture.md` 的 §1-2 必须一句话级;`domains/<bc>.md` 单文件 ≤1500 token(超出继续拆子页)。
|
|
35
|
+
|
|
36
|
+
## 与既有加载协议的关系
|
|
37
|
+
|
|
38
|
+
- 本协议**扩展** architecture-design SKILL.md「上下文加载协议」(:166-183),不替代。
|
|
39
|
+
- 变更级 architecture-design 的输入 = 本协议 ① + ②(产品级)+ ③(变更增量);语义层(五项检查判定、评审)仍走既有流程。
|
|
40
|
+
- S3.5 产品级评审门(architecture-reviewer product 视角 A1-A6)验证产物结构满足本协议(A1 结构完备 + A2 marker/锚点可解析),保证下游可按域加载。
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
# S3.5 产品级架构设计 SOP(v0.35.0,v0.14 §59/§60)
|
|
2
|
+
|
|
3
|
+
> architecture 阶段(S3 之后、S4 之前)的执行 SOP。产出 `docs/architecture/iterations/vN/architecture.md`(预测态快照)。
|
|
4
|
+
> **owner**:architecture-design skill 的 **product 模式**子代理(唯一 owner,声明见 architecture-design/SKILL.md「独立调用」扩展)。
|
|
5
|
+
> **时序(P1)**:只写快照不写全局;change 关闭时 arch-merge 回写实际增量;迭代收尾快照标 `archived` 退役。
|
|
6
|
+
|
|
7
|
+
## 输入
|
|
8
|
+
|
|
9
|
+
- prd/vN/prd.md(frozen_downstream,功能清单 F001_P0 等)
|
|
10
|
+
- prd/vN/plan.md(高阶技术设计段:模块边界/技术选型/数据流/关键聚合划分)
|
|
11
|
+
- prototype/(S2 产物,页面结构)
|
|
12
|
+
- docs/architecture/baseline.md(S1 注入)
|
|
13
|
+
- docs/architecture/CONCEPTS.md(领域词汇)
|
|
14
|
+
- 现有全局基线(旧项目逆向重建场景)
|
|
15
|
+
|
|
16
|
+
## 8 步执行流程
|
|
17
|
+
|
|
18
|
+
> 复用 architecture-design 方法论(F1-F8 + ch01-ch06),从"每 change 增量"扩展到"全系统结构级设计"。
|
|
19
|
+
|
|
20
|
+
| 步 | 动作 | 方法论 | 产出 |
|
|
21
|
+
|----|------|--------|------|
|
|
22
|
+
| 0 | 输入梳理 | 读 PRD 功能清单 + plan 技术方向 + prototype + CONCEPTS + 现有基线 | 功能域→候选业务能力映射 |
|
|
23
|
+
| 1 | 限界上下文识别 | 功能域分组 + 词汇聚类 + 活动对象矩阵(ch04,重叠>70% 合并) | Context Map:BC 表 + 关系图(6 关系类型)+ 语言边界术语表 |
|
|
24
|
+
| 2 | 聚合识别 | 聚合四要素(ch04)+ 活动对象矩阵 | 聚合注册表(唯一事实源) |
|
|
25
|
+
| 3 | 指令与事件识别 | CQRS 指令分流(ch05:Command/Read/Query + 阻断测试)+ 事件三类 | 指令表 + 事件表 + 事件流图 + 读模型投影清单 |
|
|
26
|
+
| 4 | 聚合状态迁移 | 聚合根=状态机守卫(Vernon) | stateDiagram + 状态表(含触发源上下文、guard 不变量) |
|
|
27
|
+
| 5 | 数据模型/ER(概念级) | 从聚合映射持久化(IA)+ CQRS 写读分区 | 聚合边界 ER + 实体表 + 聚合→表映射表 |
|
|
28
|
+
| 6 | 应用时序(关键用例) | AA→TA 编排(4A) | 关键用例 Top-N 跨聚合时序图 + 用例索引 |
|
|
29
|
+
| 7 | 跨域一致性检查 | F2 双对齐(AA≥1 IA 实体)+ 语义统一 + F3 变更分叉级联 | 一致性检查表 |
|
|
30
|
+
| 8 | 反模式自检 + 评审 | DDD 反模式清单 + 产品级评审门 | 自检清单 + 评审 verdict |
|
|
31
|
+
|
|
32
|
+
**顺序纪律**:聚合在前、ER 在后(ER 是派生产物,禁止先画 ER 再定聚合);BC 边界/聚合所有权/全局契约是**产品级唯一事实源**(聚合注册表),变更级只引用。
|
|
33
|
+
|
|
34
|
+
**模板**:按 `references/s3.5-architecture-template.md` 骨架产出(6 产物 + 厚锚点 + marker + provenance)。
|
|
35
|
+
|
|
36
|
+
## 产品级评审门(Step 8)
|
|
37
|
+
|
|
38
|
+
复用 architecture-reviewer agent(`agents/architecture-reviewer.md`),以 **product 视角**审查:
|
|
39
|
+
|
|
40
|
+
| 维度 | 校验 |
|
|
41
|
+
|------|------|
|
|
42
|
+
| A1 | 结构完备(6 产物章节存在 + marker/锚点可解析,机械预检) |
|
|
43
|
+
| A2 | SQL/结构有效(机械 grep,若含 sql/) |
|
|
44
|
+
| A3 | 跨域一致性(AA↔IA 双对齐,F2 门禁) |
|
|
45
|
+
| A4 | 与 PRD 功能清单覆盖映射(F001_P0 逐条 → BC/聚合/API) |
|
|
46
|
+
| A5 | 与全局基线一致性(旧项目逆向重建产物 vs 现状代码) |
|
|
47
|
+
| A6 | conventions 合规 |
|
|
48
|
+
|
|
49
|
+
规则:≤3 轮修复循环 + 收敛检测(连续两轮不一致项不缩小 → 转人工);PASS 才进 S4。
|
|
50
|
+
**skip 时**:architecture-reviewer 不执行,但 skip 必须物化(iterations/vN/SKIPPED 标记 + 理由)。
|
|
51
|
+
|
|
52
|
+
## 正向设计 vs 逆向重建
|
|
53
|
+
|
|
54
|
+
| 维度 | 正向设计(全新/已建档) | 逆向重建(旧项目首轮) |
|
|
55
|
+
|------|------------------------|----------------------|
|
|
56
|
+
| 输入 | PRD/plan/原型(预测) | 既有代码/DDL/文档(事实) |
|
|
57
|
+
| 推导方向 | 业务能力→BC→聚合→... | 代码结构→候选 BC→聚合根候选→... |
|
|
58
|
+
| 工具 | 方法论 + LLM | recon-probe.sh + codebase-recon-analyst + arch-reverse-analyst |
|
|
59
|
+
| provenance | forward-designed | reverse-engineered + 置信度(high/medium/low) |
|
|
60
|
+
| 深度 | L0 骨架 + 触及域深化 | 同(首轮强制 L0 骨架,见 v0.14 §63.3) |
|
|
61
|
+
|
|
62
|
+
逆向重建工具:`workflow-bootstrap` 的 recon-probe.sh(--ddl-out)+ codebase-recon-analyst + 新增 `arch-reverse-analyst`(v0.14 §63.2)。
|
|
63
|
+
|
|
64
|
+
## 完成条件
|
|
65
|
+
|
|
66
|
+
- `docs/architecture/iterations/vN/architecture.md` 已产出(6 产物,provenance 标注)
|
|
67
|
+
- 产品级评审门 verdict = PASS(或 skip 已物化)
|
|
68
|
+
- orchestrator.yaml 中 ARCH 阶段状态 = completed(workflow_phase: architecture)
|
|
69
|
+
- **未触发** arch-merge 全局覆盖写(预测态不进实际态,P1)
|
|
70
|
+
|
|
71
|
+
## 常见陷阱
|
|
72
|
+
|
|
73
|
+
- **过度详设**:契约级(每 API schema/每表全字段)留给 change 落地涌现,产品级只做结构级(P4)。
|
|
74
|
+
- **skip 不物化**:跳过必须写 iterations/vN/SKIPPED + 理由,否则 S4 arch-readiness 卡死 hotfix 通道(v0.32.2 C1 死锁链同类)。
|
|
75
|
+
- **事件只识别不投影**:引入事件必须补"读模型投影清单"(§3.4),否则读模型更新无定义。
|
|
76
|
+
- **ER 先行**:先画 ER 再定聚合 = 数据库驱动设计,违背 DDD(顺序纪律)。
|
|
@@ -11,7 +11,7 @@ type: session-handoff
|
|
|
11
11
|
version: 1
|
|
12
12
|
created_at: <ISO 8601>
|
|
13
13
|
requirement_id: <req-id | null>
|
|
14
|
-
workflow_phase: <S1-S5 | change-level | null>
|
|
14
|
+
workflow_phase: <S1-S5 | architecture | change-level | null>
|
|
15
15
|
state_machine: <8态之一 | null>
|
|
16
16
|
change_dir: <path | null>
|
|
17
17
|
---
|
|
@@ -26,7 +26,7 @@ change_dir: <path | null>
|
|
|
26
26
|
### §2 工作流状态(自动检测,引用不复制)
|
|
27
27
|
|
|
28
28
|
- 活跃需求:`<req-id>` — `<title>`
|
|
29
|
-
- 产品级阶段:`<S1-S5>`(详见 `.team-flow/requirements/<req-id>/orchestrator.yaml`)
|
|
29
|
+
- 产品级阶段:`<S1-S5 | architecture>`(详见 `.team-flow/requirements/<req-id>/orchestrator.yaml`)
|
|
30
30
|
- 变更级状态:`<state>`(详见 `<change>/.team-flow.yaml`)
|
|
31
31
|
- PRD 版本:`<vN>`,冻结状态:`<frozen_downstream | frozen_absolute | unfrozen>`
|
|
32
32
|
|
|
@@ -137,6 +137,7 @@ Generate one at a time. Confirm each before next. This prevents scope drift —
|
|
|
137
137
|
|
|
138
138
|
### tasks.md
|
|
139
139
|
- `## File Structure`, `## Interfaces`, numbered tasks, exact file paths, TDD phases, ≤5 min steps, no placeholders, every requirement mapped, explicit dependencies
|
|
140
|
+
- **接口交叉核对(v0.35.0,v0.14 §61.1)**:若 `architecture/api.md` 存在,机械比对 `tasks.md` `## Interfaces` 声明的端点集合与 `api.md` 架构路由表端点集合——tasks 引用了 api.md 未声明的端点、或 api.md 声明的关键端点 tasks 未落地 → 告警修正(traceability 从自报升级为机械比对)
|
|
140
141
|
|
|
141
142
|
**If any artifact fails validation, fix before handing off to contract-builder.**
|
|
142
143
|
|