phasegate 0.128.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 CHANGED
@@ -7,6 +7,18 @@ 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
+
10
22
  ## [0.128.0] - 2026-05-08
11
23
 
12
24
  ### Fixed
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "phasegate",
3
- "version": "0.128.0",
3
+ "version": "0.129.0",
4
4
  "packageManager": "pnpm@10.30.1",
5
5
  "description": "Phasegate — AI-agnostic quality defense toolkit. Enforces structural integrity between design intent and code.",
6
6
  "license": "MIT",
@@ -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';
@@ -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(
@@ -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";
@@ -455,27 +456,6 @@ function toL1Config(resolvedConfig: HarnessConfigV2) {
455
456
  * HarnessConfigV2 (resolved) から biome-ast-engine が期待する architecture 情報を抽出する。
456
457
  * architecture が未設定の場合は undefined を返し、biome-ast-engine 側の default (clean) に委ねる。
457
458
  */
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
-
479
459
  function toArchitectureInput(resolvedConfig: HarnessConfigV2) {
480
460
  if (!resolvedConfig.architecture) {
481
461
  return undefined;