phasegate 0.126.0 → 0.128.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md
CHANGED
|
@@ -7,6 +7,33 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
7
7
|
|
|
8
8
|
## [Unreleased]
|
|
9
9
|
|
|
10
|
+
## [0.128.0] - 2026-05-08
|
|
11
|
+
|
|
12
|
+
### Fixed
|
|
13
|
+
|
|
14
|
+
- **WI-091 finding #1 follow-up — `validate --layer L4` で `layers.L4.enabled: false` が runtime で実際に機能するよう composition root に config を thread (GitHub Issue #4)** — v0.127.0 publish 後の dogfood (`/tmp/phasegate-dogfood-wi091`, phasegate@0.127.0) で finding #1 の修正が runtime で機能していないことが判明したため緊急修正。
|
|
15
|
+
- **症状**: `phasegate.config.json` に `layers.L4.enabled: false` を設定して `phasegate validate --layer L4` を実行しても、L4-001/002 が `[PASS]` (実際には実行された) となり、L4-003 だけが `[SKIP]` (strictOnly のため)。期待挙動は L4-001/002/003 すべて `[SKIP]`。
|
|
16
|
+
- **根本原因**: `scripts/harness/main.ts:979` の `validate` case で `createValidatorSystemModule()` が config 引数なしで呼ばれており、`composition-root.ts:111-114` の `const configData = (config ?? DEFAULT_CONFIG)` で常に `DEFAULT_CONFIG` (L4.enabled=true) が使われていた。WI-091 finding #1 で `RunL4ValidatorsUseCase` に追加した gate (`if (!layerConfig.enabled) return [];`) はソースに正しく入っていたが、上流 DI で user の config が threading されていないため runtime で常に enabled=true 判定となり gate が hit せず drift / consistency / dead-code service が呼ばれていた。WI-085 retrospective (`feedback_dogfood_before_release.md`) で記録した「composition root の DI 配線漏れ」と同種の bug が再発した形。
|
|
17
|
+
- **修正**: `main.ts` に `toValidatorSystemConfig(resolvedConfig: HarnessConfigV2 | undefined)` translator を追加し、HarnessConfigV2 から validator-system が期待する shape (`{ project: { preset }, layers: { L2/L3/L4: { enabled } } }`) に変換。`validate` case で `createValidatorSystemModule(toValidatorSystemConfig(resolvedConfig))` を呼ぶように修正。`validators` field は thread しない設計判断 — preset-style の `["drift-detector"]` が validator-code-style の `L4-001/002/003` を override し全 SKIP になる症状を回避するため、`validators` の解決は composition root 側の `defaultValidators[layer]` フォールバックに委ねる。
|
|
18
|
+
- **テスト**: spawn 経由結合テスト 2 ケース (`scripts/harness/__tests__/integration/harness-api/validate-layer-config.integration.test.ts`) 新規追加:
|
|
19
|
+
- `layers.L4.enabled: false` で `validate --layer L4` 実行時、L4 全 validator が `[SKIP]` 表示 + 総合判定 PASS + exit 0
|
|
20
|
+
- `layers.L4.enabled: true` で L4 validator が enabled で実行 (回帰防止)
|
|
21
|
+
- 全 3516 テスト (前回 3514 + 新規 2) グリーン、L1 lint 違反なし。
|
|
22
|
+
- **スコープ外 (別 follow-up commit で対応)**: 同種の DI 配線漏れが `harness-api/infrastructure/adapters/validator-system-execution-adapter.ts:27/38/51` (phasegate:detect-drift / phasegate:check-ready 等の harness-api flow) と `integrations/pre-commit.ts:306/338` (Husky pre-commit) にも存在するが、別ハンドラ経路で `resolvedConfig` がスコープ外のため別途修正。
|
|
23
|
+
- **教訓 (memory 反映)**: `feedback_dogfood_before_release.md` に「`paths` config / Artifact / PhaseConfigProviderPort 改修」と並べて「composition root の `createValidatorSystemModule(config?)` 経路」を追記。`createValidatorSystemModule()` を呼ぶ全 site (現状 6 箇所) で config が threading されているか毎回 grep 確認する規律を強化する。
|
|
24
|
+
|
|
25
|
+
## [0.127.0] - 2026-05-08
|
|
26
|
+
|
|
27
|
+
### Fixed
|
|
28
|
+
|
|
29
|
+
- **WI-091 — `layers.L4.enabled: false` 無視 / `--help` がサブコマンドで no-op / drift-detect が括弧 qualifier で破綻する 3 件を解消 (GitHub Issue #4)** — 外部レポーター nakataj-mti が pnpm monorepo 環境 (defense `standard` / architecture `clean`) で報告した 5 件の bug+DX gap (`L4.enabled` 無視 / warning でも overall FAIL / `--help` 副作用走行 / `paths` 設定が L2-001 に未配線 / drift element の括弧 qualifier 破綻) のうち、リスクの低い 3 件 (#1, #3, #5 immediate) を本リリースで先行修正。残る #2 (severity 集計セマンティクス) と #4 (paths threading 完成) は後続 WI に切り出す方針 (本 description の `スコープ外` 参照)。
|
|
30
|
+
- **finding #1 — L4 enabled gate 追加 (`run-l4-validators-usecase.ts`)**: L3 (`run-l3-validators-usecase.ts:74-78`) と対称な `if (!layerConfig.enabled) return [];` ガードを `getLayerConfig` 直後に追加。`layers.L4.enabled: false` 設定で drift / consistency / dead-code service が呼ばれず、空配列を返すことで集計層で SKIP として表示される。dogfood 再現済 (`/tmp/phasegate-dogfood-wi091`, phasegate@0.126.0)。整合性テスト 2 ケース (`IT-UC-RunL4-007/008`) 追加。
|
|
31
|
+
- **finding #3 — `--help` / `-h` を全 subcommand に pre-dispatch で集約 (`main.ts`)**: 51 個の subcommand のうち 3 個のみが inline `--help` を持っており、残り ~48 個は silent ignore で `update-skills --help` → 8 skills 再 deploy / `phasegate:detect-drift --help` → drift 実 run / `validate --help` → phase gate 実走 という副作用走行を起こしていた。`main()` 内に `SUBCOMMAND_HELP` table (13 entry) と `printSubcommandHelp` helper を追加し、`switch(command)` の手前で `hasFlag(args, "--help") || hasFlag(args, "-h")` を最優先で解釈 → usage 出力 + exit 0。table 未登録の subcommand は `Usage: phasegate <cmd> [options]\n(use 'phasegate --help' for the full command reference)` の generic fallback で exit 0。dogfood 再現済 3 ケースが本 fix で停止することを spawn 経由 5 ケース (副作用ナシ確認込み) で検証。
|
|
32
|
+
- **finding #5 immediate — drift-detect の design heading から括弧 qualifier を normalize (`markdown-design-document-adapter.ts`)**: `extractConceptNames` が markdown heading から `(〜)` / `(〜)` qualifier (例: `(エンティティ・新規)`, `(legacy)`) を strip しないため code 側 class 名と exact match できず false-positive drift を出していた問題を解消。半角・全角括弧両対応、global flag で連続 / 複数 qualifier (`Foo(A)(B)` → `Foo`) も処理、strip 後 0 文字になる病的 heading は concepts に含めない。source code 側 (`biome-ast-source-code-analyzer-adapter.ts`) は AST node name から識別子のみ取得 (括弧含まず) のため design 側 normalize で十分。整合性テスト 4 ケース (`IT-REPO-DesignDoc-007〜010`) 追加。`pointers:` block 仕様による element → file path 明示は別 WI に切り出し。
|
|
33
|
+
- **既存 inline `--help` 処理は残置**: `main.ts` の 3 箇所 (line 982 / 1028 / 1112) は pre-dispatch で hit する関係で dead code 化するが本 commit では削除せず (テスト互換性確保のため)。clean-up は別 commit で漸進可。
|
|
34
|
+
- **テスト**: 全 3514 テスト (前回 3510 + 新規 11: finding #1 で 2 + finding #3 で 5 + finding #5 で 4) グリーン。L1 lint 違反なし。
|
|
35
|
+
- **スコープ外 (別 WI 起票予定)**: finding #2 (warning-severity でも overall FAIL の集計セマンティクス) は ADR レベルの後方互換戦略判断が必要なため story-implementor 案件として分離。finding #4 (`paths.designDocs` を L2-001 へ完全 threading) は WI-085 で `inceptionDocs` 側のみ通った threading 漏れの補完で phase-nodes 3 ファイル + traceability-model 2 ファイルの placeholder 化を伴う story-implementor 案件として分離。
|
|
36
|
+
|
|
10
37
|
## [0.126.0] - 2026-05-08
|
|
11
38
|
|
|
12
39
|
### Fixed
|
package/package.json
CHANGED
package/scripts/harness/main.ts
CHANGED
|
@@ -219,6 +219,128 @@ function validateKnownFlags(args: readonly string[], known: readonly string[]):
|
|
|
219
219
|
return null;
|
|
220
220
|
}
|
|
221
221
|
|
|
222
|
+
const SUBCOMMAND_HELP: Record<string, string> = {
|
|
223
|
+
init: `Usage: phasegate init [options]
|
|
224
|
+
|
|
225
|
+
Initialize phasegate in the current project: deploy skills + design docs + phasegate.config.json.
|
|
226
|
+
|
|
227
|
+
Options:
|
|
228
|
+
--name <project-name> Project name (default: "my-project")
|
|
229
|
+
--preset <full|standard|minimal|custom> Phase dependency preset (default: "standard")
|
|
230
|
+
--skills <core|all> Skill set to deploy (default: "all")
|
|
231
|
+
--agent <claude|codex|both> Agent integration target (default: "claude")
|
|
232
|
+
--with-husky Install Husky pre-commit hooks
|
|
233
|
+
--yes Skip confirmation prompts
|
|
234
|
+
--help, -h Show this help`,
|
|
235
|
+
"update-skills": `Usage: phasegate update-skills [options]
|
|
236
|
+
|
|
237
|
+
Redeploy skills in .claude/skills/ from the installed phasegate version. WARNING: overwrites existing skill files.
|
|
238
|
+
|
|
239
|
+
Options:
|
|
240
|
+
--skills <core|all> Skill set to deploy
|
|
241
|
+
--agent <claude|codex|both> Agent integration target
|
|
242
|
+
--help, -h Show this help`,
|
|
243
|
+
validate: `Usage: phasegate validate [options]
|
|
244
|
+
|
|
245
|
+
Run validators against the project. Without --layer, runs all enabled layers (L0/L2/L3/L4).
|
|
246
|
+
|
|
247
|
+
Options:
|
|
248
|
+
--layer <L0|L2|L3|L4> Run only the specified layer
|
|
249
|
+
--json Output machine-readable JSON
|
|
250
|
+
--help, -h Show this help`,
|
|
251
|
+
lint: `Usage: phasegate lint [options]
|
|
252
|
+
|
|
253
|
+
Run L1 Biome AST checks across the project.
|
|
254
|
+
|
|
255
|
+
Options:
|
|
256
|
+
--json Output machine-readable JSON
|
|
257
|
+
--help, -h Show this help`,
|
|
258
|
+
migrate: `Usage: phasegate migrate [options]
|
|
259
|
+
|
|
260
|
+
Migrate phasegate.config.json from older schema versions. Backs up the original to phasegate.config.json.bak.
|
|
261
|
+
|
|
262
|
+
Options:
|
|
263
|
+
--dry-run Preview changes without writing
|
|
264
|
+
--help, -h Show this help`,
|
|
265
|
+
"list-errors": `Usage: phasegate list-errors [options]
|
|
266
|
+
|
|
267
|
+
List validator error catalog entries.
|
|
268
|
+
|
|
269
|
+
Options:
|
|
270
|
+
--layer <L0|L1|L2|L3|L4> Filter by layer
|
|
271
|
+
--format <table|json> Output format (default: "table")
|
|
272
|
+
--help, -h Show this help`,
|
|
273
|
+
"phasegate:status": `Usage: phasegate phasegate:status
|
|
274
|
+
|
|
275
|
+
Display harness status (enabled validators, schema version, hook deployment).`,
|
|
276
|
+
"phasegate:detect-drift": `Usage: phasegate phasegate:detect-drift [options]
|
|
277
|
+
|
|
278
|
+
Run L4-001 drift detection between design documents and source code. WARNING: scans the project filesystem.
|
|
279
|
+
|
|
280
|
+
Options:
|
|
281
|
+
--json Output machine-readable JSON (default for this command)
|
|
282
|
+
--help, -h Show this help`,
|
|
283
|
+
"phasegate:check-ready": `Usage: phasegate phasegate:check-ready
|
|
284
|
+
|
|
285
|
+
Check whether the harness is ready (config valid, hooks deployed).`,
|
|
286
|
+
"phasegate:complete-check": `Usage: phasegate phasegate:complete-check
|
|
287
|
+
|
|
288
|
+
Run completion check (used by Stop hook). Validates phase-gate, metadata, and test-quality.`,
|
|
289
|
+
"phasegate:check-phase": `Usage: phasegate phasegate:check-phase [options]
|
|
290
|
+
|
|
291
|
+
Check phase gate for a specific unit.
|
|
292
|
+
|
|
293
|
+
Options:
|
|
294
|
+
--unit <unitId> Target unit ID (e.g., harness-api). If omitted,
|
|
295
|
+
the first positional argument is used.
|
|
296
|
+
--json Output result as JSON.
|
|
297
|
+
--help, -h Show this help.
|
|
298
|
+
|
|
299
|
+
Examples:
|
|
300
|
+
phasegate phasegate:check-phase --unit harness-api
|
|
301
|
+
phasegate phasegate:check-phase harness-api --json`,
|
|
302
|
+
"check-change-category": `Usage: phasegate check-change-category --paths <csv> [options]
|
|
303
|
+
|
|
304
|
+
Classify changed file paths into quick-mode categories and report
|
|
305
|
+
whether Full Mode is required.
|
|
306
|
+
|
|
307
|
+
Options:
|
|
308
|
+
--paths <csv> Comma-separated file paths to classify.
|
|
309
|
+
--format <human|json> Output format. Default: human.
|
|
310
|
+
--fail-on-full-required Exit with code 1 when Full Mode is required.
|
|
311
|
+
--help, -h Show this help.
|
|
312
|
+
|
|
313
|
+
Examples:
|
|
314
|
+
phasegate check-change-category --paths src/foo.ts,src/bar.ts
|
|
315
|
+
phasegate check-change-category --paths src/foo.ts --format json`,
|
|
316
|
+
"ci:generate-template": `Usage: phasegate ci:generate-template [options]
|
|
317
|
+
|
|
318
|
+
Generates a CI template configuration.
|
|
319
|
+
|
|
320
|
+
Options:
|
|
321
|
+
--preset <id> Preset name (e.g. standard, strict). Required.
|
|
322
|
+
--type <type> Template purpose (NOT CI platform name). One of:
|
|
323
|
+
aidlc-gate — AIDLC phase gate checks
|
|
324
|
+
consistency-check — Doc/code consistency checks
|
|
325
|
+
pre-commit — Pre-commit hook template
|
|
326
|
+
--render Render the template to stdout
|
|
327
|
+
--json Output in JSON format
|
|
328
|
+
|
|
329
|
+
Examples:
|
|
330
|
+
phasegate ci:generate-template --preset standard --type aidlc-gate
|
|
331
|
+
phasegate ci:generate-template --preset strict --type pre-commit --render`,
|
|
332
|
+
};
|
|
333
|
+
|
|
334
|
+
function printSubcommandHelp(command: string): void {
|
|
335
|
+
const help = SUBCOMMAND_HELP[command];
|
|
336
|
+
if (help) {
|
|
337
|
+
console.log(help);
|
|
338
|
+
} else {
|
|
339
|
+
console.log(`Usage: phasegate ${command} [options]`);
|
|
340
|
+
console.log("(use 'phasegate --help' for the full command reference)");
|
|
341
|
+
}
|
|
342
|
+
}
|
|
343
|
+
|
|
222
344
|
/** フラグとその値を除いた位置引数のみを返す */
|
|
223
345
|
function parsePositionalArgs(args: readonly string[], flagsWithValues: readonly string[] = []): string[] {
|
|
224
346
|
const result: string[] = [];
|
|
@@ -333,6 +455,27 @@ function toL1Config(resolvedConfig: HarnessConfigV2) {
|
|
|
333
455
|
* HarnessConfigV2 (resolved) から biome-ast-engine が期待する architecture 情報を抽出する。
|
|
334
456
|
* architecture が未設定の場合は undefined を返し、biome-ast-engine 側の default (clean) に委ねる。
|
|
335
457
|
*/
|
|
458
|
+
/**
|
|
459
|
+
* HarnessConfigV2 (resolved) から validator-system の `createValidatorSystemModule` が
|
|
460
|
+
* 期待する shape (`{ project: { preset }, layers: { L2/L3/L4: { enabled } } }`) に変換する。
|
|
461
|
+
*
|
|
462
|
+
* WI-091 finding #1 follow-up: 直接 resolvedConfig を渡すと preset-style の
|
|
463
|
+
* `validators: ["drift-detector"]` が validator-code (L4-001/002/003) を上書きし
|
|
464
|
+
* 全 SKIP になる症状が出るため、`enabled` field のみ thread し validators の
|
|
465
|
+
* 解決は composition root 側の defaultValidators[layer] フォールバックに委ねる。
|
|
466
|
+
*/
|
|
467
|
+
function toValidatorSystemConfig(resolvedConfig: HarnessConfigV2 | undefined): object | undefined {
|
|
468
|
+
if (!resolvedConfig) return undefined;
|
|
469
|
+
return {
|
|
470
|
+
project: { preset: resolvedConfig.project.preset },
|
|
471
|
+
layers: {
|
|
472
|
+
L2: { enabled: resolvedConfig.layers.L2.enabled },
|
|
473
|
+
L3: { enabled: resolvedConfig.layers.L3.enabled },
|
|
474
|
+
L4: { enabled: resolvedConfig.layers.L4.enabled },
|
|
475
|
+
},
|
|
476
|
+
};
|
|
477
|
+
}
|
|
478
|
+
|
|
336
479
|
function toArchitectureInput(resolvedConfig: HarnessConfigV2) {
|
|
337
480
|
if (!resolvedConfig.architecture) {
|
|
338
481
|
return undefined;
|
|
@@ -478,6 +621,12 @@ async function main(): Promise<void> {
|
|
|
478
621
|
process.exit(0);
|
|
479
622
|
}
|
|
480
623
|
|
|
624
|
+
// Pre-dispatch: 全 subcommand で --help / -h を最優先で解釈し usage 出力 (副作用走行を防ぐ — WI-091 finding #3)
|
|
625
|
+
if (hasFlag(args, "--help") || hasFlag(args, "-h")) {
|
|
626
|
+
printSubcommandHelp(command);
|
|
627
|
+
process.exit(0);
|
|
628
|
+
}
|
|
629
|
+
|
|
481
630
|
const json = hasFlag(args, "--json");
|
|
482
631
|
|
|
483
632
|
// Cross-unit wiring: 設定を先に解決し、各Unit に注入する
|
|
@@ -848,7 +997,7 @@ async function main(): Promise<void> {
|
|
|
848
997
|
|
|
849
998
|
// ── validator-system ──
|
|
850
999
|
case "validate": {
|
|
851
|
-
const mod = createValidatorSystemModule();
|
|
1000
|
+
const mod = createValidatorSystemModule(toValidatorSystemConfig(resolvedConfig));
|
|
852
1001
|
const layer = parseFlag(args, "--layer") as "L0" | "L2" | "L3" | "L4" | "all" | undefined;
|
|
853
1002
|
const unit = parseFlag(args, "--unit");
|
|
854
1003
|
const phase = parseFlag(args, "--phase");
|
|
@@ -69,6 +69,10 @@ export class RunL4ValidatorsUseCase {
|
|
|
69
69
|
throw new ValidatorExecutionError(`Failed to get L4 LayerConfig: ${err instanceof Error ? err.message : String(err)}`, err);
|
|
70
70
|
}
|
|
71
71
|
|
|
72
|
+
if (!layerConfig.enabled) {
|
|
73
|
+
return [];
|
|
74
|
+
}
|
|
75
|
+
|
|
72
76
|
const results = this.executionService.execute(definitions, [layerConfig]);
|
|
73
77
|
const overrideMap = new Map<string, ValidationResult>(results.map((result) => [result.validatorId.value, result]));
|
|
74
78
|
|
package/scripts/harness/validator-system/infrastructure/adapters/markdown-design-document-adapter.ts
CHANGED
|
@@ -52,7 +52,15 @@ function extractConceptNames(markdown: string): string[] {
|
|
|
52
52
|
// 既知のメタ見出しは暗黙的にスキップ
|
|
53
53
|
if (isMetaHeading(name)) continue;
|
|
54
54
|
// 名前から末尾のスキップマーカーを落とす (念のため)
|
|
55
|
-
|
|
55
|
+
// WI-091 finding #5: `(〜)` / `(〜)` qualifier (例: `(エンティティ・新規)`) を strip
|
|
56
|
+
// して code 側の class 名と exact match できるようにする
|
|
57
|
+
const stripped = name
|
|
58
|
+
.replace(SKIP_MARKER, '')
|
|
59
|
+
.replace(/[((][^))]*[))]/g, '')
|
|
60
|
+
.trim();
|
|
61
|
+
if (stripped.length > 0) {
|
|
62
|
+
headings.push(stripped);
|
|
63
|
+
}
|
|
56
64
|
}
|
|
57
65
|
return headings;
|
|
58
66
|
}
|