@gordon.gan/specflow 1.2.0-beta → 1.2.1-beta

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -14,8 +14,10 @@ SpecFlow 把 **OpenSpec**(结构化需求规划)和 **Superpowers**(TDD、
14
14
  | Cursor | `specflow:propose` 等命令 | [Cursor 指南](./CURSOR_PACKAGING_AND_USAGE_GUIDE.md) |
15
15
  | OpenAI Codex | `$specflow-propose` 等技能 | [Codex 指南](./CODEX_PACKAGING_AND_USAGE_GUIDE.md) |
16
16
  | 多语言 / Go Profile | SpecFlow + 语言专项 skills | [语言 Profile 指南](./LANGUAGE_PROFILE_USAGE_GUIDE.md) |
17
- | 多仓 / 前后端一体需求 | Contract Hub + Spokes + 产物说明 | [多仓完整指南](./MULTI_REPO_GUIDE.md) |
17
+ | 多仓 / 前后端一体需求(**权威**) | Contract Hub + Spokes + 产物与 CLI | [多仓完整指南](./MULTI_REPO_GUIDE.md) |
18
18
  | 多仓原生能力(设计) | Store / References / Workset | [多仓技术方案](./MULTI_REPO_TECHNICAL_DESIGN.md) |
19
+ | 多仓场景示例(TALOS) | contracts + api + web 实操路径 | [TALOS 多仓教程](./TALOS_MULTI_REPO_TUTORIAL.md) |
20
+ | TALOS 公共需求详例 | 工作区邀请成员(Hub→BE→FE→联调) | [公共需求 Walkthrough](./docs/TALOS_SHARED_REQUIREMENT_WALKTHROUGH.md) |
19
21
  | 产物与作用 | explore / proposal / delta / design / tasks / 主 specs | [产物说明](./SPECFLOW_ARTIFACTS.md) |
20
22
 
21
23
  ---
@@ -115,7 +117,7 @@ npm install -g @gordon.gan/specflow
115
117
  npm install -g github:Gordon-Gan-Jiang/specflow
116
118
 
117
119
  # 验证
118
- specflow --version # 当前 1.1.0
120
+ specflow --version # npm / package.json 为准(开发中可见 1.2.0-beta)
119
121
  specflow --help
120
122
  ```
121
123
 
@@ -130,13 +132,32 @@ cd specflow && npm install && npm run build && npm link
130
132
 
131
133
  ```bash
132
134
  cd your-project
133
- specflow init # 默认:Claude + Cursor
134
- specflow init --ide codex # 仅 Codex
135
- specflow init --ide all # Claude + Cursor + Codex
135
+ specflow init # 默认:Claude + Cursor,英文产物
136
+ specflow init --artifact-language zh-CN # 简体中文产物
137
+ specflow init --artifact-language zh # zh zh-CN CLI 别名
138
+ specflow init --ide codex # 仅 Codex
139
+ specflow init --ide all --artifact-language en # Claude + Cursor + Codex
136
140
  ```
137
141
 
138
142
  init 会创建 `specflow/` 目录、写入 `config.yaml`,并按 `--ide` 生成对应托管资产(skills、commands、prompts 等),同时幂等地追加 `.gitignore` 忽略可再生的 prompts/schemas/templates。
139
143
 
144
+ 产物语言保存在项目配置中:
145
+
146
+ ```yaml
147
+ schema: specflow
148
+
149
+ artifacts:
150
+ language: zh-CN # en | zh-CN;未配置时默认为 en
151
+ ```
152
+
153
+ 语言配置控制 proposal、spec、design、tasks 等产物的自然语言叙述。SpecFlow
154
+ 解析依赖的 `ADDED Requirements`、`Requirement:`、`Scenario:`、`WHEN`、`THEN`
155
+ 等协议标记始终保持英文;capability ID、change name、路径、命令和代码也不会翻译。
156
+
157
+ `init` 对已有 `specflow/config.yaml` 永不覆盖,包括使用
158
+ `--force-assets` 或传入不同的 `--artifact-language`。已有项目需要直接编辑
159
+ `artifacts.language`;修改只影响后续新建或主动重写的内容,不会自动翻译历史产物。
160
+
140
161
  ### 跑通第一个变更
141
162
 
142
163
  **需求已清晰:**
@@ -149,6 +170,8 @@ init 会创建 `specflow/` 目录、写入 `config.yaml`,并按 `--ide` 生成
149
170
  /specflow:archive
150
171
  ```
151
172
 
173
+ 需要少打断确认时,可用 `/specflow:apply --yes`:自动接受成功的 Gate A/B 确认,并在构建成功后串行执行 review → test → verify;失败、Block、设计缺口仍会停下,且不会自动 archive。
174
+
152
175
  **需求模糊:**
153
176
 
154
177
  ```
@@ -247,7 +270,7 @@ CLI 从当前目录**向上查找**项目根(识别 `specflow/config.yaml`)
247
270
 
248
271
  | 命令 | 说明 |
249
272
  |------|------|
250
- | `specflow init [--ide claude\|cursor\|codex\|both\|all]` | 初始化项目目录与 IDE 托管资产 |
273
+ | `specflow init [--ide claude\|cursor\|codex\|both\|all] [--artifact-language en\|zh-CN]` | 初始化项目目录、产物语言与 IDE 托管资产;`zh` 是 `zh-CN` 的别名 |
251
274
  | `specflow sync [--ide ...] [--no-parity-strict]` | 从已安装的 specflow 包同步/更新 IDE 资产(升级后用) |
252
275
  | `specflow doctor [--parity] [--json]` | 诊断 IDE 资产是否完整、迁移状态是否正常 |
253
276
  | `specflow parity-report [--json]` | 对比 Claude / Cursor / Codex 能力是否一致 |
@@ -393,11 +416,10 @@ specflow doctor --parity
393
416
  specflow parity-report
394
417
  ```
395
418
 
396
- 重新初始化(init 检测到已初始化会拒绝,需先删除 `specflow/config.yaml` 等标记文件):
419
+ 刷新已初始化项目的托管资产(不会覆盖 `specflow/config.yaml`):
397
420
 
398
421
  ```bash
399
- rm -rf specflow/config.yaml .claude/specflow/ # 按需清理其他 IDE 目录
400
- specflow init
422
+ specflow init --force-assets --ide all
401
423
  ```
402
424
 
403
425
  ---
@@ -9,6 +9,7 @@ export interface InitResult {
9
9
  }
10
10
  export interface InitOptions {
11
11
  readonly ide?: InitIdeTarget;
12
+ readonly artifactLanguage?: string;
12
13
  readonly forceAssets?: boolean;
13
14
  readonly parityStrict?: boolean;
14
15
  }
@@ -7,13 +7,19 @@ import { validateReportAgainstManifest } from '../../integrations/shared/parity-
7
7
  import { appendManagedBlock } from '../../integrations/shared/marker-write.js';
8
8
  import { getRegeneratableIgnoreLines } from '../../integrations/shared/managed-assets.js';
9
9
  import { detectMigrationState } from '../../integrations/shared/migration-state.js';
10
- const CONFIG_YAML = `schema: specflow
10
+ import { DEFAULT_ARTIFACT_LANGUAGE, requireArtifactLanguage, } from '../../core/artifact-language.js';
11
+ function renderConfigYaml(artifactLanguage) {
12
+ return `schema: specflow
13
+
14
+ artifacts:
15
+ language: ${artifactLanguage}
11
16
 
12
17
  # Project context (customize for your project)
13
18
  # context: |
14
19
  # Tech stack: ...
15
20
  # Architecture: ...
16
21
  `;
22
+ }
17
23
  function findPackageRoot() {
18
24
  const currentFile = fileURLToPath(import.meta.url);
19
25
  let dir = join(currentFile, '..');
@@ -32,8 +38,8 @@ async function createDirectoryStructure(projectRoot) {
32
38
  fs.mkdir(join(projectRoot, 'specflow', 'specs'), { recursive: true }),
33
39
  ]);
34
40
  }
35
- async function writeConfig(projectRoot) {
36
- await fs.writeFile(join(projectRoot, 'specflow', 'config.yaml'), CONFIG_YAML, 'utf-8');
41
+ async function writeConfig(projectRoot, artifactLanguage) {
42
+ await fs.writeFile(join(projectRoot, 'specflow', 'config.yaml'), renderConfigYaml(artifactLanguage), 'utf-8');
37
43
  }
38
44
  async function pathExists(path) {
39
45
  try {
@@ -52,6 +58,9 @@ async function hasIdeAssets(projectRoot, ide) {
52
58
  return validateReportAgainstManifest(report).ok;
53
59
  }
54
60
  export async function initProject(projectRoot, packageRoot, options = {}) {
61
+ const artifactLanguage = options.artifactLanguage === undefined
62
+ ? DEFAULT_ARTIFACT_LANGUAGE
63
+ : requireArtifactLanguage(options.artifactLanguage);
55
64
  const ide = options.ide ?? 'both';
56
65
  const forceAssets = options.forceAssets ?? false;
57
66
  const parityStrict = options.parityStrict ?? true;
@@ -60,14 +69,17 @@ export async function initProject(projectRoot, packageRoot, options = {}) {
60
69
  const migrationState = await detectMigrationState(projectRoot);
61
70
  if (!initialized) {
62
71
  await createDirectoryStructure(projectRoot);
63
- await writeConfig(projectRoot);
72
+ await writeConfig(projectRoot, artifactLanguage);
64
73
  }
74
+ const languageEditMessage = options.artifactLanguage
75
+ ? ' Edit specflow/config.yaml explicitly to change artifact language in an initialized project.'
76
+ : '';
65
77
  const selectedIdeTargets = adapters.map((a) => a.ide);
66
78
  const allTargetsHealthy = (await Promise.all(selectedIdeTargets.map((target) => hasIdeAssets(projectRoot, target)))).every(Boolean);
67
79
  if (initialized && !forceAssets && allTargetsHealthy) {
68
80
  return {
69
81
  status: 'already_initialized',
70
- message: `Project at ${projectRoot} is already initialized for ide=${ide} (state=${migrationState}). Use --force-assets to refresh managed assets.`,
82
+ message: `Project at ${projectRoot} is already initialized for ide=${ide} (state=${migrationState}). Use --force-assets to refresh managed assets.${languageEditMessage}`,
71
83
  };
72
84
  }
73
85
  for (const adapter of adapters) {
@@ -86,7 +98,7 @@ export async function initProject(projectRoot, packageRoot, options = {}) {
86
98
  return {
87
99
  status: initialized ? 'updated_assets' : 'initialized',
88
100
  message: initialized
89
- ? `Updated ${ide} assets at ${projectRoot}`
101
+ ? `Updated ${ide} assets at ${projectRoot}.${languageEditMessage}`
90
102
  : `Initialized specflow project at ${projectRoot}`,
91
103
  };
92
104
  }
@@ -102,6 +114,7 @@ export function registerInitCommand(program) {
102
114
  .command('init')
103
115
  .description('Initialize a project with specflow directory structure and assets')
104
116
  .option('--ide <target>', 'Target IDE assets: claude | cursor | codex | both | all', 'both')
117
+ .option('--artifact-language <language>', 'Artifact content language: en | zh-CN (alias: zh)')
105
118
  .option('--force-assets', 'Refresh managed IDE assets even when project is initialized')
106
119
  .option('--no-parity-strict', 'Disable strict parity validation after asset generation')
107
120
  .action(async (opts) => {
@@ -109,6 +122,7 @@ export function registerInitCommand(program) {
109
122
  const packageRoot = findPackageRoot();
110
123
  const result = await initProject(projectRoot, packageRoot, {
111
124
  ide: opts.ide ?? 'both',
125
+ artifactLanguage: opts.artifactLanguage,
112
126
  forceAssets: opts.forceAssets ?? false,
113
127
  parityStrict: opts.parityStrict ?? true,
114
128
  });
@@ -26,6 +26,7 @@ function readProjectConfig(projectRoot) {
26
26
  const projectConfig = parseProjectConfig(parsed);
27
27
  const config = {
28
28
  context: projectConfig.context,
29
+ artifactLanguage: projectConfig.artifactLanguage,
29
30
  references: projectConfig.references,
30
31
  };
31
32
  return { schemaName, config: config };
@@ -56,6 +57,7 @@ async function enrichInstructionConfig(projectRoot, options) {
56
57
  });
57
58
  return {
58
59
  context: parsed.context,
60
+ artifactLanguage: parsed.artifactLanguage,
59
61
  referencedStores,
60
62
  rootProvenance: {
61
63
  source: resolved.source,
@@ -105,9 +107,11 @@ export function registerInstructionsCommand(program) {
105
107
  }
106
108
  console.info(`Generates: ${instructions.generates}`);
107
109
  console.info(`Description: ${instructions.description}`);
110
+ console.info(`Artifact language: ${instructions.artifactLanguage}`);
108
111
  if (instructions.instruction) {
109
112
  console.info(`\nInstruction:\n${instructions.instruction}`);
110
113
  }
114
+ console.info(`\n${instructions.languageGuidance}`);
111
115
  const referenceGuidance = collectReferenceGuidance({ referencedStores: instructions.referencedStores });
112
116
  const guidance = referenceGuidance.claude;
113
117
  if (guidance) {
@@ -1,6 +1,7 @@
1
1
  import type { SchemaYaml } from './types.js';
2
2
  import type { Diagnostic } from '../diagnostics.js';
3
3
  import type { RootSource } from '../root-selection.js';
4
+ import { type ArtifactLanguage } from '../artifact-language.js';
4
5
  /**
5
6
  * Dependency information included in artifact instructions.
6
7
  */
@@ -29,6 +30,10 @@ export interface ArtifactInstructions {
29
30
  readonly instruction: string | undefined;
30
31
  /** Project context from the config */
31
32
  readonly context: string | undefined;
33
+ /** Canonical language for human-readable artifact content */
34
+ readonly artifactLanguage: ArtifactLanguage;
35
+ /** Rendered generation policy for the selected artifact language */
36
+ readonly languageGuidance: string;
32
37
  /** Separately budgeted referenced-store index */
33
38
  readonly referencedStores?: ReferencedStoresSection;
34
39
  /** Selected planning root provenance */
@@ -45,6 +50,7 @@ export interface ArtifactInstructions {
45
50
  */
46
51
  export interface ProjectConfig {
47
52
  readonly context?: string;
53
+ readonly artifactLanguage?: ArtifactLanguage;
48
54
  readonly referencedStores?: ReferencedStoresSection;
49
55
  readonly rootProvenance?: RootProvenanceSection;
50
56
  readonly [key: string]: unknown;
@@ -1,3 +1,4 @@
1
+ import { DEFAULT_ARTIFACT_LANGUAGE, renderArtifactLanguageGuidance, } from '../artifact-language.js';
1
2
  /**
2
3
  * Loads enriched instructions for creating an artifact.
3
4
  *
@@ -14,9 +15,12 @@ export function loadInstructions(artifactId, changeDir, schema, config) {
14
15
  throw new Error(`Artifact '${artifactId}' not found in schema '${schema.name}'`);
15
16
  }
16
17
  const dependencies = buildDependencyInfo(artifact, schema);
18
+ const artifactLanguage = config?.artifactLanguage ?? DEFAULT_ARTIFACT_LANGUAGE;
17
19
  return {
18
20
  instruction: artifact.instruction,
19
21
  context: config?.context ?? undefined,
22
+ artifactLanguage,
23
+ languageGuidance: renderArtifactLanguageGuidance(artifactLanguage),
20
24
  referencedStores: config?.referencedStores,
21
25
  rootProvenance: config?.rootProvenance,
22
26
  dependencies,
@@ -78,7 +78,6 @@ export declare const SchemaYamlSchema: z.ZodObject<{
78
78
  }>>;
79
79
  }, "strip", z.ZodTypeAny, {
80
80
  version: number;
81
- name: string;
82
81
  artifacts: {
83
82
  id: string;
84
83
  generates: string;
@@ -86,6 +85,7 @@ export declare const SchemaYamlSchema: z.ZodObject<{
86
85
  requires: string[];
87
86
  instruction?: string | undefined;
88
87
  }[];
88
+ name: string;
89
89
  apply?: {
90
90
  requires: string[];
91
91
  instruction?: string | undefined;
@@ -94,7 +94,6 @@ export declare const SchemaYamlSchema: z.ZodObject<{
94
94
  description?: string | undefined;
95
95
  }, {
96
96
  version: number;
97
- name: string;
98
97
  artifacts: {
99
98
  id: string;
100
99
  generates: string;
@@ -102,6 +101,7 @@ export declare const SchemaYamlSchema: z.ZodObject<{
102
101
  instruction?: string | undefined;
103
102
  requires?: string[] | undefined;
104
103
  }[];
104
+ name: string;
105
105
  apply?: {
106
106
  requires: string[];
107
107
  instruction?: string | undefined;
@@ -0,0 +1,7 @@
1
+ export declare const ARTIFACT_LANGUAGES: readonly ["en", "zh-CN"];
2
+ export type ArtifactLanguage = (typeof ARTIFACT_LANGUAGES)[number];
3
+ export declare const DEFAULT_ARTIFACT_LANGUAGE: ArtifactLanguage;
4
+ export declare function isArtifactLanguage(value: unknown): value is ArtifactLanguage;
5
+ export declare function normalizeArtifactLanguage(value: unknown): ArtifactLanguage | undefined;
6
+ export declare function requireArtifactLanguage(value: unknown): ArtifactLanguage;
7
+ export declare function renderArtifactLanguageGuidance(language: ArtifactLanguage): string;
@@ -0,0 +1,33 @@
1
+ export const ARTIFACT_LANGUAGES = ['en', 'zh-CN'];
2
+ export const DEFAULT_ARTIFACT_LANGUAGE = 'en';
3
+ export function isArtifactLanguage(value) {
4
+ return value === 'en' || value === 'zh-CN';
5
+ }
6
+ export function normalizeArtifactLanguage(value) {
7
+ if (value === 'zh') {
8
+ return 'zh-CN';
9
+ }
10
+ return isArtifactLanguage(value) ? value : undefined;
11
+ }
12
+ export function requireArtifactLanguage(value) {
13
+ const language = normalizeArtifactLanguage(value);
14
+ if (language) {
15
+ return language;
16
+ }
17
+ throw new Error(`Unsupported artifact language ${JSON.stringify(value)}. Supported values: en, zh-CN (alias: zh).`);
18
+ }
19
+ export function renderArtifactLanguageGuidance(language) {
20
+ const narrativeLanguage = language === 'zh-CN' ? 'Simplified Chinese' : 'English';
21
+ return [
22
+ '## Artifact language policy',
23
+ '',
24
+ `Write human-readable artifact content in ${narrativeLanguage}.`,
25
+ '',
26
+ 'Keep SpecFlow protocol markers unchanged, including:',
27
+ '- `ADDED Requirements`, `MODIFIED Requirements`, `REMOVED Requirements`, and `RENAMED Requirements`',
28
+ '- `Requirement:`, `Scenario:`, `WHEN`, and `THEN`',
29
+ '',
30
+ 'Keep capability IDs, change names, file paths, commands, code, and symbols unchanged.',
31
+ 'When modifying an existing requirement, preserve its exact name when delta matching requires it.',
32
+ ].join('\n');
33
+ }
@@ -1,4 +1,5 @@
1
1
  import type { Diagnostic } from './diagnostics.js';
2
+ import { type ArtifactLanguage } from './artifact-language.js';
2
3
  export interface NormalizedReference {
3
4
  readonly id: string;
4
5
  readonly remote?: string;
@@ -6,6 +7,7 @@ export interface NormalizedReference {
6
7
  export interface ParsedProjectConfig {
7
8
  readonly schema: string;
8
9
  readonly context?: string;
10
+ readonly artifactLanguage: ArtifactLanguage;
9
11
  readonly store?: string;
10
12
  readonly references: readonly NormalizedReference[];
11
13
  readonly diagnostics: readonly Diagnostic[];
@@ -1,4 +1,5 @@
1
1
  import { z } from 'zod';
2
+ import { DEFAULT_ARTIFACT_LANGUAGE, isArtifactLanguage, } from './artifact-language.js';
2
3
  const KEBAB_CASE_ID = /^[a-z][a-z0-9]*(-[a-z0-9]+)*$/;
3
4
  const ReferenceObjectSchema = z
4
5
  .object({
@@ -20,6 +21,29 @@ export function parseProjectConfig(raw) {
20
21
  const record = typeof raw === 'object' && raw !== null ? raw : {};
21
22
  const schema = typeof record.schema === 'string' ? record.schema : 'specflow';
22
23
  const context = typeof record.context === 'string' ? record.context : undefined;
24
+ let artifactLanguage = DEFAULT_ARTIFACT_LANGUAGE;
25
+ if (record.artifacts !== undefined) {
26
+ const artifacts = typeof record.artifacts === 'object' &&
27
+ record.artifacts !== null &&
28
+ !Array.isArray(record.artifacts)
29
+ ? record.artifacts
30
+ : undefined;
31
+ const configuredLanguage = artifacts?.language;
32
+ if (!artifacts ||
33
+ (configuredLanguage !== undefined &&
34
+ !isArtifactLanguage(configuredLanguage))) {
35
+ diagnostics.push({
36
+ severity: 'error',
37
+ code: 'invalid_artifact_language',
38
+ message: "Project artifact language must be one of: 'en', 'zh-CN'.",
39
+ target: 'config.artifacts.language',
40
+ fix: "Set artifacts.language to 'en' or 'zh-CN'.",
41
+ });
42
+ }
43
+ else if (isArtifactLanguage(configuredLanguage)) {
44
+ artifactLanguage = configuredLanguage;
45
+ }
46
+ }
23
47
  let store;
24
48
  if (record.store !== undefined) {
25
49
  if (typeof record.store === 'string' && KEBAB_CASE_ID.test(record.store)) {
@@ -66,7 +90,14 @@ export function parseProjectConfig(raw) {
66
90
  });
67
91
  }
68
92
  }
69
- return { schema, context, store, references, diagnostics };
93
+ return {
94
+ schema,
95
+ context,
96
+ artifactLanguage,
97
+ store,
98
+ references,
99
+ diagnostics,
100
+ };
70
101
  }
71
102
  export function loadProjectConfigFromObject(raw) {
72
103
  return parseProjectConfig(raw);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@gordon.gan/specflow",
3
- "version": "1.2.0-beta",
3
+ "version": "1.2.1-beta",
4
4
  "type": "module",
5
5
  "description": "SpecFlow — unified spec-driven development: OpenSpec planning + Superpowers execution in one CLI and cross-IDE workflow",
6
6
  "keywords": [
@@ -0,0 +1,30 @@
1
+ # Artifact Language Policy
2
+
3
+ Before creating or rewriting any SpecFlow artifact:
4
+
5
+ 1. Read `specflow/config.yaml` from the active planning root.
6
+ 2. Resolve `artifacts.language`:
7
+ - `en` → write human-readable artifact content in English.
8
+ - `zh-CN` → write human-readable artifact content in Simplified Chinese.
9
+ - Missing → default to `en`.
10
+ - Invalid → report the invalid value and use `en`; do not invent another language.
11
+ 3. Apply the selected language consistently to narrative prose, requirement and scenario descriptions, design rationale, and task descriptions.
12
+
13
+ ## Protected Protocol
14
+
15
+ Language selection never changes SpecFlow's machine-readable protocol. Keep these tokens exactly as written:
16
+
17
+ - `## ADDED Requirements`
18
+ - `## MODIFIED Requirements`
19
+ - `## REMOVED Requirements`
20
+ - `## RENAMED Requirements`
21
+ - `### Requirement:`
22
+ - `#### Scenario:`
23
+ - `- **WHEN**`
24
+ - `- **THEN**`
25
+ - `FROM:`
26
+ - `TO:`
27
+
28
+ Also preserve capability IDs, change names, file paths, commands, code, symbols, and established technical identifiers.
29
+
30
+ When modifying an existing requirement, preserve its exact requirement name if delta matching depends on that name. Do not translate historical artifacts automatically; the configured language applies prospectively to content created or intentionally rewritten in the current workflow.
@@ -5,6 +5,15 @@ description: "Two-phase apply — task rewrite + subagent TDD execution"
5
5
 
6
6
  # SpecFlow: Apply
7
7
 
8
+ ## Invocation mode
9
+
10
+ Inspect the current user invocation before any stage work:
11
+
12
+ - **Default mode:** `/specflow:apply` preserves every existing user confirmation gate and the default interactive behavior.
13
+ - **Yes mode:** `/specflow:apply --yes` records non-interactive confirmation mode for the current invocation only. It auto-accepts only successful acknowledgement gates; it never bypasses prerequisites, gap detection, failing verification, or a review `Block`.
14
+
15
+ Report the selected mode once at the start of the session. Do not persist it to future invocations.
16
+
8
17
  > **HARD GATE (prerequisite)**: phase must be `refined`. Run /specflow:refine first if not.
9
18
  > **HARD GATE (Phase A)**: rewritten tasks.md must be user-confirmed before Phase B.
10
19
  > **HARD GATE (Phase B)**: each task must be reviewed (spec + code quality) and user-confirmed before next task.
@@ -18,6 +27,13 @@ description: "Two-phase apply — task rewrite + subagent TDD execution"
18
27
  - Existing `tasks.md` is present (coarse first-iteration from `/specflow:propose`, or a refine-updated version).
19
28
  - `specflow` CLI is available on PATH.
20
29
 
30
+ ## Artifact Language Setup
31
+
32
+ Before Phase A rewrites `tasks.md`, read
33
+ `.claude/specflow/prompts/shared/artifact-language.md` and resolve the active
34
+ planning root's `specflow/config.yaml`. Apply the policy to rewritten task
35
+ descriptions while preserving paths, commands, code, and symbols.
36
+
21
37
  ---
22
38
 
23
39
  ## Phase A: Task Rewrite
@@ -56,7 +72,10 @@ Present the audit summary to the user: per-group task count (coarse → atomic),
56
72
 
57
73
  ### Gate A: Rewrite Confirmation
58
74
 
59
- Present the rewritten `tasks.md` to the user. **Ask the user to confirm the rewrite.** Do NOT proceed to Phase B until the user explicitly confirms.
75
+ - **Default mode:** Present the rewritten `tasks.md` and ask the user to confirm the rewrite. Do NOT proceed to Phase B until the user explicitly confirms.
76
+ - **Yes mode:** Present the rewrite audit and continue directly to Phase B after recording the rewrite as automatically accepted for this invocation.
77
+
78
+ If Phase A reports a reorganization choice or a design gap, stop regardless of mode; `--yes` does not choose a reorganization or fill a missing design decision.
60
79
 
61
80
  ---
62
81
 
@@ -108,16 +127,26 @@ ECC reviewer verdict routing:
108
127
 
109
128
  #### Gate B: Per-task Confirmation
110
129
 
111
- Present the task output and both review reports to the user. **Ask the user to confirm the task is complete.** Do NOT proceed to the next task until confirmation is received.
130
+ - **Default mode:** Present the task output and both review reports. Ask the user to confirm the task is complete. Do NOT proceed to the next task until confirmation is received.
131
+ - **Yes mode:** Present the task output and both review reports. If spec review passes and code-quality review returns `Approve` or `Warning`, record the task as automatically accepted and start the next task without waiting.
112
132
 
113
- If the user rejects, return to Stage B2a for the same task.
133
+ If either review blocks, return to Stage B2a for the same task. `--yes` never advances past a blocked review.
114
134
 
115
135
  ### Stage B3: Phase Transition
116
136
 
117
- Once all tasks are confirmed:
137
+ Once all tasks are confirmed in default mode or automatically accepted in yes mode:
118
138
  - Invoke `specflow change phase <name> --set apply` to transition the phase.
119
139
  - Summarize the build results and overall coverage.
120
- - Inform the user they can now run `/specflow:review` or `/specflow:verify`.
140
+
141
+ #### Yes-mode downstream sequence
142
+
143
+ When yes mode reaches this point:
144
+ 1. Invoke `/specflow:review`. Stop if it reports a CRITICAL or HIGH finding.
145
+ 2. Invoke `/specflow:test` only after review has no CRITICAL/HIGH findings. Stop if tests cannot be made green.
146
+ 3. Invoke `/specflow:verify` only after test succeeds. Stop if verify returns `FAIL`.
147
+ 4. Report review, test, and verification evidence. Do NOT invoke `/specflow:archive` automatically; archive remains the user's manual choice.
148
+
149
+ When default mode reaches this point, inform the user that they can now run `/specflow:review` or `/specflow:verify`.
121
150
 
122
151
  ---
123
152
 
@@ -33,6 +33,12 @@ Skip explore when you already know exactly what to build — run `/specflow:prop
33
33
  - `specflow/` exists (suggest `specflow init` if missing)
34
34
  - `specflow` CLI available on PATH
35
35
 
36
+ ## Artifact Language Setup
37
+
38
+ Read `.claude/specflow/prompts/shared/artifact-language.md` and resolve the active
39
+ planning root's `specflow/config.yaml` before writing or rewriting `explore.md`.
40
+ Apply that policy to every artifact created by this workflow.
41
+
36
42
  ## Stage 1: Create or Reuse Change
37
43
 
38
44
  If no active change directory exists for this work:
@@ -18,6 +18,12 @@ Treat every artifact here as "v1, to be iterated on" — depth matters, but so d
18
18
  - `specflow/specs/` directory should exist, indicating this is a specflow-initialized project. For a brand-new greenfield change with no existing specs, proceed — the prompt handles that case. If `specflow/` itself does not exist, suggest running `specflow init` first.
19
19
  - `specflow` CLI must be available on PATH.
20
20
 
21
+ ## Artifact Language Setup
22
+
23
+ Read `.claude/specflow/prompts/shared/artifact-language.md` and resolve the active
24
+ planning root's `specflow/config.yaml` before generating proposal, specs, design,
25
+ or tasks. Reuse the resolved policy for all four artifacts.
26
+
21
27
  ## Stage 0: Explore Handoff (when explore.md exists)
22
28
 
23
29
  Before creating a new change or generating a proposal, check for an existing exploration artifact:
@@ -26,6 +26,12 @@ emits a round diff summary.
26
26
 
27
27
  If any precondition fails, stop and instruct the user to run `/specflow:propose` first.
28
28
 
29
+ ## Artifact Language Setup
30
+
31
+ Read `.claude/specflow/prompts/shared/artifact-language.md` and resolve the active
32
+ planning root's `specflow/config.yaml` before refining any artifact. Preserve
33
+ existing requirement names where delta matching requires exact identity.
34
+
29
35
  ## Stage 1: Pre-loop setup
30
36
 
31
37
  Read, in order:
@@ -10,6 +10,12 @@ description: "Post-hoc change documentation from git diff"
10
10
  - Git repository must have uncommitted or recent committed changes to document.
11
11
  - `specflow` CLI must be available on PATH.
12
12
 
13
+ ## Artifact Language Setup
14
+
15
+ Read `.claude/specflow/prompts/shared/artifact-language.md` and resolve the active
16
+ planning root's `specflow/config.yaml` before synthesizing proposal, specs, or
17
+ tasks. Reuse the resolved policy for every generated artifact.
18
+
13
19
  ## Stage 1: Analyze Changes
14
20
 
15
21
  Run `git diff` and `git log` to capture what changed.