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.
Files changed (154) hide show
  1. package/CHANGELOG.md +73 -1
  2. package/README.ja.md +31 -1
  3. package/README.md +30 -0
  4. package/docs/ADR/031-world-model-ownership-and-corpus-lifecycle.md +155 -0
  5. package/docs/ADR/032-world-node-identity.md +198 -0
  6. package/docs/ADR/033-world-snapshot-canonicalization.md +246 -0
  7. package/docs/ADR/034-world-constraint-semantics.md +218 -0
  8. package/docs/ADR/035-world-adoption-baseline-and-waiver.md +341 -0
  9. package/docs/ADR/036-world-model-and-doc-freshness.md +169 -0
  10. package/docs/ADR/037-world-cli-and-output-contract.md +398 -0
  11. package/docs/contracts/attestation-v2.schema.json +110 -0
  12. package/docs/contracts/requirement-test-matrix.schema.json +15 -0
  13. package/docs/contracts/world-baseline.schema.json +35 -0
  14. package/docs/contracts/world-constraints.schema.json +56 -0
  15. package/docs/contracts/world-debts.schema.json +32 -0
  16. package/docs/contracts/world-obligation-report.schema.json +259 -0
  17. package/docs/contracts/world-waivers.schema.json +32 -0
  18. package/docs/guide/cli-reference.md +45 -0
  19. package/docs/guide/configuration.md +56 -0
  20. package/docs/templates/ci/aidlc-gate.yml +42 -2
  21. package/package.json +1 -1
  22. package/scripts/harness/agent-integration/application/dto/open-world-obligations-context-dto.ts +30 -0
  23. package/scripts/harness/agent-integration/application/ports/world-obligations-query-port.ts +30 -0
  24. package/scripts/harness/agent-integration/application/usecases/get-open-world-obligations-context-usecase.ts +66 -0
  25. package/scripts/harness/agent-integration/infrastructure/adapters/world-model-open-obligations-query-adapter.ts +58 -0
  26. package/scripts/harness/agent-integration/presentation/session-start-hook.ts +37 -1
  27. package/scripts/harness/agent-integration/presentation/world-obligations-session-context.ts +60 -0
  28. package/scripts/harness/attestation/application/dto/attestation-document.ts +17 -4
  29. package/scripts/harness/attestation/application/mappers/attestation-record-mapper.ts +55 -4
  30. package/scripts/harness/attestation/application/ports/sha256-capability.ts +25 -0
  31. package/scripts/harness/attestation/application/ports/world-snapshot-root-provider.ts +10 -0
  32. package/scripts/harness/attestation/application/usecases/produce-attestation-usecase.ts +33 -7
  33. package/scripts/harness/attestation/composition-root.ts +19 -4
  34. package/scripts/harness/attestation/domain/entities/attestation-record.ts +37 -2
  35. package/scripts/harness/attestation/index.ts +13 -2
  36. package/scripts/harness/attestation/infrastructure/adapters/node-crypto-content-hasher-adapter.ts +6 -6
  37. package/scripts/harness/attestation/infrastructure/adapters/node-crypto-sha256-capability.ts +19 -0
  38. package/scripts/harness/attestation/presentation/handlers/attest-handler.ts +5 -2
  39. package/scripts/harness/config-foundation/application/mappers/validator-system-config-mapper.ts +35 -8
  40. package/scripts/harness/config-foundation/application/mappers/world-model-config-mapper.ts +15 -0
  41. package/scripts/harness/config-foundation/domain/harness-config.ts +67 -87
  42. package/scripts/harness/config-foundation/domain/services/preset-resolution-service.ts +77 -88
  43. package/scripts/harness/config-foundation/domain/value-objects/world-config.ts +198 -0
  44. package/scripts/harness/config-foundation/index.ts +14 -15
  45. package/scripts/harness/config-foundation/infrastructure/presets/minimal.json +24 -0
  46. package/scripts/harness/config-foundation/infrastructure/presets/standard.json +24 -0
  47. package/scripts/harness/config-foundation/infrastructure/presets/strict.json +24 -0
  48. package/scripts/harness/config-foundation/infrastructure/schemas/harness-config-v2.schema.json +83 -0
  49. package/scripts/harness/config-foundation/infrastructure/schemas/harness-config-v3.schema.json +83 -0
  50. package/scripts/harness/harness-api/domain/value-objects/ci-check-result.ts +18 -4
  51. package/scripts/harness/harness-api/domain/value-objects/known-harness-commands.ts +4 -1
  52. package/scripts/harness/integrations/pre-commit.ts +169 -27
  53. package/scripts/harness/main.ts +276 -126
  54. package/scripts/harness/nyquist-validation/application/dto/generate-matrix-output.ts +11 -0
  55. package/scripts/harness/nyquist-validation/application/usecases/check-ac-coverage-gate-usecase.ts +6 -0
  56. package/scripts/harness/nyquist-validation/application/usecases/generate-requirement-test-matrix-usecase.ts +8 -4
  57. package/scripts/harness/nyquist-validation/domain/entities/story-mapping.ts +29 -2
  58. package/scripts/harness/nyquist-validation/domain/services/ac-coverage-gate-policy.ts +28 -0
  59. package/scripts/harness/nyquist-validation/infrastructure/adapters/markdown-requirement-source-adapter.ts +71 -4
  60. package/scripts/harness/nyquist-validation/infrastructure/schema/matrix-schema-loader.ts +4 -0
  61. package/scripts/harness/traceability-model/application/dto/changed-design-fragment-dto.ts +31 -0
  62. package/scripts/harness/traceability-model/application/dto/traceability-world-read-dto.ts +67 -0
  63. package/scripts/harness/traceability-model/application/facades/design-change-read-facade.ts +14 -0
  64. package/scripts/harness/traceability-model/application/facades/traceability-world-read-facade.ts +372 -0
  65. package/scripts/harness/traceability-model/application/ports/staged-design-change-source-port.ts +9 -0
  66. package/scripts/harness/traceability-model/application/ports/traceability-world-read-source-port.ts +61 -0
  67. package/scripts/harness/traceability-model/composition-root.ts +26 -5
  68. package/scripts/harness/traceability-model/index.ts +26 -6
  69. package/scripts/harness/traceability-model/infrastructure/adapters/file-system-traceability-world-read-adapter.ts +223 -0
  70. package/scripts/harness/traceability-model/infrastructure/adapters/git-staged-design-change-adapter.ts +155 -0
  71. package/scripts/harness/traceability-model/infrastructure/parsers/story-catalog-parser.ts +86 -8
  72. package/scripts/harness/validator-system/application/use-cases/run-l2-validators-usecase.ts +31 -0
  73. package/scripts/harness/validator-system/application/use-cases/run-l3-validators-usecase.ts +34 -0
  74. package/scripts/harness/validator-system/composition-root.ts +21 -6
  75. package/scripts/harness/validator-system/domain/ports/world-constraint-admission-policy-port.ts +28 -0
  76. package/scripts/harness/validator-system/domain/ports/world-constraint-rederivation-policy-port.ts +11 -0
  77. package/scripts/harness/validator-system/domain/services/design-change-declaration-policy.ts +75 -0
  78. package/scripts/harness/validator-system/domain/services/world-constraint-admission-service.ts +78 -0
  79. package/scripts/harness/validator-system/domain/services/world-constraint-rederivation-service.ts +76 -0
  80. package/scripts/harness/validator-system/domain/value-objects/validator-id.ts +4 -0
  81. package/scripts/harness/validator-system/infrastructure/adapters/harness-config-validator-config-adapter.ts +38 -16
  82. package/scripts/harness/validator-system/infrastructure/adapters/world-model-constraint-admission-adapter.ts +56 -0
  83. package/scripts/harness/validator-system/infrastructure/adapters/world-model-constraint-rederivation-adapter.ts +56 -0
  84. package/scripts/harness/world-model/application/dto/pinned-design-endpoint-dto.ts +19 -0
  85. package/scripts/harness/world-model/application/dto/world-inspection-dto.ts +43 -0
  86. package/scripts/harness/world-model/application/dto/world-obligation-report-dto.ts +54 -0
  87. package/scripts/harness/world-model/application/dto/world-resolved-config-input.ts +127 -0
  88. package/scripts/harness/world-model/application/dto/world-snapshot-root-dto.ts +8 -0
  89. package/scripts/harness/world-model/application/facades/pinned-design-endpoint-facade.ts +63 -0
  90. package/scripts/harness/world-model/application/facades/world-snapshot-root-facade.ts +19 -0
  91. package/scripts/harness/world-model/application/ports/obligation-report-writer-port.ts +7 -0
  92. package/scripts/harness/world-model/application/ports/world-control-declaration-repository-port.ts +57 -0
  93. package/scripts/harness/world-model/application/ports/world-fact-source-port.ts +17 -0
  94. package/scripts/harness/world-model/application/usecases/build-snapshot-use-case.ts +111 -0
  95. package/scripts/harness/world-model/application/usecases/derive-obligations-use-case.ts +155 -0
  96. package/scripts/harness/world-model/application/usecases/derive-world-obligations-use-case.ts +146 -0
  97. package/scripts/harness/world-model/application/usecases/inspect-world-use-case.ts +74 -0
  98. package/scripts/harness/world-model/application/usecases/pin-constraint-endpoint-use-case.ts +139 -0
  99. package/scripts/harness/world-model/composition-root.ts +247 -0
  100. package/scripts/harness/world-model/domain/entities/constraint-record.ts +148 -0
  101. package/scripts/harness/world-model/domain/entities/control-declarations.ts +274 -0
  102. package/scripts/harness/world-model/domain/entities/edge.ts +41 -0
  103. package/scripts/harness/world-model/domain/entities/extraction-diagnostic.ts +60 -0
  104. package/scripts/harness/world-model/domain/entities/snapshot.ts +75 -0
  105. package/scripts/harness/world-model/domain/entities/world-node.ts +210 -0
  106. package/scripts/harness/world-model/domain/ports/world-hashing-port.ts +8 -0
  107. package/scripts/harness/world-model/domain/services/canonical-json-serializer.ts +113 -0
  108. package/scripts/harness/world-model/domain/services/constraint-evaluator.ts +486 -0
  109. package/scripts/harness/world-model/domain/services/obligation-derivation-service.ts +199 -0
  110. package/scripts/harness/world-model/domain/services/policy-inputs-digest-deriver.ts +66 -0
  111. package/scripts/harness/world-model/domain/services/snapshot-root-deriver.ts +218 -0
  112. package/scripts/harness/world-model/domain/services/text-content-normalizer.ts +30 -0
  113. package/scripts/harness/world-model/domain/services/violation-fingerprint-deriver.ts +183 -0
  114. package/scripts/harness/world-model/domain/value-objects/artifact-kind.ts +58 -0
  115. package/scripts/harness/world-model/domain/value-objects/change-provenance.ts +137 -0
  116. package/scripts/harness/world-model/domain/value-objects/corpus-role.ts +57 -0
  117. package/scripts/harness/world-model/domain/value-objects/declared-key.ts +35 -0
  118. package/scripts/harness/world-model/domain/value-objects/evaluation-id.ts +41 -0
  119. package/scripts/harness/world-model/domain/value-objects/explicit-constraint-relation.ts +53 -0
  120. package/scripts/harness/world-model/domain/value-objects/explicit-node-alias.ts +30 -0
  121. package/scripts/harness/world-model/domain/value-objects/node-pin.ts +34 -0
  122. package/scripts/harness/world-model/domain/value-objects/path-key.ts +103 -0
  123. package/scripts/harness/world-model/domain/value-objects/sha256-digest.ts +39 -0
  124. package/scripts/harness/world-model/domain/value-objects/violation-fingerprint.ts +36 -0
  125. package/scripts/harness/world-model/domain/value-objects/wcr-rule-id.ts +59 -0
  126. package/scripts/harness/world-model/domain/value-objects/world-node-id.ts +222 -0
  127. package/scripts/harness/world-model/index.ts +33 -0
  128. package/scripts/harness/world-model/infrastructure/adapters/adr-fact-extractor.ts +27 -0
  129. package/scripts/harness/world-model/infrastructure/adapters/assembled-world-fact-source.ts +17 -0
  130. package/scripts/harness/world-model/infrastructure/adapters/attestation-fact-extractor.ts +323 -0
  131. package/scripts/harness/world-model/infrastructure/adapters/attestation-sha256-world-hashing-adapter.ts +15 -0
  132. package/scripts/harness/world-model/infrastructure/adapters/composite-design-fact-source.ts +23 -0
  133. package/scripts/harness/world-model/infrastructure/adapters/design-corpus-fact-extractor.ts +285 -0
  134. package/scripts/harness/world-model/infrastructure/adapters/design-fact-extraction.ts +63 -0
  135. package/scripts/harness/world-model/infrastructure/adapters/file-system-obligation-report-writer-adapter.ts +37 -0
  136. package/scripts/harness/world-model/infrastructure/adapters/file-system-world-control-repository-adapters.ts +332 -0
  137. package/scripts/harness/world-model/infrastructure/adapters/integrity-manifest-fact-extractor.ts +101 -0
  138. package/scripts/harness/world-model/infrastructure/adapters/json-fact-extractor-support.ts +151 -0
  139. package/scripts/harness/world-model/infrastructure/adapters/markdown-design-fact-extractor.ts +493 -0
  140. package/scripts/harness/world-model/infrastructure/adapters/matrix-fact-extractor.ts +283 -0
  141. package/scripts/harness/world-model/infrastructure/adapters/product-fact-extractor.ts +29 -0
  142. package/scripts/harness/world-model/infrastructure/adapters/proposal-fact-extractor.ts +29 -0
  143. package/scripts/harness/world-model/infrastructure/adapters/runtime-fact-extraction.ts +19 -0
  144. package/scripts/harness/world-model/infrastructure/adapters/source-metadata-fact-extractor.ts +22 -0
  145. package/scripts/harness/world-model/infrastructure/adapters/test-reference-source-fact-extractor.ts +22 -0
  146. package/scripts/harness/world-model/infrastructure/adapters/traceability-design-fact-adapter.ts +112 -0
  147. package/scripts/harness/world-model/infrastructure/adapters/traceability-world-read-facade-merger.ts +38 -0
  148. package/scripts/harness/world-model/infrastructure/adapters/type-script-source-fact-extractor.ts +236 -0
  149. package/scripts/harness/world-model/infrastructure/adapters/unit-fact-extractor.ts +71 -0
  150. package/scripts/harness/world-model/infrastructure/adapters/world-control-declaration-mapper.ts +383 -0
  151. package/scripts/harness/world-model/presentation/cli/world-command-support.ts +60 -0
  152. package/scripts/harness/world-model/presentation/cli/world-derive-command-handler.ts +109 -0
  153. package/scripts/harness/world-model/presentation/cli/world-inspect-command-handler.ts +194 -0
  154. package/scripts/harness/world-model/presentation/cli/world-pin-command-handler.ts +100 -0
@@ -4,36 +4,36 @@
4
4
  * @work-item-id WI-012
5
5
  * @work-item-id WI-212
6
6
  * @work-item-id WI-219
7
+ * @work-item-id WI-300
7
8
  */
8
- import { ConfigFoundationDomainError } from './errors/config-foundation-domain-error.js';
9
- import { ConfigValidationError } from './errors/config-validation-error.js';
10
- import { UnsupportedFeatureError } from './errors/unsupported-feature-error.js';
11
- import { LayersConfig } from './value-objects/layers-config.js';
12
- import { PathsConfig } from './value-objects/paths-config.js';
13
- import { PhaseDependenciesConfig } from './value-objects/phase-dependencies-config.js';
14
- import type { PhaseDependenciesPresetId } from './value-objects/phase-dependencies-config.js';
15
- import { PlanningModeConfig } from './value-objects/planning-mode-config.js';
16
- import { ProjectConfig } from './value-objects/project-config.js';
17
- import { QuickModeConfig } from './value-objects/quick-mode-config.js';
18
- import { ReportingConfig } from './value-objects/reporting-config.js';
19
- import { ValidateConfig } from './value-objects/validate-config.js';
20
- import { HarnessesConfig } from './value-objects/harnesses-config.js';
21
- import type { FeatureNameValue } from './value-objects/feature-name.js';
22
- import type { FeatureName } from './value-objects/feature-name.js';
23
- import type { L1Config } from './value-objects/l1-config.js';
24
- import type { L2Config } from './value-objects/l2-config.js';
25
- import type { L3Config } from './value-objects/l3-config.js';
26
- import type { L4Config } from './value-objects/l4-config.js';
27
- import type {
28
- ArchitectureConfigDocument,
29
- ArchitectureConfigSource,
30
- } from './value-objects/architecture-config.js';
31
-
32
- export type LayerId = 'L1' | 'L2' | 'L3' | 'L4';
33
- export type PresetId = 'minimal' | 'standard' | 'strict';
34
- export type PlanningModeValue = 'interactive' | 'embedded-qa' | 'manual';
35
- export type ModelDelegationPolicy = 'delegate-sonnet' | 'none';
9
+ import { ConfigFoundationDomainError } from "./errors/config-foundation-domain-error.js";
10
+ import { ConfigValidationError } from "./errors/config-validation-error.js";
11
+ import { UnsupportedFeatureError } from "./errors/unsupported-feature-error.js";
12
+ import type { ArchitectureConfigDocument, ArchitectureConfigSource } from "./value-objects/architecture-config.js";
13
+ import type { FeatureName, FeatureNameValue } from "./value-objects/feature-name.js";
14
+ import { HarnessesConfig } from "./value-objects/harnesses-config.js";
15
+ import type { L1Config } from "./value-objects/l1-config.js";
16
+ import type { L2Config } from "./value-objects/l2-config.js";
17
+ import type { L3Config } from "./value-objects/l3-config.js";
18
+ import type { L4Config } from "./value-objects/l4-config.js";
19
+ import { LayersConfig } from "./value-objects/layers-config.js";
20
+ import { PathsConfig } from "./value-objects/paths-config.js";
21
+ import type { PhaseDependenciesPresetId } from "./value-objects/phase-dependencies-config.js";
22
+ import { PhaseDependenciesConfig } from "./value-objects/phase-dependencies-config.js";
23
+ import { PlanningModeConfig } from "./value-objects/planning-mode-config.js";
24
+ import { ProjectConfig } from "./value-objects/project-config.js";
25
+ import { QuickModeConfig } from "./value-objects/quick-mode-config.js";
26
+ import { ReportingConfig } from "./value-objects/reporting-config.js";
27
+ import { ValidateConfig } from "./value-objects/validate-config.js";
28
+ import type { WorldConfigDocument, WorldConfigSourceDocument } from "./value-objects/world-config.js";
29
+ import { WORLD_CONFIG_DEFAULTS, WorldConfig } from "./value-objects/world-config.js";
30
+
31
+ export type LayerId = "L1" | "L2" | "L3" | "L4";
32
+ export type PresetId = "minimal" | "standard" | "strict";
33
+ export type PlanningModeValue = "interactive" | "embedded-qa" | "manual";
34
+ export type ModelDelegationPolicy = "delegate-sonnet" | "none";
36
35
  export type { PhaseDependenciesPresetId };
36
+
37
37
  type DeepPartial<T> = {
38
38
  [K in keyof T]?: T[K] extends Array<infer TItem>
39
39
  ? Array<DeepPartial<TItem>>
@@ -48,19 +48,20 @@ export interface HarnessConfigSourceDocument {
48
48
  preset: PresetId;
49
49
  languages?: string[];
50
50
  };
51
- layers: DeepPartial<HarnessConfigResolvedDocument['layers']>;
52
- quickMode: Partial<HarnessConfigResolvedDocument['quickMode']>;
53
- phaseDependencies: HarnessConfigResolvedDocument['phaseDependencies'];
54
- planningMode: HarnessConfigResolvedDocument['planningMode'];
55
- harnesses: Partial<HarnessConfigResolvedDocument['harnesses']>;
56
- paths: HarnessConfigResolvedDocument['paths'];
57
- reporting: HarnessConfigResolvedDocument['reporting'];
58
- ci?: HarnessConfigResolvedDocument['ci'];
59
- validate?: HarnessConfigResolvedDocument['validate'];
60
- preCommit?: Partial<HarnessConfigResolvedDocument['preCommit']>;
61
- modelRouting?: HarnessConfigResolvedDocument['modelRouting'];
62
- phase2Extensions?: HarnessConfigResolvedDocument['phase2Extensions'];
51
+ layers: DeepPartial<HarnessConfigResolvedDocument["layers"]>;
52
+ quickMode: Partial<HarnessConfigResolvedDocument["quickMode"]>;
53
+ phaseDependencies: HarnessConfigResolvedDocument["phaseDependencies"];
54
+ planningMode: HarnessConfigResolvedDocument["planningMode"];
55
+ harnesses: Partial<HarnessConfigResolvedDocument["harnesses"]>;
56
+ paths: HarnessConfigResolvedDocument["paths"];
57
+ reporting: HarnessConfigResolvedDocument["reporting"];
58
+ ci?: HarnessConfigResolvedDocument["ci"];
59
+ validate?: HarnessConfigResolvedDocument["validate"];
60
+ preCommit?: Partial<HarnessConfigResolvedDocument["preCommit"]>;
61
+ modelRouting?: HarnessConfigResolvedDocument["modelRouting"];
62
+ phase2Extensions?: HarnessConfigResolvedDocument["phase2Extensions"];
63
63
  architecture?: ArchitectureConfigSource;
64
+ world?: WorldConfigSourceDocument;
64
65
  }
65
66
 
66
67
  export interface HarnessConfigResolvedDocument {
@@ -142,11 +143,12 @@ export interface HarnessConfigResolvedDocument {
142
143
  documentPattern: string;
143
144
  daysThreshold: number;
144
145
  commitCountThreshold: number;
145
- evaluationMode: 'or' | 'and';
146
+ evaluationMode: "or" | "and";
146
147
  enabled?: boolean;
147
148
  }>;
148
149
  };
149
150
  architecture?: ArchitectureConfigDocument;
151
+ world?: WorldConfigDocument;
150
152
  }
151
153
 
152
154
  export type HarnessConfigV2 = HarnessConfigResolvedDocument;
@@ -159,7 +161,7 @@ export interface HarnessConfigReconstitutionProps {
159
161
  }
160
162
 
161
163
  export interface FeatureToggled {
162
- type: 'FeatureToggled';
164
+ type: "FeatureToggled";
163
165
  occurredAt: Date;
164
166
  projectName: string;
165
167
  featureName: FeatureNameValue | string;
@@ -168,7 +170,7 @@ export interface FeatureToggled {
168
170
  }
169
171
 
170
172
  export interface PresetApplied {
171
- type: 'PresetApplied';
173
+ type: "PresetApplied";
172
174
  occurredAt: Date;
173
175
  projectName: string;
174
176
  preset: PresetId;
@@ -178,23 +180,23 @@ export interface PresetApplied {
178
180
  export type DomainEvent = FeatureToggled | PresetApplied;
179
181
 
180
182
  const SUPPORTED_FEATURE_NAMES = [
181
- 'agentLessonCollection',
182
- 'cascadeUpdate',
183
- 'bundleSizeLimit',
184
- 'deadCodeGC',
183
+ "agentLessonCollection",
184
+ "cascadeUpdate",
185
+ "bundleSizeLimit",
186
+ "deadCodeGC",
185
187
  ] as const satisfies readonly FeatureNameValue[];
186
188
 
187
189
  export class UnknownLayerError extends ConfigFoundationDomainError {
188
190
  constructor(layerId: string) {
189
- super(`未知のレイヤーです: ${layerId} [L1-006]`, 'L1-006');
190
- this.name = 'UnknownLayerError';
191
+ super(`未知のレイヤーです: ${layerId} [L1-006]`, "L1-006");
192
+ this.name = "UnknownLayerError";
191
193
  }
192
194
  }
193
195
 
194
196
  export class FeatureActivationRuleError extends ConfigFoundationDomainError {
195
197
  constructor(message: string) {
196
- super(`${message} [L1-005]`, 'L1-005');
197
- this.name = 'FeatureActivationRuleError';
198
+ super(`${message} [L1-005]`, "L1-005");
199
+ this.name = "FeatureActivationRuleError";
198
200
  }
199
201
  }
200
202
 
@@ -207,11 +209,8 @@ function deepClone<T>(value: T): T {
207
209
  return value.map((item) => deepClone(item)) as T;
208
210
  }
209
211
 
210
- if (value !== null && typeof value === 'object') {
211
- const clonedEntries = Object.entries(value).map(([key, entryValue]) => [
212
- key,
213
- deepClone(entryValue),
214
- ]);
212
+ if (value !== null && typeof value === "object") {
213
+ const clonedEntries = Object.entries(value).map(([key, entryValue]) => [key, deepClone(entryValue)]);
215
214
 
216
215
  return Object.fromEntries(clonedEntries) as T;
217
216
  }
@@ -226,7 +225,7 @@ function createFeatureToggledEvent(
226
225
  currentState: boolean,
227
226
  ): FeatureToggled {
228
227
  return Object.freeze({
229
- type: 'FeatureToggled',
228
+ type: "FeatureToggled",
230
229
  occurredAt: new Date(),
231
230
  projectName,
232
231
  featureName,
@@ -240,14 +239,14 @@ function assertSupportedFeature(name: FeatureName): FeatureNameValue {
240
239
 
241
240
  if (!SUPPORTED_FEATURE_NAMES.includes(raw as FeatureNameValue)) {
242
241
  throw new UnsupportedFeatureError(
243
- `機能名 "${raw}" は利用できません。利用可能: ${SUPPORTED_FEATURE_NAMES.join(', ')}`,
242
+ `機能名 "${raw}" は利用できません。利用可能: ${SUPPORTED_FEATURE_NAMES.join(", ")}`,
244
243
  );
245
244
  }
246
245
 
247
246
  return raw as FeatureNameValue;
248
247
  }
249
248
 
250
- function toHarnessesDocument(harnesses: HarnessesConfig): HarnessConfigResolvedDocument['harnesses'] {
249
+ function toHarnessesDocument(harnesses: HarnessesConfig): HarnessConfigResolvedDocument["harnesses"] {
251
250
  return {
252
251
  agentLessonCollection: harnesses.agentLessonCollection,
253
252
  cascadeUpdate: harnesses.cascadeUpdate,
@@ -303,22 +302,17 @@ export class HarnessConfig {
303
302
  const project = ProjectConfig.create(props.resolvedDocument.project);
304
303
  const layers = LayersConfig.create(props.resolvedDocument.layers);
305
304
  const quickMode = QuickModeConfig.create(props.resolvedDocument.quickMode);
306
- const phaseDependencies = PhaseDependenciesConfig.create(
307
- props.resolvedDocument.phaseDependencies,
308
- );
309
- const planningMode = PlanningModeConfig.create(
310
- props.resolvedDocument.planningMode,
311
- );
305
+ const phaseDependencies = PhaseDependenciesConfig.create(props.resolvedDocument.phaseDependencies);
306
+ const planningMode = PlanningModeConfig.create(props.resolvedDocument.planningMode);
312
307
  const harnesses = HarnessesConfig.create(props.resolvedDocument.harnesses);
313
308
  const paths = PathsConfig.create(props.resolvedDocument.paths);
314
309
  const reporting = ReportingConfig.create(props.resolvedDocument.reporting);
315
310
  const validate = ValidateConfig.create(props.resolvedDocument.validate);
311
+ const world = WorldConfig.create(props.resolvedDocument.world ?? WORLD_CONFIG_DEFAULTS).toDocument();
316
312
 
317
- if (
318
- props.sourceDocument.project.preset !== props.resolvedDocument.project.preset
319
- ) {
313
+ if (props.sourceDocument.project.preset !== props.resolvedDocument.project.preset) {
320
314
  throw new ConfigValidationError(
321
- 'sourceDocument.project.preset と resolvedDocument.project.preset は一致しなければなりません',
315
+ "sourceDocument.project.preset と resolvedDocument.project.preset は一致しなければなりません",
322
316
  );
323
317
  }
324
318
 
@@ -333,7 +327,7 @@ export class HarnessConfig {
333
327
  reporting,
334
328
  validate,
335
329
  sourceDocument: props.sourceDocument,
336
- resolvedDocument: props.resolvedDocument,
330
+ resolvedDocument: { ...props.resolvedDocument, world },
337
331
  pendingEvents: props.pendingEvents ?? [],
338
332
  });
339
333
  }
@@ -355,14 +349,7 @@ export class HarnessConfig {
355
349
  ...this.resolvedDocument,
356
350
  harnesses: toHarnessesDocument(nextHarnesses),
357
351
  };
358
- this.pendingEvents.push(
359
- createFeatureToggledEvent(
360
- this.project.name,
361
- featureName,
362
- previousState,
363
- true,
364
- ),
365
- );
352
+ this.pendingEvents.push(createFeatureToggledEvent(this.project.name, featureName, previousState, true));
366
353
  }
367
354
 
368
355
  disableFeature(name: FeatureName): void {
@@ -382,18 +369,11 @@ export class HarnessConfig {
382
369
  ...this.resolvedDocument,
383
370
  harnesses: toHarnessesDocument(nextHarnesses),
384
371
  };
385
- this.pendingEvents.push(
386
- createFeatureToggledEvent(
387
- this.project.name,
388
- featureName,
389
- previousState,
390
- false,
391
- ),
392
- );
372
+ this.pendingEvents.push(createFeatureToggledEvent(this.project.name, featureName, previousState, false));
393
373
  }
394
374
 
395
375
  getLayerConfig(layerId: LayerId): L1Config | L2Config | L3Config | L4Config {
396
- if (!['L1', 'L2', 'L3', 'L4'].includes(layerId)) {
376
+ if (!["L1", "L2", "L3", "L4"].includes(layerId)) {
397
377
  throw new UnknownLayerError(layerId);
398
378
  }
399
379
 
@@ -2,43 +2,43 @@
2
2
  * @layer domain
3
3
  * @unit config-foundation
4
4
  * @work-item-id WI-212
5
+ * @work-item-id WI-300
5
6
  */
6
- import { ConfigFoundationDomainError } from '../errors/config-foundation-domain-error.js';
7
- import type {
8
- HarnessConfigResolvedDocument,
9
- HarnessConfigSourceDocument,
10
- } from '../harness-config.js';
11
- import { HarnessesConfig } from '../value-objects/harnesses-config.js';
12
- import type { FeatureToggle } from '../value-objects/feature-toggle.js';
7
+ import { ConfigFoundationDomainError } from "../errors/config-foundation-domain-error.js";
8
+ import type { HarnessConfigResolvedDocument, HarnessConfigSourceDocument } from "../harness-config.js";
9
+ import type { FeatureToggle } from "../value-objects/feature-toggle.js";
10
+ import { HarnessesConfig } from "../value-objects/harnesses-config.js";
11
+ import { WORLD_CONFIG_DEFAULTS, WorldConfig, type WorldConfigDocument } from "../value-objects/world-config.js";
13
12
 
14
13
  export interface PresetDefinition {
15
- layers: HarnessConfigResolvedDocument['layers'];
16
- quickMode: HarnessConfigResolvedDocument['quickMode'];
17
- phaseDependencies: HarnessConfigResolvedDocument['phaseDependencies'];
18
- planningMode: HarnessConfigResolvedDocument['planningMode'];
19
- harnesses: HarnessConfigResolvedDocument['harnesses'];
20
- paths: HarnessConfigResolvedDocument['paths'];
21
- reporting: HarnessConfigResolvedDocument['reporting'];
22
- validate: HarnessConfigResolvedDocument['validate'];
23
- preCommit?: HarnessConfigResolvedDocument['preCommit'];
14
+ layers: HarnessConfigResolvedDocument["layers"];
15
+ quickMode: HarnessConfigResolvedDocument["quickMode"];
16
+ phaseDependencies: HarnessConfigResolvedDocument["phaseDependencies"];
17
+ planningMode: HarnessConfigResolvedDocument["planningMode"];
18
+ harnesses: HarnessConfigResolvedDocument["harnesses"];
19
+ paths: HarnessConfigResolvedDocument["paths"];
20
+ reporting: HarnessConfigResolvedDocument["reporting"];
21
+ validate: HarnessConfigResolvedDocument["validate"];
22
+ preCommit?: HarnessConfigResolvedDocument["preCommit"];
23
+ world?: WorldConfigDocument;
24
24
  }
25
25
 
26
26
  export class InvalidPresetDefinitionError extends ConfigFoundationDomainError {
27
27
  constructor(message: string) {
28
- super(`${message} [L1-007]`, 'L1-007');
29
- this.name = 'InvalidPresetDefinitionError';
28
+ super(`${message} [L1-007]`, "L1-007");
29
+ this.name = "InvalidPresetDefinitionError";
30
30
  }
31
31
  }
32
32
 
33
33
  export class ConfigMergeError extends ConfigFoundationDomainError {
34
34
  constructor(message: string) {
35
- super(`${message} [L1-008]`, 'L1-008');
36
- this.name = 'ConfigMergeError';
35
+ super(`${message} [L1-008]`, "L1-008");
36
+ this.name = "ConfigMergeError";
37
37
  }
38
38
  }
39
39
 
40
40
  function isPlainObject(value: unknown): value is Record<string, unknown> {
41
- return value !== null && typeof value === 'object' && !Array.isArray(value);
41
+ return value !== null && typeof value === "object" && !Array.isArray(value);
42
42
  }
43
43
 
44
44
  function deepClone<T>(value: T): T {
@@ -47,9 +47,7 @@ function deepClone<T>(value: T): T {
47
47
  }
48
48
 
49
49
  if (isPlainObject(value)) {
50
- return Object.fromEntries(
51
- Object.entries(value).map(([key, entryValue]) => [key, deepClone(entryValue)]),
52
- ) as T;
50
+ return Object.fromEntries(Object.entries(value).map(([key, entryValue]) => [key, deepClone(entryValue)])) as T;
53
51
  }
54
52
 
55
53
  return value;
@@ -74,10 +72,7 @@ function deepMerge<T>(baseValue: T, overrideValue: unknown, path: string): T {
74
72
  }
75
73
 
76
74
  const merged: Record<string, unknown> = {};
77
- const keys = new Set([
78
- ...Object.keys(baseValue),
79
- ...Object.keys(overrideValue),
80
- ]);
75
+ const keys = new Set([...Object.keys(baseValue), ...Object.keys(overrideValue)]);
81
76
 
82
77
  for (const key of keys) {
83
78
  const nestedBaseValue = (baseValue as Record<string, unknown>)[key];
@@ -88,11 +83,7 @@ function deepMerge<T>(baseValue: T, overrideValue: unknown, path: string): T {
88
83
  continue;
89
84
  }
90
85
 
91
- merged[key] = deepMerge(
92
- nestedBaseValue,
93
- nestedOverrideValue,
94
- `${path}.${key}`,
95
- );
86
+ merged[key] = deepMerge(nestedBaseValue, nestedOverrideValue, `${path}.${key}`);
96
87
  }
97
88
 
98
89
  return merged as T;
@@ -105,35 +96,26 @@ function deepMerge<T>(baseValue: T, overrideValue: unknown, path: string): T {
105
96
  return deepClone(overrideValue as T);
106
97
  }
107
98
 
108
- function assertValidPresetDefinition(
109
- presetDefinition: PresetDefinition,
110
- ): void {
99
+ function assertValidPresetDefinition(presetDefinition: PresetDefinition): void {
111
100
  const requiredKeys: Array<keyof PresetDefinition> = [
112
- 'layers',
113
- 'quickMode',
114
- 'phaseDependencies',
115
- 'planningMode',
116
- 'harnesses',
117
- 'paths',
118
- 'reporting',
119
- 'validate',
101
+ "layers",
102
+ "quickMode",
103
+ "phaseDependencies",
104
+ "planningMode",
105
+ "harnesses",
106
+ "paths",
107
+ "reporting",
108
+ "validate",
120
109
  ];
121
110
 
122
111
  for (const key of requiredKeys) {
123
- if (
124
- !(key in presetDefinition) ||
125
- (presetDefinition as unknown as Record<string, unknown>)[key] === undefined
126
- ) {
127
- throw new InvalidPresetDefinitionError(
128
- `presetDefinition.${key} は必須です`,
129
- );
112
+ if (!(key in presetDefinition) || (presetDefinition as unknown as Record<string, unknown>)[key] === undefined) {
113
+ throw new InvalidPresetDefinitionError(`presetDefinition.${key} は必須です`);
130
114
  }
131
115
  }
132
116
  }
133
117
 
134
- function toHarnessesDocument(
135
- harnesses: HarnessesConfig,
136
- ): HarnessConfigResolvedDocument['harnesses'] {
118
+ function toHarnessesDocument(harnesses: HarnessesConfig): HarnessConfigResolvedDocument["harnesses"] {
137
119
  return {
138
120
  agentLessonCollection: harnesses.agentLessonCollection,
139
121
  cascadeUpdate: harnesses.cascadeUpdate,
@@ -149,49 +131,58 @@ export class PresetResolutionService {
149
131
  ): HarnessConfigResolvedDocument {
150
132
  assertValidPresetDefinition(presetDefinition);
151
133
 
134
+ const layers = deepMerge(presetDefinition.layers, sourceDocument.layers, "layers");
135
+ const paths = deepMerge(presetDefinition.paths, sourceDocument.paths, "paths");
136
+ const world = deepMerge(presetDefinition.world ?? WORLD_CONFIG_DEFAULTS, sourceDocument.world, "world");
137
+ const explicitCorpus = sourceDocument.world?.corpus;
138
+ const explicitInputs = sourceDocument.world?.inputs;
139
+ const derivedProductRoot = paths.designDocs.endsWith("/construction")
140
+ ? paths.designDocs.slice(0, -"/construction".length)
141
+ : paths.designDocs;
142
+ const resolvedWorld: WorldConfigDocument = {
143
+ ...world,
144
+ corpus: {
145
+ ...world.corpus,
146
+ productRoots:
147
+ explicitCorpus?.productRoots === undefined && !world.corpus.productRoots.includes(derivedProductRoot)
148
+ ? [...world.corpus.productRoots, derivedProductRoot]
149
+ : world.corpus.productRoots,
150
+ inceptionRoots:
151
+ explicitCorpus?.inceptionRoots === undefined ? [paths.inceptionDocs] : world.corpus.inceptionRoots,
152
+ },
153
+ inputs: {
154
+ ...world.inputs,
155
+ matrixPath:
156
+ explicitInputs?.matrixPath === undefined
157
+ ? (layers.L3.requirementMatrixPath ?? world.inputs.matrixPath)
158
+ : world.inputs.matrixPath,
159
+ },
160
+ };
161
+
152
162
  return {
153
163
  project: {
154
164
  name: sourceDocument.project.name,
155
165
  preset: sourceDocument.project.preset,
156
- languages: sourceDocument.project.languages ?? ['typescript'],
166
+ languages: sourceDocument.project.languages ?? ["typescript"],
157
167
  },
158
- layers: deepMerge(presetDefinition.layers, sourceDocument.layers, 'layers'),
159
- quickMode: deepMerge(
160
- presetDefinition.quickMode,
161
- sourceDocument.quickMode,
162
- 'quickMode',
163
- ),
168
+ layers,
169
+ quickMode: deepMerge(presetDefinition.quickMode, sourceDocument.quickMode, "quickMode"),
164
170
  phaseDependencies: deepMerge(
165
171
  presetDefinition.phaseDependencies,
166
172
  sourceDocument.phaseDependencies,
167
- 'phaseDependencies',
168
- ),
169
- planningMode: deepMerge(
170
- presetDefinition.planningMode,
171
- sourceDocument.planningMode,
172
- 'planningMode',
173
- ),
174
- harnesses: deepMerge(
175
- presetDefinition.harnesses,
176
- sourceDocument.harnesses,
177
- 'harnesses',
178
- ),
179
- paths: deepMerge(presetDefinition.paths, sourceDocument.paths, 'paths'),
180
- reporting: deepMerge(
181
- presetDefinition.reporting,
182
- sourceDocument.reporting,
183
- 'reporting',
184
- ),
185
- validate: deepMerge(
186
- presetDefinition.validate,
187
- sourceDocument.validate,
188
- 'validate',
173
+ "phaseDependencies",
189
174
  ),
175
+ planningMode: deepMerge(presetDefinition.planningMode, sourceDocument.planningMode, "planningMode"),
176
+ harnesses: deepMerge(presetDefinition.harnesses, sourceDocument.harnesses, "harnesses"),
177
+ paths,
178
+ reporting: deepMerge(presetDefinition.reporting, sourceDocument.reporting, "reporting"),
179
+ validate: deepMerge(presetDefinition.validate, sourceDocument.validate, "validate"),
190
180
  preCommit: deepMerge(
191
- presetDefinition.preCommit ?? { implementationExtensions: ['.ts'] },
181
+ presetDefinition.preCommit ?? { implementationExtensions: [".ts"] },
192
182
  sourceDocument.preCommit,
193
- 'preCommit',
183
+ "preCommit",
194
184
  ),
185
+ world: WorldConfig.create(resolvedWorld).toDocument(),
195
186
  };
196
187
  }
197
188
 
@@ -200,9 +191,7 @@ export class PresetResolutionService {
200
191
  override: FeatureToggle,
201
192
  ): HarnessConfigResolvedDocument {
202
193
  const harnesses = HarnessesConfig.create(document.harnesses);
203
- const nextHarnesses = override.enabled
204
- ? harnesses.enable(override.name)
205
- : harnesses.disable(override.name);
194
+ const nextHarnesses = override.enabled ? harnesses.enable(override.name) : harnesses.disable(override.name);
206
195
 
207
196
  return {
208
197
  ...deepClone(document),