phasegate 0.16.0 → 0.31.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 (215) hide show
  1. package/README.ja.md +71 -39
  2. package/README.md +69 -9
  3. package/docs/ADR/ADR-013-story-reflection-gate.md +100 -0
  4. package/docs/guide/configuration.md +244 -7
  5. package/package.json +4 -2
  6. package/scripts/harness/adr-foundation/domain/ports/adr-document-parser-port.ts +1 -0
  7. package/scripts/harness/adr-foundation/domain/ports/adr-frontmatter-parser-port.ts +1 -0
  8. package/scripts/harness/adr-foundation/domain/ports/adr-repository-port.ts +1 -0
  9. package/scripts/harness/adr-foundation/domain/value-objects/adr-status.ts +6 -6
  10. package/scripts/harness/agent-integration/application/dto/handle-pre-tool-use-dto.ts +3 -1
  11. package/scripts/harness/agent-integration/application/usecases/handle-pre-tool-use-usecase.ts +108 -2
  12. package/scripts/harness/agent-integration/domain/ports/config-query-port.ts +2 -0
  13. package/scripts/harness/agent-integration/domain/ports/phase-gate-query-port.ts +1 -1
  14. package/scripts/harness/agent-integration/domain/ports/story-reflection-query-port.ts +8 -0
  15. package/scripts/harness/agent-integration/domain/services/bash-write-target-extractor.ts +258 -0
  16. package/scripts/harness/agent-integration/domain/services/hook-to-cli-translator.ts +21 -4
  17. package/scripts/harness/agent-integration/domain/value-objects/protected-file-list.ts +20 -0
  18. package/scripts/harness/agent-integration/domain/value-objects/story-reflection-query-result.ts +63 -0
  19. package/scripts/harness/agent-integration/infrastructure/adapters/file-system-story-reflection-query-adapter.ts +122 -0
  20. package/scripts/harness/agent-integration/infrastructure/adapters/harness-config-config-query-adapter.ts +20 -0
  21. package/scripts/harness/agent-integration/infrastructure/adapters/phase-gate-query-adapter.ts +17 -3
  22. package/scripts/harness/agent-integration/presentation/pre-tool-use-hook.ts +29 -2
  23. package/scripts/harness/biome-ast-engine/domain/services/lint-runner.ts +24 -0
  24. package/scripts/harness/biome-ast-engine/domain/services/rule-definition-registry.ts +1 -1
  25. package/scripts/harness/biome-ast-engine/domain/value-objects/source-module-snapshot.ts +5 -2
  26. package/scripts/harness/biome-ast-engine/infrastructure/adapters/node-workspace-file-adapter.ts +1 -1
  27. package/scripts/harness/biome-ast-engine/infrastructure/adapters/typescript-source-module-analyzer-adapter.ts +1 -1
  28. package/scripts/harness/biome-ast-engine/infrastructure/parsers/unit-comment-parser.ts +12 -7
  29. package/scripts/harness/ci-governance/composition-root.ts +1 -0
  30. package/scripts/harness/config-foundation/application/mappers/phase-config-section-mapper.ts +44 -0
  31. package/scripts/harness/config-foundation/application/usecases/load-resolved-config-use-case.ts +20 -1
  32. package/scripts/harness/config-foundation/domain/harness-config.ts +2 -1
  33. package/scripts/harness/config-foundation/domain/value-objects/phase-dependencies-config.ts +18 -4
  34. package/scripts/harness/config-foundation/infrastructure/schemas/harness-config-v2.schema.json +185 -10
  35. package/scripts/harness/config-foundation/infrastructure/validators/ajv-config-schema-validator.ts +2 -1
  36. package/scripts/harness/harness-api/application/dto/command-dispatch-input.ts +1 -0
  37. package/scripts/harness/harness-api/application/dto/command-dispatch-output.ts +1 -0
  38. package/scripts/harness/harness-api/application/dto/exit-code-decision-input.ts +1 -0
  39. package/scripts/harness/harness-api/application/dto/exit-code-decision-output.ts +1 -0
  40. package/scripts/harness/harness-api/application/dto/harness-api-response-contract.ts +1 -0
  41. package/scripts/harness/harness-api/application/dto/initialize-registry-input.ts +1 -0
  42. package/scripts/harness/harness-api/application/dto/registry-summary-output.ts +1 -0
  43. package/scripts/harness/harness-api/application/dto/status-derivation-input.ts +1 -0
  44. package/scripts/harness/harness-api/application/mappers/harness-api-response-mapper.ts +1 -0
  45. package/scripts/harness/harness-api/application/usecases/decide-exit-code-usecase.ts +1 -0
  46. package/scripts/harness/harness-api/application/usecases/derive-harness-status-usecase.ts +1 -0
  47. package/scripts/harness/harness-api/application/usecases/dispatch-command-usecase.ts +1 -0
  48. package/scripts/harness/harness-api/application/usecases/initialize-command-registry-usecase.ts +1 -0
  49. package/scripts/harness/harness-api/composition-root.ts +1 -0
  50. package/scripts/harness/harness-api/domain/ports/artifact-scanner-port.ts +1 -0
  51. package/scripts/harness/harness-api/domain/ports/biome-lint-port.ts +1 -0
  52. package/scripts/harness/harness-api/domain/ports/config-query-port.ts +1 -0
  53. package/scripts/harness/harness-api/domain/ports/impact-analysis-port.ts +1 -0
  54. package/scripts/harness/harness-api/domain/ports/phase-gate-query-port.ts +1 -0
  55. package/scripts/harness/harness-api/domain/ports/validator-execution-port.ts +1 -0
  56. package/scripts/harness/harness-api/domain/services/command-dispatch-service.ts +1 -0
  57. package/scripts/harness/harness-api/domain/services/command-registry.ts +1 -0
  58. package/scripts/harness/harness-api/domain/services/status-derivation-service.ts +1 -0
  59. package/scripts/harness/harness-api/domain/value-objects/artifact-scan-result.ts +1 -0
  60. package/scripts/harness/harness-api/domain/value-objects/check-ready-result.ts +1 -0
  61. package/scripts/harness/harness-api/domain/value-objects/ci-check-result.ts +1 -0
  62. package/scripts/harness/harness-api/domain/value-objects/cli-command-definition.ts +1 -0
  63. package/scripts/harness/harness-api/domain/value-objects/command-input-spec.ts +1 -0
  64. package/scripts/harness/harness-api/domain/value-objects/drift-report-summary.ts +1 -0
  65. package/scripts/harness/harness-api/domain/value-objects/exit-code-spec.ts +1 -0
  66. package/scripts/harness/harness-api/domain/value-objects/harness-api-response.ts +1 -0
  67. package/scripts/harness/harness-api/domain/value-objects/harness-status-summary.ts +1 -0
  68. package/scripts/harness/harness-api/domain/value-objects/layer-health.ts +1 -0
  69. package/scripts/harness/harness-api/domain/value-objects/phase-info.ts +1 -0
  70. package/scripts/harness/harness-api/index.ts +1 -0
  71. package/scripts/harness/harness-api/infrastructure/adapters/biome-ast-engine-lint-adapter.ts +1 -0
  72. package/scripts/harness/harness-api/infrastructure/adapters/file-system-artifact-scanner-adapter.ts +1 -0
  73. package/scripts/harness/harness-api/infrastructure/adapters/harness-config-query-adapter.ts +1 -0
  74. package/scripts/harness/harness-api/infrastructure/adapters/nyquist-validation-impact-analysis-adapter.ts +1 -0
  75. package/scripts/harness/harness-api/infrastructure/adapters/phase-dependency-model-query-adapter.ts +1 -0
  76. package/scripts/harness/harness-api/infrastructure/adapters/validator-system-execution-adapter.ts +1 -0
  77. package/scripts/harness/harness-api/presentation/dto/cli-output-options.ts +1 -0
  78. package/scripts/harness/harness-api/presentation/formatters/harness-api-json-formatter.ts +1 -0
  79. package/scripts/harness/harness-api/presentation/handlers/check-phase-handler.ts +1 -0
  80. package/scripts/harness/harness-api/presentation/handlers/check-ready-handler.ts +1 -0
  81. package/scripts/harness/harness-api/presentation/handlers/ci-check-handler.ts +1 -0
  82. package/scripts/harness/harness-api/presentation/handlers/complete-check-handler.ts +1 -0
  83. package/scripts/harness/harness-api/presentation/handlers/detect-drift-handler.ts +1 -0
  84. package/scripts/harness/harness-api/presentation/handlers/impact-analysis-handler.ts +1 -0
  85. package/scripts/harness/harness-api/presentation/handlers/lint-handler.ts +1 -0
  86. package/scripts/harness/harness-api/presentation/handlers/status-handler.ts +1 -0
  87. package/scripts/harness/harness-error/infrastructure/adapters/legacy-error-reporter-adapter.ts +7 -1
  88. package/scripts/harness/integrations/pre-commit.ts +1 -0
  89. package/scripts/harness/main.ts +154 -34
  90. package/scripts/harness/phase-dependency-model/application/dto/resolve-gate-result-dto.ts +14 -0
  91. package/scripts/harness/phase-dependency-model/application/services/phase-gate-result-mapper.ts +20 -0
  92. package/scripts/harness/phase-dependency-model/application/usecases/check-story-reflection-usecase.ts +42 -0
  93. package/scripts/harness/phase-dependency-model/application/usecases/resolve-gate-usecase.ts +161 -0
  94. package/scripts/harness/phase-dependency-model/composition-root.ts +57 -1
  95. package/scripts/harness/phase-dependency-model/domain/definitions/{default-phase-dependencies.ts → full-phase-dependencies.ts} +3 -3
  96. package/scripts/harness/phase-dependency-model/domain/definitions/{default-phase-nodes.ts → full-phase-nodes.ts} +1 -1
  97. package/scripts/harness/phase-dependency-model/domain/definitions/full-story-reflection-defaults.ts +28 -0
  98. package/scripts/harness/phase-dependency-model/domain/definitions/minimal-phase-dependencies.ts +32 -0
  99. package/scripts/harness/phase-dependency-model/domain/definitions/minimal-phase-nodes.ts +50 -0
  100. package/scripts/harness/phase-dependency-model/domain/definitions/minimal-story-reflection-defaults.ts +8 -0
  101. package/scripts/harness/phase-dependency-model/domain/definitions/standard-phase-dependencies.ts +39 -0
  102. package/scripts/harness/phase-dependency-model/domain/definitions/standard-phase-nodes.ts +118 -0
  103. package/scripts/harness/phase-dependency-model/domain/definitions/standard-story-reflection-defaults.ts +23 -0
  104. package/scripts/harness/phase-dependency-model/domain/models/phase-structure.ts +95 -23
  105. package/scripts/harness/phase-dependency-model/domain/ports/glob-matcher-port.ts +8 -0
  106. package/scripts/harness/phase-dependency-model/domain/ports/phase-config-provider-port.ts +2 -0
  107. package/scripts/harness/phase-dependency-model/domain/ports/story-annotation-verifier-port.ts +14 -0
  108. package/scripts/harness/phase-dependency-model/domain/ports/story-reflection-file-system-port.ts +16 -0
  109. package/scripts/harness/phase-dependency-model/domain/services/gate-graph.ts +223 -0
  110. package/scripts/harness/phase-dependency-model/domain/services/story-reflection-checker.ts +66 -0
  111. package/scripts/harness/phase-dependency-model/domain/values/gate-definition.ts +127 -0
  112. package/scripts/harness/phase-dependency-model/domain/values/gate-name.ts +40 -0
  113. package/scripts/harness/phase-dependency-model/domain/values/gate-story-annotation.ts +39 -0
  114. package/scripts/harness/phase-dependency-model/domain/values/phase-customization-policy.ts +16 -4
  115. package/scripts/harness/phase-dependency-model/domain/values/story-reflection-config.ts +44 -0
  116. package/scripts/harness/phase-dependency-model/domain/values/story-reflection-mapping.ts +91 -0
  117. package/scripts/harness/phase-dependency-model/domain/values/story-reflection-result.ts +55 -0
  118. package/scripts/harness/phase-dependency-model/infrastructure/adapters/picomatch-glob-matcher.ts +17 -0
  119. package/scripts/harness/phase-dependency-model/infrastructure/adapters/story-annotation-verifier-adapter.ts +46 -0
  120. package/scripts/harness/phase-dependency-model/infrastructure/config/custom-gates-config-parser.ts +22 -0
  121. package/scripts/harness/phase-dependency-model/infrastructure/config/harness-config-phase-config-provider.ts +78 -2
  122. package/scripts/harness/phase-dependency-model/infrastructure/filesystem/file-system-story-reflection-adapter.ts +94 -0
  123. package/scripts/harness/phase-dependency-model/presentation/cli/check-phase-gate-command-handler.ts +12 -4
  124. package/scripts/harness/phase-dependency-model/presentation/cli/story-reflection-status-presenter.ts +87 -0
  125. package/scripts/harness/regression-suite/application/dto/analyze-migration-input.ts +1 -0
  126. package/scripts/harness/regression-suite/application/dto/analyze-migration-output.ts +1 -0
  127. package/scripts/harness/regression-suite/application/dto/configure-ci-gate-input.ts +1 -0
  128. package/scripts/harness/regression-suite/application/dto/configure-ci-gate-output.ts +1 -0
  129. package/scripts/harness/regression-suite/application/dto/migrate-v0-tests-input.ts +1 -0
  130. package/scripts/harness/regression-suite/application/dto/migrate-v0-tests-output.ts +1 -0
  131. package/scripts/harness/regression-suite/application/dto/run-regression-suite-input.ts +1 -0
  132. package/scripts/harness/regression-suite/application/dto/run-regression-suite-output.ts +1 -0
  133. package/scripts/harness/regression-suite/application/mappers/migration-mapping-mapper.ts +1 -0
  134. package/scripts/harness/regression-suite/application/mappers/test-execution-summary-mapper.ts +1 -0
  135. package/scripts/harness/regression-suite/application/usecases/analyze-v0-migration-usecase.ts +1 -0
  136. package/scripts/harness/regression-suite/application/usecases/configure-ci-gate-usecase.ts +1 -0
  137. package/scripts/harness/regression-suite/application/usecases/migrate-v0-tests-usecase.ts +1 -0
  138. package/scripts/harness/regression-suite/application/usecases/run-agent-independence-guard-usecase.ts +1 -0
  139. package/scripts/harness/regression-suite/application/usecases/run-gng-gate-regression-usecase.ts +1 -0
  140. package/scripts/harness/regression-suite/application/usecases/run-k-requirements-regression-usecase.ts +1 -0
  141. package/scripts/harness/regression-suite/application/usecases/run-k14-k15-regression-usecase.ts +1 -0
  142. package/scripts/harness/regression-suite/composition-root.ts +1 -0
  143. package/scripts/harness/regression-suite/domain/aggregates/v0-test-migration.ts +1 -0
  144. package/scripts/harness/regression-suite/domain/ports/ci-gate-result-writer-port.ts +1 -0
  145. package/scripts/harness/regression-suite/domain/ports/config-query-port.ts +1 -0
  146. package/scripts/harness/regression-suite/domain/ports/import-analyzer-port.ts +1 -0
  147. package/scripts/harness/regression-suite/domain/ports/migration-mapping-repository-port.ts +1 -0
  148. package/scripts/harness/regression-suite/domain/ports/suite-registry-port.ts +1 -0
  149. package/scripts/harness/regression-suite/domain/ports/test-runner-port.ts +1 -0
  150. package/scripts/harness/regression-suite/domain/ports/v0-spec-reader-port.ts +1 -0
  151. package/scripts/harness/regression-suite/domain/services/import-guard-service.ts +1 -0
  152. package/scripts/harness/regression-suite/domain/services/migration-analyzer.ts +1 -0
  153. package/scripts/harness/regression-suite/domain/services/regression-runner.ts +1 -0
  154. package/scripts/harness/regression-suite/domain/value-objects/agent-independence-test.ts +1 -0
  155. package/scripts/harness/regression-suite/domain/value-objects/biome-modification-spec.ts +1 -0
  156. package/scripts/harness/regression-suite/domain/value-objects/ci-gate-config.ts +1 -0
  157. package/scripts/harness/regression-suite/domain/value-objects/coverage-rate.ts +1 -0
  158. package/scripts/harness/regression-suite/domain/value-objects/gng-condition-test.ts +1 -0
  159. package/scripts/harness/regression-suite/domain/value-objects/import-violation.ts +1 -0
  160. package/scripts/harness/regression-suite/domain/value-objects/k-requirement-test.ts +1 -0
  161. package/scripts/harness/regression-suite/domain/value-objects/migration-mapping.ts +1 -0
  162. package/scripts/harness/regression-suite/domain/value-objects/regression-suite-definition.ts +1 -0
  163. package/scripts/harness/regression-suite/domain/value-objects/suite-id.ts +1 -0
  164. package/scripts/harness/regression-suite/domain/value-objects/test-execution-summary.ts +1 -0
  165. package/scripts/harness/regression-suite/domain/value-objects/test-failure-detail.ts +1 -0
  166. package/scripts/harness/regression-suite/domain/value-objects/v0-test-id.ts +1 -0
  167. package/scripts/harness/regression-suite/domain/value-objects/v1-test-path.ts +1 -0
  168. package/scripts/harness/regression-suite/infrastructure/adapters/biome-ast-import-analyzer-adapter.ts +1 -0
  169. package/scripts/harness/regression-suite/infrastructure/adapters/file-system-v0-spec-reader-adapter.ts +1 -0
  170. package/scripts/harness/regression-suite/infrastructure/adapters/harness-config-query-adapter.ts +1 -0
  171. package/scripts/harness/regression-suite/infrastructure/adapters/json-ci-gate-result-writer-adapter.ts +1 -0
  172. package/scripts/harness/regression-suite/infrastructure/adapters/markdown-migration-mapping-repository-adapter.ts +1 -0
  173. package/scripts/harness/regression-suite/infrastructure/adapters/static-suite-registry-adapter.ts +1 -0
  174. package/scripts/harness/regression-suite/infrastructure/adapters/vitest-test-runner-adapter.ts +1 -0
  175. package/scripts/harness/regression-suite/infrastructure/registry/agent-independence-suite-definition.ts +1 -0
  176. package/scripts/harness/regression-suite/infrastructure/registry/gng-gate-suite-definition.ts +1 -0
  177. package/scripts/harness/regression-suite/infrastructure/registry/k-requirements-suite-definition.ts +1 -0
  178. package/scripts/harness/regression-suite/infrastructure/registry/v0-migration-suite-definition.ts +1 -0
  179. package/scripts/harness/setup/skill-deployer.ts +82 -5
  180. package/scripts/harness/shared-kernel/harness-api.ts +1 -0
  181. package/scripts/harness/skill-quality/composition-root.ts +1 -0
  182. package/scripts/harness/skill-quality/infrastructure/adapters/ajv-lesson-artifact-schema-adapter.ts +5 -4
  183. package/scripts/harness/traceability-model/domain/services/metadata-validator.ts +12 -10
  184. package/scripts/harness/traceability-model/infrastructure/parsers/source-metadata-parser.ts +16 -2
  185. package/skills/cascade-updater/SKILL.md +16 -3
  186. package/skills/codebase-mapper/SKILL.md +9 -9
  187. package/skills/codex-delegator/SKILL.md +5 -56
  188. package/skills/consistency-checker/SKILL.md +5 -9
  189. 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 +6 -3
  190. package/skills/doc-freshness-checker/SKILL.md +6 -6
  191. package/skills/engineering-perspective/SKILL.md +2 -58
  192. package/skills/engineering-perspective/references/domain-model.md +4 -135
  193. package/skills/implementation-readiness-checker/SKILL.md +18 -72
  194. package/skills/it-test-designer/SKILL.md +25 -161
  195. package/skills/it-test-designer/references/it-test-design-template.md +131 -0
  196. package/skills/it-test-logic-designer/SKILL.md +13 -388
  197. package/skills/it-test-logic-designer/references/controller-test-patterns.md +100 -0
  198. package/skills/it-test-logic-designer/references/repository-test-patterns.md +206 -0
  199. package/skills/it-test-logic-designer/references/usecase-test-patterns.md +87 -0
  200. package/skills/pointer-validator/SKILL.md +4 -4
  201. package/skills/scenario-test-designer/SKILL.md +4 -68
  202. package/skills/scenario-test-designer/references/scenario-test-design-template.md +41 -0
  203. package/skills/scenario-test-designer/references/scenario-test-plan-template.md +35 -0
  204. package/skills/scenario-test-logic-designer/SKILL.md +21 -304
  205. package/skills/scenario-test-logic-designer/references/msw-patterns.md +36 -0
  206. package/skills/scenario-test-logic-designer/references/playwright-patterns.md +237 -0
  207. package/skills/test-coverage-checker/SKILL.md +39 -121
  208. package/skills/test-coverage-checker/references/coverage-report-template.md +99 -0
  209. package/skills/uiux-designer/SKILL.md +27 -92
  210. package/skills/uiux-designer/references/data-testid-convention.md +38 -0
  211. package/skills/uiux-designer/references/uiux-design-template.md +105 -0
  212. package/skills/unit-test-designer/SKILL.md +5 -106
  213. package/skills/unit-test-designer/references/unit-test-design-template.md +127 -0
  214. package/skills/unit-test-logic-designer/SKILL.md +28 -250
  215. package/skills/unit-test-logic-designer/references/test-patterns.md +207 -0
@@ -0,0 +1,55 @@
1
+ /**
2
+ * @layer domain
3
+ * @unit phase-dependency-model
4
+ */
5
+
6
+ import type { StoryReflectionMapping } from './story-reflection-mapping.js';
7
+
8
+ export interface StoryReflectionViolation {
9
+ readonly storyId: string;
10
+ readonly mapping: StoryReflectionMapping;
11
+ readonly inceptionPath: string;
12
+ readonly productPath: string;
13
+ }
14
+
15
+ interface StoryReflectionResultCreateArgs {
16
+ readonly passed: boolean;
17
+ readonly violations: readonly StoryReflectionViolation[];
18
+ readonly warnings: readonly StoryReflectionViolation[];
19
+ }
20
+
21
+ export class StoryReflectionResult {
22
+ readonly passed: boolean;
23
+ readonly violations: readonly StoryReflectionViolation[];
24
+ readonly warnings: readonly StoryReflectionViolation[];
25
+
26
+ private constructor(args: StoryReflectionResultCreateArgs) {
27
+ this.passed = args.passed;
28
+ this.violations = Object.freeze([...args.violations]);
29
+ this.warnings = Object.freeze([...args.warnings]);
30
+ Object.freeze(this);
31
+ }
32
+
33
+ static pass(): StoryReflectionResult {
34
+ return new StoryReflectionResult({
35
+ passed: true,
36
+ violations: [],
37
+ warnings: [],
38
+ });
39
+ }
40
+
41
+ static create(args: {
42
+ violations: readonly StoryReflectionViolation[];
43
+ warnings: readonly StoryReflectionViolation[];
44
+ }): StoryReflectionResult {
45
+ return new StoryReflectionResult({
46
+ passed: args.violations.length === 0,
47
+ violations: args.violations,
48
+ warnings: args.warnings,
49
+ });
50
+ }
51
+
52
+ isBlocked(): boolean {
53
+ return this.violations.length > 0;
54
+ }
55
+ }
@@ -0,0 +1,17 @@
1
+ // @unit phase-dependency-model
2
+ // @layer infrastructure
3
+
4
+ import { createRequire } from 'node:module';
5
+ import type { GlobMatcherPort } from '../../domain/ports/glob-matcher-port.js';
6
+
7
+ const require = createRequire(import.meta.url);
8
+ const picomatch = require('picomatch') as (
9
+ pattern: string,
10
+ options?: { readonly dot?: boolean },
11
+ ) => (path: string) => boolean;
12
+
13
+ export class PicomatchGlobMatcher implements GlobMatcherPort {
14
+ match(pattern: string, path: string): boolean {
15
+ return picomatch(pattern, { dot: true })(path);
16
+ }
17
+ }
@@ -0,0 +1,46 @@
1
+ // @unit phase-dependency-model
2
+ // @layer infrastructure
3
+
4
+ import type { StoryAnnotationVerifierPort } from '../../domain/ports/story-annotation-verifier-port.js';
5
+ import { ProjectRelativePath } from '../../../traceability-model/domain/value-objects/project-relative-path.js';
6
+ import type { MarkdownDesignDocumentGateway } from '../../../traceability-model/infrastructure/gateways/markdown-design-document-gateway.js';
7
+
8
+ export interface StoryAnnotationVerifierAdapterDeps {
9
+ readonly designDocumentGateway: Pick<
10
+ MarkdownDesignDocumentGateway,
11
+ 'readStoryAnnotations'
12
+ >;
13
+ }
14
+
15
+ export class StoryAnnotationVerifierAdapter
16
+ implements StoryAnnotationVerifierPort
17
+ {
18
+ private readonly designDocumentGateway: StoryAnnotationVerifierAdapterDeps['designDocumentGateway'];
19
+
20
+ constructor(deps: StoryAnnotationVerifierAdapterDeps) {
21
+ this.designDocumentGateway = deps.designDocumentGateway;
22
+ }
23
+
24
+ async verify(targetFilePath: string, tag: string) {
25
+ if (tag.trim() !== '@story-id') {
26
+ return Object.freeze({
27
+ hasAnnotation: false,
28
+ });
29
+ }
30
+
31
+ const filePath = ProjectRelativePath.create(targetFilePath);
32
+ const annotations =
33
+ await this.designDocumentGateway.readStoryAnnotations(filePath);
34
+
35
+ if (annotations.length === 0) {
36
+ return Object.freeze({
37
+ hasAnnotation: false,
38
+ });
39
+ }
40
+
41
+ return Object.freeze({
42
+ hasAnnotation: true,
43
+ storyId: annotations[0]?.storyId.value,
44
+ });
45
+ }
46
+ }
@@ -0,0 +1,22 @@
1
+ // @unit phase-dependency-model
2
+ // @layer infrastructure
3
+
4
+ import { GateGraph } from '../../domain/services/gate-graph.js';
5
+ import { GateDefinition } from '../../domain/values/gate-definition.js';
6
+
7
+ export interface CustomGatesConfigParseResult {
8
+ readonly gates: readonly GateDefinition[];
9
+ readonly graph: GateGraph;
10
+ }
11
+
12
+ export class CustomGatesConfigParser {
13
+ parse(raw: readonly unknown[]): CustomGatesConfigParseResult {
14
+ const gates = Object.freeze(raw.map((entry) => GateDefinition.fromRaw(entry)));
15
+ const graph = GateGraph.build([...gates]);
16
+
17
+ return Object.freeze({
18
+ gates,
19
+ graph,
20
+ });
21
+ }
22
+ }
@@ -5,8 +5,34 @@
5
5
 
6
6
  import type { PhaseConfigProviderPort } from '../../domain/ports/phase-config-provider-port.js';
7
7
  import { PlanningMode } from '../../domain/values/planning-mode.js';
8
- import { PhaseCustomizationPolicy } from '../../domain/values/phase-customization-policy.js';
8
+ import {
9
+ PhaseCustomizationPolicy,
10
+ type PresetName,
11
+ } from '../../domain/values/phase-customization-policy.js';
9
12
  import { CustomRule } from '../../domain/values/custom-rule.js';
13
+ import { StoryReflectionConfig } from '../../domain/values/story-reflection-config.js';
14
+ import { StoryReflectionMapping } from '../../domain/values/story-reflection-mapping.js';
15
+ import { FULL_STORY_REFLECTION_DEFAULTS } from '../../domain/definitions/full-story-reflection-defaults.js';
16
+ import { STANDARD_STORY_REFLECTION_DEFAULTS } from '../../domain/definitions/standard-story-reflection-defaults.js';
17
+ import { MINIMAL_STORY_REFLECTION_DEFAULTS } from '../../domain/definitions/minimal-story-reflection-defaults.js';
18
+
19
+ export interface StoryReflectionMappingInput {
20
+ readonly inception: string;
21
+ readonly product: string;
22
+ readonly required: boolean;
23
+ }
24
+
25
+ export interface StoryReflectionSectionInput {
26
+ readonly enabled?: boolean;
27
+ readonly mappings?: readonly StoryReflectionMappingInput[];
28
+ }
29
+
30
+ export type PhasePresetInput =
31
+ | 'default'
32
+ | 'full'
33
+ | 'standard'
34
+ | 'minimal'
35
+ | 'custom';
10
36
 
11
37
  export interface PhaseConfigSection {
12
38
  readonly planningMode?:
@@ -18,7 +44,7 @@ export interface PhaseConfigSection {
18
44
  readonly overrides?: Record<string, string>;
19
45
  };
20
46
  readonly customization?: {
21
- readonly preset?: 'default' | 'custom';
47
+ readonly preset?: PhasePresetInput;
22
48
  readonly overrideEnabled?: boolean;
23
49
  readonly rules?: ReadonlyArray<{
24
50
  readonly targetPhase: string;
@@ -26,9 +52,22 @@ export interface PhaseConfigSection {
26
52
  readonly action: readonly string[];
27
53
  }>;
28
54
  };
55
+ readonly storyReflection?: StoryReflectionSectionInput;
29
56
  readonly reportingOutputDir?: string;
30
57
  }
31
58
 
59
+ /**
60
+ * プリセットごとの storyReflection デフォルト定義。
61
+ * `default` は v1.0 で `full` に統合されたため同一値にエイリアスする。
62
+ */
63
+ const PRESET_STORY_REFLECTION_DEFAULTS: Record<PresetName, StoryReflectionConfig> = {
64
+ full: FULL_STORY_REFLECTION_DEFAULTS,
65
+ standard: STANDARD_STORY_REFLECTION_DEFAULTS,
66
+ minimal: MINIMAL_STORY_REFLECTION_DEFAULTS,
67
+ // custom プリセットは明示設定を強制するためデフォルトは無効扱い
68
+ custom: StoryReflectionConfig.disabled(),
69
+ };
70
+
32
71
  export interface HarnessConfigPhaseConfigProviderDeps {
33
72
  readonly config: PhaseConfigSection;
34
73
  readonly defaultOutputDir: string;
@@ -95,4 +134,41 @@ export class HarnessConfigPhaseConfigProvider
95
134
  async getReportingOutputDir(): Promise<string> {
96
135
  return this.config.reportingOutputDir ?? this.defaultOutputDir;
97
136
  }
137
+
138
+ async getStoryReflectionConfig(): Promise<StoryReflectionConfig> {
139
+ const policy = await this.getCustomizationPolicy();
140
+ const presetDefault = PRESET_STORY_REFLECTION_DEFAULTS[policy.preset];
141
+ const section = this.config.storyReflection;
142
+
143
+ if (section === undefined) {
144
+ return presetDefault;
145
+ }
146
+
147
+ // enabled 明示 false → disabled で即返す(mappings 無視)
148
+ if (section.enabled === false) {
149
+ return StoryReflectionConfig.disabled();
150
+ }
151
+
152
+ // enabled 省略時はプリセットの enabled を継承
153
+ const enabled = section.enabled ?? presetDefault.enabled;
154
+
155
+ // mappings 省略 → プリセットデフォルトの mappings を流用
156
+ const rawMappings = section.mappings;
157
+ if (rawMappings === undefined) {
158
+ return StoryReflectionConfig.create({
159
+ enabled,
160
+ mappings: presetDefault.mappings,
161
+ });
162
+ }
163
+
164
+ const mappings = rawMappings.map((m) =>
165
+ StoryReflectionMapping.create({
166
+ inception: m.inception,
167
+ product: m.product,
168
+ required: m.required,
169
+ }),
170
+ );
171
+
172
+ return StoryReflectionConfig.create({ enabled, mappings });
173
+ }
98
174
  }
@@ -0,0 +1,94 @@
1
+ /**
2
+ * @layer infrastructure
3
+ * @unit phase-dependency-model
4
+ */
5
+
6
+ import { readdir, readFile, access } from 'node:fs/promises';
7
+ import path from 'node:path';
8
+ import type { StoryReflectionFileSystemPort } from '../../domain/ports/story-reflection-file-system-port.js';
9
+
10
+ export interface FileSystemStoryReflectionAdapterDeps {
11
+ readonly rootDir: string;
12
+ /** inception ディレクトリのルート(デフォルト: docs/inception) */
13
+ readonly inceptionRoot?: string;
14
+ }
15
+
16
+ /**
17
+ * ファイルシステム上の docs/inception ディレクトリ列挙と
18
+ * product 文書内 `@story-id` アノテーション検索を実装するアダプタ。
19
+ *
20
+ * 存在しないパス・読めないファイルは true/false に正規化し例外を投げない
21
+ * ことで、上位 (StoryReflectionChecker) の純粋性を保つ。
22
+ */
23
+ export class FileSystemStoryReflectionAdapter
24
+ implements StoryReflectionFileSystemPort
25
+ {
26
+ private readonly rootDir: string;
27
+ private readonly inceptionRoot: string;
28
+
29
+ constructor(deps: FileSystemStoryReflectionAdapterDeps) {
30
+ this.rootDir = deps.rootDir;
31
+ this.inceptionRoot = deps.inceptionRoot ?? 'docs/inception';
32
+ }
33
+
34
+ async listStoryDirectories(unitId: string): Promise<readonly string[]> {
35
+ const unitDir = path.join(this.rootDir, this.inceptionRoot, unitId);
36
+
37
+ let entries;
38
+ try {
39
+ entries = await readdir(unitDir, { withFileTypes: true });
40
+ } catch {
41
+ return [];
42
+ }
43
+
44
+ return entries
45
+ .filter((entry) => entry.isDirectory())
46
+ .map((entry) => entry.name)
47
+ .filter((name) => !name.startsWith('_') && !name.startsWith('.'))
48
+ .sort();
49
+ }
50
+
51
+ async fileExists(relativePath: string): Promise<boolean> {
52
+ const absolutePath = path.join(this.rootDir, relativePath);
53
+ try {
54
+ await access(absolutePath);
55
+ return true;
56
+ } catch {
57
+ return false;
58
+ }
59
+ }
60
+
61
+ async fileContainsStoryAnnotation(
62
+ productPath: string,
63
+ storyId: string,
64
+ ): Promise<boolean> {
65
+ const absolutePath = path.join(this.rootDir, productPath);
66
+
67
+ let content: string;
68
+ try {
69
+ content = await readFile(absolutePath, 'utf8');
70
+ } catch {
71
+ return false;
72
+ }
73
+
74
+ // `@story-id` の直後にカンマ/空白区切りで列挙される story ID を抽出。
75
+ // 例: `@story-id US-001`, `@story-id US-001, US-002`,
76
+ // `<!-- @story-id US-001 -->`
77
+ // 行末または `-->` まで(story ID 自体の `-` は許容するため `-->` を明示終端に使う)。
78
+ const pattern = /@story-id[ \t]+([^\n\r]+)/g;
79
+ let match: RegExpExecArray | null;
80
+ while ((match = pattern.exec(content)) !== null) {
81
+ // `-->` 以降の HTML コメント閉じ記号を取り除く
82
+ const raw = match[1].replace(/-->.*$/, '');
83
+ const ids = raw
84
+ .split(/[\s,]+/)
85
+ .map((s) => s.trim())
86
+ .filter((s) => s.length > 0);
87
+ if (ids.includes(storyId)) {
88
+ return true;
89
+ }
90
+ }
91
+
92
+ return false;
93
+ }
94
+ }
@@ -3,13 +3,13 @@
3
3
  * @unit phase-dependency-model
4
4
  */
5
5
 
6
- import type { CheckPhaseGateUseCase, CheckPhaseGateInput } from '../../application/usecases/check-phase-gate-usecase.js';
7
6
  import type { PhaseGateResultDto } from '../../application/dto/phase-gate-result-dto.js';
8
7
 
9
8
  export interface CheckPhaseGateCommandInput {
10
9
  readonly targetLevel: number;
11
10
  readonly unitId?: string;
12
11
  readonly storyId?: string;
12
+ readonly targetFilePath?: string;
13
13
  readonly json?: boolean;
14
14
  }
15
15
 
@@ -20,11 +20,18 @@ export interface CheckPhaseGateCommandOutput {
20
20
  }
21
21
 
22
22
  export interface CheckPhaseGateCommandHandlerDeps {
23
- readonly checkPhaseGateUseCase: Pick<CheckPhaseGateUseCase, 'execute'>;
23
+ readonly checkPhaseGateUseCase: {
24
+ execute(input: {
25
+ readonly targetLevel: 1 | 2 | 3;
26
+ readonly unitId?: string;
27
+ readonly storyId?: string;
28
+ readonly targetFilePath?: string;
29
+ }): Promise<PhaseGateResultDto>;
30
+ };
24
31
  }
25
32
 
26
33
  export class CheckPhaseGateCommandHandler {
27
- private readonly useCase: Pick<CheckPhaseGateUseCase, 'execute'>;
34
+ private readonly useCase: CheckPhaseGateCommandHandlerDeps['checkPhaseGateUseCase'];
28
35
 
29
36
  constructor(deps: CheckPhaseGateCommandHandlerDeps) {
30
37
  this.useCase = deps.checkPhaseGateUseCase;
@@ -42,10 +49,11 @@ export class CheckPhaseGateCommandHandler {
42
49
  }
43
50
 
44
51
  try {
45
- const useCaseInput: CheckPhaseGateInput = {
52
+ const useCaseInput = {
46
53
  targetLevel: input.targetLevel as 1 | 2 | 3,
47
54
  unitId: input.unitId,
48
55
  storyId: input.storyId,
56
+ targetFilePath: input.targetFilePath,
49
57
  };
50
58
 
51
59
  const result = await this.useCase.execute(useCaseInput);
@@ -0,0 +1,87 @@
1
+ // @unit phase-dependency-model
2
+ // @layer presentation
3
+ /**
4
+ * StoryReflectionStatusPresenter
5
+ *
6
+ * CLI (`phasegate:status`, `phasegate validate --layer L2`) 用の
7
+ * storyReflection 状態整形を担うプレゼンター。
8
+ *
9
+ * 責務:
10
+ * - status コマンド向けの 1 行サマリー生成(有効/無効・preset・mapping 数)
11
+ * - validate --layer L2 向けの検証結果サマリー生成
12
+ * (violations / warnings 件数と代表情報)
13
+ *
14
+ * 呼び出し元 (main.ts / presentation) で設定と CheckStoryReflectionUseCase の
15
+ * 実行結果を受け取り、人間可読な行を組み立てる。
16
+ */
17
+
18
+ import type { StoryReflectionConfig } from '../../domain/values/story-reflection-config.js';
19
+ import type { StoryReflectionResult } from '../../domain/values/story-reflection-result.js';
20
+ import type { PresetName } from '../../domain/values/phase-customization-policy.js';
21
+
22
+ export interface StoryReflectionStatusLineInput {
23
+ readonly config: StoryReflectionConfig;
24
+ readonly preset: PresetName;
25
+ }
26
+
27
+ export interface StoryReflectionValidationSummaryInput {
28
+ readonly config: StoryReflectionConfig;
29
+ readonly preset: PresetName;
30
+ readonly result: StoryReflectionResult;
31
+ }
32
+
33
+ export class StoryReflectionStatusPresenter {
34
+ formatStatusLine(input: StoryReflectionStatusLineInput): string {
35
+ const { config, preset } = input;
36
+ const state = config.enabled ? 'enabled' : 'disabled';
37
+ const required = config.mappings.filter((m) => m.required).length;
38
+ const optional = config.mappings.filter((m) => !m.required).length;
39
+
40
+ return [
41
+ 'storyReflection:',
42
+ state,
43
+ `preset=${preset}`,
44
+ `mappings=${config.mappings.length}`,
45
+ `required=${required}`,
46
+ `optional=${optional}`,
47
+ ].join(' ');
48
+ }
49
+
50
+ formatValidationSummary(input: StoryReflectionValidationSummaryInput): string {
51
+ const { config, preset, result } = input;
52
+ const lines: string[] = [];
53
+
54
+ if (!config.enabled) {
55
+ lines.push(
56
+ `[L2-STORY-REFLECTION] disabled (preset=${preset}, violations=0, warnings=0)`,
57
+ );
58
+ return lines.join('\n');
59
+ }
60
+
61
+ const status = result.isBlocked() ? 'failed' : 'passed';
62
+ const violations = result.violations.length;
63
+ const warnings = result.warnings.length;
64
+
65
+ lines.push(
66
+ `[L2-STORY-REFLECTION] ${status} (preset=${preset}, mappings=${config.mappings.length}, violations=${violations}, warnings=${warnings})`,
67
+ );
68
+
69
+ if (result.isBlocked()) {
70
+ for (const violation of result.violations) {
71
+ lines.push(
72
+ ` - ${violation.storyId}: ${violation.productPath} に @story-id ${violation.storyId} が未反映 (inception: ${violation.inceptionPath})`,
73
+ );
74
+ }
75
+ }
76
+
77
+ if (warnings > 0) {
78
+ for (const warning of result.warnings) {
79
+ lines.push(
80
+ ` ! ${warning.storyId}: ${warning.productPath} に @story-id ${warning.storyId} が未反映 (optional)`,
81
+ );
82
+ }
83
+ }
84
+
85
+ return lines.join('\n');
86
+ }
87
+ }
@@ -1,3 +1,4 @@
1
+ // @layer application
1
2
  export interface AnalyzeMigrationInput {
2
3
  dryRun?: boolean;
3
4
  outOfScopePattern?: string[];
@@ -1,3 +1,4 @@
1
+ // @layer application
1
2
  export interface AnalyzeMigrationOutput {
2
3
  totalCount: number;
3
4
  migratedCount: number;
@@ -1,3 +1,4 @@
1
+ // @layer application
1
2
  import type { SuiteIdValue } from '../../domain/value-objects/suite-id.js';
2
3
  import type { ExecutionMode } from '../../domain/value-objects/ci-gate-config.js';
3
4
 
@@ -1,3 +1,4 @@
1
+ // @layer application
1
2
  import type { SuiteIdValue } from '../../domain/value-objects/suite-id.js';
2
3
  import type { ExecutionMode } from '../../domain/value-objects/ci-gate-config.js';
3
4
 
@@ -1,3 +1,4 @@
1
+ // @layer application
1
2
  export interface MigrateV0TestsInput {
2
3
  confirmExecute?: boolean;
3
4
  outOfScopePattern?: string[];
@@ -1,3 +1,4 @@
1
+ // @layer application
1
2
  export interface MigrationMappingOutput {
2
3
  v0TestId: string;
3
4
  v1TestPath: string;
@@ -1,3 +1,4 @@
1
+ // @layer application
1
2
  import type { SuiteIdValue } from '../../domain/value-objects/suite-id.js';
2
3
 
3
4
  export interface RunRegressionSuiteInput {
@@ -1,3 +1,4 @@
1
+ // @layer application
1
2
  export interface TestFailureDetailOutput {
2
3
  testCaseId: string;
3
4
  errorMessage: string;
@@ -1,3 +1,4 @@
1
+ // @layer application
1
2
  import type { V0TestMigration } from '../../domain/aggregates/v0-test-migration.js';
2
3
  import type { MigrationMappingOutput } from '../dto/migrate-v0-tests-output.js';
3
4
 
@@ -1,3 +1,4 @@
1
+ // @layer application
1
2
  import type { TestExecutionSummary } from '../../domain/value-objects/test-execution-summary.js';
2
3
  import type { RunRegressionSuiteOutput } from '../dto/run-regression-suite-output.js';
3
4
 
@@ -1,3 +1,4 @@
1
+ // @layer application
1
2
  import { MigrationAnalyzer } from '../../domain/services/migration-analyzer.js';
2
3
  import type { V0SpecReaderPort } from '../../domain/ports/v0-spec-reader-port.js';
3
4
  import type { MigrationMappingRepositoryPort } from '../../domain/ports/migration-mapping-repository-port.js';
@@ -1,3 +1,4 @@
1
+ // @layer application
1
2
  import { SuiteId } from '../../domain/value-objects/suite-id.js';
2
3
  import { CiGateConfig } from '../../domain/value-objects/ci-gate-config.js';
3
4
  import type { ConfigQueryPort } from '../../domain/ports/config-query-port.js';
@@ -1,3 +1,4 @@
1
+ // @layer application
1
2
  import { MigrationAnalyzer } from '../../domain/services/migration-analyzer.js';
2
3
  import type { V0SpecReaderPort } from '../../domain/ports/v0-spec-reader-port.js';
3
4
  import type { MigrationMappingRepositoryPort } from '../../domain/ports/migration-mapping-repository-port.js';
@@ -1,3 +1,4 @@
1
+ // @layer application
1
2
  import { SuiteId } from '../../domain/value-objects/suite-id.js';
2
3
  import { TestExecutionSummary } from '../../domain/value-objects/test-execution-summary.js';
3
4
  import { TestFailureDetail } from '../../domain/value-objects/test-failure-detail.js';
@@ -1,3 +1,4 @@
1
+ // @layer application
1
2
  import { SuiteId } from '../../domain/value-objects/suite-id.js';
2
3
  import { TestExecutionSummary } from '../../domain/value-objects/test-execution-summary.js';
3
4
  import type { SuiteRegistryPort } from '../../domain/ports/suite-registry-port.js';
@@ -1,3 +1,4 @@
1
+ // @layer application
1
2
  import { SuiteId } from '../../domain/value-objects/suite-id.js';
2
3
  import { TestExecutionSummary } from '../../domain/value-objects/test-execution-summary.js';
3
4
  import type { SuiteRegistryPort } from '../../domain/ports/suite-registry-port.js';
@@ -1,3 +1,4 @@
1
+ // @layer application
1
2
  import { SuiteId } from '../../domain/value-objects/suite-id.js';
2
3
  import { TestExecutionSummary } from '../../domain/value-objects/test-execution-summary.js';
3
4
  import type { SuiteRegistryPort } from '../../domain/ports/suite-registry-port.js';
@@ -1,4 +1,5 @@
1
1
  /**
2
+ * @layer infrastructure
2
3
  * @unit regression-suite
3
4
  *
4
5
  * Composition Root - wires all dependencies together
@@ -1,3 +1,4 @@
1
+ // @layer domain
1
2
  import type { V0TestId } from '../value-objects/v0-test-id.js';
2
3
  import type { V1TestPath } from '../value-objects/v1-test-path.js';
3
4
  import type { BiomeModificationSpec } from '../value-objects/biome-modification-spec.js';
@@ -1,3 +1,4 @@
1
+ // @layer domain
1
2
  import type { SuiteIdValue } from '../value-objects/suite-id.js';
2
3
  import type { TestExecutionSummary } from '../value-objects/test-execution-summary.js';
3
4
 
@@ -1,3 +1,4 @@
1
+ // @layer domain
1
2
  export interface ConfigQueryPort {
2
3
  getCoverageThreshold(): Promise<number>;
3
4
  }
@@ -1,3 +1,4 @@
1
+ // @layer domain
1
2
  export interface ImportAnalyzerPort {
2
3
  analyzeImports(targetModule: string): Promise<string[]>;
3
4
  }
@@ -1,3 +1,4 @@
1
+ // @layer domain
1
2
  import type { V0TestMigration } from '../aggregates/v0-test-migration.js';
2
3
  import type { V0TestId } from '../value-objects/v0-test-id.js';
3
4
  import type { MigrationMapping } from '../value-objects/migration-mapping.js';
@@ -1,3 +1,4 @@
1
+ // @layer domain
1
2
  import type { SuiteId } from '../value-objects/suite-id.js';
2
3
  import type { RegressionSuiteDefinition } from '../value-objects/regression-suite-definition.js';
3
4
 
@@ -1,3 +1,4 @@
1
+ // @layer domain
1
2
  import type { TestCase } from '../value-objects/regression-suite-definition.js';
2
3
  import type { CoverageRate } from '../value-objects/coverage-rate.js';
3
4
  import type { TestFailureDetail } from '../value-objects/test-failure-detail.js';
@@ -1,3 +1,4 @@
1
+ // @layer domain
1
2
  import type { V0TestId } from '../value-objects/v0-test-id.js';
2
3
 
3
4
  export interface V0SpecReaderPort {
@@ -1,3 +1,4 @@
1
+ // @layer domain
1
2
  import type { AgentIndependenceTest } from '../value-objects/agent-independence-test.js';
2
3
  import { ImportViolation } from '../value-objects/import-violation.js';
3
4
  import type { ImportAnalyzerPort } from '../ports/import-analyzer-port.js';
@@ -1,3 +1,4 @@
1
+ // @layer domain
1
2
  import { V0TestMigration } from '../aggregates/v0-test-migration.js';
2
3
  import { V1TestPath } from '../value-objects/v1-test-path.js';
3
4
  import { BiomeModificationSpec } from '../value-objects/biome-modification-spec.js';