phasegate 0.229.0 → 0.264.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 +73 -1
- package/README.ja.md +31 -1
- package/README.md +30 -0
- package/docs/ADR/031-world-model-ownership-and-corpus-lifecycle.md +155 -0
- package/docs/ADR/032-world-node-identity.md +198 -0
- package/docs/ADR/033-world-snapshot-canonicalization.md +246 -0
- package/docs/ADR/034-world-constraint-semantics.md +218 -0
- package/docs/ADR/035-world-adoption-baseline-and-waiver.md +341 -0
- package/docs/ADR/036-world-model-and-doc-freshness.md +169 -0
- package/docs/ADR/037-world-cli-and-output-contract.md +398 -0
- package/docs/contracts/attestation-v2.schema.json +110 -0
- package/docs/contracts/requirement-test-matrix.schema.json +15 -0
- package/docs/contracts/world-baseline.schema.json +35 -0
- package/docs/contracts/world-constraints.schema.json +56 -0
- package/docs/contracts/world-debts.schema.json +32 -0
- package/docs/contracts/world-obligation-report.schema.json +259 -0
- package/docs/contracts/world-waivers.schema.json +32 -0
- package/docs/guide/cli-reference.md +45 -0
- package/docs/guide/configuration.md +56 -0
- package/docs/templates/ci/aidlc-gate.yml +42 -2
- package/package.json +1 -1
- package/scripts/harness/agent-integration/application/dto/open-world-obligations-context-dto.ts +30 -0
- package/scripts/harness/agent-integration/application/ports/world-obligations-query-port.ts +30 -0
- package/scripts/harness/agent-integration/application/usecases/get-open-world-obligations-context-usecase.ts +66 -0
- package/scripts/harness/agent-integration/infrastructure/adapters/world-model-open-obligations-query-adapter.ts +58 -0
- package/scripts/harness/agent-integration/presentation/session-start-hook.ts +37 -1
- package/scripts/harness/agent-integration/presentation/world-obligations-session-context.ts +60 -0
- package/scripts/harness/attestation/application/dto/attestation-document.ts +17 -4
- package/scripts/harness/attestation/application/mappers/attestation-record-mapper.ts +55 -4
- package/scripts/harness/attestation/application/ports/sha256-capability.ts +25 -0
- package/scripts/harness/attestation/application/ports/world-snapshot-root-provider.ts +10 -0
- package/scripts/harness/attestation/application/usecases/produce-attestation-usecase.ts +33 -7
- package/scripts/harness/attestation/composition-root.ts +19 -4
- package/scripts/harness/attestation/domain/entities/attestation-record.ts +37 -2
- package/scripts/harness/attestation/index.ts +13 -2
- package/scripts/harness/attestation/infrastructure/adapters/node-crypto-content-hasher-adapter.ts +6 -6
- package/scripts/harness/attestation/infrastructure/adapters/node-crypto-sha256-capability.ts +19 -0
- package/scripts/harness/attestation/presentation/handlers/attest-handler.ts +5 -2
- package/scripts/harness/config-foundation/application/mappers/validator-system-config-mapper.ts +35 -8
- package/scripts/harness/config-foundation/application/mappers/world-model-config-mapper.ts +15 -0
- package/scripts/harness/config-foundation/domain/harness-config.ts +67 -87
- package/scripts/harness/config-foundation/domain/services/preset-resolution-service.ts +77 -88
- package/scripts/harness/config-foundation/domain/value-objects/world-config.ts +198 -0
- package/scripts/harness/config-foundation/index.ts +14 -15
- package/scripts/harness/config-foundation/infrastructure/presets/minimal.json +24 -0
- package/scripts/harness/config-foundation/infrastructure/presets/standard.json +24 -0
- package/scripts/harness/config-foundation/infrastructure/presets/strict.json +24 -0
- package/scripts/harness/config-foundation/infrastructure/schemas/harness-config-v2.schema.json +83 -0
- package/scripts/harness/config-foundation/infrastructure/schemas/harness-config-v3.schema.json +83 -0
- package/scripts/harness/harness-api/domain/value-objects/ci-check-result.ts +18 -4
- package/scripts/harness/harness-api/domain/value-objects/known-harness-commands.ts +4 -1
- package/scripts/harness/integrations/pre-commit.ts +169 -27
- package/scripts/harness/main.ts +276 -126
- package/scripts/harness/nyquist-validation/application/dto/generate-matrix-output.ts +11 -0
- package/scripts/harness/nyquist-validation/application/usecases/check-ac-coverage-gate-usecase.ts +6 -0
- package/scripts/harness/nyquist-validation/application/usecases/generate-requirement-test-matrix-usecase.ts +8 -4
- package/scripts/harness/nyquist-validation/domain/entities/story-mapping.ts +29 -2
- package/scripts/harness/nyquist-validation/domain/services/ac-coverage-gate-policy.ts +28 -0
- package/scripts/harness/nyquist-validation/infrastructure/adapters/markdown-requirement-source-adapter.ts +71 -4
- package/scripts/harness/nyquist-validation/infrastructure/schema/matrix-schema-loader.ts +4 -0
- package/scripts/harness/traceability-model/application/dto/changed-design-fragment-dto.ts +31 -0
- package/scripts/harness/traceability-model/application/dto/traceability-world-read-dto.ts +67 -0
- package/scripts/harness/traceability-model/application/facades/design-change-read-facade.ts +14 -0
- package/scripts/harness/traceability-model/application/facades/traceability-world-read-facade.ts +372 -0
- package/scripts/harness/traceability-model/application/ports/staged-design-change-source-port.ts +9 -0
- package/scripts/harness/traceability-model/application/ports/traceability-world-read-source-port.ts +61 -0
- package/scripts/harness/traceability-model/composition-root.ts +26 -5
- package/scripts/harness/traceability-model/index.ts +26 -6
- package/scripts/harness/traceability-model/infrastructure/adapters/file-system-traceability-world-read-adapter.ts +223 -0
- package/scripts/harness/traceability-model/infrastructure/adapters/git-staged-design-change-adapter.ts +155 -0
- package/scripts/harness/traceability-model/infrastructure/parsers/story-catalog-parser.ts +86 -8
- package/scripts/harness/validator-system/application/use-cases/run-l2-validators-usecase.ts +31 -0
- package/scripts/harness/validator-system/application/use-cases/run-l3-validators-usecase.ts +34 -0
- package/scripts/harness/validator-system/composition-root.ts +21 -6
- package/scripts/harness/validator-system/domain/ports/world-constraint-admission-policy-port.ts +28 -0
- package/scripts/harness/validator-system/domain/ports/world-constraint-rederivation-policy-port.ts +11 -0
- package/scripts/harness/validator-system/domain/services/design-change-declaration-policy.ts +75 -0
- package/scripts/harness/validator-system/domain/services/world-constraint-admission-service.ts +78 -0
- package/scripts/harness/validator-system/domain/services/world-constraint-rederivation-service.ts +76 -0
- package/scripts/harness/validator-system/domain/value-objects/validator-id.ts +4 -0
- package/scripts/harness/validator-system/infrastructure/adapters/harness-config-validator-config-adapter.ts +38 -16
- package/scripts/harness/validator-system/infrastructure/adapters/world-model-constraint-admission-adapter.ts +56 -0
- package/scripts/harness/validator-system/infrastructure/adapters/world-model-constraint-rederivation-adapter.ts +56 -0
- package/scripts/harness/world-model/application/dto/pinned-design-endpoint-dto.ts +19 -0
- package/scripts/harness/world-model/application/dto/world-inspection-dto.ts +43 -0
- package/scripts/harness/world-model/application/dto/world-obligation-report-dto.ts +54 -0
- package/scripts/harness/world-model/application/dto/world-resolved-config-input.ts +127 -0
- package/scripts/harness/world-model/application/dto/world-snapshot-root-dto.ts +8 -0
- package/scripts/harness/world-model/application/facades/pinned-design-endpoint-facade.ts +63 -0
- package/scripts/harness/world-model/application/facades/world-snapshot-root-facade.ts +19 -0
- package/scripts/harness/world-model/application/ports/obligation-report-writer-port.ts +7 -0
- package/scripts/harness/world-model/application/ports/world-control-declaration-repository-port.ts +57 -0
- package/scripts/harness/world-model/application/ports/world-fact-source-port.ts +17 -0
- package/scripts/harness/world-model/application/usecases/build-snapshot-use-case.ts +111 -0
- package/scripts/harness/world-model/application/usecases/derive-obligations-use-case.ts +155 -0
- package/scripts/harness/world-model/application/usecases/derive-world-obligations-use-case.ts +146 -0
- package/scripts/harness/world-model/application/usecases/inspect-world-use-case.ts +74 -0
- package/scripts/harness/world-model/application/usecases/pin-constraint-endpoint-use-case.ts +139 -0
- package/scripts/harness/world-model/composition-root.ts +247 -0
- package/scripts/harness/world-model/domain/entities/constraint-record.ts +148 -0
- package/scripts/harness/world-model/domain/entities/control-declarations.ts +274 -0
- package/scripts/harness/world-model/domain/entities/edge.ts +41 -0
- package/scripts/harness/world-model/domain/entities/extraction-diagnostic.ts +60 -0
- package/scripts/harness/world-model/domain/entities/snapshot.ts +75 -0
- package/scripts/harness/world-model/domain/entities/world-node.ts +210 -0
- package/scripts/harness/world-model/domain/ports/world-hashing-port.ts +8 -0
- package/scripts/harness/world-model/domain/services/canonical-json-serializer.ts +113 -0
- package/scripts/harness/world-model/domain/services/constraint-evaluator.ts +486 -0
- package/scripts/harness/world-model/domain/services/obligation-derivation-service.ts +199 -0
- package/scripts/harness/world-model/domain/services/policy-inputs-digest-deriver.ts +66 -0
- package/scripts/harness/world-model/domain/services/snapshot-root-deriver.ts +218 -0
- package/scripts/harness/world-model/domain/services/text-content-normalizer.ts +30 -0
- package/scripts/harness/world-model/domain/services/violation-fingerprint-deriver.ts +183 -0
- package/scripts/harness/world-model/domain/value-objects/artifact-kind.ts +58 -0
- package/scripts/harness/world-model/domain/value-objects/change-provenance.ts +137 -0
- package/scripts/harness/world-model/domain/value-objects/corpus-role.ts +57 -0
- package/scripts/harness/world-model/domain/value-objects/declared-key.ts +35 -0
- package/scripts/harness/world-model/domain/value-objects/evaluation-id.ts +41 -0
- package/scripts/harness/world-model/domain/value-objects/explicit-constraint-relation.ts +53 -0
- package/scripts/harness/world-model/domain/value-objects/explicit-node-alias.ts +30 -0
- package/scripts/harness/world-model/domain/value-objects/node-pin.ts +34 -0
- package/scripts/harness/world-model/domain/value-objects/path-key.ts +103 -0
- package/scripts/harness/world-model/domain/value-objects/sha256-digest.ts +39 -0
- package/scripts/harness/world-model/domain/value-objects/violation-fingerprint.ts +36 -0
- package/scripts/harness/world-model/domain/value-objects/wcr-rule-id.ts +59 -0
- package/scripts/harness/world-model/domain/value-objects/world-node-id.ts +222 -0
- package/scripts/harness/world-model/index.ts +33 -0
- package/scripts/harness/world-model/infrastructure/adapters/adr-fact-extractor.ts +27 -0
- package/scripts/harness/world-model/infrastructure/adapters/assembled-world-fact-source.ts +17 -0
- package/scripts/harness/world-model/infrastructure/adapters/attestation-fact-extractor.ts +323 -0
- package/scripts/harness/world-model/infrastructure/adapters/attestation-sha256-world-hashing-adapter.ts +15 -0
- package/scripts/harness/world-model/infrastructure/adapters/composite-design-fact-source.ts +23 -0
- package/scripts/harness/world-model/infrastructure/adapters/design-corpus-fact-extractor.ts +285 -0
- package/scripts/harness/world-model/infrastructure/adapters/design-fact-extraction.ts +63 -0
- package/scripts/harness/world-model/infrastructure/adapters/file-system-obligation-report-writer-adapter.ts +37 -0
- package/scripts/harness/world-model/infrastructure/adapters/file-system-world-control-repository-adapters.ts +332 -0
- package/scripts/harness/world-model/infrastructure/adapters/integrity-manifest-fact-extractor.ts +101 -0
- package/scripts/harness/world-model/infrastructure/adapters/json-fact-extractor-support.ts +151 -0
- package/scripts/harness/world-model/infrastructure/adapters/markdown-design-fact-extractor.ts +493 -0
- package/scripts/harness/world-model/infrastructure/adapters/matrix-fact-extractor.ts +283 -0
- package/scripts/harness/world-model/infrastructure/adapters/product-fact-extractor.ts +29 -0
- package/scripts/harness/world-model/infrastructure/adapters/proposal-fact-extractor.ts +29 -0
- package/scripts/harness/world-model/infrastructure/adapters/runtime-fact-extraction.ts +19 -0
- package/scripts/harness/world-model/infrastructure/adapters/source-metadata-fact-extractor.ts +22 -0
- package/scripts/harness/world-model/infrastructure/adapters/test-reference-source-fact-extractor.ts +22 -0
- package/scripts/harness/world-model/infrastructure/adapters/traceability-design-fact-adapter.ts +112 -0
- package/scripts/harness/world-model/infrastructure/adapters/traceability-world-read-facade-merger.ts +38 -0
- package/scripts/harness/world-model/infrastructure/adapters/type-script-source-fact-extractor.ts +236 -0
- package/scripts/harness/world-model/infrastructure/adapters/unit-fact-extractor.ts +71 -0
- package/scripts/harness/world-model/infrastructure/adapters/world-control-declaration-mapper.ts +383 -0
- package/scripts/harness/world-model/presentation/cli/world-command-support.ts +60 -0
- package/scripts/harness/world-model/presentation/cli/world-derive-command-handler.ts +109 -0
- package/scripts/harness/world-model/presentation/cli/world-inspect-command-handler.ts +194 -0
- package/scripts/harness/world-model/presentation/cli/world-pin-command-handler.ts +100 -0
|
@@ -5,6 +5,9 @@
|
|
|
5
5
|
* DI 組み立て — validator-system の全依存関係を構築する
|
|
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
|
+
* @work-item-id WI-301
|
|
9
|
+
* @work-item-id WI-302
|
|
10
|
+
* @work-item-id WI-305
|
|
8
11
|
*/
|
|
9
12
|
|
|
10
13
|
import { join } from "node:path";
|
|
@@ -17,6 +20,7 @@ import { RunL2ValidatorsUseCase } from "./application/use-cases/run-l2-validator
|
|
|
17
20
|
import { RunL3ValidatorsUseCase } from "./application/use-cases/run-l3-validators-usecase.js";
|
|
18
21
|
import { RunL4ValidatorsUseCase } from "./application/use-cases/run-l4-validators-usecase.js";
|
|
19
22
|
import { RunQuickModeUseCase } from "./application/use-cases/run-quick-mode-usecase.js";
|
|
23
|
+
import { DesignChangeDeclarationPolicy } from "./domain/services/design-change-declaration-policy.js";
|
|
20
24
|
import {
|
|
21
25
|
ArchitectureSemanticAnalysisService,
|
|
22
26
|
type ArchitectureSemanticPolicy,
|
|
@@ -55,6 +59,8 @@ import { PhaseDependencyPhaseGatePolicyAdapter } from "./infrastructure/adapters
|
|
|
55
59
|
import { SourceFileTextScannerAdapter } from "./infrastructure/adapters/source-file-text-scanner-adapter.js";
|
|
56
60
|
import { TraceabilityMetadataPolicyAdapter } from "./infrastructure/adapters/traceability-metadata-policy-adapter.js";
|
|
57
61
|
import { TraceabilityWorkItemStatusPolicyAdapter } from "./infrastructure/adapters/traceability-work-item-status-policy-adapter.js";
|
|
62
|
+
import { WorldModelConstraintAdmissionAdapter } from "./infrastructure/adapters/world-model-constraint-admission-adapter.js";
|
|
63
|
+
import { WorldModelConstraintRederivationAdapter } from "./infrastructure/adapters/world-model-constraint-rederivation-adapter.js";
|
|
58
64
|
import { ReportValidationResultsHandler } from "./presentation/handlers/report-validation-results-handler.js";
|
|
59
65
|
import { RunQuickModeHandler } from "./presentation/handlers/run-quick-mode-handler.js";
|
|
60
66
|
import { RunValidatorsHandler } from "./presentation/handlers/run-validators-handler.js";
|
|
@@ -99,12 +105,6 @@ const DEFAULT_CONFIG = {
|
|
|
99
105
|
|
|
100
106
|
/** バリデータ定義カタログ */
|
|
101
107
|
export function buildDefaultRegistry(): ValidatorRegistry {
|
|
102
|
-
const defaultRule = ValidationRule.create({
|
|
103
|
-
ruleName: "default-rule",
|
|
104
|
-
errorTemplate: { code: "L2-001", severity: "error", messageTemplate: "{{message}}" },
|
|
105
|
-
fixExample: null,
|
|
106
|
-
});
|
|
107
|
-
|
|
108
108
|
const createDef = (
|
|
109
109
|
id: string,
|
|
110
110
|
layer: "L2" | "L3" | "L4",
|
|
@@ -134,6 +134,7 @@ export function buildDefaultRegistry(): ValidatorRegistry {
|
|
|
134
134
|
createDef("L2-015", "L2", "always", "ContractTraceabilityPolicyPort"),
|
|
135
135
|
// WI-258 / ADR-030 §Decision.3.②: L2-016 (coverage-attestation-gating, fail-closed, default-ON)。
|
|
136
136
|
createDef("L2-016", "L2", "always", "CoverageAttestationGatingPolicyPort"),
|
|
137
|
+
createDef("L2-017", "L2", "always", "WorldConstraintAdmissionPolicyPort"),
|
|
137
138
|
createDef("L3-001", "L3", "always"),
|
|
138
139
|
createDef("L3-002", "L3", "strictOnly"),
|
|
139
140
|
createDef("L3-003", "L3", "always"),
|
|
@@ -146,6 +147,7 @@ export function buildDefaultRegistry(): ValidatorRegistry {
|
|
|
146
147
|
// WI-268 / ADR-030 §Decision.1・§Decision.3.② 第2段: L3-007 (coverage-attestation-verification)
|
|
147
148
|
// は fail-closed / default-ON。L2-016 の authoritative 相棒。
|
|
148
149
|
createDef("L3-007", "L3", "always", "CoverageAttestationVerificationPolicyPort"),
|
|
150
|
+
createDef("L3-008", "L3", "always", "WorldConstraintRederivationPolicyPort"),
|
|
149
151
|
createDef("L4-001", "L4", "always"),
|
|
150
152
|
createDef("L4-002", "L4", "always"),
|
|
151
153
|
createDef("L4-003", "L4", "strictOnly"),
|
|
@@ -170,6 +172,7 @@ export interface ValidatorSystemModule {
|
|
|
170
172
|
aggregateValidationResultsUseCase: AggregateValidationResultsUseCase;
|
|
171
173
|
runFullValidationUseCase: RunFullValidationUseCase;
|
|
172
174
|
driftDetectionService: DriftDetectionService;
|
|
175
|
+
designChangeDeclarationPolicy: DesignChangeDeclarationPolicy;
|
|
173
176
|
handlers: {
|
|
174
177
|
runValidators: RunValidatorsHandler;
|
|
175
178
|
runQuickMode: RunQuickModeHandler;
|
|
@@ -184,6 +187,7 @@ export function createValidatorSystemModule(config?: object): ValidatorSystemMod
|
|
|
184
187
|
const defaultFailOnWarning = configData.validate?.failOnWarning ?? false;
|
|
185
188
|
const registry = buildDefaultRegistry();
|
|
186
189
|
const executionService = new ValidatorExecutionService({ configPort });
|
|
190
|
+
const designChangeDeclarationPolicy = new DesignChangeDeclarationPolicy();
|
|
187
191
|
const contractMapper = new ValidationResultContractMapper();
|
|
188
192
|
const phaseGatePolicyPort = new PhaseDependencyPhaseGatePolicyAdapter();
|
|
189
193
|
const metadataPolicyPort = new TraceabilityMetadataPolicyAdapter();
|
|
@@ -201,6 +205,14 @@ export function createValidatorSystemModule(config?: object): ValidatorSystemMod
|
|
|
201
205
|
// WI-258 / ADR-030 §Decision.3.②: L2-016 (coverage-attestation-gating) 用アダプタ。
|
|
202
206
|
// docs/product/construction/*/coverage_report.md を cwd 起点で走査する(targetPaths 非依存)。
|
|
203
207
|
const coverageAttestationGatingPolicyPort = new FileSystemCoverageAttestationGatingAdapter(process.cwd());
|
|
208
|
+
const worldConstraintAdmissionPolicyPort = new WorldModelConstraintAdmissionAdapter({
|
|
209
|
+
rootDir: process.cwd(),
|
|
210
|
+
resolvedConfig: (configData as { world?: import("../world-model/index.js").WorldResolvedConfigInput }).world,
|
|
211
|
+
});
|
|
212
|
+
const worldConstraintRederivationPolicyPort = new WorldModelConstraintRederivationAdapter({
|
|
213
|
+
rootDir: process.cwd(),
|
|
214
|
+
resolvedConfig: (configData as { world?: import("../world-model/index.js").WorldResolvedConfigInput }).world,
|
|
215
|
+
});
|
|
204
216
|
// WI-259 / ADR-030 §Decision.3.④: L3-006 (injection-scan, advisory) 用アダプタ。
|
|
205
217
|
// 指示搭載ファイル群(skills/**/SKILL.md / CLAUDE.md / AGENTS.md / agent-context / .claude/settings.json)を
|
|
206
218
|
// cwd 起点で走査する(targetPaths 非依存)。
|
|
@@ -249,6 +261,7 @@ export function createValidatorSystemModule(config?: object): ValidatorSystemMod
|
|
|
249
261
|
workItemStatusPolicyPort,
|
|
250
262
|
contractTraceabilityPolicyPort,
|
|
251
263
|
coverageAttestationGatingPolicyPort,
|
|
264
|
+
worldConstraintAdmissionPolicyPort,
|
|
252
265
|
});
|
|
253
266
|
|
|
254
267
|
// WI-227 / H16-03: L3-005 のスコープ対象 story-id を config から取得(既定 [])。
|
|
@@ -267,6 +280,7 @@ export function createValidatorSystemModule(config?: object): ValidatorSystemMod
|
|
|
267
280
|
performanceScannerPort,
|
|
268
281
|
injectionScanPolicyPort,
|
|
269
282
|
coverageAttestationVerificationPolicyPort,
|
|
283
|
+
worldConstraintRederivationPolicyPort,
|
|
270
284
|
acBoundStories,
|
|
271
285
|
});
|
|
272
286
|
|
|
@@ -367,6 +381,7 @@ export function createValidatorSystemModule(config?: object): ValidatorSystemMod
|
|
|
367
381
|
aggregateValidationResultsUseCase,
|
|
368
382
|
runFullValidationUseCase,
|
|
369
383
|
driftDetectionService,
|
|
384
|
+
designChangeDeclarationPolicy,
|
|
370
385
|
handlers,
|
|
371
386
|
};
|
|
372
387
|
}
|
package/scripts/harness/validator-system/domain/ports/world-constraint-admission-policy-port.ts
ADDED
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
// @unit validator-system
|
|
2
|
+
// @layer domain
|
|
3
|
+
// @work-item-id WI-301
|
|
4
|
+
|
|
5
|
+
export type WorldAdmissionClassification = "adopted-legacy" | "new-structural" | "invalid-declaration" | "waived";
|
|
6
|
+
|
|
7
|
+
export interface WorldConstraintAdmissionObligation {
|
|
8
|
+
readonly ruleId: string;
|
|
9
|
+
readonly violationFingerprint: string;
|
|
10
|
+
readonly constraintId: string | null;
|
|
11
|
+
readonly classification: WorldAdmissionClassification;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
export interface WorldConstraintAdmissionDiagnostic {
|
|
15
|
+
readonly code: string;
|
|
16
|
+
readonly path: string;
|
|
17
|
+
readonly message: string;
|
|
18
|
+
readonly scope: "constraint" | "other";
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
export interface WorldConstraintAdmissionObservation {
|
|
22
|
+
readonly obligations: readonly WorldConstraintAdmissionObligation[];
|
|
23
|
+
readonly diagnostics: readonly WorldConstraintAdmissionDiagnostic[];
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
export interface WorldConstraintAdmissionPolicyPort {
|
|
27
|
+
collect(): Promise<WorldConstraintAdmissionObservation>;
|
|
28
|
+
}
|
package/scripts/harness/validator-system/domain/ports/world-constraint-rederivation-policy-port.ts
ADDED
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
// @unit validator-system
|
|
2
|
+
// @layer domain
|
|
3
|
+
// @work-item-id WI-302
|
|
4
|
+
|
|
5
|
+
import type { WorldConstraintAdmissionObservation } from "./world-constraint-admission-policy-port.js";
|
|
6
|
+
|
|
7
|
+
export type WorldConstraintRederivationObservation = WorldConstraintAdmissionObservation;
|
|
8
|
+
|
|
9
|
+
export interface WorldConstraintRederivationPolicyPort {
|
|
10
|
+
collect(): Promise<WorldConstraintRederivationObservation>;
|
|
11
|
+
}
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
// @unit validator-system
|
|
2
|
+
// @layer domain
|
|
3
|
+
// @work-item-id WI-305
|
|
4
|
+
|
|
5
|
+
export interface DesignChangedFragmentInput {
|
|
6
|
+
readonly corpusRole: "product" | "inception";
|
|
7
|
+
readonly declaredKey: string;
|
|
8
|
+
readonly path: string;
|
|
9
|
+
readonly workItemIds: readonly string[];
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
export interface DesignPinnedEndpointInput {
|
|
13
|
+
readonly constraintId: string;
|
|
14
|
+
readonly endpoint: "claimant" | "premise";
|
|
15
|
+
readonly corpusRole: "product" | "inception";
|
|
16
|
+
readonly declaredKey: string;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
export interface DesignChangeDeclarationFinding {
|
|
20
|
+
readonly code: "design-change-declaration-missing";
|
|
21
|
+
readonly corpusRole: "product" | "inception";
|
|
22
|
+
readonly declaredKey: string;
|
|
23
|
+
readonly path: string;
|
|
24
|
+
readonly expectedWorkItemIds: readonly string[];
|
|
25
|
+
readonly constraintIds: readonly string[];
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
export interface DesignChangeDeclarationEvaluation {
|
|
29
|
+
readonly checkedFragmentCount: number;
|
|
30
|
+
readonly findings: readonly DesignChangeDeclarationFinding[];
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
export interface DesignChangeDeclarationInput {
|
|
34
|
+
readonly changedFragments: readonly DesignChangedFragmentInput[];
|
|
35
|
+
readonly pinnedEndpoints: readonly DesignPinnedEndpointInput[];
|
|
36
|
+
readonly trailerWorkItemIds: readonly string[];
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
const compare = (left: string, right: string): number => (left < right ? -1 : left > right ? 1 : 0);
|
|
40
|
+
const keyOf = (value: { readonly corpusRole: string; readonly declaredKey: string }): string =>
|
|
41
|
+
`${value.corpusRole}\u0000${value.declaredKey}`;
|
|
42
|
+
const uniqueSorted = (values: readonly string[]): readonly string[] =>
|
|
43
|
+
Object.freeze([...new Set(values)].sort(compare));
|
|
44
|
+
|
|
45
|
+
export class DesignChangeDeclarationPolicy {
|
|
46
|
+
evaluate(input: DesignChangeDeclarationInput): DesignChangeDeclarationEvaluation {
|
|
47
|
+
const endpointsByFragment = new Map<string, DesignPinnedEndpointInput[]>();
|
|
48
|
+
for (const endpoint of input.pinnedEndpoints) {
|
|
49
|
+
const key = keyOf(endpoint);
|
|
50
|
+
const current = endpointsByFragment.get(key) ?? [];
|
|
51
|
+
current.push(endpoint);
|
|
52
|
+
endpointsByFragment.set(key, current);
|
|
53
|
+
}
|
|
54
|
+
const trailerIds = new Set(input.trailerWorkItemIds);
|
|
55
|
+
const pinnedChanges = input.changedFragments
|
|
56
|
+
.filter((fragment) => endpointsByFragment.has(keyOf(fragment)))
|
|
57
|
+
.sort((left, right) => compare(keyOf(left), keyOf(right)) || compare(left.path, right.path));
|
|
58
|
+
const findings = pinnedChanges.flatMap((fragment): readonly DesignChangeDeclarationFinding[] => {
|
|
59
|
+
if (fragment.workItemIds.some((workItemId) => trailerIds.has(workItemId))) return [];
|
|
60
|
+
return [
|
|
61
|
+
Object.freeze({
|
|
62
|
+
code: "design-change-declaration-missing" as const,
|
|
63
|
+
corpusRole: fragment.corpusRole,
|
|
64
|
+
declaredKey: fragment.declaredKey,
|
|
65
|
+
path: fragment.path,
|
|
66
|
+
expectedWorkItemIds: uniqueSorted(fragment.workItemIds),
|
|
67
|
+
constraintIds: uniqueSorted(
|
|
68
|
+
(endpointsByFragment.get(keyOf(fragment)) ?? []).map((endpoint) => endpoint.constraintId),
|
|
69
|
+
),
|
|
70
|
+
}),
|
|
71
|
+
];
|
|
72
|
+
});
|
|
73
|
+
return Object.freeze({ checkedFragmentCount: pinnedChanges.length, findings: Object.freeze(findings) });
|
|
74
|
+
}
|
|
75
|
+
}
|
package/scripts/harness/validator-system/domain/services/world-constraint-admission-service.ts
ADDED
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
// @unit validator-system
|
|
2
|
+
// @layer domain
|
|
3
|
+
// @work-item-id WI-301
|
|
4
|
+
|
|
5
|
+
import type {
|
|
6
|
+
WorldAdmissionClassification,
|
|
7
|
+
WorldConstraintAdmissionObservation,
|
|
8
|
+
} from "../ports/world-constraint-admission-policy-port.js";
|
|
9
|
+
|
|
10
|
+
export interface WorldConstraintAdmissionFinding {
|
|
11
|
+
readonly severity: "error" | "warning";
|
|
12
|
+
readonly ruleId: string | null;
|
|
13
|
+
readonly violationFingerprint: string | null;
|
|
14
|
+
readonly constraintId: string | null;
|
|
15
|
+
readonly classification: WorldAdmissionClassification | "constraint-input-invalid" | "local-evaluation-incomplete";
|
|
16
|
+
readonly message: string;
|
|
17
|
+
readonly suggestion: string;
|
|
18
|
+
readonly sourcePath: string | null;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
const LOCAL_TRUST_NOTICE = "Local L2 evidence can be forged; authoritative L3 re-derivation is required.";
|
|
22
|
+
const AUTHORITATIVE_SUGGESTION =
|
|
23
|
+
"Repair the declaration or structural finding, then rely on authoritative L3 clean-corpus re-derivation.";
|
|
24
|
+
|
|
25
|
+
const compareNullable = (left: string | null, right: string | null): number =>
|
|
26
|
+
(left ?? "") < (right ?? "") ? -1 : (left ?? "") > (right ?? "") ? 1 : 0;
|
|
27
|
+
|
|
28
|
+
export class WorldConstraintAdmissionService {
|
|
29
|
+
evaluate(observation: WorldConstraintAdmissionObservation): readonly WorldConstraintAdmissionFinding[] {
|
|
30
|
+
const obligationFindings = observation.obligations.map((obligation): WorldConstraintAdmissionFinding => {
|
|
31
|
+
const blocking =
|
|
32
|
+
obligation.classification === "new-structural" || obligation.classification === "invalid-declaration";
|
|
33
|
+
const label =
|
|
34
|
+
obligation.classification === "invalid-declaration"
|
|
35
|
+
? "non-adoptable invalid World constraint declaration"
|
|
36
|
+
: obligation.classification === "new-structural"
|
|
37
|
+
? "new World structural violation"
|
|
38
|
+
: obligation.classification === "adopted-legacy"
|
|
39
|
+
? "adopted legacy World violation"
|
|
40
|
+
: "actively waived World violation";
|
|
41
|
+
return Object.freeze({
|
|
42
|
+
severity: blocking ? "error" : "warning",
|
|
43
|
+
ruleId: obligation.ruleId,
|
|
44
|
+
violationFingerprint: obligation.violationFingerprint,
|
|
45
|
+
constraintId: obligation.constraintId,
|
|
46
|
+
classification: obligation.classification,
|
|
47
|
+
message: `L2 local fast-path reports ${label}: ${obligation.ruleId} ${obligation.violationFingerprint}. ${LOCAL_TRUST_NOTICE}`,
|
|
48
|
+
suggestion: AUTHORITATIVE_SUGGESTION,
|
|
49
|
+
sourcePath: null,
|
|
50
|
+
});
|
|
51
|
+
});
|
|
52
|
+
const diagnosticFindings = observation.diagnostics.map((item): WorldConstraintAdmissionFinding => {
|
|
53
|
+
const constraintInput = item.scope === "constraint";
|
|
54
|
+
return Object.freeze({
|
|
55
|
+
severity: constraintInput ? "error" : "warning",
|
|
56
|
+
ruleId: constraintInput ? "WCR-001" : null,
|
|
57
|
+
violationFingerprint: null,
|
|
58
|
+
constraintId: null,
|
|
59
|
+
classification: constraintInput ? "constraint-input-invalid" : "local-evaluation-incomplete",
|
|
60
|
+
message: constraintInput
|
|
61
|
+
? `L2 local fast-path cannot admit constraint declaration input (${item.code}): ${item.message}. ${LOCAL_TRUST_NOTICE}`
|
|
62
|
+
: `L2 local fast-path could not complete non-constraint policy observation (${item.code}): ${item.message}. ${LOCAL_TRUST_NOTICE}`,
|
|
63
|
+
suggestion: AUTHORITATIVE_SUGGESTION,
|
|
64
|
+
sourcePath: item.path,
|
|
65
|
+
});
|
|
66
|
+
});
|
|
67
|
+
|
|
68
|
+
return Object.freeze(
|
|
69
|
+
[...obligationFindings, ...diagnosticFindings].sort(
|
|
70
|
+
(left, right) =>
|
|
71
|
+
compareNullable(left.ruleId, right.ruleId) ||
|
|
72
|
+
compareNullable(left.violationFingerprint, right.violationFingerprint) ||
|
|
73
|
+
compareNullable(left.sourcePath, right.sourcePath) ||
|
|
74
|
+
left.classification.localeCompare(right.classification),
|
|
75
|
+
),
|
|
76
|
+
);
|
|
77
|
+
}
|
|
78
|
+
}
|
package/scripts/harness/validator-system/domain/services/world-constraint-rederivation-service.ts
ADDED
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
// @unit validator-system
|
|
2
|
+
// @layer domain
|
|
3
|
+
// @work-item-id WI-302
|
|
4
|
+
|
|
5
|
+
import type { WorldAdmissionClassification } from "../ports/world-constraint-admission-policy-port.js";
|
|
6
|
+
import type { WorldConstraintRederivationObservation } from "../ports/world-constraint-rederivation-policy-port.js";
|
|
7
|
+
|
|
8
|
+
export interface WorldConstraintRederivationFinding {
|
|
9
|
+
readonly severity: "error" | "warning";
|
|
10
|
+
readonly ruleId: string | null;
|
|
11
|
+
readonly violationFingerprint: string | null;
|
|
12
|
+
readonly constraintId: string | null;
|
|
13
|
+
readonly classification:
|
|
14
|
+
| WorldAdmissionClassification
|
|
15
|
+
| "constraint-input-invalid"
|
|
16
|
+
| "authoritative-evaluation-failed";
|
|
17
|
+
readonly message: string;
|
|
18
|
+
readonly suggestion: string;
|
|
19
|
+
readonly sourcePath: string | null;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
const REPAIR_SUGGESTION =
|
|
23
|
+
"Repair the versioned declaration or current corpus finding, then rerun authoritative L3 clean-corpus re-derivation.";
|
|
24
|
+
|
|
25
|
+
const compareNullable = (left: string | null, right: string | null): number =>
|
|
26
|
+
(left ?? "") < (right ?? "") ? -1 : (left ?? "") > (right ?? "") ? 1 : 0;
|
|
27
|
+
|
|
28
|
+
export class WorldConstraintRederivationService {
|
|
29
|
+
evaluate(observation: WorldConstraintRederivationObservation): readonly WorldConstraintRederivationFinding[] {
|
|
30
|
+
const obligationFindings = observation.obligations.map((obligation): WorldConstraintRederivationFinding => {
|
|
31
|
+
const blocking =
|
|
32
|
+
obligation.classification === "new-structural" || obligation.classification === "invalid-declaration";
|
|
33
|
+
const label =
|
|
34
|
+
obligation.classification === "invalid-declaration"
|
|
35
|
+
? "non-adoptable invalid World constraint declaration"
|
|
36
|
+
: obligation.classification === "new-structural"
|
|
37
|
+
? "new World structural violation"
|
|
38
|
+
: obligation.classification === "adopted-legacy"
|
|
39
|
+
? "adopted legacy World violation"
|
|
40
|
+
: "actively waived World violation";
|
|
41
|
+
return Object.freeze({
|
|
42
|
+
severity: blocking ? "error" : "warning",
|
|
43
|
+
ruleId: obligation.ruleId,
|
|
44
|
+
violationFingerprint: obligation.violationFingerprint,
|
|
45
|
+
constraintId: obligation.constraintId,
|
|
46
|
+
classification: obligation.classification,
|
|
47
|
+
message: `L3 authoritative clean-corpus re-derivation reports ${label}: ${obligation.ruleId} ${obligation.violationFingerprint}.`,
|
|
48
|
+
suggestion: REPAIR_SUGGESTION,
|
|
49
|
+
sourcePath: null,
|
|
50
|
+
});
|
|
51
|
+
});
|
|
52
|
+
const diagnosticFindings = observation.diagnostics.map((item): WorldConstraintRederivationFinding => {
|
|
53
|
+
const constraintInput = item.scope === "constraint";
|
|
54
|
+
return Object.freeze({
|
|
55
|
+
severity: "error",
|
|
56
|
+
ruleId: constraintInput ? "WCR-001" : null,
|
|
57
|
+
violationFingerprint: null,
|
|
58
|
+
constraintId: null,
|
|
59
|
+
classification: constraintInput ? "constraint-input-invalid" : "authoritative-evaluation-failed",
|
|
60
|
+
message: `L3 authoritative clean-corpus re-derivation cannot produce a trustworthy result (${item.code}): ${item.message}.`,
|
|
61
|
+
suggestion: REPAIR_SUGGESTION,
|
|
62
|
+
sourcePath: item.path,
|
|
63
|
+
});
|
|
64
|
+
});
|
|
65
|
+
|
|
66
|
+
return Object.freeze(
|
|
67
|
+
[...obligationFindings, ...diagnosticFindings].sort(
|
|
68
|
+
(left, right) =>
|
|
69
|
+
compareNullable(left.ruleId, right.ruleId) ||
|
|
70
|
+
compareNullable(left.violationFingerprint, right.violationFingerprint) ||
|
|
71
|
+
compareNullable(left.sourcePath, right.sourcePath) ||
|
|
72
|
+
left.classification.localeCompare(right.classification),
|
|
73
|
+
),
|
|
74
|
+
);
|
|
75
|
+
}
|
|
76
|
+
}
|
|
@@ -14,6 +14,8 @@
|
|
|
14
14
|
* WI-258 (ADR-030 §Decision.3.②) で L2-016(coverage-attestation-gating, fail-closed)を追加
|
|
15
15
|
* WI-259 (ADR-030 §Decision.3.④) で L3-006(injection-scan, advisory warning-only)を追加
|
|
16
16
|
* WI-268 (ADR-030 §Decision.1・§Decision.3.② 第2段) で L3-007(coverage-attestation-verification, fail-closed)を追加
|
|
17
|
+
* WI-301 で L2-017(world-constraint-admission, local fast-path)を追加
|
|
18
|
+
* WI-302 で L3-008(world-constraint-rederivation, authoritative)を追加
|
|
17
19
|
*/
|
|
18
20
|
|
|
19
21
|
export class InvalidValidatorIdError extends Error {
|
|
@@ -38,6 +40,7 @@ const VALIDATOR_NAME_MAP: Record<string, string> = {
|
|
|
38
40
|
"L2-014": "work-item-status-staleness",
|
|
39
41
|
"L2-015": "contract-traceability-coverage",
|
|
40
42
|
"L2-016": "coverage-attestation-gating",
|
|
43
|
+
"L2-017": "world-constraint-admission",
|
|
41
44
|
"L3-001": "security",
|
|
42
45
|
"L3-002": "performance",
|
|
43
46
|
"L3-003": "coverage",
|
|
@@ -45,6 +48,7 @@ const VALIDATOR_NAME_MAP: Record<string, string> = {
|
|
|
45
48
|
"L3-005": "ac-bound-coverage",
|
|
46
49
|
"L3-006": "injection-scan",
|
|
47
50
|
"L3-007": "coverage-attestation-verification",
|
|
51
|
+
"L3-008": "world-constraint-rederivation",
|
|
48
52
|
"L4-001": "drift-detect",
|
|
49
53
|
"L4-002": "consistency-check",
|
|
50
54
|
"L4-003": "dead-code",
|
|
@@ -3,28 +3,39 @@
|
|
|
3
3
|
* @unit validator-system
|
|
4
4
|
* @work-item-id WI-156
|
|
5
5
|
* @work-item-id WI-212
|
|
6
|
+
* @work-item-id WI-301
|
|
7
|
+
* @work-item-id WI-302
|
|
6
8
|
*
|
|
7
9
|
* HarnessConfigValidatorConfigAdapter — ValidatorConfigPort実装
|
|
8
10
|
* HarnessConfigV2からLayerConfig VOを構築する
|
|
9
11
|
*/
|
|
10
|
-
|
|
11
|
-
import {
|
|
12
|
-
import
|
|
12
|
+
|
|
13
|
+
import type { ValidatorConfigPort } from "../../domain/ports/validator-config-port.js";
|
|
14
|
+
import { LayerConfig } from "../../domain/value-objects/layer-config.js";
|
|
15
|
+
import { ValidatorId } from "../../domain/value-objects/validator-id.js";
|
|
13
16
|
|
|
14
17
|
export interface HarnessConfigLayers {
|
|
15
18
|
L2?: { enabled?: boolean; validators?: string[]; strictOnly?: boolean; preset?: string };
|
|
16
|
-
L3?: {
|
|
19
|
+
L3?: {
|
|
20
|
+
enabled?: boolean;
|
|
21
|
+
validators?: string[];
|
|
22
|
+
strictOnly?: boolean;
|
|
23
|
+
preset?: string;
|
|
24
|
+
coverageThreshold?: number;
|
|
25
|
+
bundleSizeLimit?: number;
|
|
26
|
+
};
|
|
17
27
|
L4?: { enabled?: boolean; validators?: string[]; strictOnly?: boolean; preset?: string; deadCodeGC?: boolean };
|
|
18
28
|
}
|
|
19
29
|
|
|
20
30
|
export interface HarnessConfigV2Like {
|
|
21
|
-
preset?:
|
|
22
|
-
project?: { preset?:
|
|
31
|
+
preset?: "minimal" | "standard" | "strict";
|
|
32
|
+
project?: { preset?: "minimal" | "standard" | "strict"; languages?: readonly string[] };
|
|
23
33
|
layers?: HarnessConfigLayers;
|
|
24
34
|
harnesses?: {
|
|
25
35
|
bundleSizeLimit?: number;
|
|
26
36
|
deadCodeGC?: boolean;
|
|
27
37
|
};
|
|
38
|
+
world?: { enabled?: boolean };
|
|
28
39
|
}
|
|
29
40
|
|
|
30
41
|
export class HarnessConfigValidatorConfigAdapter implements ValidatorConfigPort {
|
|
@@ -34,20 +45,23 @@ export class HarnessConfigValidatorConfigAdapter implements ValidatorConfigPort
|
|
|
34
45
|
this.config = config;
|
|
35
46
|
}
|
|
36
47
|
|
|
37
|
-
async getLayerConfig(layer:
|
|
38
|
-
const preset = (this.config.project?.preset ?? this.config.preset ??
|
|
39
|
-
|
|
48
|
+
async getLayerConfig(layer: "L2" | "L3" | "L4"): Promise<LayerConfig> {
|
|
49
|
+
const preset = (this.config.project?.preset ?? this.config.preset ?? "standard") as
|
|
50
|
+
| "minimal"
|
|
51
|
+
| "standard"
|
|
52
|
+
| "strict";
|
|
53
|
+
const strictOnly = preset === "strict";
|
|
40
54
|
const layerData = this.config.layers?.[layer] ?? {};
|
|
41
55
|
|
|
42
56
|
const defaultValidators: Record<string, string[]> = {
|
|
43
|
-
L2: [
|
|
44
|
-
L3: [
|
|
45
|
-
L4: [
|
|
57
|
+
L2: ["L2-001", "L2-002", "L2-003", "L2-013", "L2-014", "L2-015"],
|
|
58
|
+
L3: ["L3-001", "L3-002", "L3-003", "L3-004"],
|
|
59
|
+
L4: ["L4-001", "L4-002", "L4-003", "L4-004", "L4-005", "L4-006"],
|
|
46
60
|
};
|
|
47
61
|
|
|
48
62
|
const thresholds: Record<string, number> = {};
|
|
49
63
|
|
|
50
|
-
if (layer ===
|
|
64
|
+
if (layer === "L3") {
|
|
51
65
|
const l3 = this.config.layers?.L3;
|
|
52
66
|
if (l3?.coverageThreshold !== undefined) thresholds.coverageThreshold = l3.coverageThreshold;
|
|
53
67
|
if (l3?.bundleSizeLimit !== undefined) thresholds.bundleSizeLimit = l3.bundleSizeLimit;
|
|
@@ -56,16 +70,24 @@ export class HarnessConfigValidatorConfigAdapter implements ValidatorConfigPort
|
|
|
56
70
|
}
|
|
57
71
|
}
|
|
58
72
|
|
|
59
|
-
if (layer ===
|
|
73
|
+
if (layer === "L4") {
|
|
60
74
|
if (this.config.harnesses?.deadCodeGC !== undefined) {
|
|
61
75
|
thresholds.deadCodeGC = this.config.harnesses.deadCodeGC ? 1 : 0;
|
|
62
76
|
}
|
|
63
77
|
}
|
|
64
78
|
|
|
79
|
+
const configuredValidatorIds = layerData.validators ?? defaultValidators[layer];
|
|
80
|
+
const automaticWorldValidatorId = layer === "L2" ? "L2-017" : layer === "L3" ? "L3-008" : null;
|
|
81
|
+
const selectedValidatorIds =
|
|
82
|
+
automaticWorldValidatorId === null
|
|
83
|
+
? configuredValidatorIds
|
|
84
|
+
: this.config.world?.enabled === true
|
|
85
|
+
? [...configuredValidatorIds, automaticWorldValidatorId]
|
|
86
|
+
: configuredValidatorIds.filter((validatorId) => validatorId !== automaticWorldValidatorId);
|
|
65
87
|
return LayerConfig.create({
|
|
66
88
|
layer,
|
|
67
89
|
enabled: layerData.enabled !== false,
|
|
68
|
-
validatorIds: (
|
|
90
|
+
validatorIds: [...new Set(selectedValidatorIds.map((idOrName) => this.normalizeValidatorId(idOrName)))],
|
|
69
91
|
thresholds,
|
|
70
92
|
strictOnly: layerData.strictOnly ?? strictOnly,
|
|
71
93
|
preset,
|
|
@@ -74,7 +96,7 @@ export class HarnessConfigValidatorConfigAdapter implements ValidatorConfigPort
|
|
|
74
96
|
|
|
75
97
|
async getProjectLanguages(): Promise<readonly string[]> {
|
|
76
98
|
const languages = this.config.project?.languages;
|
|
77
|
-
return languages && languages.length > 0 ? [...languages] : [
|
|
99
|
+
return languages && languages.length > 0 ? [...languages] : ["typescript"];
|
|
78
100
|
}
|
|
79
101
|
|
|
80
102
|
private normalizeValidatorId(idOrName: string): string {
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
// @unit validator-system
|
|
2
|
+
// @layer infrastructure
|
|
3
|
+
// @work-item-id WI-301
|
|
4
|
+
|
|
5
|
+
import { createWorldModelModule, type WorldResolvedConfigInput } from "../../../world-model/index.js";
|
|
6
|
+
import type {
|
|
7
|
+
WorldConstraintAdmissionObservation,
|
|
8
|
+
WorldConstraintAdmissionPolicyPort,
|
|
9
|
+
} from "../../domain/ports/world-constraint-admission-policy-port.js";
|
|
10
|
+
|
|
11
|
+
interface Options {
|
|
12
|
+
readonly rootDir: string;
|
|
13
|
+
readonly resolvedConfig?: WorldResolvedConfigInput;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
export class WorldModelConstraintAdmissionAdapter implements WorldConstraintAdmissionPolicyPort {
|
|
17
|
+
constructor(private readonly options: Options) {}
|
|
18
|
+
|
|
19
|
+
async collect(): Promise<WorldConstraintAdmissionObservation> {
|
|
20
|
+
const module = createWorldModelModule({
|
|
21
|
+
rootDir: this.options.rootDir,
|
|
22
|
+
resolvedConfig: this.options.resolvedConfig,
|
|
23
|
+
});
|
|
24
|
+
const actual = await module.deriveWorldObligationsUseCase.execute({ writeReport: false });
|
|
25
|
+
const constraintsPath =
|
|
26
|
+
this.options.resolvedConfig?.declarations?.constraintsPath ?? "phasegate.world-constraints.json";
|
|
27
|
+
if (actual.status === "execution-failure") {
|
|
28
|
+
return Object.freeze({
|
|
29
|
+
obligations: Object.freeze([]),
|
|
30
|
+
diagnostics: Object.freeze(
|
|
31
|
+
actual.diagnostics.map((item) =>
|
|
32
|
+
Object.freeze({
|
|
33
|
+
code: item.code,
|
|
34
|
+
path: item.path,
|
|
35
|
+
message: item.message,
|
|
36
|
+
scope: item.path === constraintsPath ? ("constraint" as const) : ("other" as const),
|
|
37
|
+
}),
|
|
38
|
+
),
|
|
39
|
+
),
|
|
40
|
+
});
|
|
41
|
+
}
|
|
42
|
+
return Object.freeze({
|
|
43
|
+
obligations: Object.freeze(
|
|
44
|
+
actual.result.report.structuralObligations.map((item) =>
|
|
45
|
+
Object.freeze({
|
|
46
|
+
ruleId: item.ruleId,
|
|
47
|
+
violationFingerprint: item.violationFingerprint,
|
|
48
|
+
constraintId: item.constraintId,
|
|
49
|
+
classification: item.classification,
|
|
50
|
+
}),
|
|
51
|
+
),
|
|
52
|
+
),
|
|
53
|
+
diagnostics: Object.freeze([]),
|
|
54
|
+
});
|
|
55
|
+
}
|
|
56
|
+
}
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
// @unit validator-system
|
|
2
|
+
// @layer infrastructure
|
|
3
|
+
// @work-item-id WI-302
|
|
4
|
+
|
|
5
|
+
import { createWorldModelModule, type WorldResolvedConfigInput } from "../../../world-model/index.js";
|
|
6
|
+
import type {
|
|
7
|
+
WorldConstraintRederivationObservation,
|
|
8
|
+
WorldConstraintRederivationPolicyPort,
|
|
9
|
+
} from "../../domain/ports/world-constraint-rederivation-policy-port.js";
|
|
10
|
+
|
|
11
|
+
interface Options {
|
|
12
|
+
readonly rootDir: string;
|
|
13
|
+
readonly resolvedConfig?: WorldResolvedConfigInput;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
export class WorldModelConstraintRederivationAdapter implements WorldConstraintRederivationPolicyPort {
|
|
17
|
+
constructor(private readonly options: Options) {}
|
|
18
|
+
|
|
19
|
+
async collect(): Promise<WorldConstraintRederivationObservation> {
|
|
20
|
+
const module = createWorldModelModule({
|
|
21
|
+
rootDir: this.options.rootDir,
|
|
22
|
+
resolvedConfig: this.options.resolvedConfig,
|
|
23
|
+
});
|
|
24
|
+
const actual = await module.deriveWorldObligationsUseCase.execute({ writeReport: false });
|
|
25
|
+
const constraintsPath =
|
|
26
|
+
this.options.resolvedConfig?.declarations?.constraintsPath ?? "phasegate.world-constraints.json";
|
|
27
|
+
if (actual.status === "execution-failure") {
|
|
28
|
+
return Object.freeze({
|
|
29
|
+
obligations: Object.freeze([]),
|
|
30
|
+
diagnostics: Object.freeze(
|
|
31
|
+
actual.diagnostics.map((item) =>
|
|
32
|
+
Object.freeze({
|
|
33
|
+
code: item.code,
|
|
34
|
+
path: item.path,
|
|
35
|
+
message: item.message,
|
|
36
|
+
scope: item.path === constraintsPath ? ("constraint" as const) : ("other" as const),
|
|
37
|
+
}),
|
|
38
|
+
),
|
|
39
|
+
),
|
|
40
|
+
});
|
|
41
|
+
}
|
|
42
|
+
return Object.freeze({
|
|
43
|
+
obligations: Object.freeze(
|
|
44
|
+
actual.result.report.structuralObligations.map((item) =>
|
|
45
|
+
Object.freeze({
|
|
46
|
+
ruleId: item.ruleId,
|
|
47
|
+
violationFingerprint: item.violationFingerprint,
|
|
48
|
+
constraintId: item.constraintId,
|
|
49
|
+
classification: item.classification,
|
|
50
|
+
}),
|
|
51
|
+
),
|
|
52
|
+
),
|
|
53
|
+
diagnostics: Object.freeze([]),
|
|
54
|
+
});
|
|
55
|
+
}
|
|
56
|
+
}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
// @unit world-model
|
|
2
|
+
// @layer application
|
|
3
|
+
// @work-item-id WI-305
|
|
4
|
+
|
|
5
|
+
export interface PinnedDesignEndpointDto {
|
|
6
|
+
readonly constraintId: string;
|
|
7
|
+
readonly endpoint: "claimant" | "premise";
|
|
8
|
+
readonly nodeId: string;
|
|
9
|
+
readonly corpusRole: "product" | "inception";
|
|
10
|
+
readonly declaredKey: string;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
export type PinnedDesignEndpointReadResultDto =
|
|
14
|
+
| {
|
|
15
|
+
readonly state: "available";
|
|
16
|
+
readonly endpoints: readonly PinnedDesignEndpointDto[];
|
|
17
|
+
readonly diagnosticCodes: readonly string[];
|
|
18
|
+
}
|
|
19
|
+
| { readonly state: "unavailable"; readonly diagnosticCodes: readonly string[] };
|