phasegate 0.134.0 → 0.135.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 +11 -0
- package/bin/phasegate +2 -0
- package/docs/contracts/lesson-artifact.schema.json +62 -0
- package/docs/contracts/requirement-test-matrix.schema.json +62 -0
- package/docs/guide/layer-model.md +2 -2
- package/docs/principles/architecture-philosophy.md +26 -55
- package/docs/principles/model-routing.md +30 -165
- package/docs/principles/testing-rules.md +66 -648
- package/package.json +4 -3
- package/scripts/harness/config-foundation/application/mappers/validator-system-config-mapper.ts +2 -2
- package/scripts/harness/config-foundation/infrastructure/presets/minimal.json +1 -1
- package/scripts/harness/config-foundation/infrastructure/presets/standard.json +1 -1
- package/scripts/harness/config-foundation/infrastructure/presets/strict.json +1 -1
- package/scripts/harness/harness-error/infrastructure/adapters/validator-registry-bridge-adapter.ts +2 -0
- package/scripts/harness/harness-error/infrastructure/registry/l4-error-definitions.ts +14 -0
- package/scripts/harness/phase2-extensions/composition-root.ts +7 -1
- package/scripts/harness/phase2-extensions/infrastructure/adapters/file-system-document-scanner-adapter.ts +16 -2
- package/scripts/harness/phase2-extensions/infrastructure/adapters/harness-config-freshness-adapter.ts +13 -2
- package/scripts/harness/phase2-extensions/infrastructure/adapters/regex-pointer-extractor-adapter.ts +35 -4
- package/scripts/harness/quick-mode/infrastructure/adapters/validator-system-validator-id-registry-adapter.ts +1 -1
- package/scripts/harness/skill-quality/infrastructure/adapters/validator-id-registry-bridge-adapter.ts +1 -1
- package/scripts/harness/validator-system/application/dto/run-l4-validators-input.ts +1 -0
- package/scripts/harness/validator-system/application/use-cases/run-full-validation-usecase.ts +1 -0
- package/scripts/harness/validator-system/application/use-cases/run-l4-validators-usecase.ts +133 -3
- package/scripts/harness/validator-system/composition-root.ts +8 -2
- package/scripts/harness/validator-system/domain/value-objects/validator-id.ts +11 -4
- package/scripts/harness/validator-system/infrastructure/adapters/biome-ast-source-code-analyzer-adapter.ts +29 -10
- package/scripts/harness/validator-system/infrastructure/adapters/harness-config-validator-config-adapter.ts +11 -2
|
@@ -12,9 +12,23 @@ import { basename, join, relative, sep } from 'node:path';
|
|
|
12
12
|
|
|
13
13
|
const HARNESS_ROOT = join(process.cwd(), 'scripts', 'harness');
|
|
14
14
|
|
|
15
|
+
export interface BiomeAstSourceCodeAnalyzerAdapterOptions {
|
|
16
|
+
readonly sourceRoot?: string;
|
|
17
|
+
/** スキャン対象から除外するパスパターン(デフォルト: テストディレクトリを除外) */
|
|
18
|
+
readonly excludePattern?: RegExp;
|
|
19
|
+
}
|
|
20
|
+
|
|
15
21
|
export class BiomeAstSourceCodeAnalyzerAdapter implements SourceCodeAnalyzerPort {
|
|
22
|
+
private readonly sourceRoot: string;
|
|
23
|
+
private readonly excludePattern: RegExp;
|
|
24
|
+
|
|
25
|
+
constructor(options: BiomeAstSourceCodeAnalyzerAdapterOptions = {}) {
|
|
26
|
+
this.sourceRoot = options.sourceRoot ?? HARNESS_ROOT;
|
|
27
|
+
this.excludePattern = options.excludePattern ?? /__tests__\//;
|
|
28
|
+
}
|
|
29
|
+
|
|
16
30
|
async analyzeExports(targetUnits?: readonly string[]): Promise<readonly SourceAnalysisResult[]> {
|
|
17
|
-
const targetFiles = await collectTargetFiles(targetUnits);
|
|
31
|
+
const targetFiles = await collectTargetFiles(this.sourceRoot, this.excludePattern, targetUnits);
|
|
18
32
|
if (targetFiles.length === 0) return [];
|
|
19
33
|
|
|
20
34
|
const program = ts.createProgram(targetFiles, {
|
|
@@ -30,7 +44,7 @@ export class BiomeAstSourceCodeAnalyzerAdapter implements SourceCodeAnalyzerPort
|
|
|
30
44
|
const sourceFile = program.getSourceFile(filePath);
|
|
31
45
|
if (!sourceFile) continue;
|
|
32
46
|
results.push({
|
|
33
|
-
unitName: resolveUnitName(filePath),
|
|
47
|
+
unitName: resolveUnitName(this.sourceRoot, filePath),
|
|
34
48
|
filePath,
|
|
35
49
|
exports: extractExports(sourceFile),
|
|
36
50
|
imports: extractImports(sourceFile),
|
|
@@ -134,26 +148,31 @@ function extractImports(sourceFile: ts.SourceFile): SourceAnalysisResult['import
|
|
|
134
148
|
return imports;
|
|
135
149
|
}
|
|
136
150
|
|
|
137
|
-
async function collectTargetFiles(
|
|
151
|
+
async function collectTargetFiles(
|
|
152
|
+
sourceRoot: string,
|
|
153
|
+
excludePattern: RegExp,
|
|
154
|
+
targetUnits?: readonly string[],
|
|
155
|
+
): Promise<readonly string[]> {
|
|
138
156
|
const roots = targetUnits && targetUnits.length > 0
|
|
139
|
-
? targetUnits.map((unit) => join(
|
|
140
|
-
: [
|
|
157
|
+
? targetUnits.map((unit) => join(sourceRoot, unit))
|
|
158
|
+
: [sourceRoot];
|
|
141
159
|
|
|
142
160
|
const files: string[] = [];
|
|
143
161
|
for (const root of roots) {
|
|
144
|
-
files.push(...await walkTsFiles(root));
|
|
162
|
+
files.push(...await walkTsFiles(root, excludePattern));
|
|
145
163
|
}
|
|
146
164
|
|
|
147
165
|
return files;
|
|
148
166
|
}
|
|
149
167
|
|
|
150
|
-
async function walkTsFiles(root: string): Promise<string[]> {
|
|
168
|
+
async function walkTsFiles(root: string, excludePattern: RegExp): Promise<string[]> {
|
|
151
169
|
try {
|
|
152
170
|
const entries = await readdir(root, { withFileTypes: true });
|
|
153
171
|
const files = await Promise.all(entries.map(async (entry) => {
|
|
154
172
|
const fullPath = join(root, entry.name);
|
|
173
|
+
if (excludePattern.test(fullPath)) return [];
|
|
155
174
|
if (entry.isDirectory()) {
|
|
156
|
-
return walkTsFiles(fullPath);
|
|
175
|
+
return walkTsFiles(fullPath, excludePattern);
|
|
157
176
|
}
|
|
158
177
|
return fullPath.endsWith('.ts') ? [fullPath] : [];
|
|
159
178
|
}));
|
|
@@ -163,8 +182,8 @@ async function walkTsFiles(root: string): Promise<string[]> {
|
|
|
163
182
|
}
|
|
164
183
|
}
|
|
165
184
|
|
|
166
|
-
function resolveUnitName(filePath: string): string {
|
|
167
|
-
const relativePath = relative(
|
|
185
|
+
function resolveUnitName(sourceRoot: string, filePath: string): string {
|
|
186
|
+
const relativePath = relative(sourceRoot, filePath);
|
|
168
187
|
const [firstSegment] = relativePath.split(sep);
|
|
169
188
|
return firstSegment || basename(filePath);
|
|
170
189
|
}
|
|
@@ -6,6 +6,7 @@
|
|
|
6
6
|
* HarnessConfigV2からLayerConfig VOを構築する
|
|
7
7
|
*/
|
|
8
8
|
import { LayerConfig } from '../../domain/value-objects/layer-config.js';
|
|
9
|
+
import { ValidatorId } from '../../domain/value-objects/validator-id.js';
|
|
9
10
|
import type { ValidatorConfigPort } from '../../domain/ports/validator-config-port.js';
|
|
10
11
|
|
|
11
12
|
export interface HarnessConfigLayers {
|
|
@@ -39,7 +40,7 @@ export class HarnessConfigValidatorConfigAdapter implements ValidatorConfigPort
|
|
|
39
40
|
const defaultValidators: Record<string, string[]> = {
|
|
40
41
|
L2: ['L2-001', 'L2-002', 'L2-003'],
|
|
41
42
|
L3: ['L3-001', 'L3-002', 'L3-003', 'L3-004'],
|
|
42
|
-
L4: ['L4-001', 'L4-002', 'L4-003'],
|
|
43
|
+
L4: ['L4-001', 'L4-002', 'L4-003', 'L4-004', 'L4-005'],
|
|
43
44
|
};
|
|
44
45
|
|
|
45
46
|
const thresholds: Record<string, number> = {};
|
|
@@ -62,10 +63,18 @@ export class HarnessConfigValidatorConfigAdapter implements ValidatorConfigPort
|
|
|
62
63
|
return LayerConfig.create({
|
|
63
64
|
layer,
|
|
64
65
|
enabled: layerData.enabled !== false,
|
|
65
|
-
validatorIds: layerData.validators ?? defaultValidators[layer],
|
|
66
|
+
validatorIds: (layerData.validators ?? defaultValidators[layer]).map((idOrName) => this.normalizeValidatorId(idOrName)),
|
|
66
67
|
thresholds,
|
|
67
68
|
strictOnly: layerData.strictOnly ?? strictOnly,
|
|
68
69
|
preset,
|
|
69
70
|
});
|
|
70
71
|
}
|
|
72
|
+
|
|
73
|
+
private normalizeValidatorId(idOrName: string): string {
|
|
74
|
+
try {
|
|
75
|
+
return ValidatorId.create(idOrName).value;
|
|
76
|
+
} catch {
|
|
77
|
+
return ValidatorId.fromName(idOrName).value;
|
|
78
|
+
}
|
|
79
|
+
}
|
|
71
80
|
}
|