phasegate 0.127.0 → 0.129.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 +27 -0
- package/package.json +1 -1
- package/scripts/harness/config-foundation/application/mappers/validator-system-config-mapper.ts +19 -0
- package/scripts/harness/config-foundation/index.ts +1 -0
- package/scripts/harness/harness-api/infrastructure/adapters/validator-system-execution-adapter.ts +19 -3
- package/scripts/harness/integrations/pre-commit.ts +17 -2
- package/scripts/harness/main.ts +2 -1
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.129.0] - 2026-05-08
|
|
11
|
+
|
|
12
|
+
### Fixed
|
|
13
|
+
|
|
14
|
+
- **WI-092 — `createValidatorSystemModule()` 残 5 site の config threading 漏れを sweep** — v0.128.0 で `validate --layer L4` 経路のみ修正した DI 配線漏れの follow-up として、harness-api / pre-commit 経路でも user config (`layers.L2/L3/L4.enabled`) が validator-system composition root に渡るよう修正。
|
|
15
|
+
- **対象**: `ValidatorSystemExecutionAdapter` の `runL3Validators()` / `runAllValidators()` / `runDriftDetection()`、および `runPreCommitCli()` / `runCommitMsgCli()` の計 5 site。
|
|
16
|
+
- **共通 translator 化**: `toValidatorSystemConfig()` を `config-foundation/application/mappers/validator-system-config-mapper.ts` に移動し、`main.ts` / harness-api adapter / pre-commit CLI から共通利用。渡す値は `project.preset` と `layers.L2/L3/L4.enabled` のみに限定し、`validators` 配列は渡さない。validator catalog は validator-system の default 解決に委ねる。
|
|
17
|
+
- **fallback**: `phasegate.config.json` 不在時のみ validator-system の default config にフォールバック。不正 config は従来通り runtime error として扱う。
|
|
18
|
+
- **検証 (publish 前 local/self-host)**: PhaseGate 自身の `phasegate.config.json` (`layers.L4.enabled: false`) で `validate --layer L4` は exit 0 / PASS / validator 0 件。`phasegate:detect-drift --json` は drift detection direct 経路を維持し、既存 drift 2065 件により exit 1。
|
|
19
|
+
- **テスト**: `pnpm test` は 452 files / 3518 tests pass。対象テスト 3 files / 11 tests pass。変更ファイルの `validate-metadata` pass。
|
|
20
|
+
- **post-publish dogfood**: npm publish 後に、別ディレクトリで `npx phasegate@0.129.0` を使って `phasegate:detect-drift` / `validate --layer L4` / pre-commit 経路を確認する。
|
|
21
|
+
|
|
22
|
+
## [0.128.0] - 2026-05-08
|
|
23
|
+
|
|
24
|
+
### Fixed
|
|
25
|
+
|
|
26
|
+
- **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 で機能していないことが判明したため緊急修正。
|
|
27
|
+
- **症状**: `phasegate.config.json` に `layers.L4.enabled: false` を設定して `phasegate validate --layer L4` を実行しても、L4-001/002 が `[PASS]` (実際には実行された) となり、L4-003 だけが `[SKIP]` (strictOnly のため)。期待挙動は L4-001/002/003 すべて `[SKIP]`。
|
|
28
|
+
- **根本原因**: `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 が再発した形。
|
|
29
|
+
- **修正**: `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]` フォールバックに委ねる。
|
|
30
|
+
- **テスト**: spawn 経由結合テスト 2 ケース (`scripts/harness/__tests__/integration/harness-api/validate-layer-config.integration.test.ts`) 新規追加:
|
|
31
|
+
- `layers.L4.enabled: false` で `validate --layer L4` 実行時、L4 全 validator が `[SKIP]` 表示 + 総合判定 PASS + exit 0
|
|
32
|
+
- `layers.L4.enabled: true` で L4 validator が enabled で実行 (回帰防止)
|
|
33
|
+
- 全 3516 テスト (前回 3514 + 新規 2) グリーン、L1 lint 違反なし。
|
|
34
|
+
- **スコープ外 (別 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` がスコープ外のため別途修正。
|
|
35
|
+
- **教訓 (memory 反映)**: `feedback_dogfood_before_release.md` に「`paths` config / Artifact / PhaseConfigProviderPort 改修」と並べて「composition root の `createValidatorSystemModule(config?)` 経路」を追記。`createValidatorSystemModule()` を呼ぶ全 site (現状 6 箇所) で config が threading されているか毎回 grep 確認する規律を強化する。
|
|
36
|
+
|
|
10
37
|
## [0.127.0] - 2026-05-08
|
|
11
38
|
|
|
12
39
|
### Fixed
|
package/package.json
CHANGED
package/scripts/harness/config-foundation/application/mappers/validator-system-config-mapper.ts
ADDED
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @layer application
|
|
3
|
+
* @unit config-foundation
|
|
4
|
+
* @work-item-id WI-092
|
|
5
|
+
*/
|
|
6
|
+
import type { HarnessConfigV2 } from '../../domain/harness-config.js';
|
|
7
|
+
|
|
8
|
+
export function toValidatorSystemConfig(resolvedConfig: HarnessConfigV2 | undefined): object | undefined {
|
|
9
|
+
if (!resolvedConfig) return undefined;
|
|
10
|
+
|
|
11
|
+
return {
|
|
12
|
+
project: { preset: resolvedConfig.project.preset },
|
|
13
|
+
layers: {
|
|
14
|
+
L2: { enabled: resolvedConfig.layers.L2.enabled },
|
|
15
|
+
L3: { enabled: resolvedConfig.layers.L3.enabled },
|
|
16
|
+
L4: { enabled: resolvedConfig.layers.L4.enabled },
|
|
17
|
+
},
|
|
18
|
+
};
|
|
19
|
+
}
|
|
@@ -4,6 +4,7 @@
|
|
|
4
4
|
export { createConfigFoundationModule } from './composition-root.js';
|
|
5
5
|
|
|
6
6
|
export { LoadResolvedConfigUseCase } from './application/usecases/load-resolved-config-use-case.js';
|
|
7
|
+
export { toValidatorSystemConfig } from './application/mappers/validator-system-config-mapper.js';
|
|
7
8
|
|
|
8
9
|
export type { ResolvedConfigOutput } from './application/dto/resolved-config-output.js';
|
|
9
10
|
export type { FeatureToggleResult } from './application/dto/feature-toggle-result.js';
|
package/scripts/harness/harness-api/infrastructure/adapters/validator-system-execution-adapter.ts
CHANGED
|
@@ -1,10 +1,14 @@
|
|
|
1
|
+
// @unit harness-api
|
|
1
2
|
// @layer infrastructure
|
|
3
|
+
// @work-item-id WI-092
|
|
2
4
|
// validator-system-execution-adapter.ts — ValidatorSystemExecutionAdapter
|
|
3
5
|
// Wave 2完了後にリアル実装へ差し替え(旧: @stub: wave2-pending)
|
|
4
6
|
|
|
5
7
|
import type { ValidatorExecutionPort } from '../../domain/ports/validator-execution-port.js';
|
|
6
8
|
import type { ValidatorCheckItem } from '../../domain/value-objects/ci-check-result.js';
|
|
7
9
|
import type { DriftItem } from '../../domain/value-objects/drift-report-summary.js';
|
|
10
|
+
import { toValidatorSystemConfig } from '../../../config-foundation/application/mappers/validator-system-config-mapper.js';
|
|
11
|
+
import { ConfigNotFoundError } from '../../../config-foundation/infrastructure/repositories/file-system-config-repository.js';
|
|
8
12
|
|
|
9
13
|
// Override interface preserved for testing
|
|
10
14
|
export interface IValidatorSystemStub {
|
|
@@ -21,10 +25,22 @@ export class ValidatorSystemExecutionAdapter implements ValidatorExecutionPort {
|
|
|
21
25
|
}
|
|
22
26
|
|
|
23
27
|
private static createRealImpl(): IValidatorSystemStub {
|
|
28
|
+
async function loadValidatorSystemConfig(): Promise<object | undefined> {
|
|
29
|
+
const { createConfigFoundationModule } = await import('../../../config-foundation/composition-root.js');
|
|
30
|
+
const configMod = createConfigFoundationModule();
|
|
31
|
+
try {
|
|
32
|
+
const resolvedConfig = await configMod.usecases.loadResolvedConfigUseCase.execute();
|
|
33
|
+
return toValidatorSystemConfig(resolvedConfig.config);
|
|
34
|
+
} catch (err) {
|
|
35
|
+
if (err instanceof ConfigNotFoundError) return undefined;
|
|
36
|
+
throw err;
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
|
|
24
40
|
return {
|
|
25
41
|
async runL3Validators(): Promise<ValidatorCheckItem[]> {
|
|
26
42
|
const { createValidatorSystemModule } = await import('../../../validator-system/composition-root.js');
|
|
27
|
-
const mod = createValidatorSystemModule();
|
|
43
|
+
const mod = createValidatorSystemModule(await loadValidatorSystemConfig());
|
|
28
44
|
const results = await mod.runL3ValidatorsUseCase.execute({ targetPaths: [] });
|
|
29
45
|
return results.map((r) => ({
|
|
30
46
|
validatorId: r.validatorId,
|
|
@@ -35,7 +51,7 @@ export class ValidatorSystemExecutionAdapter implements ValidatorExecutionPort {
|
|
|
35
51
|
|
|
36
52
|
async runAllValidators(): Promise<ValidatorCheckItem[]> {
|
|
37
53
|
const { createValidatorSystemModule } = await import('../../../validator-system/composition-root.js');
|
|
38
|
-
const mod = createValidatorSystemModule();
|
|
54
|
+
const mod = createValidatorSystemModule(await loadValidatorSystemConfig());
|
|
39
55
|
const report = await mod.runFullValidationUseCase.execute({ targetPaths: [], unitName: '', currentPhase: '' });
|
|
40
56
|
return report.results.map((r) => ({
|
|
41
57
|
validatorId: r.validatorId,
|
|
@@ -48,7 +64,7 @@ export class ValidatorSystemExecutionAdapter implements ValidatorExecutionPort {
|
|
|
48
64
|
// ISSUE-005 P1-5: L4-001 の DriftDetectionService を直接呼び出し、
|
|
49
65
|
// phasegate:detect-drift と validate --layer L4 の結果を一致させる
|
|
50
66
|
const { createValidatorSystemModule } = await import('../../../validator-system/composition-root.js');
|
|
51
|
-
const mod = createValidatorSystemModule();
|
|
67
|
+
const mod = createValidatorSystemModule(await loadValidatorSystemConfig());
|
|
52
68
|
const reports = await mod.driftDetectionService.detect();
|
|
53
69
|
return reports.map((r) => ({
|
|
54
70
|
direction: r.direction,
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* @unit harness-api
|
|
3
3
|
* @layer presentation
|
|
4
|
+
* @work-item-id WI-092
|
|
4
5
|
*
|
|
5
6
|
* Pre-commit CLI entry.
|
|
6
7
|
* Runs L2 validators against staged TypeScript files AND design-document
|
|
@@ -15,6 +16,9 @@
|
|
|
15
16
|
|
|
16
17
|
import { execSync } from "node:child_process";
|
|
17
18
|
import { readFile } from "node:fs/promises";
|
|
19
|
+
import { createConfigFoundationModule } from "../config-foundation/composition-root.js";
|
|
20
|
+
import { toValidatorSystemConfig } from "../config-foundation/application/mappers/validator-system-config-mapper.js";
|
|
21
|
+
import { ConfigNotFoundError } from "../config-foundation/infrastructure/repositories/file-system-config-repository.js";
|
|
18
22
|
import { createTraceabilityModelModule } from "../traceability-model/composition-root.js";
|
|
19
23
|
import type { ValidateMetadataCommandOutput } from "../traceability-model/presentation/cli/validate-metadata-command-handler.js";
|
|
20
24
|
import type { AggregatedValidationReport } from "../validator-system/application/dto/aggregated-validation-report.js";
|
|
@@ -34,6 +38,17 @@ const WORK_ITEM_PATH_PATTERN = /(?:^|\/)WI-\d+(?:\/|$)/;
|
|
|
34
38
|
const WORK_ITEM_TRAILER_PATTERN = /^Work-Item:\s*WI-\d+\s*$/m;
|
|
35
39
|
const TEST_FILE_SUFFIXES = Object.freeze([".test.ts", ".test.tsx", ".spec.ts", ".spec.tsx"]);
|
|
36
40
|
|
|
41
|
+
async function loadValidatorSystemConfig(): Promise<object | undefined> {
|
|
42
|
+
const configMod = createConfigFoundationModule();
|
|
43
|
+
try {
|
|
44
|
+
const resolvedConfig = await configMod.usecases.loadResolvedConfigUseCase.execute();
|
|
45
|
+
return toValidatorSystemConfig(resolvedConfig.config);
|
|
46
|
+
} catch (err) {
|
|
47
|
+
if (err instanceof ConfigNotFoundError) return undefined;
|
|
48
|
+
throw err;
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
|
|
37
52
|
function isTestFile(path: string): boolean {
|
|
38
53
|
return TEST_FILE_SUFFIXES.some((suffix) => path.endsWith(suffix));
|
|
39
54
|
}
|
|
@@ -303,7 +318,7 @@ export async function runPreCommit(
|
|
|
303
318
|
export async function runPreCommitCli(): Promise<void> {
|
|
304
319
|
try {
|
|
305
320
|
const stagedFiles = getStagedFiles();
|
|
306
|
-
const validatorMod = createValidatorSystemModule();
|
|
321
|
+
const validatorMod = createValidatorSystemModule(await loadValidatorSystemConfig());
|
|
307
322
|
const traceabilityMod = createTraceabilityModelModule(process.cwd());
|
|
308
323
|
|
|
309
324
|
const result = await runPreCommit(
|
|
@@ -335,7 +350,7 @@ export async function runCommitMsgCli(commitMessagePath: string | undefined): Pr
|
|
|
335
350
|
|
|
336
351
|
const stagedFiles = getStagedFiles();
|
|
337
352
|
const commitMessage = await readFile(commitMessagePath, "utf-8");
|
|
338
|
-
const validatorMod = createValidatorSystemModule();
|
|
353
|
+
const validatorMod = createValidatorSystemModule(await loadValidatorSystemConfig());
|
|
339
354
|
const traceabilityMod = createTraceabilityModelModule(process.cwd());
|
|
340
355
|
|
|
341
356
|
const result = await runPreCommit(
|
package/scripts/harness/main.ts
CHANGED
|
@@ -14,6 +14,7 @@ import { createAdrFoundationModule } from "./adr-foundation/composition-root.js"
|
|
|
14
14
|
import { createBiomeAstEngineModule } from "./biome-ast-engine/composition-root.js";
|
|
15
15
|
import { buildCiGovernance } from "./ci-governance/composition-root.js";
|
|
16
16
|
import { toPhaseConfigSection } from "./config-foundation/application/mappers/phase-config-section-mapper.js";
|
|
17
|
+
import { toValidatorSystemConfig } from "./config-foundation/application/mappers/validator-system-config-mapper.js";
|
|
17
18
|
import { createConfigFoundationModule } from "./config-foundation/composition-root.js";
|
|
18
19
|
import { ConfigValidationError } from "./config-foundation/domain/errors/config-validation-error.js";
|
|
19
20
|
import type { HarnessConfigV2 } from "./config-foundation/domain/harness-config.js";
|
|
@@ -976,7 +977,7 @@ async function main(): Promise<void> {
|
|
|
976
977
|
|
|
977
978
|
// ── validator-system ──
|
|
978
979
|
case "validate": {
|
|
979
|
-
const mod = createValidatorSystemModule();
|
|
980
|
+
const mod = createValidatorSystemModule(toValidatorSystemConfig(resolvedConfig));
|
|
980
981
|
const layer = parseFlag(args, "--layer") as "L0" | "L2" | "L3" | "L4" | "all" | undefined;
|
|
981
982
|
const unit = parseFlag(args, "--unit");
|
|
982
983
|
const phase = parseFlag(args, "--phase");
|