@xulthekl/team-flow 0.46.0 → 0.48.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 +3 -3
- package/.claude-plugin/plugin.json +2 -2
- package/.codex-plugin/plugin.json +1 -1
- package/.cursor-plugin/marketplace.json +2 -2
- package/.cursor-plugin/plugin.json +2 -2
- package/.github/plugin/marketplace.json +2 -2
- package/AGENTS.md +5 -4
- package/CHANGELOG.md +29 -0
- package/GEMINI.md +1 -1
- package/INSTALL.md +1 -1
- package/README.md +3 -3
- package/agents/prd-completeness-reviewer.md +22 -5
- package/agents/prd-writer.md +68 -0
- package/docs/README_en.md +1 -1
- package/docs/solutions/INDEX.md +1 -0
- package/docs/solutions/cross-phase/2026-08-21-no-summary.md +17 -0
- package/docs/usage-guide.md +1 -1
- package/gemini-extension.json +1 -1
- package/hooks/session-start +2 -2
- package/llms.txt +1 -1
- package/package.json +2 -2
- package/plugin.json +2 -2
- package/scripts/ensure-branch.mjs +94 -4
- package/scripts/lib/cmd-repo-layout.mjs +51 -0
- package/scripts/lib/config-loader.mjs +17 -1
- package/scripts/lib/conventions-generator.mjs +61 -2
- package/scripts/lib/execution-plan.mjs +10 -7
- package/scripts/lib/glaf4-delegation.mjs +64 -26
- package/scripts/team-flow.mjs +3 -0
- package/skills/ce-brainstorm/SKILL.md +11 -19
- package/skills/ce-brainstorm/references/brainstorm-sections.md +3 -11
- package/skills/ce-brainstorm/references/evidence-chain-validation.md +1 -1
- package/skills/ce-brainstorm/references/prototype-loop.md +10 -8
- package/skills/contract-builder/references/glaf4-delegation.md +6 -4
- package/skills/workflow-orchestrator/SKILL.md +8 -1
- package/skills/workflow-orchestrator/references/s2-prd-prototype-loop.md +10 -1
- package/skills/workflow-start/SKILL.md +10 -0
- package/templates/prd-brainstorm-profile.md +4 -1
- package/templates/prd.md +32 -3
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* repo-layout — 项目布局检测 CLI(multi-repo-support-design v1.0 §3)
|
|
4
|
+
*
|
|
5
|
+
* 用法:tf repo-layout detect <root> [--json]
|
|
6
|
+
* 判定项目布局(single / monorepo / multi-repo)+ 代码仓库清单,写 team-flow.config.json 的 repo_layout 段。
|
|
7
|
+
* 由 workflow-start DP-0 / orchestrator S1 项目模式确认调用;detect/review/isolate 按模式路由。
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
import { resolve } from 'node:path';
|
|
11
|
+
import { existsSync } from 'node:fs';
|
|
12
|
+
import { detectRepoLayout, writeRepoLayoutConfig } from './conventions-generator.mjs';
|
|
13
|
+
|
|
14
|
+
export async function run(args) {
|
|
15
|
+
const positionals = args.filter(a => !a.startsWith('--'));
|
|
16
|
+
const json = args.includes('--json');
|
|
17
|
+
const subcommand = positionals[0];
|
|
18
|
+
const root = positionals[1];
|
|
19
|
+
|
|
20
|
+
if (subcommand !== 'detect' || !root) {
|
|
21
|
+
console.error('Usage: tf repo-layout detect <root> [--json]');
|
|
22
|
+
process.exit(2);
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
const rootPath = resolve(root);
|
|
26
|
+
if (!existsSync(rootPath)) {
|
|
27
|
+
console.error(`❌ 项目根不存在: ${rootPath}`);
|
|
28
|
+
process.exit(1);
|
|
29
|
+
}
|
|
30
|
+
const repoLayout = detectRepoLayout(rootPath);
|
|
31
|
+
writeRepoLayoutConfig(rootPath, repoLayout);
|
|
32
|
+
|
|
33
|
+
if (json) {
|
|
34
|
+
console.log(JSON.stringify({ ok: true, ...repoLayout }));
|
|
35
|
+
} else {
|
|
36
|
+
const repoCount = Object.keys(repoLayout.repos).length;
|
|
37
|
+
console.log(`✅ repo_layout: ${repoLayout.mode}(${repoCount} 个代码仓库)`);
|
|
38
|
+
if (repoCount > 0) {
|
|
39
|
+
console.log(` 仓库清单: ${Object.keys(repoLayout.repos).join(', ')}`);
|
|
40
|
+
}
|
|
41
|
+
console.log(` config 已写 ${rootPath}/.team-flow/team-flow.config.json`);
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
// 直接运行
|
|
46
|
+
if (import.meta.url === `file://${process.argv[1]}`) {
|
|
47
|
+
run(process.argv.slice(2)).catch(err => {
|
|
48
|
+
console.error(err);
|
|
49
|
+
process.exit(1);
|
|
50
|
+
});
|
|
51
|
+
}
|
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
// Config loader for team-flow
|
|
2
2
|
// Loads team-flow.config.json and merges with built-in defaults.
|
|
3
|
-
// Lookup order: (1) projectRoot, (2) git root, (3) home directory.
|
|
3
|
+
// Lookup order: (1) projectRoot, (2) git root, (3) workspace root, (4) home directory.
|
|
4
4
|
|
|
5
5
|
import { readFileSync, existsSync } from 'node:fs';
|
|
6
6
|
import { join } from 'node:path';
|
|
7
7
|
import { execFileSync } from 'node:child_process';
|
|
8
|
+
import { detectWorkspaceRoot } from './git-utils.mjs';
|
|
8
9
|
|
|
9
10
|
const DEFAULTS = {
|
|
10
11
|
artifacts: {
|
|
@@ -35,6 +36,12 @@ const DEFAULTS = {
|
|
|
35
36
|
version: null,
|
|
36
37
|
delegation_mode: 'auto',
|
|
37
38
|
},
|
|
39
|
+
repo_layout: {
|
|
40
|
+
// 项目布局(multi-repo-support-design v1.0 §3)
|
|
41
|
+
// 项目模式确认(DP-0 / orchestrator S1)时写入;detect/review/isolate 按模式路由
|
|
42
|
+
mode: null,
|
|
43
|
+
repos: {},
|
|
44
|
+
},
|
|
38
45
|
};
|
|
39
46
|
|
|
40
47
|
export const MODEL_PROFILES = Object.freeze([
|
|
@@ -106,6 +113,15 @@ function findConfigFile(startDir) {
|
|
|
106
113
|
// Not a git repo — skip
|
|
107
114
|
}
|
|
108
115
|
|
|
116
|
+
// 3.5 multi-repo-support-design v1.0(P3 评审 #2 修复):change 目录 → 工作区根(changes/ 父目录)的 .team-flow/。
|
|
117
|
+
// 根非 git 仓库的 multi-repo 下,detect 写项目根 config 后,change 目录 loadConfig 需经此读到(findConfigFile
|
|
118
|
+
// 三级查找(changeDir→git root→home)不覆盖非 git 根的项目根 .team-flow/)。
|
|
119
|
+
const workspaceRoot = detectWorkspaceRoot(startDir);
|
|
120
|
+
if (workspaceRoot && workspaceRoot !== startDir) {
|
|
121
|
+
const wsTeamFlowDir = join(workspaceRoot, '.team-flow', 'team-flow.config.json');
|
|
122
|
+
if (existsSync(wsTeamFlowDir)) return wsTeamFlowDir;
|
|
123
|
+
}
|
|
124
|
+
|
|
109
125
|
// 4. Check home directory
|
|
110
126
|
const homePath = join(process.env.HOME || '', 'team-flow.config.json');
|
|
111
127
|
if (existsSync(homePath)) return homePath;
|
|
@@ -59,10 +59,13 @@ export function detectGlaf4DevPlugin(pluginsFilePath = PLUGINS_INSTALLED_PATH) {
|
|
|
59
59
|
* @returns {{ is_glaf4_java: boolean, glaf4_dev_available: boolean, glaf4_dev_version: string|null, delegation_mode: 'auto'|'manual'|'off' }}
|
|
60
60
|
*/
|
|
61
61
|
export function detectGlaf4Delegation(root, options = {}) {
|
|
62
|
-
const techStack = detectTechStack(root);
|
|
63
62
|
// is_glaf4_java = Java 技术栈命中(pom.xml/build.gradle 存在即可,v2.1 §4)
|
|
64
63
|
// glaf4-dev 只处理 Java,Spring/JUnit 细分由 contract-builder 已有检测负责
|
|
65
|
-
|
|
64
|
+
// multi-repo-support-design v1.0 §4.1:多仓库下按 repos 清单聚合判定——任一仓库 Java → 项目级 true
|
|
65
|
+
const repos = Array.isArray(options.repos) ? options.repos : null;
|
|
66
|
+
const isGlaf4Java = repos && repos.length > 0
|
|
67
|
+
? repos.some(r => detectTechStack(r).language === 'java')
|
|
68
|
+
: detectTechStack(root).language === 'java';
|
|
66
69
|
const plugin = detectGlaf4DevPlugin(options.pluginsFilePath);
|
|
67
70
|
const mode = options.delegationMode || 'auto';
|
|
68
71
|
return {
|
|
@@ -104,6 +107,62 @@ export function writeGlaf4DevConfig(root, glaf4DevInfo) {
|
|
|
104
107
|
writeFileSync(configPath, JSON.stringify(config, null, 2), 'utf-8');
|
|
105
108
|
}
|
|
106
109
|
|
|
110
|
+
// ── repo_layout 检测(multi-repo-support-design v1.0 §3,2026-08-21)─────────────
|
|
111
|
+
|
|
112
|
+
// 非代码仓库目录(team-flow 产物/基础设施),扫描时排除
|
|
113
|
+
const NON_REPO_DIRS = new Set([
|
|
114
|
+
'changes', '.team-flow', 'docs', 'doc', 'node_modules', '.worktrees',
|
|
115
|
+
'requirement', 'prototype', 'specs', 'data', 'path', 'template',
|
|
116
|
+
]);
|
|
117
|
+
|
|
118
|
+
/**
|
|
119
|
+
* 识别项目布局(single / monorepo / multi-repo,v1.0 §3.1)
|
|
120
|
+
* @param {string} root 项目根目录
|
|
121
|
+
* @returns {{ mode: 'single'|'monorepo'|'multi-repo', repos: Record<string,string> }}
|
|
122
|
+
*/
|
|
123
|
+
export function detectRepoLayout(root) {
|
|
124
|
+
// 1. 根直接含技术栈特征(pom.xml/package.json/build.gradle)→ single 或 monorepo(Maven 聚合/多子模块)
|
|
125
|
+
if (existsSync(join(root, 'pom.xml')) || existsSync(join(root, 'package.json')) || existsSync(join(root, 'build.gradle'))) {
|
|
126
|
+
// P3 评审 #6:子模块排除 NON_REPO_DIRS(changes/docs/data 等含 package.json 会被 scanSubProjects 误计为模块 → 误判 monorepo)
|
|
127
|
+
const subModules = scanSubProjects(root).filter(m => !NON_REPO_DIRS.has(m.name));
|
|
128
|
+
const repos = {};
|
|
129
|
+
for (const m of subModules) repos[m.name] = m.path;
|
|
130
|
+
return { mode: subModules.length > 0 ? 'monorepo' : 'single', repos };
|
|
131
|
+
}
|
|
132
|
+
// 2. 根无技术栈特征 → 扫描子目录识别独立代码仓库(含 .git 或有技术栈语言)
|
|
133
|
+
const repos = {};
|
|
134
|
+
const entries = readdirSync(root, { withFileTypes: true });
|
|
135
|
+
for (const entry of entries) {
|
|
136
|
+
if (!entry.isDirectory()) continue;
|
|
137
|
+
if (entry.name.startsWith('.') || NON_REPO_DIRS.has(entry.name)) continue;
|
|
138
|
+
const sub = join(root, entry.name);
|
|
139
|
+
const hasGit = existsSync(join(sub, '.git'));
|
|
140
|
+
const tech = detectTechStack(sub);
|
|
141
|
+
if (hasGit || tech.language) {
|
|
142
|
+
repos[entry.name] = sub;
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
const repoCount = Object.keys(repos).length;
|
|
146
|
+
return { mode: repoCount >= 2 ? 'multi-repo' : 'single', repos };
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
/**
|
|
150
|
+
* 写 repo_layout 段到 team-flow.config.json(v1.0 §3.2)
|
|
151
|
+
* @param {string} root 项目根
|
|
152
|
+
* @param {{ mode: 'single'|'monorepo'|'multi-repo', repos: Record<string,string> }} repoLayout
|
|
153
|
+
*/
|
|
154
|
+
export function writeRepoLayoutConfig(root, repoLayout) {
|
|
155
|
+
const teamFlowDir = join(root, '.team-flow');
|
|
156
|
+
const configPath = join(teamFlowDir, 'team-flow.config.json');
|
|
157
|
+
mkdirSync(teamFlowDir, { recursive: true });
|
|
158
|
+
let config = {};
|
|
159
|
+
if (existsSync(configPath)) {
|
|
160
|
+
try { config = JSON.parse(readFileSync(configPath, 'utf-8')); } catch { config = {}; }
|
|
161
|
+
}
|
|
162
|
+
config.repo_layout = repoLayout;
|
|
163
|
+
writeFileSync(configPath, JSON.stringify(config, null, 2), 'utf-8');
|
|
164
|
+
}
|
|
165
|
+
|
|
107
166
|
// ── 常量 ─────────────────────────────────────────────────────────────────────
|
|
108
167
|
|
|
109
168
|
const TEMPLATE_DIR = join(import.meta.dirname, '../../templates/conventions');
|
|
@@ -271,12 +271,12 @@ function getPhysicalReviewsDirectory(changeDir) {
|
|
|
271
271
|
let directory = changeRoot;
|
|
272
272
|
for (const component of ['.superpowers', 'sdd', 'reviews']) {
|
|
273
273
|
directory = join(directory, component);
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
throw new Error(`Review report evidence cannot read the ${component} overlay directory: ${error.message}`);
|
|
274
|
+
// multi-repo-support v1.0 §4.2(cli-command-2 修复):overlay 目录自动创建,修 ENOENT
|
|
275
|
+
// (首次 review 时 .superpowers/sdd/reviews/ 尚不存在,recordReview 写入前先建)
|
|
276
|
+
if (!existsSync(directory)) {
|
|
277
|
+
mkdirSync(directory, { recursive: true });
|
|
279
278
|
}
|
|
279
|
+
const metadata = lstatSync(directory);
|
|
280
280
|
if (metadata.isSymbolicLink() || !metadata.isDirectory()) {
|
|
281
281
|
throw new Error('Review report evidence requires physical .superpowers/sdd/reviews overlay directories');
|
|
282
282
|
}
|
|
@@ -312,8 +312,11 @@ function validateReviewRange(changeDir, base, head, repoPath) {
|
|
|
312
312
|
// This happens either through automatic fallback (subRepoPath set above)
|
|
313
313
|
// or through explicit --repo pointing to a different repository.
|
|
314
314
|
if (!subRepoPath && repoPath) {
|
|
315
|
-
|
|
316
|
-
|
|
315
|
+
// multi-repo-support v1.0 §4.2(cli-command-2 修复):--repo 场景下 change 目录可能无 git
|
|
316
|
+
//(多仓库 changes/ 未版本化),defaultRoot 比较容错返回 null,不因 change 目录无 git 报错
|
|
317
|
+
let defaultRoot = null;
|
|
318
|
+
try { defaultRoot = resolveGitRoot(changeDir); } catch {}
|
|
319
|
+
if (defaultRoot && gitRoot !== defaultRoot) subRepoPath = gitRoot;
|
|
317
320
|
}
|
|
318
321
|
|
|
319
322
|
const effectiveRoot = subRepoPath || gitRoot;
|
|
@@ -3,8 +3,10 @@
|
|
|
3
3
|
* glaf4-delegation — GLAF4 委托协议 CLI(v2.1 §6.6/§6.3/§6.7,P2 实施委托全链路)
|
|
4
4
|
*
|
|
5
5
|
* 用法:
|
|
6
|
-
* tf glaf4-delegation detect <root> [--delegation-mode <mode>] [--json]
|
|
7
|
-
* 运行时探测(v2.1 §4 接口①,C1
|
|
6
|
+
* tf glaf4-delegation detect <root> [--delegation-mode <mode>] [--target-repo <模块路径>] [--json]
|
|
7
|
+
* 运行时探测(v2.1 §4 接口①,C1 修复接线 + multi-repo-support v1.0 §4.1):
|
|
8
|
+
* root 解析(change 目录→项目根)+ 写 .team-flow/team-flow.config.json 的 glaf4_dev 段(项目根)。
|
|
9
|
+
* multi-repo 下按 repo_layout 清单聚合判定 is_glaf4_java;--target-repo 精确探测指定模块。
|
|
8
10
|
* contract-builder 产出 execution-contract 时(DP-4 前)显式调用此命令,recommend 才能读到 glaf4_dev。
|
|
9
11
|
* tf glaf4-delegation confirm <change-dir> --mode <mode> --write-set <json> [--json]
|
|
10
12
|
* DP-4 委托方案确认:mode 枚举标量入 state,write_set_boundary 落 .superpowers/glaf4/write-set.json,
|
|
@@ -28,7 +30,9 @@ import { existsSync, mkdirSync, readFileSync, readdirSync, rmSync, writeFileSync
|
|
|
28
30
|
import { join, isAbsolute, relative, resolve, normalize, sep } from 'node:path';
|
|
29
31
|
import { readState, writeState } from './state-loader.mjs';
|
|
30
32
|
import { getOverlayPaths } from './sdd-overlay.mjs';
|
|
31
|
-
import { detectGlaf4Delegation, writeGlaf4DevConfig } from './conventions-generator.mjs';
|
|
33
|
+
import { detectGlaf4Delegation, detectTechStack, writeGlaf4DevConfig } from './conventions-generator.mjs';
|
|
34
|
+
import { detectWorkspaceRoot, getGitRoot } from './git-utils.mjs';
|
|
35
|
+
import { loadConfig } from './config-loader.mjs';
|
|
32
36
|
|
|
33
37
|
// DP-4 委托模式合法枚举(对应 glaf4-dev 七模式中可委托 change 的六种)
|
|
34
38
|
export const GLAF4_DELEGATION_MODES = [
|
|
@@ -72,26 +76,42 @@ export function hashWriteSet(writeSet) {
|
|
|
72
76
|
* @param {string} [delegationMode] 覆盖 delegation_mode(auto/manual/off)
|
|
73
77
|
* @returns {object} { ok, is_glaf4_java, glaf4_dev_available, glaf4_dev_version, delegation_mode, configPath }
|
|
74
78
|
*/
|
|
75
|
-
export function detectAndWriteConfig(root, delegationMode) {
|
|
76
|
-
|
|
79
|
+
export function detectAndWriteConfig(root, delegationMode, targetRepo) {
|
|
80
|
+
// multi-repo-support-design v1.0 §4.1(cli-command-1 修复):root 解析——change 目录(含 changes/)→ 项目根;否则 git 根
|
|
81
|
+
const projectRoot = resolveProjectRoot(root);
|
|
82
|
+
|
|
83
|
+
// 读 repo_layout(config 已固化时)
|
|
84
|
+
const config = loadConfig(projectRoot);
|
|
85
|
+
const repoLayout = config?.repo_layout || null;
|
|
86
|
+
|
|
87
|
+
// 探测目标构造(P3 自查补全 + P4 validator W1 放宽,2026-08-21):
|
|
88
|
+
// --target-repo 精确 > repo_layout 清单聚合(repos 非空即聚合,不限 multi-repo——
|
|
89
|
+
// 壳仓库含 package.json 误判 monorepo 时也应聚合,否则 cli-command-1 在真实项目失效)>
|
|
90
|
+
// root 有技术栈(探测 root,如 detect(svcA))>
|
|
91
|
+
// root 无技术栈(change 文档目录/容器根)→ 探测解析后项目根(单仓库项目根有 pom.xml)
|
|
92
|
+
let repos = null;
|
|
93
|
+
let probeRoot = root;
|
|
94
|
+
if (targetRepo) {
|
|
95
|
+
probeRoot = targetRepo;
|
|
96
|
+
} else if (repoLayout?.repos && Object.keys(repoLayout.repos).length > 0) {
|
|
97
|
+
repos = Object.values(repoLayout.repos);
|
|
98
|
+
} else if (!detectTechStack(root).language) {
|
|
99
|
+
probeRoot = projectRoot;
|
|
100
|
+
}
|
|
101
|
+
const detection = detectGlaf4Delegation(probeRoot, { delegationMode, repos });
|
|
77
102
|
|
|
78
|
-
//
|
|
79
|
-
// loadConfig(changeDir) 只查 changeDir→git root→home,不查 target_root → 委托链静默断裂。
|
|
80
|
-
// 写 git root 冗余副本保证从任意 changeDir 都能读到探测结果。gitRoot 提前解析供 mode 优先级使用。
|
|
103
|
+
// git root(冗余副本判断 + mode 优先级)
|
|
81
104
|
let gitRoot = null;
|
|
82
105
|
try {
|
|
83
|
-
gitRoot =
|
|
84
|
-
cwd: root, encoding: 'utf-8', stdio: ['pipe', 'pipe', 'pipe'],
|
|
85
|
-
}).trim();
|
|
106
|
+
gitRoot = getGitRoot(projectRoot);
|
|
86
107
|
} catch {
|
|
87
108
|
// 非 git 仓库,跳过
|
|
88
109
|
}
|
|
89
110
|
|
|
90
|
-
//
|
|
91
|
-
// 上轮只查目标 root,非 Java 服务无本地 config → 默认 auto → 覆盖 git root 副本的 off(用户 off 意图被静默翻转)。
|
|
111
|
+
// delegation_mode 优先级链:显式 > 目标 root 已有 > git root 已有 > auto
|
|
92
112
|
let effectiveMode = delegationMode;
|
|
93
113
|
if (!effectiveMode) {
|
|
94
|
-
effectiveMode = readGlaf4DelegationMode(
|
|
114
|
+
effectiveMode = readGlaf4DelegationMode(projectRoot)
|
|
95
115
|
|| (gitRoot ? readGlaf4DelegationMode(gitRoot) : null)
|
|
96
116
|
|| 'auto';
|
|
97
117
|
}
|
|
@@ -100,16 +120,17 @@ export function detectAndWriteConfig(root, delegationMode) {
|
|
|
100
120
|
version: detection.glaf4_dev_version,
|
|
101
121
|
delegationMode: effectiveMode,
|
|
102
122
|
};
|
|
103
|
-
|
|
123
|
+
// config 主副本写项目根(cli-command-1 修复:不再写 change 目录)
|
|
124
|
+
// multi-repo-support v1.0:OR 聚合保留已有 enabled=true——项目级 GLAF4 能力一旦声明,
|
|
125
|
+
// 不因后续非 Java 目标探测而覆盖丢失(非 Java change detect 不应禁用项目委托)
|
|
126
|
+
const existingProjEnabled = readGitRootGlaf4Enabled(projectRoot);
|
|
127
|
+
const projEnabled = info.enabled || existingProjEnabled;
|
|
128
|
+
writeGlaf4DevConfig(projectRoot, { ...info, enabled: projEnabled, delegationMode: effectiveMode });
|
|
104
129
|
|
|
105
130
|
let gitRootConfig = null;
|
|
106
|
-
if (gitRoot && gitRoot !==
|
|
107
|
-
// 第三轮复评 Important①(2026-08-18):多服务混合 monorepo 下 git root 副本 last-write-wins 污染——
|
|
108
|
-
// 非 Java 服务 detect 会把 Java 服务的 enabled=true 覆盖成 false。改为 OR 聚合:
|
|
109
|
-
// 项目级能力一旦声明(任一服务 enabled=true),不因后续非 Java 服务探测而丢失。
|
|
131
|
+
if (gitRoot && gitRoot !== projectRoot) {
|
|
110
132
|
const existingEnabled = readGitRootGlaf4Enabled(gitRoot);
|
|
111
133
|
const aggregatedEnabled = info.enabled || existingEnabled;
|
|
112
|
-
// 第四轮复评:git root 副本 mode 保留已有值(显式传参才覆盖)——用户 off 意图不因新探测静默翻转。
|
|
113
134
|
const gitRootMode = readGlaf4DelegationMode(gitRoot);
|
|
114
135
|
const gitRootEffectiveMode = delegationMode || gitRootMode || effectiveMode;
|
|
115
136
|
writeGlaf4DevConfig(gitRoot, { ...info, enabled: aggregatedEnabled, delegationMode: gitRootEffectiveMode });
|
|
@@ -119,11 +140,27 @@ export function detectAndWriteConfig(root, delegationMode) {
|
|
|
119
140
|
return {
|
|
120
141
|
ok: true,
|
|
121
142
|
...detection,
|
|
122
|
-
configPath: join(
|
|
143
|
+
configPath: join(projectRoot, '.team-flow', 'team-flow.config.json'),
|
|
123
144
|
gitRootConfig,
|
|
145
|
+
projectRoot,
|
|
124
146
|
};
|
|
125
147
|
}
|
|
126
148
|
|
|
149
|
+
/**
|
|
150
|
+
* root 解析(multi-repo-support-design v1.0 §4.1):change 目录(含 changes/)→ 项目根;否则 git 根;兜底直接用 root
|
|
151
|
+
* @param {string} root
|
|
152
|
+
* @returns {string}
|
|
153
|
+
*/
|
|
154
|
+
function resolveProjectRoot(root) {
|
|
155
|
+
const ws = detectWorkspaceRoot(root);
|
|
156
|
+
if (ws) return ws;
|
|
157
|
+
try {
|
|
158
|
+
return getGitRoot(root);
|
|
159
|
+
} catch {
|
|
160
|
+
return root;
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
|
|
127
164
|
/**
|
|
128
165
|
* 读 git root 现有 config 的 glaf4_dev.enabled(第三轮复评 Important① OR 聚合用)
|
|
129
166
|
* @param {string} gitRoot
|
|
@@ -394,7 +431,7 @@ export function resetDelegation(changeDir) {
|
|
|
394
431
|
|
|
395
432
|
export async function run(args) {
|
|
396
433
|
const positionals = args.filter(a => !a.startsWith('--'));
|
|
397
|
-
const flags = new Set(args.filter(a => a.startsWith('--') && a !== '--mode' && a !== '--write-set' && a !== '--run-dir' && a !== '--target-root' && a !== '--json'));
|
|
434
|
+
const flags = new Set(args.filter(a => a.startsWith('--') && a !== '--mode' && a !== '--write-set' && a !== '--run-dir' && a !== '--target-root' && a !== '--target-repo' && a !== '--delegation-mode' && a !== '--json'));
|
|
398
435
|
const opt = (name) => {
|
|
399
436
|
const i = args.indexOf(`--${name}`);
|
|
400
437
|
return i >= 0 ? args[i + 1] : undefined;
|
|
@@ -404,7 +441,7 @@ export async function run(args) {
|
|
|
404
441
|
const json = flags.has('--json') || args.includes('--json');
|
|
405
442
|
|
|
406
443
|
const usage = `Usage:
|
|
407
|
-
tf glaf4-delegation detect <root> [--delegation-mode <auto|manual|off>]
|
|
444
|
+
tf glaf4-delegation detect <root> [--delegation-mode <auto|manual|off>] [--target-repo <模块路径>]
|
|
408
445
|
tf glaf4-delegation confirm <change-dir> --mode <mode> --write-set <json-file>
|
|
409
446
|
tf glaf4-delegation verify-write-set <change-dir> --run-dir <run-dir>
|
|
410
447
|
tf glaf4-delegation verify-tasks <change-dir>
|
|
@@ -424,15 +461,16 @@ export async function run(args) {
|
|
|
424
461
|
try {
|
|
425
462
|
if (subcommand === 'detect') {
|
|
426
463
|
const mode = opt('delegation-mode');
|
|
464
|
+
const targetRepo = opt('target-repo');
|
|
427
465
|
// 第四轮复评 Minor-1(2026-08-18):枚举校验——非法值(如 'foo')等同 auto 放行会让用户配置失真
|
|
428
466
|
if (mode !== undefined && !['auto', 'manual', 'off'].includes(mode)) {
|
|
429
467
|
console.error(`--delegation-mode 必须为 auto/manual/off 之一(实际: ${mode})`);
|
|
430
468
|
process.exit(2);
|
|
431
469
|
}
|
|
432
|
-
const result = detectAndWriteConfig(changeDir, mode);
|
|
470
|
+
const result = detectAndWriteConfig(changeDir, mode, targetRepo);
|
|
433
471
|
const msg = result.glaf4_dev_available
|
|
434
|
-
? `探测: is_glaf4_java=${result.is_glaf4_java}, glaf4-dev v${result.glaf4_dev_version} 可用, delegation_mode=${result.delegation_mode} → config 已写 ${result.configPath}`
|
|
435
|
-
: `探测: is_glaf4_java=${result.is_glaf4_java}, glaf4-dev 不可用 → config 已写 ${result.configPath}`;
|
|
472
|
+
? `探测: is_glaf4_java=${result.is_glaf4_java}, glaf4-dev v${result.glaf4_dev_version} 可用, delegation_mode=${result.delegation_mode} → config 已写 ${result.configPath}${result.projectRoot ? `(项目根 ${result.projectRoot})` : ''}`
|
|
473
|
+
: `探测: is_glaf4_java=${result.is_glaf4_java}, glaf4-dev 不可用 → config 已写 ${result.configPath}${result.projectRoot ? `(项目根 ${result.projectRoot})` : ''}`;
|
|
436
474
|
print(result.ok, result, msg);
|
|
437
475
|
} else if (subcommand === 'confirm') {
|
|
438
476
|
const mode = opt('mode');
|
package/scripts/team-flow.mjs
CHANGED
|
@@ -42,6 +42,7 @@ const COMMANDS = {
|
|
|
42
42
|
'test-matrix-export': () => import('./lib/test-matrix-export.mjs'),
|
|
43
43
|
'glaf4-evidence-export': () => import('./lib/glaf4-evidence-export.mjs'),
|
|
44
44
|
'glaf4-delegation': () => import('./lib/glaf4-delegation.mjs'),
|
|
45
|
+
'repo-layout': () => import('./lib/cmd-repo-layout.mjs'),
|
|
45
46
|
test: () => import('./lib/test-record.mjs'),
|
|
46
47
|
};
|
|
47
48
|
|
|
@@ -76,6 +77,8 @@ Commands:
|
|
|
76
77
|
Aggregate glaf4-dev run PASS evidence → surefire line (v2.1 §7; feed test record --from)
|
|
77
78
|
glaf4-delegation <sub> <dir> [--mode <m> --write-set <json> | --run-dir <run> | --delegation-mode <mode>]
|
|
78
79
|
GLAF4 委托协议 (v2.1 §4/6.3/6.6/6.7): detect / confirm / verify-write-set / verify-tasks / record-partial / reset
|
|
80
|
+
repo-layout detect <root>
|
|
81
|
+
Detect project layout (single/monorepo/multi-repo) + code repos, write repo_layout config (v1.0 §3)
|
|
79
82
|
test record <dir> --from <runner-output> [--runner auto|maven-surefire|jest|pytest]
|
|
80
83
|
Record programmatic test evidence (v0.13 §50; feeds tests-passing gate)
|
|
81
84
|
config [options] Display or modify configuration
|
|
@@ -19,7 +19,7 @@ Brainstorming answers **WHAT** to build through collaborative dialogue, producin
|
|
|
19
19
|
|
|
20
20
|
> **显式参数规约**:orchestrator 调用时必须传入 `mode: orchestrated`。ce-brainstorm 检测到该参数即跳过 Phase 3.5 并在输出中回执"原型循环已委托编排层"。未收到该参数时默认为 standalone 模式。
|
|
21
21
|
>
|
|
22
|
-
> **重要:`orchestrated` 模式仅跳过 Phase 3.5(原型内循环)。Phase 0(含 PRD 模板选择)、Phase 1(含 1.4/1.5/1.6)、Phase 2、Phase 3、QA-4、Phase 3.6、版本归档均正常执行,不可跳过。**
|
|
22
|
+
> **重要:`orchestrated` 模式仅跳过 Phase 3.5(原型内循环)。Phase 0(含 PRD 模板选择)、Phase 1(含 1.3b/1.4/1.5/1.6)、Phase 2、Phase 3、QA-4、Phase 3.6、版本归档均正常执行,不可跳过。**
|
|
23
23
|
|
|
24
24
|
## Core Principles
|
|
25
25
|
|
|
@@ -40,12 +40,12 @@ Brainstorming answers **WHAT** to build through collaborative dialogue, producin
|
|
|
40
40
|
| 职责 | 执行方 | 说明 |
|
|
41
41
|
|------|--------|------|
|
|
42
42
|
| 需求澄清、场景确认、流程确认、方案决策 | **主会话** | 需要用户交互和判断的工作 |
|
|
43
|
-
| PRD 文档撰写(Phase 3) |
|
|
43
|
+
| PRD 文档撰写(Phase 3) | **prd-writer agent**(v0.47) | 执行性文档生成(契约级 §8.4),主会话做 QA 和冻结 |
|
|
44
44
|
| 流程图绘制(mermaid) | **子代理**(推荐) | 基于已确认的流程数据生成图表 |
|
|
45
45
|
| 活动表批量生成 | **子代理**(推荐) | 基于已确认的 L4 子流程生成表格 |
|
|
46
46
|
| 综合报告(synthesis summary) | **子代理**(可选) | 大量数据的汇总整理 |
|
|
47
47
|
|
|
48
|
-
**子代理委托方式**:使用 `Agent` 工具(`context: fork` 或自定义 agent),将已确认的结构化数据作为输入,要求子代理按模板产出。主会话审查产出后决定接受或修正。
|
|
48
|
+
**子代理委托方式**:使用 `Agent` 工具(`context: fork` 或自定义 agent),将已确认的结构化数据作为输入,要求子代理按模板产出。主会话审查产出后决定接受或修正。PRD 撰写(Phase 3)固定委托命名 agent **prd-writer**(预加载 ce-brainstorm,只执行 Phase 3、不提问);其余执行性产出(流程图/活动表/综合报告)可委托通用子代理。
|
|
49
49
|
|
|
50
50
|
### Stage Breakpoints
|
|
51
51
|
|
|
@@ -155,6 +155,8 @@ For detailed routing logic, read `references/phase0-routing.md`. Summary:
|
|
|
155
155
|
|
|
156
156
|
**1.3 Dialogue** — Follow Interaction Rules. Fire blindspot gate (if tripwire armed) and visual-probe gate (before first shape decision). Rigor probes fire as open-ended questions before Phase 2. Before exit: integration check for non-obvious consequences. **Exit when**: primary actor, outcome, scope, success criteria all known or recorded as assumptions.
|
|
157
157
|
|
|
158
|
+
**1.3b 功能细节澄清(v0.47)** — Follow the brainstorm profile's「功能细节(契约级)」core dimension. Standard/Deep scope **强制契约级澄清**(UI 布局/字段/交互/异常/权限;非 UI 触发/输入输出/处理/异常/幂等并发/性能),Lightweight 简化。产出 **detail_ledger**(`requirement/vN/detail-ledger.md`,逐功能维度 → 已澄清/待澄清/NA),供 Phase 3 §8.4 撰写 + 冻结前 D6 核对。
|
|
159
|
+
|
|
158
160
|
**1.4 Dialogue Log Persistence** — Automated step, no user interaction. Trigger: Phase 1.3 dialogue exits. Traverse each Q&A round extracting original text + decisions, generate dialogue summary and decision summary table. Write to `requirement/vN/dialogue-log.md` (create or append). No ledger update.
|
|
159
161
|
|
|
160
162
|
**1.5 Business Scenario Analysis** — Read `references/business-scenarios.md` for methodology. Trigger: Phase 1.4 completed. Extract business scenarios from dialogue and context, produce QA-1 quality check, then **blocking question** for user confirmation. Output: `requirement/vN/business-analysis.md` (requirements + scenarios sections). Status marked 🔵 pending confirmation, ✅ confirmed on user approval. No ledger update at this stage.
|
|
@@ -191,34 +193,23 @@ Propose **2-3 approaches** (or recommend directly if one is clearly best). Use n
|
|
|
191
193
|
- `requirement/ledger.md` — all requirement/scenario/process items and their associations
|
|
192
194
|
- `requirement/vN/dialogue-log.md` — §1.2 revision record reference path
|
|
193
195
|
- `requirement/vN/business-analysis.md` — data source for §2/§3/§7/§8
|
|
196
|
+
- `requirement/vN/detail-ledger.md` — 功能细节澄清产出(v0.47),§8.4 逐功能详述数据源 + D6 核对基准
|
|
194
197
|
|
|
195
198
|
**⛔ MANDATORY:生成PRD文档前,必须先读取 `references/brainstorm-sections.md`**
|
|
196
199
|
|
|
197
|
-
**§8.4
|
|
198
|
-
- **详细程度**:保留原始需求文档中的关键细节,不要过度概括
|
|
199
|
-
- **必须保留的内容**:
|
|
200
|
-
- 页面布局(上下分栏、标准列表等)
|
|
201
|
-
- 搜索模块(具体字段)
|
|
202
|
-
- 表格列定义(完整字段列表)
|
|
203
|
-
- 交互规则(默认选中、点击切换、筛选联动等)
|
|
204
|
-
- 按领域动态字段(如有)
|
|
205
|
-
- 动态列名说明
|
|
206
|
-
- 操作说明(已发布/草稿状态等)
|
|
207
|
-
- 级联选择逻辑(如有)
|
|
208
|
-
- **⛔ 错误行为**:只提取输入/输出/业务规则,丢失原始需求文档中的大量关键细节
|
|
209
|
-
- **⛔ 正确行为**:充分利用原始需求文档的详细内容,保持信息完整性
|
|
200
|
+
**§8.4 功能模块提取规则(v0.47)**:规范唯一权威 = 模板 `templates/prd.md` §8.4「必含维度检查清单」(UI 11 维 / 非 UI 7 维双形态 + NA 机制),**本处不再重复维护维度清单**。生成 PRD 前必须读取模板检查清单,逐功能模块按适用维度详述;维度不适用标注 `NA + 理由`;**未标注 NA 且未覆盖 = 缺失**。
|
|
210
201
|
|
|
211
202
|
Read `references/brainstorm-sections.md` for doc-warranted criteria. If warranted: read template from `PRD_TEMPLATE_PATH`, fill via `references/prd-mapping.md`, write to `requirement/{ITERATION_VERSION}/prd.md`. Vocabulary capture: update `CONCEPTS.md` with resolved domain terms (only if it exists).
|
|
212
203
|
|
|
213
|
-
>
|
|
204
|
+
> **子代理委托(v0.47)**:Phase 3 PRD 撰写委托 **prd-writer** agent。主会话将已确认结构化数据(business-analysis.md + dialogue-log.md + **detail_ledger** + synthesis summary + template_path)作为参数传入;prd-writer 按模板 §8.4 契约级检查清单逐功能详述,不提问、不虚构,`missing_info` 返回主会话决定是否回 Phase 1.3 补澄清。主会话负责 QA-4 审查和冻结确认。
|
|
214
205
|
|
|
215
206
|
### Phase 3.5: Prototype Inner Loop
|
|
216
207
|
|
|
217
|
-
**`orchestrated` mode skips this phase.** For standalone: read `references/prototype-loop.md`. Trigger: PRD
|
|
208
|
+
**`orchestrated` mode skips this phase.** For standalone: read `references/prototype-loop.md`. Trigger: PRD 有 UI 功能则执行原型循环;**完整性评审(§3.5.5)对 standalone 全路径适用**(含非 UI / 跳过原型路径,不因无 UI 而跳过)。Steps: produce prototype → review vs PRD → fix loop (max 3) → completeness review → freeze PRD.
|
|
218
209
|
|
|
219
210
|
### QA-4: PRD Quality Check
|
|
220
211
|
|
|
221
|
-
Fires after Phase 3 (or Phase 3.5 if prototype loop ran). Read `references/evidence-chain-validation.md` for QA-4 criteria. Evaluates PRD completeness and traceability against business analysis artifacts.
|
|
212
|
+
Fires after Phase 3 (or Phase 3.5 if prototype loop ran). Read `references/evidence-chain-validation.md` for QA-4 criteria. Evaluates PRD completeness and traceability against business analysis artifacts. **冻结前完整性评审(6 维,含 §8.4 契约级细节 D6)的派发点已归并**:standalone 路径由 Phase 3.5(`references/prototype-loop.md` §3.5.5)派发 prd-completeness-reviewer;orchestrated 路径由 orchestrator S2 派发(见 `workflow-orchestrator/references/s2-prd-prototype-loop.md`);**QA-4 自身不重复派发**,仅按评审结果判定是否回 Phase 1.3/Phase 3 修订。
|
|
222
213
|
|
|
223
214
|
### Phase 3.6: PRD ↔ Scenario/Process Bidirectional Validation
|
|
224
215
|
|
|
@@ -250,6 +241,7 @@ requirement/
|
|
|
250
241
|
├── vN/ # Iteration version
|
|
251
242
|
│ ├── prd.md # PRD document
|
|
252
243
|
│ ├── dialogue-log.md # Dialogue log (Phase 1.4 output)
|
|
244
|
+
│ ├── detail-ledger.md # 功能细节澄清产出(v0.47,§8.4 数据源 + D6 核对基准)
|
|
253
245
|
│ └── business-analysis.md # Business analysis (requirements + scenarios + processes)
|
|
254
246
|
doc/
|
|
255
247
|
└── active-registry/
|
|
@@ -267,17 +267,9 @@ as template placeholder.
|
|
|
267
267
|
所属流程 (BP-xxx). Skip §8.3 (hardware/network) and §8.5 (non-functional)
|
|
268
268
|
unless the brainstorm explicitly covered these.
|
|
269
269
|
|
|
270
|
-
**§8.4
|
|
271
|
-
-
|
|
272
|
-
-
|
|
273
|
-
- 页面布局(上下分栏、标准列表等)
|
|
274
|
-
- 搜索模块(具体字段)
|
|
275
|
-
- 表格列定义(完整字段列表)
|
|
276
|
-
- 交互规则(默认选中、点击切换、筛选联动等)
|
|
277
|
-
- 按领域动态字段(如有)
|
|
278
|
-
- 动态列名说明
|
|
279
|
-
- 操作说明(已发布/草稿状态等)
|
|
280
|
-
- 级联选择逻辑(如有)
|
|
270
|
+
**§8.4 功能模块提取规则(v0.47)**:
|
|
271
|
+
- **规范权威**:模板 `templates/prd.md` §8.4「必含维度检查清单」是唯一权威(UI 11 维/非 UI 7 维双形态 + NA 机制),本文件不再重复维护维度清单。撰写(prd-writer)与审查(prd-completeness-reviewer D6)均以模板为基准。
|
|
272
|
+
- **详细程度**:保留原始需求文档中的关键细节,不要过度概括(页面布局/搜索字段/表格列/交互规则/动态字段/级联逻辑等——逐项见模板检查清单)
|
|
281
273
|
- **错误行为**:只提取输入/输出/业务规则,丢失原始需求文档中的大量关键细节
|
|
282
274
|
- **正确行为**:充分利用原始需求文档的详细内容,保持信息完整性
|
|
283
275
|
|
|
@@ -16,7 +16,7 @@ This reference covers three connected operations after PRD generation: QA-4 qual
|
|
|
16
16
|
| C5 | Consistency | PRD §2 process overview table matches business-analysis.md process list? | Error |
|
|
17
17
|
| C6 | Consistency | PRD §3 process descriptions match business-analysis.md process details? | Error |
|
|
18
18
|
| C7 | Metadata | PRD frontmatter complete (title / project_name / iteration_version / date / prd_template)? | Warning |
|
|
19
|
-
| C8 |
|
|
19
|
+
| C8 | Detail | §8.4 契约级细节:逐功能模块按模板检查清单覆盖适用维度(UI 11 维/非 UI 7 维,单一权威 = 模板 §8.4)+ §7↔§8.4 交叉核对无悬空功能(v0.47 并入 D6 模型:核心维度缺失/悬空 = Critical,辅助维度缺失 = Important) | Critical |
|
|
20
20
|
|
|
21
21
|
**Verdict rule:** All Error-level checks pass → PASS. Any Error fails → FAIL. Warnings are reported but do not block.
|
|
22
22
|
|
|
@@ -9,8 +9,8 @@ PRD 文档写入后、Handoff 之前,执行原型内循环。原型是 PRD 的
|
|
|
9
9
|
检查 PRD 草稿中是否包含 UI/画面/交互相关功能点(§4 画面原型、§7 系统功能清单中的 UI 功能)。
|
|
10
10
|
|
|
11
11
|
- **包含 UI 功能点** → 使用平台阻塞问题工具询问用户:"PRD 包含 UI 功能点,是否需要产出原型进行验证?"
|
|
12
|
-
- **不包含 UI 功能点** →
|
|
13
|
-
- **用户选择跳过** →
|
|
12
|
+
- **不包含 UI 功能点** → 跳过原型内循环,**先走 §3.5.5 PRD 完整性评审,再冻结(§3.5.6,跳过 prototype-review.md 写入)**,进入 Phase 4
|
|
13
|
+
- **用户选择跳过** → 跳过原型,**先走 §3.5.5 PRD 完整性评审**,再冻结
|
|
14
14
|
|
|
15
15
|
## 3.5.2 原型产出
|
|
16
16
|
|
|
@@ -37,19 +37,21 @@ PRD 文档写入后、Handoff 之前,执行原型内循环。原型是 PRD 的
|
|
|
37
37
|
- **最多循环 3 次**,超过则标记为"需人工介入",在 PRD 中记录未解决项
|
|
38
38
|
- 每次修正触发复利捕获:`tf solutions capture --phase prd --domain <domain> --type pitfall --severity medium --summary "<修正原因>"`
|
|
39
39
|
|
|
40
|
-
## 3.5.5 PRD
|
|
40
|
+
## 3.5.5 PRD 完整性评审(冻结前门禁,v0.47 全路径适用)
|
|
41
41
|
|
|
42
|
-
|
|
42
|
+
**所有 standalone 路径的冻结前必过门禁**:有原型(原型审查通过后)、无 UI 功能点(§3.5.1)、用户跳过原型(§3.5.1)三条路径均须派发——不因跳过原型循环而跳过完整性评审(orchestrated 路径对应 `s2-prd-prototype-loop.md` step 3.5)。
|
|
43
43
|
|
|
44
|
-
|
|
44
|
+
派发 `prd-completeness-reviewer` 子代理(独立上下文),评审 PRD「是否完整到能支撑后续 plan/spec 实施」(区别于 Phase 2.6 claim verifier——后者管"说得对不对",本评审管"说得全不全")。
|
|
45
|
+
|
|
46
|
+
- 派发:按名派发插件 agent `prd-completeness-reviewer`(定义见插件 `agents/prd-completeness-reviewer.md`),传入 `prd_path` + `concepts_path`(可选)+ `template_path`(默认 `templates/prd.md`)+ `detail_ledger_path`(如有)。
|
|
45
47
|
- agent 直接写审查报告到 `requirement/{ITERATION_VERSION}/prd-completeness-review.md`。
|
|
46
|
-
- 判定(柔性):PASS / PASS_WITH_WARNINGS → 进入冻结;**FAIL(Critical>0)→ 回 Phase 1.3 补充**后重审。
|
|
47
|
-
-
|
|
48
|
+
- 判定(柔性):PASS / PASS_WITH_WARNINGS → 进入冻结;**FAIL(Critical>0)→ 回 Phase 1.3/Phase 3 补充**后重审。
|
|
49
|
+
- 6 维度:用户故事完整性(Critical)/验收标准(Critical)/边界与非功能(Important)/术语一致性(Minor)/范围闭环(Important)/§8.4 契约级细节(核心维度缺失·悬空功能=Critical,辅助维度缺失=Important)。
|
|
48
50
|
|
|
49
51
|
## 3.5.6 冻结
|
|
50
52
|
|
|
51
53
|
完整性评审通过后:
|
|
52
|
-
1. 写入 `requirement/{ITERATION_VERSION}/prototype-review.md`(审查结论 + 版本 + 日期 +
|
|
54
|
+
1. 写入 `requirement/{ITERATION_VERSION}/prototype-review.md`(审查结论 + 版本 + 日期 + 循环次数;**无原型路径跳过本步**,完整性评审结论已落盘 `prd-completeness-review.md`)
|
|
53
55
|
2. PRD 标记为 frozen(在 PRD frontmatter 中增加 `frozen: true` + `frozen_date: YYYY-MM-DD`),并在正文标题下插入冻结声明(措辞见 `references/prd-mapping.md`「冻结声明」节)
|
|
54
56
|
3. **冻结语义为 `frozen_downstream`(非升版)**:后续阶段(ce-plan、spec-writer)**不可直接回改** PRD;如 plan 或实施暴露 scope 问题,经 **S3→S2 回退在 vN 内修订**并记录「决策与变更履历」(不升版)。**仅当启动新迭代 vN+1 或用户显式绝对冻结(`frozen: absolute`)时才需升版。**
|
|
55
57
|
4. 同步更新正文 §1.1 文档状态为「已冻结-下游」(与 frontmatter `frozen: true` 一致)
|
|
@@ -9,17 +9,19 @@
|
|
|
9
9
|
contract-builder 产出 execution-contract 时(DP-4 前)实时探测——**显式运行 CLI 命令**(第三轮复评接线统一:探测必须写 config,纯库函数不落盘):
|
|
10
10
|
|
|
11
11
|
```bash
|
|
12
|
-
tf glaf4-delegation detect <target_root> [--delegation-mode <auto|manual|off>]
|
|
12
|
+
tf glaf4-delegation detect <target_root> [--delegation-mode <auto|manual|off>] [--target-repo <模块路径>]
|
|
13
13
|
```
|
|
14
14
|
|
|
15
|
+
**target_root 语义(multi-repo-support-design v1.0 §4.1,cli-command-1 修复)**:传入**项目根或 change 目录均可**——detect 自动解析:change 目录(含 `changes/`)→ 项目根,config 主副本写**项目根** `.team-flow/team-flow.config.json`(不写 change 目录)。**多仓库项目(`repo_layout: multi-repo`)推荐传 `--target-repo <模块路径>`**(如 change 涉及 `batch-fytx-msg`),或依赖自动扫描:按 `repo_layout.repos` 清单聚合判定——任一代码仓库是 Java → 项目级 `is_glaf4_java=true`。
|
|
16
|
+
|
|
15
17
|
`detect` 内部调用 `conventions-generator.mjs` 的 `detectGlaf4Delegation(root)` 解析 `~/.claude/plugins/installed_plugins.json`(glaf4-dev 条目含 installPath + version),产出三态:
|
|
16
18
|
|
|
17
|
-
- `is_glaf4_java`(技术栈命中:pom.xml/build.gradle + Spring Boot/JUnit5/Mockito
|
|
19
|
+
- `is_glaf4_java`(技术栈命中:pom.xml/build.gradle + Spring Boot/JUnit5/Mockito;**多仓库下按 repos 清单聚合,任一仓库 Java → true**)
|
|
18
20
|
- `glaf4_dev_available`(插件可用,含 version)
|
|
19
21
|
- `delegation_mode`(auto/manual/off,用户可开关)
|
|
20
22
|
|
|
21
|
-
探测结果写
|
|
22
|
-
(git root ≠ target_root 时写 git root
|
|
23
|
+
探测结果写 `<项目根>/.team-flow/team-flow.config.json` 的 `glaf4_dev: {enabled, version, delegation_mode}` 段
|
|
24
|
+
(git root ≠ target_root 时写 git root 冗余副本;未传 `--delegation-mode` 保留已有值)。
|
|
23
25
|
|
|
24
26
|
**判定**:`is_glaf4_java && glaf4_dev_available && delegation_mode !== 'off'` → 产出 GLAF4 Delegation 段。
|
|
25
27
|
**依赖**:`recommendExecutionModesForChange` 读 `config.glaf4_dev.enabled` 决定是否注入 glaf4-delegation——**必须**先跑 detect 写 config,否则委托链不可达。
|
|
@@ -42,6 +42,13 @@ Do NOT invoke for:
|
|
|
42
42
|
**conventions 注入(v0.11 §33)**:
|
|
43
43
|
- 读取 conventions 配置,注入为需求分析上下文
|
|
44
44
|
|
|
45
|
+
**项目模式确认(multi-repo-support-design v1.0 §3.3,2026-08-21)**:S1 路由时确认项目布局,写 config 供 detect/review/isolate 按模式路由——
|
|
46
|
+
1. 定位项目根(`detectWorkspaceRoot` / `getGitRoot`);`<项目根>/.team-flow/team-flow.config.json` 已有 `repo_layout` 段 → 直接读取(已固化跳过)
|
|
47
|
+
2. 否则运行 `tf repo-layout detect <项目根>`:判定 `single`/`monorepo`/`multi-repo` + 代码仓库清单,写 `<项目根>/.team-flow/team-flow.config.json` 的 `repo_layout` 段
|
|
48
|
+
3. 多仓库项目向用户展示判定结果(AskUserQuestion 确认);单仓库自动;修正 repos 清单编辑 config 的 `repo_layout.repos`
|
|
49
|
+
4. 影响:detect(按仓库清单探测 GLAF4)/ review(`--repo` 放宽 git 约束)/ isolate(共享分支检测)
|
|
50
|
+
5. 边界:本步骤识别存量结构;全新项目骨架引导归 workflow-bootstrap B1.5
|
|
51
|
+
|
|
45
52
|
### S2: PRD + 原型阶段
|
|
46
53
|
|
|
47
54
|
**⛔ MANDATORY:执行S2阶段前,必须先读取 `references/s2-prd-prototype-loop.md`**
|
|
@@ -66,7 +73,7 @@ prd_draft → user_review → prototype_loop → prd_frozen → completed
|
|
|
66
73
|
- **错误行为**:PRD草稿完成后直接标记S3阶段完成
|
|
67
74
|
- **正确行为**:PRD草稿完成后等待用户查看,确认后继续S2阶段的后续步骤
|
|
68
75
|
|
|
69
|
-
调用 `/ce-brainstorm`(mode: orchestrated)产出 PRD
|
|
76
|
+
调用 `/ce-brainstorm`(mode: orchestrated)产出 PRD 草稿(Phase 3 由 prd-writer agent 契约级撰写,v0.47);**冻结前派 `prd-completeness-reviewer` 子代理做 PRD 完整性评审**(v0.15.0,管"说得全不全";v0.47 并入 §8.4 契约级细节 D6 维度);原型循环由编排层直接编排(prototype skill 内部编排产出 → prototype-reviewer 自动评审 → 人工评审 → 冻结);冻结语义为 `frozen_downstream`(迭代内变更不升版)。反馈环路检查点:scope 是否合理。详见 `references/s2-prd-prototype-loop.md`。
|
|
70
77
|
|
|
71
78
|
### ARCH: 产品级架构设计(v0.36.0 新增;2026-08-19 LT 调整上移 S3 前——S3 计划/S4 拆分是最终任务拆分,须基于架构)
|
|
72
79
|
|