phasegate 0.191.0 → 0.222.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 +15 -0
- package/README.ja.md +52 -15
- package/README.md +39 -11
- package/docs/ADR/030-injection-threat-model-and-trust-root.md +145 -0
- package/docs/guide/hooks-integration.md +101 -1
- package/docs/guide/installation.md +1 -1
- package/docs/guide/quick-vs-full-mode.md +1 -1
- package/docs/guide/skills-overview.md +7 -8
- package/package.json +1 -1
- package/scripts/harness/agent-integration/presentation/phasegate-status-context.ts +131 -63
- package/scripts/harness/agent-integration/presentation/session-start-hook.ts +31 -4
- package/scripts/harness/agent-integration/presentation/spotlight.ts +65 -0
- package/scripts/harness/biome-ast-engine/application/mappers/build-harness-error-payload-output-mapper.ts +3 -3
- package/scripts/harness/biome-ast-engine/infrastructure/mappers/rule-violation-code-mapper.ts +3 -3
- package/scripts/harness/biome-ast-engine/presentation/cli/harness-lint-command-handler.ts +6 -4
- package/scripts/harness/ci-governance/application/dto/pin-integrity-input.ts +8 -0
- package/scripts/harness/ci-governance/application/dto/pin-integrity-output.ts +9 -0
- package/scripts/harness/ci-governance/application/dto/verify-integrity-input.ts +7 -0
- package/scripts/harness/ci-governance/application/dto/verify-integrity-output.ts +10 -0
- package/scripts/harness/ci-governance/application/usecases/pin-integrity-usecase.ts +60 -0
- package/scripts/harness/ci-governance/application/usecases/verify-integrity-usecase.ts +46 -0
- package/scripts/harness/ci-governance/composition-root.ts +67 -64
- package/scripts/harness/ci-governance/domain/ports/integrity-manifest-repository-port.ts +14 -0
- package/scripts/harness/ci-governance/domain/ports/sha256-hasher-port.ts +10 -0
- package/scripts/harness/ci-governance/domain/services/integrity-checker.ts +42 -0
- package/scripts/harness/ci-governance/domain/value-objects/integrity-drift.ts +16 -0
- package/scripts/harness/ci-governance/domain/value-objects/integrity-manifest.ts +49 -0
- package/scripts/harness/ci-governance/domain/value-objects/integrity-target.ts +40 -0
- package/scripts/harness/ci-governance/infrastructure/adapters/file-system-sha256-hasher-adapter.ts +17 -0
- package/scripts/harness/ci-governance/infrastructure/adapters/harness-api-command-existence-adapter.ts +7 -73
- package/scripts/harness/ci-governance/infrastructure/adapters/integrity-manifest-json-repository-adapter.ts +83 -0
- package/scripts/harness/ci-governance/presentation/handlers/integrity-handler.ts +76 -0
- package/scripts/harness/config-foundation/application/mappers/validator-system-config-mapper.ts +60 -28
- package/scripts/harness/harness-api/domain/value-objects/ci-check-result.ts +33 -8
- package/scripts/harness/harness-api/domain/value-objects/known-harness-commands.ts +90 -0
- package/scripts/harness/harness-error/infrastructure/registry/l1-error-definitions.ts +9 -9
- package/scripts/harness/installation/application/bundled-skill-selection.ts +2 -5
- package/scripts/harness/installation/application/usecases/run-reconcile.ts +69 -1
- package/scripts/harness/main.ts +257 -105
- package/scripts/harness/phase-dependency-model/infrastructure/filesystem/file-system-story-reflection-adapter.ts +65 -3
- package/scripts/harness/quick-mode/domain/services/quick-mode-judgment-engine.ts +44 -40
- package/scripts/harness/setup/skill-deployer.ts +2 -4
- package/scripts/harness/validator-system/application/use-cases/run-l2-validators-usecase.ts +82 -49
- package/scripts/harness/validator-system/application/use-cases/run-l3-validators-usecase.ts +133 -53
- package/scripts/harness/validator-system/composition-root.ts +153 -99
- package/scripts/harness/validator-system/domain/ports/coverage-attestation-gating-policy-port.ts +14 -0
- package/scripts/harness/validator-system/domain/ports/coverage-attestation-verification-policy-port.ts +30 -0
- package/scripts/harness/validator-system/domain/ports/injection-scan-policy-port.ts +14 -0
- package/scripts/harness/validator-system/domain/services/coverage-attestation-gating-service.ts +56 -0
- package/scripts/harness/validator-system/domain/services/coverage-attestation-verification-service.ts +45 -0
- package/scripts/harness/validator-system/domain/services/injection-pattern-scan-service.ts +118 -0
- package/scripts/harness/validator-system/domain/value-objects/attestation-verification-report.ts +59 -0
- package/scripts/harness/validator-system/domain/value-objects/coverage-gating-report.ts +67 -0
- package/scripts/harness/validator-system/domain/value-objects/injection-scan-report.ts +55 -0
- package/scripts/harness/validator-system/domain/value-objects/validator-id.ts +37 -31
- package/scripts/harness/validator-system/infrastructure/adapters/adr-foundation-reference-adapter.ts +13 -7
- package/scripts/harness/validator-system/infrastructure/adapters/file-system-coverage-attestation-gating-adapter.ts +87 -0
- package/scripts/harness/validator-system/infrastructure/adapters/file-system-coverage-attestation-verification-adapter.ts +165 -0
- package/scripts/harness/validator-system/infrastructure/adapters/file-system-injection-scan-adapter.ts +82 -0
- package/skills/README.md +1 -1
- package/skills/codebase-mapper/SKILL.md +1 -1
- package/skills/consistency-checker/references//343/203/201/343/202/247/343/203/203/343/202/257/343/203/252/343/202/271/343/203/210.md +1 -1
- package/skills/doc-health-checker/SKILL.md +148 -0
- package/skills/release-publisher/SKILL.md +101 -0
- package/skills/skill-creator/SKILL.md +74 -332
- package/skills/story-implementor/SKILL.md +52 -0
- package/skills/story-mapper/SKILL.md +4 -0
- package/skills/story-writer/SKILL.md +9 -0
- package/skills/uiux-designer/references/uiux-design-template.md +4 -4
- package/skills/unit-designer/SKILL.md +3 -1
- package/templates/.claude/scripts/deny-check.sh +260 -0
- package/skills/doc-freshness-checker/SKILL.md +0 -140
- package/skills/implementation-planner/SKILL.md +0 -169
- package/skills/implementation-planner/references/document-structure.md +0 -116
- package/skills/implementation-planner/references/plan-template.md +0 -177
- package/skills/implementation-planner/references/workflow.md +0 -164
- package/skills/pointer-validator/SKILL.md +0 -105
|
@@ -6,77 +6,93 @@
|
|
|
6
6
|
* @work-item-id WI-110 / WI-111 / WI-132 / WI-133 / WI-136 / WI-137 / WI-138 / WI-156
|
|
7
7
|
* @work-item-id WI-217
|
|
8
8
|
*/
|
|
9
|
-
|
|
10
|
-
import {
|
|
11
|
-
import {
|
|
12
|
-
import {
|
|
13
|
-
import {
|
|
14
|
-
import {
|
|
15
|
-
import {
|
|
16
|
-
import {
|
|
17
|
-
import {
|
|
18
|
-
import {
|
|
19
|
-
import { RunQuickModeUseCase } from
|
|
20
|
-
import {
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
import {
|
|
25
|
-
import {
|
|
26
|
-
import {
|
|
27
|
-
import {
|
|
28
|
-
import {
|
|
29
|
-
import {
|
|
30
|
-
import {
|
|
31
|
-
import {
|
|
32
|
-
import {
|
|
33
|
-
import {
|
|
34
|
-
import {
|
|
35
|
-
import {
|
|
36
|
-
import {
|
|
37
|
-
import {
|
|
38
|
-
import {
|
|
39
|
-
import {
|
|
40
|
-
import {
|
|
41
|
-
import {
|
|
42
|
-
import {
|
|
43
|
-
import {
|
|
44
|
-
import {
|
|
45
|
-
import {
|
|
46
|
-
import {
|
|
47
|
-
import {
|
|
48
|
-
import {
|
|
49
|
-
import {
|
|
50
|
-
import {
|
|
51
|
-
import {
|
|
52
|
-
import {
|
|
53
|
-
import {
|
|
9
|
+
|
|
10
|
+
import { join } from "node:path";
|
|
11
|
+
import { buildPhase2Extensions } from "../phase2-extensions/composition-root.js";
|
|
12
|
+
import { ValidationResultContractMapper } from "./application/mappers/validation-result-contract-mapper.js";
|
|
13
|
+
import { AggregateValidationResultsUseCase } from "./application/use-cases/aggregate-validation-results-usecase.js";
|
|
14
|
+
import { RunFullValidationUseCase } from "./application/use-cases/run-full-validation-usecase.js";
|
|
15
|
+
import { RunL1ValidatorsUseCase } from "./application/use-cases/run-l1-validators-usecase.js";
|
|
16
|
+
import { RunL2ValidatorsUseCase } from "./application/use-cases/run-l2-validators-usecase.js";
|
|
17
|
+
import { RunL3ValidatorsUseCase } from "./application/use-cases/run-l3-validators-usecase.js";
|
|
18
|
+
import { RunL4ValidatorsUseCase } from "./application/use-cases/run-l4-validators-usecase.js";
|
|
19
|
+
import { RunQuickModeUseCase } from "./application/use-cases/run-quick-mode-usecase.js";
|
|
20
|
+
import {
|
|
21
|
+
ArchitectureSemanticAnalysisService,
|
|
22
|
+
type ArchitectureSemanticPolicy,
|
|
23
|
+
} from "./domain/services/l4/architecture-semantic-analysis-service.js";
|
|
24
|
+
import { ConsistencyCheckService } from "./domain/services/l4/consistency-check-service.js";
|
|
25
|
+
import { DeadCodeDetectionService } from "./domain/services/l4/dead-code-detection-service.js";
|
|
26
|
+
import { DriftDetectionService } from "./domain/services/l4/drift-detection-service.js";
|
|
27
|
+
import { ValidatorExecutionService } from "./domain/services/validator-execution-service.js";
|
|
28
|
+
import { ValidatorRegistry } from "./domain/services/validator-registry.js";
|
|
29
|
+
import { ValidationRule } from "./domain/value-objects/validation-rule.js";
|
|
30
|
+
import { ValidatorDefinition } from "./domain/value-objects/validator-definition.js";
|
|
31
|
+
import { ValidatorId } from "./domain/value-objects/validator-id.js";
|
|
32
|
+
import { AdrFoundationReferenceAdapter } from "./infrastructure/adapters/adr-foundation-reference-adapter.js";
|
|
33
|
+
import { AstPerformanceScannerAdapter } from "./infrastructure/adapters/ast-performance-scanner-adapter.js";
|
|
34
|
+
import { BiomeAstSourceCodeAnalyzerAdapter } from "./infrastructure/adapters/biome-ast-source-code-analyzer-adapter.js";
|
|
35
|
+
import { BiomeAstTestQualityAnalyzerAdapter } from "./infrastructure/adapters/biome-ast-test-quality-analyzer-adapter.js";
|
|
36
|
+
import { CliCommandRegistryAdapter } from "./infrastructure/adapters/cli-command-registry-adapter.js";
|
|
37
|
+
import { E2eTestFileRegistryAdapter } from "./infrastructure/adapters/e2e-test-file-registry-adapter.js";
|
|
38
|
+
import { FileSystemArchitectureSemanticSourceAdapter } from "./infrastructure/adapters/file-system-architecture-semantic-source-adapter.js";
|
|
39
|
+
import { FileSystemContractTraceabilityPolicyAdapter } from "./infrastructure/adapters/file-system-contract-traceability-policy-adapter.js";
|
|
40
|
+
import { FileSystemCoverageAttestationGatingAdapter } from "./infrastructure/adapters/file-system-coverage-attestation-gating-adapter.js";
|
|
41
|
+
import { FileSystemCoverageAttestationVerificationAdapter } from "./infrastructure/adapters/file-system-coverage-attestation-verification-adapter.js";
|
|
42
|
+
import { FileSystemInjectionScanAdapter } from "./infrastructure/adapters/file-system-injection-scan-adapter.js";
|
|
43
|
+
import { FileSystemSecurityPatternScannerAdapter } from "./infrastructure/adapters/file-system-security-pattern-scanner-adapter.js";
|
|
44
|
+
import { FileSystemSkillCatalogDriftAdapter } from "./infrastructure/adapters/file-system-skill-catalog-drift-adapter.js";
|
|
45
|
+
import { FileSystemWorkItemReflectionAdapter } from "./infrastructure/adapters/file-system-work-item-reflection-adapter.js";
|
|
46
|
+
import { HarnessConfigValidatorConfigAdapter } from "./infrastructure/adapters/harness-config-validator-config-adapter.js";
|
|
47
|
+
import { ImportGraphSourceAnalysisAdapter } from "./infrastructure/adapters/import-graph-source-analysis-adapter.js";
|
|
48
|
+
import { ItTestFileAnalyzerAdapter } from "./infrastructure/adapters/it-test-file-analyzer-adapter.js";
|
|
49
|
+
import { JsonCoverageReportAdapter } from "./infrastructure/adapters/json-coverage-report-adapter.js";
|
|
50
|
+
import { MarkdownDesignDocumentAdapter } from "./infrastructure/adapters/markdown-design-document-adapter.js";
|
|
51
|
+
import { NyquistAcBoundCoveragePolicyAdapter } from "./infrastructure/adapters/nyquist-ac-bound-coverage-policy-adapter.js";
|
|
52
|
+
import { NyquistAcCoveragePolicyAdapter } from "./infrastructure/adapters/nyquist-ac-coverage-policy-adapter.js";
|
|
53
|
+
import { NyquistAcLevelTraceabilityAdapter } from "./infrastructure/adapters/nyquist-ac-level-traceability-adapter.js";
|
|
54
|
+
import { PhaseDependencyPhaseGatePolicyAdapter } from "./infrastructure/adapters/phase-dependency-phase-gate-policy-adapter.js";
|
|
55
|
+
import { SourceFileTextScannerAdapter } from "./infrastructure/adapters/source-file-text-scanner-adapter.js";
|
|
56
|
+
import { TraceabilityMetadataPolicyAdapter } from "./infrastructure/adapters/traceability-metadata-policy-adapter.js";
|
|
57
|
+
import { TraceabilityWorkItemStatusPolicyAdapter } from "./infrastructure/adapters/traceability-work-item-status-policy-adapter.js";
|
|
58
|
+
import { ReportValidationResultsHandler } from "./presentation/handlers/report-validation-results-handler.js";
|
|
59
|
+
import { RunQuickModeHandler } from "./presentation/handlers/run-quick-mode-handler.js";
|
|
60
|
+
import { RunValidatorsHandler } from "./presentation/handlers/run-validators-handler.js";
|
|
54
61
|
|
|
55
62
|
/** デフォルト設定(ハードコード fallback) */
|
|
56
63
|
const DEFAULT_CONFIG = {
|
|
57
|
-
preset:
|
|
64
|
+
preset: "standard" as const,
|
|
58
65
|
layers: {
|
|
59
|
-
L2: { enabled: true, validators: [
|
|
60
|
-
L3: {
|
|
61
|
-
|
|
66
|
+
L2: { enabled: true, validators: ["L2-001", "L2-002", "L2-003", "L2-013", "L2-014", "L2-015", "L2-016"] },
|
|
67
|
+
L3: {
|
|
68
|
+
enabled: true,
|
|
69
|
+
validators: ["L3-001", "L3-002", "L3-003", "L3-004", "L3-006", "L3-007"],
|
|
70
|
+
coverageThreshold: 90,
|
|
71
|
+
bundleSizeLimit: 512000,
|
|
72
|
+
requirementMatrixPath: ".harness/requirement-test-matrix.json",
|
|
73
|
+
},
|
|
74
|
+
L4: { enabled: true, validators: ["L4-001", "L4-002", "L4-003", "L4-004", "L4-005", "L4-006"] },
|
|
62
75
|
},
|
|
63
76
|
paths: {
|
|
64
|
-
designDocs:
|
|
65
|
-
inceptionDocs:
|
|
77
|
+
designDocs: "docs/product/construction",
|
|
78
|
+
inceptionDocs: "docs/inception",
|
|
66
79
|
},
|
|
67
80
|
validate: { failOnWarning: false },
|
|
68
81
|
architecture: {
|
|
69
82
|
capabilityPolicies: {
|
|
70
|
-
domain: { allowed: [], denied: [
|
|
71
|
-
application: { allowed: [
|
|
72
|
-
infrastructure: {
|
|
73
|
-
|
|
83
|
+
domain: { allowed: [], denied: ["filesystem", "network", "database", "process-env", "subprocess", "user-io"] },
|
|
84
|
+
application: { allowed: ["time", "random"], denied: ["filesystem", "network", "database", "subprocess"] },
|
|
85
|
+
infrastructure: {
|
|
86
|
+
allowed: ["filesystem", "network", "database", "process-env", "time", "random", "subprocess", "user-io"],
|
|
87
|
+
denied: [],
|
|
88
|
+
},
|
|
89
|
+
presentation: { allowed: ["user-io", "time"], denied: ["database", "subprocess"] },
|
|
74
90
|
},
|
|
75
91
|
decisionPolicies: {
|
|
76
|
-
domain: { expected: [
|
|
77
|
-
application: { expected: [
|
|
78
|
-
infrastructure: { expected: [
|
|
79
|
-
presentation: { expected: [
|
|
92
|
+
domain: { expected: ["business-rule-branch", "validation-rule", "state-transition"], advisoryOnly: true },
|
|
93
|
+
application: { expected: ["policy-selection", "error-construction"], advisoryOnly: true },
|
|
94
|
+
infrastructure: { expected: ["error-construction"], advisoryOnly: true },
|
|
95
|
+
presentation: { expected: ["validation-rule", "error-construction"], advisoryOnly: true },
|
|
80
96
|
},
|
|
81
97
|
},
|
|
82
98
|
};
|
|
@@ -84,47 +100,61 @@ const DEFAULT_CONFIG = {
|
|
|
84
100
|
/** バリデータ定義カタログ */
|
|
85
101
|
export function buildDefaultRegistry(): ValidatorRegistry {
|
|
86
102
|
const defaultRule = ValidationRule.create({
|
|
87
|
-
ruleName:
|
|
88
|
-
errorTemplate: { code:
|
|
103
|
+
ruleName: "default-rule",
|
|
104
|
+
errorTemplate: { code: "L2-001", severity: "error", messageTemplate: "{{message}}" },
|
|
89
105
|
fixExample: null,
|
|
90
106
|
});
|
|
91
107
|
|
|
92
|
-
const createDef = (
|
|
108
|
+
const createDef = (
|
|
109
|
+
id: string,
|
|
110
|
+
layer: "L2" | "L3" | "L4",
|
|
111
|
+
enabledCondition: "always" | "strictOnly" = "always",
|
|
112
|
+
externalPolicyRef: string | null = null,
|
|
113
|
+
) =>
|
|
93
114
|
ValidatorDefinition.create({
|
|
94
115
|
validatorId: ValidatorId.create(id),
|
|
95
116
|
layer,
|
|
96
|
-
rules: [
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
117
|
+
rules: [
|
|
118
|
+
ValidationRule.create({
|
|
119
|
+
ruleName: `${id}-rule`,
|
|
120
|
+
errorTemplate: { code: id, severity: "error", messageTemplate: "{{message}}" },
|
|
121
|
+
fixExample: null,
|
|
122
|
+
}),
|
|
123
|
+
],
|
|
101
124
|
enabledCondition,
|
|
102
125
|
externalPolicyRef,
|
|
103
126
|
});
|
|
104
127
|
|
|
105
128
|
const definitions = [
|
|
106
|
-
createDef(
|
|
107
|
-
createDef(
|
|
108
|
-
createDef(
|
|
109
|
-
createDef(
|
|
110
|
-
createDef(
|
|
111
|
-
createDef(
|
|
112
|
-
|
|
113
|
-
createDef(
|
|
114
|
-
createDef(
|
|
115
|
-
createDef(
|
|
129
|
+
createDef("L2-001", "L2", "always", "PhaseGatePolicyPort"),
|
|
130
|
+
createDef("L2-002", "L2", "always", "MetadataPolicyPort"),
|
|
131
|
+
createDef("L2-003", "L2", "always"),
|
|
132
|
+
createDef("L2-013", "L2", "always", "CliE2eTestExistenceService"),
|
|
133
|
+
createDef("L2-014", "L2", "always", "WorkItemStatusPolicyPort"),
|
|
134
|
+
createDef("L2-015", "L2", "always", "ContractTraceabilityPolicyPort"),
|
|
135
|
+
// WI-258 / ADR-030 §Decision.3.②: L2-016 (coverage-attestation-gating, fail-closed, default-ON)。
|
|
136
|
+
createDef("L2-016", "L2", "always", "CoverageAttestationGatingPolicyPort"),
|
|
137
|
+
createDef("L3-001", "L3", "always"),
|
|
138
|
+
createDef("L3-002", "L3", "strictOnly"),
|
|
139
|
+
createDef("L3-003", "L3", "always"),
|
|
140
|
+
createDef("L3-004", "L3", "always", "AcCoveragePolicyPort"),
|
|
116
141
|
// WI-227 / H16-03: L3-005 (ac-bound-coverage) は registry には登録するが
|
|
117
142
|
// default-OFF(DEFAULT_CONFIG.layers.L3.validators に含めない)。fail-closed / opt-in。
|
|
118
|
-
createDef(
|
|
119
|
-
|
|
120
|
-
createDef(
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
createDef(
|
|
124
|
-
createDef(
|
|
143
|
+
createDef("L3-005", "L3", "always", "AcBoundCoveragePolicyPort"),
|
|
144
|
+
// WI-259 / ADR-030 §Decision.3.④: L3-006 (injection-scan) は advisory (warning-only, default-ON)。
|
|
145
|
+
createDef("L3-006", "L3", "always", "InjectionScanPolicyPort"),
|
|
146
|
+
// WI-268 / ADR-030 §Decision.1・§Decision.3.② 第2段: L3-007 (coverage-attestation-verification)
|
|
147
|
+
// は fail-closed / default-ON。L2-016 の authoritative 相棒。
|
|
148
|
+
createDef("L3-007", "L3", "always", "CoverageAttestationVerificationPolicyPort"),
|
|
149
|
+
createDef("L4-001", "L4", "always"),
|
|
150
|
+
createDef("L4-002", "L4", "always"),
|
|
151
|
+
createDef("L4-003", "L4", "strictOnly"),
|
|
152
|
+
createDef("L4-004", "L4", "always"),
|
|
153
|
+
createDef("L4-005", "L4", "always"),
|
|
154
|
+
createDef("L4-006", "L4", "always", "SkillCatalogDriftPort"),
|
|
125
155
|
// WI-222 / HF2-05: L4-007 (ac-level-traceability) は registry には登録するが
|
|
126
156
|
// default-OFF(DEFAULT_CONFIG.layers.L4.validators に含めない)。advisory-only。
|
|
127
|
-
createDef(
|
|
157
|
+
createDef("L4-007", "L4", "always", "AcLevelTraceabilityPort"),
|
|
128
158
|
];
|
|
129
159
|
|
|
130
160
|
return new ValidatorRegistry(definitions);
|
|
@@ -162,26 +192,47 @@ export function createValidatorSystemModule(config?: object): ValidatorSystemMod
|
|
|
162
192
|
const acBoundCoveragePolicyPort = new NyquistAcBoundCoveragePolicyAdapter();
|
|
163
193
|
// L3-003: テストカバレッジレポート(vitest --coverage の json-summary 出力)を読み取る。
|
|
164
194
|
// 未配線だと L3-003 は装飾的な pass になり 90% 閾値が形骸化するため必ず配線する。
|
|
165
|
-
const coverageReportPort = new JsonCoverageReportAdapter(
|
|
166
|
-
join(process.cwd(), 'coverage', 'coverage-summary.json'),
|
|
167
|
-
);
|
|
195
|
+
const coverageReportPort = new JsonCoverageReportAdapter(join(process.cwd(), "coverage", "coverage-summary.json"));
|
|
168
196
|
const testQualityAnalyzerPort = new BiomeAstTestQualityAnalyzerAdapter();
|
|
169
197
|
const securityScannerPort = new FileSystemSecurityPatternScannerAdapter();
|
|
170
198
|
const performanceScannerPort = new AstPerformanceScannerAdapter();
|
|
171
199
|
const workItemStatusPolicyPort = new TraceabilityWorkItemStatusPolicyAdapter(process.cwd());
|
|
172
200
|
const contractTraceabilityPolicyPort = new FileSystemContractTraceabilityPolicyAdapter();
|
|
201
|
+
// WI-258 / ADR-030 §Decision.3.②: L2-016 (coverage-attestation-gating) 用アダプタ。
|
|
202
|
+
// docs/product/construction/*/coverage_report.md を cwd 起点で走査する(targetPaths 非依存)。
|
|
203
|
+
const coverageAttestationGatingPolicyPort = new FileSystemCoverageAttestationGatingAdapter(process.cwd());
|
|
204
|
+
// WI-259 / ADR-030 §Decision.3.④: L3-006 (injection-scan, advisory) 用アダプタ。
|
|
205
|
+
// 指示搭載ファイル群(skills/**/SKILL.md / CLAUDE.md / AGENTS.md / agent-context / .claude/settings.json)を
|
|
206
|
+
// cwd 起点で走査する(targetPaths 非依存)。
|
|
207
|
+
const injectionScanPolicyPort = new FileSystemInjectionScanAdapter(process.cwd());
|
|
208
|
+
// WI-268 / ADR-030 §Decision.1・§Decision.3.② 第2段: L3-007 (coverage-attestation-verification) 用アダプタ。
|
|
209
|
+
// coverage_report の @attestation 参照を requirement-test-matrix に突合する(fail-closed)。
|
|
210
|
+
const coverageAttestationVerificationPolicyPort = new FileSystemCoverageAttestationVerificationAdapter(
|
|
211
|
+
process.cwd(),
|
|
212
|
+
(configData.layers?.L3 as { requirementMatrixPath?: string } | undefined)?.requirementMatrixPath ??
|
|
213
|
+
".harness/requirement-test-matrix.json",
|
|
214
|
+
);
|
|
173
215
|
|
|
174
216
|
const cwd = process.cwd();
|
|
175
|
-
const designDocsRoot = configData.paths?.designDocs ??
|
|
176
|
-
const inceptionDocsRoot = configData.paths?.inceptionDocs ??
|
|
217
|
+
const designDocsRoot = configData.paths?.designDocs ?? "docs/product/construction";
|
|
218
|
+
const inceptionDocsRoot = configData.paths?.inceptionDocs ?? "docs/inception";
|
|
177
219
|
const docsRoot = join(cwd, designDocsRoot);
|
|
178
|
-
const e2eTestFileRegistryPort = new E2eTestFileRegistryAdapter({
|
|
220
|
+
const e2eTestFileRegistryPort = new E2eTestFileRegistryAdapter({
|
|
221
|
+
e2eTestRoot: join(cwd, "scripts/harness/__tests__/e2e"),
|
|
222
|
+
});
|
|
179
223
|
const cliCommandRegistryPort = new CliCommandRegistryAdapter({
|
|
180
224
|
commands: [
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
225
|
+
"validate",
|
|
226
|
+
"lint",
|
|
227
|
+
"ci-check",
|
|
228
|
+
"phasegate:check-ready",
|
|
229
|
+
"phasegate:check-phase",
|
|
230
|
+
"phasegate:ci-check",
|
|
231
|
+
"phasegate:detect-drift",
|
|
232
|
+
"phasegate:lint",
|
|
233
|
+
"phasegate:complete-check",
|
|
234
|
+
"phasegate:impact-analysis",
|
|
235
|
+
"phasegate:status",
|
|
185
236
|
],
|
|
186
237
|
});
|
|
187
238
|
|
|
@@ -197,6 +248,7 @@ export function createValidatorSystemModule(config?: object): ValidatorSystemMod
|
|
|
197
248
|
cliCommandRegistryPort,
|
|
198
249
|
workItemStatusPolicyPort,
|
|
199
250
|
contractTraceabilityPolicyPort,
|
|
251
|
+
coverageAttestationGatingPolicyPort,
|
|
200
252
|
});
|
|
201
253
|
|
|
202
254
|
// WI-227 / H16-03: L3-005 のスコープ対象 story-id を config から取得(既定 [])。
|
|
@@ -213,19 +265,21 @@ export function createValidatorSystemModule(config?: object): ValidatorSystemMod
|
|
|
213
265
|
coverageReportPort,
|
|
214
266
|
securityScannerPort,
|
|
215
267
|
performanceScannerPort,
|
|
268
|
+
injectionScanPolicyPort,
|
|
269
|
+
coverageAttestationVerificationPolicyPort,
|
|
216
270
|
acBoundStories,
|
|
217
271
|
});
|
|
218
272
|
|
|
219
273
|
const markdownDesignDocumentPort = new MarkdownDesignDocumentAdapter(docsRoot);
|
|
220
274
|
const sourceCodeAnalyzerAdapter = new BiomeAstSourceCodeAnalyzerAdapter();
|
|
221
|
-
const adrReferencePort = new AdrFoundationReferenceAdapter();
|
|
275
|
+
const adrReferencePort = new AdrFoundationReferenceAdapter(cwd);
|
|
222
276
|
const sourceAnalysisPort = new ImportGraphSourceAnalysisAdapter();
|
|
223
277
|
const architectureSemanticSourcePort = new FileSystemArchitectureSemanticSourceAdapter();
|
|
224
278
|
const skillCatalogDriftPort = new FileSystemSkillCatalogDriftAdapter(cwd);
|
|
225
279
|
// WI-222 / HF2-05: L4-007 (advisory) 用の AC 単位トレーサビリティ port。
|
|
226
280
|
// matrix path は L3-004 と同じ config キーを参照する。
|
|
227
281
|
const acLevelTraceabilityPort = new NyquistAcLevelTraceabilityAdapter({
|
|
228
|
-
matrixFilePath: configData.layers?.L3?.requirementMatrixPath ??
|
|
282
|
+
matrixFilePath: configData.layers?.L3?.requirementMatrixPath ?? ".harness/requirement-test-matrix.json",
|
|
229
283
|
});
|
|
230
284
|
const workItemReflectionPort = new FileSystemWorkItemReflectionAdapter(cwd);
|
|
231
285
|
|
|
@@ -275,11 +329,11 @@ export function createValidatorSystemModule(config?: object): ValidatorSystemMod
|
|
|
275
329
|
|
|
276
330
|
const aggregateValidationResultsUseCase = new AggregateValidationResultsUseCase();
|
|
277
331
|
const itTestFileAnalyzerPort = new ItTestFileAnalyzerAdapter({
|
|
278
|
-
itTestRoot: join(cwd,
|
|
332
|
+
itTestRoot: join(cwd, "scripts/harness/__tests__/integration"),
|
|
279
333
|
// アダプター自体のテストファイルは vi.mock() を使用しているため誤検知防止で除外
|
|
280
334
|
excludePattern: /it-test-file-analyzer-adapter\.test\.ts$/,
|
|
281
335
|
});
|
|
282
|
-
const sourceFileTextScannerPort = new SourceFileTextScannerAdapter({ sourceRoot: join(cwd,
|
|
336
|
+
const sourceFileTextScannerPort = new SourceFileTextScannerAdapter({ sourceRoot: join(cwd, "scripts/harness") });
|
|
283
337
|
const runL1ValidatorsUseCase = new RunL1ValidatorsUseCase({
|
|
284
338
|
itTestFileAnalyzerPort,
|
|
285
339
|
sourceFileTextScannerPort,
|
package/scripts/harness/validator-system/domain/ports/coverage-attestation-gating-policy-port.ts
ADDED
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
// @unit validator-system
|
|
2
|
+
// @layer domain
|
|
3
|
+
// @work-item-id WI-258
|
|
4
|
+
|
|
5
|
+
import type { CoverageReportGatingModel } from "../value-objects/coverage-gating-report.js";
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* WI-258 / ADR-030 §Decision.3.② — coverage_report 走査結果の供給ポート。
|
|
9
|
+
* 走査対象(docs/product/construction/*/coverage_report.md)の解決は infrastructure が担う
|
|
10
|
+
* (cwd 起点・targetPaths 非依存の corpus 走査)。
|
|
11
|
+
*/
|
|
12
|
+
export interface CoverageAttestationGatingPolicyPort {
|
|
13
|
+
collect(): Promise<readonly CoverageReportGatingModel[]>;
|
|
14
|
+
}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
// @unit validator-system
|
|
2
|
+
// @layer domain
|
|
3
|
+
// @work-item-id WI-268
|
|
4
|
+
|
|
5
|
+
import type {
|
|
6
|
+
AttestationReference,
|
|
7
|
+
AttestationScopeEvidence,
|
|
8
|
+
} from "../value-objects/attestation-verification-report.js";
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* WI-268 / ADR-030 §Decision.1・§Decision.3.②(第2段) — L3-007 の走査・解決結果供給ポート。
|
|
12
|
+
*
|
|
13
|
+
* 参照走査(ungated-legacy 免除込み)と matrix 由来の解決可能スコープ解決は infrastructure が担う
|
|
14
|
+
* (cwd 起点・targetPaths 非依存の corpus 走査)。
|
|
15
|
+
*/
|
|
16
|
+
export interface CoverageAttestationVerificationCollectResult {
|
|
17
|
+
/** ungated-legacy を除いた coverage_report から抽出した attestation 参照。 */
|
|
18
|
+
readonly references: readonly AttestationReference[];
|
|
19
|
+
/** matrix 由来の解決可能スコープ。references が空のときは空集合でよい(matrix 未読)。 */
|
|
20
|
+
readonly evidence: AttestationScopeEvidence;
|
|
21
|
+
/**
|
|
22
|
+
* 参照ありで matrix を読めなかった fail-closed シグナル。
|
|
23
|
+
* null なら matrix 読み込みは問題なし(または参照 0 件で matrix 未読)。
|
|
24
|
+
*/
|
|
25
|
+
readonly matrixError: string | null;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
export interface CoverageAttestationVerificationPolicyPort {
|
|
29
|
+
collect(): Promise<CoverageAttestationVerificationCollectResult>;
|
|
30
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
// @unit validator-system
|
|
2
|
+
// @layer domain
|
|
3
|
+
// @work-item-id WI-259
|
|
4
|
+
|
|
5
|
+
import type { InjectionScanTarget } from "../value-objects/injection-scan-report.js";
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* WI-259 / ADR-030 §Decision.3.④ — 指示搭載ファイルの供給ポート。
|
|
9
|
+
* 走査対象(skills/**/SKILL.md / CLAUDE.md / AGENTS.md / docs/templates/agent-context/** /
|
|
10
|
+
* .claude/settings.json)の解決は infrastructure が担う(cwd 起点・targetPaths 非依存の corpus 走査)。
|
|
11
|
+
*/
|
|
12
|
+
export interface InjectionScanPolicyPort {
|
|
13
|
+
collect(): Promise<readonly InjectionScanTarget[]>;
|
|
14
|
+
}
|
package/scripts/harness/validator-system/domain/services/coverage-attestation-gating-service.ts
ADDED
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
// @unit validator-system
|
|
2
|
+
// @layer domain
|
|
3
|
+
// @work-item-id WI-258
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* WI-258 / ADR-030 §Decision.3.② — coverage-attestation-gating (L2-016) の判定ドメインサービス。
|
|
7
|
+
*
|
|
8
|
+
* INV-A: hasLegacyMarker のファイルは error を生成せず legacyCount に計上し warning を 1 件生成(見える負債)。
|
|
9
|
+
* INV-B: マーカー無しファイルで attestation 参照を持たない ✅ claim は error violation(fail-closed)。
|
|
10
|
+
* INV-C: ✅ を持たないファイルは violation も warning も生成しない(対象外)。
|
|
11
|
+
*/
|
|
12
|
+
|
|
13
|
+
import {
|
|
14
|
+
type CoverageGatingFinding,
|
|
15
|
+
CoverageGatingReport,
|
|
16
|
+
type CoverageReportGatingModel,
|
|
17
|
+
} from "../value-objects/coverage-gating-report.js";
|
|
18
|
+
|
|
19
|
+
export class CoverageAttestationGatingService {
|
|
20
|
+
check(models: readonly CoverageReportGatingModel[]): CoverageGatingReport {
|
|
21
|
+
const violations: CoverageGatingFinding[] = [];
|
|
22
|
+
const warnings: CoverageGatingFinding[] = [];
|
|
23
|
+
let legacyCount = 0;
|
|
24
|
+
|
|
25
|
+
for (const model of models) {
|
|
26
|
+
if (model.hasLegacyMarker) {
|
|
27
|
+
// INV-A: 免除だが可視化。claim の有無に関わらず legacy として計上する
|
|
28
|
+
// (マーカーは「このファイルはまだゲートされていない負債」の宣言であるため)。
|
|
29
|
+
legacyCount += 1;
|
|
30
|
+
warnings.push({
|
|
31
|
+
severity: "warning",
|
|
32
|
+
sourcePath: model.path,
|
|
33
|
+
message: `ungated-legacy coverage_report (attestation ゲート未適用の負債): ${model.path}`,
|
|
34
|
+
suggestion:
|
|
35
|
+
"各 ✅ 主張に <!-- @attestation <id> --> を付与し、@coverage-gating: ungated-legacy マーカーを除去して段階返済すること。",
|
|
36
|
+
});
|
|
37
|
+
continue;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
// INV-B / INV-C: マーカー無しファイルの各 ✅ claim を検査する。
|
|
41
|
+
for (const claim of model.claims) {
|
|
42
|
+
if (!claim.hasAttestationRef) {
|
|
43
|
+
violations.push({
|
|
44
|
+
severity: "error",
|
|
45
|
+
sourcePath: model.path,
|
|
46
|
+
message: `${model.path}:${claim.lineNumber} の ✅ 主張に attestation 参照がありません(bare ✅ は fail-closed)。`,
|
|
47
|
+
suggestion:
|
|
48
|
+
"✅ 主張に <!-- @attestation <id> --> を付与するか、未返済なら <!-- @coverage-gating: ungated-legacy --> マーカーで免除(負債可視化)すること。",
|
|
49
|
+
});
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
return CoverageGatingReport.create(violations, warnings, legacyCount);
|
|
55
|
+
}
|
|
56
|
+
}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
// @unit validator-system
|
|
2
|
+
// @layer domain
|
|
3
|
+
// @work-item-id WI-268
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* WI-268 / ADR-030 §Decision.1・§Decision.3.②(第2段) — coverage-attestation-verification
|
|
7
|
+
* (L3-007) の突合ドメインサービス。
|
|
8
|
+
*
|
|
9
|
+
* INV-A: 各 reference の id が evidence.resolvableScopeIds に含まれなければ error finding を生成
|
|
10
|
+
* (fail-closed。空手形の attestation を遮断)。
|
|
11
|
+
* INV-B: references が空なら report は空(検査対象なし → pass)。
|
|
12
|
+
* INV-C: 生成 finding は必ず severity='error'(advisory ではなく blocking tier)。
|
|
13
|
+
*/
|
|
14
|
+
|
|
15
|
+
import {
|
|
16
|
+
type AttestationReference,
|
|
17
|
+
type AttestationScopeEvidence,
|
|
18
|
+
type AttestationVerificationFinding,
|
|
19
|
+
AttestationVerificationReport,
|
|
20
|
+
} from "../value-objects/attestation-verification-report.js";
|
|
21
|
+
|
|
22
|
+
export class CoverageAttestationVerificationService {
|
|
23
|
+
verify(
|
|
24
|
+
references: readonly AttestationReference[],
|
|
25
|
+
evidence: AttestationScopeEvidence,
|
|
26
|
+
): AttestationVerificationReport {
|
|
27
|
+
const findings: AttestationVerificationFinding[] = [];
|
|
28
|
+
|
|
29
|
+
for (const reference of references) {
|
|
30
|
+
// INV-A: matrix 由来の解決可能スコープに存在しない参照は fail-closed の error。
|
|
31
|
+
if (!evidence.resolvableScopeIds.has(reference.id)) {
|
|
32
|
+
findings.push({
|
|
33
|
+
severity: "error",
|
|
34
|
+
sourcePath: reference.sourcePath,
|
|
35
|
+
lineNumber: reference.lineNumber,
|
|
36
|
+
message: `${reference.sourcePath}:${reference.lineNumber} の @attestation "${reference.id}" は requirement-test-matrix 上のテスト参照に解決できません(空手形 attestation は fail-closed)。`,
|
|
37
|
+
suggestion:
|
|
38
|
+
"@attestation <id> の id を、matrix 上に存在し testReferences を 1 件以上持つ story-id にしてください(phasegate:generate-matrix で最新化)。返済前なら <!-- @coverage-gating: ungated-legacy --> マーカーで免除(負債可視化)すること。",
|
|
39
|
+
});
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
return AttestationVerificationReport.create(findings);
|
|
44
|
+
}
|
|
45
|
+
}
|