phasegate 0.15.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 (229) hide show
  1. package/README.ja.md +103 -71
  2. package/README.md +73 -13
  3. package/bin/{harness → phasegate} +1 -1
  4. package/docs/ADR/ADR-013-story-reflection-gate.md +100 -0
  5. package/docs/guide/cli-reference.md +9 -9
  6. package/docs/guide/configuration.md +245 -8
  7. package/docs/guide/hooks-integration.md +1 -1
  8. package/docs/guide/installation.md +6 -6
  9. package/docs/guide/layer-model.md +5 -5
  10. package/docs/guide/skills-overview.md +1 -1
  11. package/package.json +12 -10
  12. package/scripts/harness/adr-foundation/domain/ports/adr-document-parser-port.ts +1 -0
  13. package/scripts/harness/adr-foundation/domain/ports/adr-frontmatter-parser-port.ts +1 -0
  14. package/scripts/harness/adr-foundation/domain/ports/adr-repository-port.ts +1 -0
  15. package/scripts/harness/adr-foundation/domain/value-objects/adr-status.ts +6 -6
  16. package/scripts/harness/agent-integration/application/dto/handle-pre-tool-use-dto.ts +3 -1
  17. package/scripts/harness/agent-integration/application/usecases/handle-pre-tool-use-usecase.ts +109 -3
  18. package/scripts/harness/agent-integration/application/usecases/handle-stop-usecase.ts +1 -1
  19. package/scripts/harness/agent-integration/domain/ports/config-query-port.ts +2 -0
  20. package/scripts/harness/agent-integration/domain/ports/phase-gate-query-port.ts +1 -1
  21. package/scripts/harness/agent-integration/domain/ports/story-reflection-query-port.ts +8 -0
  22. package/scripts/harness/agent-integration/domain/services/bash-write-target-extractor.ts +258 -0
  23. package/scripts/harness/agent-integration/domain/services/hook-to-cli-translator.ts +25 -8
  24. package/scripts/harness/agent-integration/domain/value-objects/protected-file-list.ts +20 -0
  25. package/scripts/harness/agent-integration/domain/value-objects/story-reflection-query-result.ts +63 -0
  26. package/scripts/harness/agent-integration/infrastructure/adapters/child-process-cli-executor-adapter.ts +2 -2
  27. package/scripts/harness/agent-integration/infrastructure/adapters/file-system-story-reflection-query-adapter.ts +122 -0
  28. package/scripts/harness/agent-integration/infrastructure/adapters/harness-api-cli-command-registry-adapter.ts +10 -10
  29. package/scripts/harness/agent-integration/infrastructure/adapters/harness-config-config-query-adapter.ts +20 -0
  30. package/scripts/harness/agent-integration/infrastructure/adapters/phase-gate-query-adapter.ts +17 -3
  31. package/scripts/harness/agent-integration/presentation/pre-tool-use-hook.ts +29 -2
  32. package/scripts/harness/biome-ast-engine/domain/services/lint-runner.ts +24 -0
  33. package/scripts/harness/biome-ast-engine/domain/services/rule-definition-registry.ts +1 -1
  34. package/scripts/harness/biome-ast-engine/domain/value-objects/source-module-snapshot.ts +5 -2
  35. package/scripts/harness/biome-ast-engine/infrastructure/adapters/node-workspace-file-adapter.ts +1 -1
  36. package/scripts/harness/biome-ast-engine/infrastructure/adapters/typescript-source-module-analyzer-adapter.ts +1 -1
  37. package/scripts/harness/biome-ast-engine/infrastructure/parsers/unit-comment-parser.ts +12 -7
  38. package/scripts/harness/ci-governance/composition-root.ts +1 -0
  39. package/scripts/harness/ci-governance/infrastructure/adapters/agents-md-file-adapter.ts +2 -2
  40. package/scripts/harness/ci-governance/infrastructure/adapters/yaml-template-renderer-adapter.ts +2 -2
  41. package/scripts/harness/config-foundation/application/mappers/phase-config-section-mapper.ts +44 -0
  42. package/scripts/harness/config-foundation/application/usecases/load-resolved-config-use-case.ts +20 -1
  43. package/scripts/harness/config-foundation/domain/harness-config.ts +2 -1
  44. package/scripts/harness/config-foundation/domain/value-objects/phase-dependencies-config.ts +18 -4
  45. package/scripts/harness/config-foundation/infrastructure/schemas/harness-config-v2.schema.json +185 -10
  46. package/scripts/harness/config-foundation/infrastructure/validators/ajv-config-schema-validator.ts +2 -1
  47. package/scripts/harness/harness-api/application/dto/command-dispatch-input.ts +1 -0
  48. package/scripts/harness/harness-api/application/dto/command-dispatch-output.ts +1 -0
  49. package/scripts/harness/harness-api/application/dto/exit-code-decision-input.ts +1 -0
  50. package/scripts/harness/harness-api/application/dto/exit-code-decision-output.ts +1 -0
  51. package/scripts/harness/harness-api/application/dto/harness-api-response-contract.ts +1 -0
  52. package/scripts/harness/harness-api/application/dto/initialize-registry-input.ts +1 -0
  53. package/scripts/harness/harness-api/application/dto/registry-summary-output.ts +1 -0
  54. package/scripts/harness/harness-api/application/dto/status-derivation-input.ts +1 -0
  55. package/scripts/harness/harness-api/application/mappers/harness-api-response-mapper.ts +1 -0
  56. package/scripts/harness/harness-api/application/usecases/decide-exit-code-usecase.ts +4 -3
  57. package/scripts/harness/harness-api/application/usecases/derive-harness-status-usecase.ts +1 -0
  58. package/scripts/harness/harness-api/application/usecases/dispatch-command-usecase.ts +1 -0
  59. package/scripts/harness/harness-api/application/usecases/initialize-command-registry-usecase.ts +1 -0
  60. package/scripts/harness/harness-api/composition-root.ts +1 -0
  61. package/scripts/harness/harness-api/domain/ports/artifact-scanner-port.ts +1 -0
  62. package/scripts/harness/harness-api/domain/ports/biome-lint-port.ts +1 -0
  63. package/scripts/harness/harness-api/domain/ports/config-query-port.ts +1 -0
  64. package/scripts/harness/harness-api/domain/ports/impact-analysis-port.ts +1 -0
  65. package/scripts/harness/harness-api/domain/ports/phase-gate-query-port.ts +1 -0
  66. package/scripts/harness/harness-api/domain/ports/validator-execution-port.ts +1 -0
  67. package/scripts/harness/harness-api/domain/services/command-dispatch-service.ts +17 -16
  68. package/scripts/harness/harness-api/domain/services/command-registry.ts +4 -3
  69. package/scripts/harness/harness-api/domain/services/status-derivation-service.ts +1 -0
  70. package/scripts/harness/harness-api/domain/value-objects/artifact-scan-result.ts +1 -0
  71. package/scripts/harness/harness-api/domain/value-objects/check-ready-result.ts +1 -0
  72. package/scripts/harness/harness-api/domain/value-objects/ci-check-result.ts +1 -0
  73. package/scripts/harness/harness-api/domain/value-objects/cli-command-definition.ts +11 -10
  74. package/scripts/harness/harness-api/domain/value-objects/command-input-spec.ts +1 -0
  75. package/scripts/harness/harness-api/domain/value-objects/drift-report-summary.ts +1 -0
  76. package/scripts/harness/harness-api/domain/value-objects/exit-code-spec.ts +1 -0
  77. package/scripts/harness/harness-api/domain/value-objects/harness-api-response.ts +1 -0
  78. package/scripts/harness/harness-api/domain/value-objects/harness-status-summary.ts +1 -0
  79. package/scripts/harness/harness-api/domain/value-objects/layer-health.ts +1 -0
  80. package/scripts/harness/harness-api/domain/value-objects/phase-info.ts +1 -0
  81. package/scripts/harness/harness-api/index.ts +1 -0
  82. package/scripts/harness/harness-api/infrastructure/adapters/biome-ast-engine-lint-adapter.ts +1 -0
  83. package/scripts/harness/harness-api/infrastructure/adapters/file-system-artifact-scanner-adapter.ts +1 -0
  84. package/scripts/harness/harness-api/infrastructure/adapters/harness-config-query-adapter.ts +1 -0
  85. package/scripts/harness/harness-api/infrastructure/adapters/nyquist-validation-impact-analysis-adapter.ts +1 -0
  86. package/scripts/harness/harness-api/infrastructure/adapters/phase-dependency-model-query-adapter.ts +1 -0
  87. package/scripts/harness/harness-api/infrastructure/adapters/validator-system-execution-adapter.ts +1 -0
  88. package/scripts/harness/harness-api/presentation/dto/cli-output-options.ts +1 -0
  89. package/scripts/harness/harness-api/presentation/formatters/harness-api-json-formatter.ts +1 -0
  90. package/scripts/harness/harness-api/presentation/handlers/check-phase-handler.ts +2 -1
  91. package/scripts/harness/harness-api/presentation/handlers/check-ready-handler.ts +2 -1
  92. package/scripts/harness/harness-api/presentation/handlers/ci-check-handler.ts +2 -1
  93. package/scripts/harness/harness-api/presentation/handlers/complete-check-handler.ts +2 -1
  94. package/scripts/harness/harness-api/presentation/handlers/detect-drift-handler.ts +2 -1
  95. package/scripts/harness/harness-api/presentation/handlers/impact-analysis-handler.ts +2 -1
  96. package/scripts/harness/harness-api/presentation/handlers/lint-handler.ts +2 -1
  97. package/scripts/harness/harness-api/presentation/handlers/status-handler.ts +4 -3
  98. package/scripts/harness/harness-error/infrastructure/adapters/legacy-error-reporter-adapter.ts +7 -1
  99. package/scripts/harness/integrations/pre-commit.ts +1 -0
  100. package/scripts/harness/main.ts +173 -53
  101. package/scripts/harness/phase-dependency-model/application/dto/resolve-gate-result-dto.ts +14 -0
  102. package/scripts/harness/phase-dependency-model/application/services/phase-gate-result-mapper.ts +20 -0
  103. package/scripts/harness/phase-dependency-model/application/usecases/check-story-reflection-usecase.ts +42 -0
  104. package/scripts/harness/phase-dependency-model/application/usecases/resolve-gate-usecase.ts +161 -0
  105. package/scripts/harness/phase-dependency-model/composition-root.ts +57 -1
  106. package/scripts/harness/phase-dependency-model/domain/definitions/{default-phase-dependencies.ts → full-phase-dependencies.ts} +3 -3
  107. package/scripts/harness/phase-dependency-model/domain/definitions/{default-phase-nodes.ts → full-phase-nodes.ts} +1 -1
  108. package/scripts/harness/phase-dependency-model/domain/definitions/full-story-reflection-defaults.ts +28 -0
  109. package/scripts/harness/phase-dependency-model/domain/definitions/minimal-phase-dependencies.ts +32 -0
  110. package/scripts/harness/phase-dependency-model/domain/definitions/minimal-phase-nodes.ts +50 -0
  111. package/scripts/harness/phase-dependency-model/domain/definitions/minimal-story-reflection-defaults.ts +8 -0
  112. package/scripts/harness/phase-dependency-model/domain/definitions/standard-phase-dependencies.ts +39 -0
  113. package/scripts/harness/phase-dependency-model/domain/definitions/standard-phase-nodes.ts +118 -0
  114. package/scripts/harness/phase-dependency-model/domain/definitions/standard-story-reflection-defaults.ts +23 -0
  115. package/scripts/harness/phase-dependency-model/domain/models/phase-structure.ts +95 -23
  116. package/scripts/harness/phase-dependency-model/domain/ports/glob-matcher-port.ts +8 -0
  117. package/scripts/harness/phase-dependency-model/domain/ports/phase-config-provider-port.ts +2 -0
  118. package/scripts/harness/phase-dependency-model/domain/ports/story-annotation-verifier-port.ts +14 -0
  119. package/scripts/harness/phase-dependency-model/domain/ports/story-reflection-file-system-port.ts +16 -0
  120. package/scripts/harness/phase-dependency-model/domain/services/gate-graph.ts +223 -0
  121. package/scripts/harness/phase-dependency-model/domain/services/story-reflection-checker.ts +66 -0
  122. package/scripts/harness/phase-dependency-model/domain/values/gate-definition.ts +127 -0
  123. package/scripts/harness/phase-dependency-model/domain/values/gate-name.ts +40 -0
  124. package/scripts/harness/phase-dependency-model/domain/values/gate-story-annotation.ts +39 -0
  125. package/scripts/harness/phase-dependency-model/domain/values/phase-customization-policy.ts +16 -4
  126. package/scripts/harness/phase-dependency-model/domain/values/story-reflection-config.ts +44 -0
  127. package/scripts/harness/phase-dependency-model/domain/values/story-reflection-mapping.ts +91 -0
  128. package/scripts/harness/phase-dependency-model/domain/values/story-reflection-result.ts +55 -0
  129. package/scripts/harness/phase-dependency-model/infrastructure/adapters/picomatch-glob-matcher.ts +17 -0
  130. package/scripts/harness/phase-dependency-model/infrastructure/adapters/story-annotation-verifier-adapter.ts +46 -0
  131. package/scripts/harness/phase-dependency-model/infrastructure/config/custom-gates-config-parser.ts +22 -0
  132. package/scripts/harness/phase-dependency-model/infrastructure/config/harness-config-phase-config-provider.ts +78 -2
  133. package/scripts/harness/phase-dependency-model/infrastructure/filesystem/file-system-story-reflection-adapter.ts +94 -0
  134. package/scripts/harness/phase-dependency-model/presentation/cli/check-phase-gate-command-handler.ts +12 -4
  135. package/scripts/harness/phase-dependency-model/presentation/cli/story-reflection-status-presenter.ts +87 -0
  136. package/scripts/harness/quick-mode/application/usecases/execute-quick-ci-check-usecase.ts +1 -1
  137. package/scripts/harness/quick-mode/presentation/handlers/ci-check-quick-mode-handler.ts +1 -1
  138. package/scripts/harness/regression-suite/application/dto/analyze-migration-input.ts +1 -0
  139. package/scripts/harness/regression-suite/application/dto/analyze-migration-output.ts +1 -0
  140. package/scripts/harness/regression-suite/application/dto/configure-ci-gate-input.ts +1 -0
  141. package/scripts/harness/regression-suite/application/dto/configure-ci-gate-output.ts +1 -0
  142. package/scripts/harness/regression-suite/application/dto/migrate-v0-tests-input.ts +1 -0
  143. package/scripts/harness/regression-suite/application/dto/migrate-v0-tests-output.ts +1 -0
  144. package/scripts/harness/regression-suite/application/dto/run-regression-suite-input.ts +1 -0
  145. package/scripts/harness/regression-suite/application/dto/run-regression-suite-output.ts +1 -0
  146. package/scripts/harness/regression-suite/application/mappers/migration-mapping-mapper.ts +1 -0
  147. package/scripts/harness/regression-suite/application/mappers/test-execution-summary-mapper.ts +1 -0
  148. package/scripts/harness/regression-suite/application/usecases/analyze-v0-migration-usecase.ts +1 -0
  149. package/scripts/harness/regression-suite/application/usecases/configure-ci-gate-usecase.ts +1 -0
  150. package/scripts/harness/regression-suite/application/usecases/migrate-v0-tests-usecase.ts +1 -0
  151. package/scripts/harness/regression-suite/application/usecases/run-agent-independence-guard-usecase.ts +1 -0
  152. package/scripts/harness/regression-suite/application/usecases/run-gng-gate-regression-usecase.ts +1 -0
  153. package/scripts/harness/regression-suite/application/usecases/run-k-requirements-regression-usecase.ts +1 -0
  154. package/scripts/harness/regression-suite/application/usecases/run-k14-k15-regression-usecase.ts +1 -0
  155. package/scripts/harness/regression-suite/composition-root.ts +1 -0
  156. package/scripts/harness/regression-suite/domain/aggregates/v0-test-migration.ts +1 -0
  157. package/scripts/harness/regression-suite/domain/ports/ci-gate-result-writer-port.ts +1 -0
  158. package/scripts/harness/regression-suite/domain/ports/config-query-port.ts +1 -0
  159. package/scripts/harness/regression-suite/domain/ports/import-analyzer-port.ts +1 -0
  160. package/scripts/harness/regression-suite/domain/ports/migration-mapping-repository-port.ts +1 -0
  161. package/scripts/harness/regression-suite/domain/ports/suite-registry-port.ts +1 -0
  162. package/scripts/harness/regression-suite/domain/ports/test-runner-port.ts +1 -0
  163. package/scripts/harness/regression-suite/domain/ports/v0-spec-reader-port.ts +1 -0
  164. package/scripts/harness/regression-suite/domain/services/import-guard-service.ts +1 -0
  165. package/scripts/harness/regression-suite/domain/services/migration-analyzer.ts +1 -0
  166. package/scripts/harness/regression-suite/domain/services/regression-runner.ts +1 -0
  167. package/scripts/harness/regression-suite/domain/value-objects/agent-independence-test.ts +1 -0
  168. package/scripts/harness/regression-suite/domain/value-objects/biome-modification-spec.ts +1 -0
  169. package/scripts/harness/regression-suite/domain/value-objects/ci-gate-config.ts +1 -0
  170. package/scripts/harness/regression-suite/domain/value-objects/coverage-rate.ts +1 -0
  171. package/scripts/harness/regression-suite/domain/value-objects/gng-condition-test.ts +1 -0
  172. package/scripts/harness/regression-suite/domain/value-objects/import-violation.ts +1 -0
  173. package/scripts/harness/regression-suite/domain/value-objects/k-requirement-test.ts +1 -0
  174. package/scripts/harness/regression-suite/domain/value-objects/migration-mapping.ts +1 -0
  175. package/scripts/harness/regression-suite/domain/value-objects/regression-suite-definition.ts +1 -0
  176. package/scripts/harness/regression-suite/domain/value-objects/suite-id.ts +1 -0
  177. package/scripts/harness/regression-suite/domain/value-objects/test-execution-summary.ts +1 -0
  178. package/scripts/harness/regression-suite/domain/value-objects/test-failure-detail.ts +1 -0
  179. package/scripts/harness/regression-suite/domain/value-objects/v0-test-id.ts +1 -0
  180. package/scripts/harness/regression-suite/domain/value-objects/v1-test-path.ts +1 -0
  181. package/scripts/harness/regression-suite/infrastructure/adapters/biome-ast-import-analyzer-adapter.ts +1 -0
  182. package/scripts/harness/regression-suite/infrastructure/adapters/file-system-v0-spec-reader-adapter.ts +1 -0
  183. package/scripts/harness/regression-suite/infrastructure/adapters/harness-config-query-adapter.ts +1 -0
  184. package/scripts/harness/regression-suite/infrastructure/adapters/json-ci-gate-result-writer-adapter.ts +1 -0
  185. package/scripts/harness/regression-suite/infrastructure/adapters/markdown-migration-mapping-repository-adapter.ts +1 -0
  186. package/scripts/harness/regression-suite/infrastructure/adapters/static-suite-registry-adapter.ts +1 -0
  187. package/scripts/harness/regression-suite/infrastructure/adapters/vitest-test-runner-adapter.ts +1 -0
  188. package/scripts/harness/regression-suite/infrastructure/registry/agent-independence-suite-definition.ts +1 -0
  189. package/scripts/harness/regression-suite/infrastructure/registry/gng-gate-suite-definition.ts +1 -0
  190. package/scripts/harness/regression-suite/infrastructure/registry/k-requirements-suite-definition.ts +1 -0
  191. package/scripts/harness/regression-suite/infrastructure/registry/v0-migration-suite-definition.ts +1 -0
  192. package/scripts/harness/setup/skill-deployer.ts +82 -5
  193. package/scripts/harness/shared-kernel/harness-api.ts +1 -0
  194. package/scripts/harness/skill-quality/composition-root.ts +1 -0
  195. package/scripts/harness/skill-quality/infrastructure/adapters/ajv-lesson-artifact-schema-adapter.ts +5 -4
  196. package/scripts/harness/traceability-model/domain/services/metadata-validator.ts +12 -10
  197. package/scripts/harness/traceability-model/infrastructure/parsers/source-metadata-parser.ts +16 -2
  198. package/scripts/harness/validator-system/composition-root.ts +3 -3
  199. package/skills/cascade-updater/SKILL.md +16 -3
  200. package/skills/codebase-mapper/SKILL.md +9 -9
  201. package/skills/codex-delegator/SKILL.md +5 -56
  202. package/skills/consistency-checker/SKILL.md +5 -9
  203. 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
  204. package/skills/doc-freshness-checker/SKILL.md +6 -6
  205. package/skills/engineering-perspective/SKILL.md +2 -58
  206. package/skills/engineering-perspective/references/domain-model.md +4 -135
  207. package/skills/implementation-readiness-checker/SKILL.md +18 -72
  208. package/skills/it-test-designer/SKILL.md +25 -161
  209. package/skills/it-test-designer/references/it-test-design-template.md +131 -0
  210. package/skills/it-test-logic-designer/SKILL.md +13 -388
  211. package/skills/it-test-logic-designer/references/controller-test-patterns.md +100 -0
  212. package/skills/it-test-logic-designer/references/repository-test-patterns.md +206 -0
  213. package/skills/it-test-logic-designer/references/usecase-test-patterns.md +87 -0
  214. package/skills/pointer-validator/SKILL.md +4 -4
  215. package/skills/scenario-test-designer/SKILL.md +4 -68
  216. package/skills/scenario-test-designer/references/scenario-test-design-template.md +41 -0
  217. package/skills/scenario-test-designer/references/scenario-test-plan-template.md +35 -0
  218. package/skills/scenario-test-logic-designer/SKILL.md +21 -304
  219. package/skills/scenario-test-logic-designer/references/msw-patterns.md +36 -0
  220. package/skills/scenario-test-logic-designer/references/playwright-patterns.md +237 -0
  221. package/skills/test-coverage-checker/SKILL.md +39 -121
  222. package/skills/test-coverage-checker/references/coverage-report-template.md +99 -0
  223. package/skills/uiux-designer/SKILL.md +27 -92
  224. package/skills/uiux-designer/references/data-testid-convention.md +38 -0
  225. package/skills/uiux-designer/references/uiux-design-template.md +105 -0
  226. package/skills/unit-test-designer/SKILL.md +5 -106
  227. package/skills/unit-test-designer/references/unit-test-design-template.md +127 -0
  228. package/skills/unit-test-logic-designer/SKILL.md +28 -250
  229. package/skills/unit-test-logic-designer/references/test-patterns.md +207 -0
@@ -2,7 +2,7 @@
2
2
 
3
3
  ## phasegate.config.json
4
4
 
5
- Place at project root. Generated by `npx harness init`.
5
+ Place at project root. Generated by `npx phasegate init`.
6
6
 
7
7
  This file is the **Single Source of Truth** for all quality configuration in a Phasegate project. Every layer validator, skill, and harness behavior reads from this file.
8
8
 
@@ -27,9 +27,14 @@ This file is the **Single Source of Truth** for all quality configuration in a P
27
27
  "relaxedGates": ["phase-gate", "2-phase-execution"]
28
28
  },
29
29
  "phaseDependencies": {
30
- "preset": "default", // "default" | "custom"
30
+ "preset": "standard", // "full" | "standard" | "minimal" | "custom" ("default" -> "full")
31
31
  "override": false,
32
- "customRules": []
32
+ "customRules": [],
33
+ "gates": [], // Optional. Custom phase gates (preset: "custom"). See gates[] reference below.
34
+ "storyReflection": { // Optional. Defaults per preset when omitted.
35
+ "enabled": true,
36
+ "mappings": [] // Omit to use the preset's built-in mappings.
37
+ }
33
38
  },
34
39
  "planningMode": {
35
40
  "default": "interactive", // "interactive" | "embedded-qa"
@@ -108,11 +113,243 @@ The five layers are:
108
113
 
109
114
  #### `phaseDependencies`
110
115
 
111
- | Sub-field | Type | Default | Description |
112
- |---------------|------------|-------------|--------------------------------------------------------------------|
113
- | `preset` | `string` | `"default"` | `"default"` uses the built-in AIDLC phase dependency graph. `"custom"` enables `customRules`. |
114
- | `override` | `boolean` | `false` | When `true`, custom rules fully replace the default graph instead of extending it. |
115
- | `customRules` | `array` | `[]` | Array of custom phase dependency rules. Only used when `preset` is `"custom"`. |
116
+ | Sub-field | Type | Default | Description |
117
+ |--------------------|------------|--------------|--------------------------------------------------------------------|
118
+ | `preset` | `string` | `"standard"` | One of `"full"`, `"standard"`, `"minimal"`, `"custom"`. `"default"` is accepted for backward compatibility and falls back to `"full"`. |
119
+ | `override` | `boolean` | `false` | When `true`, custom rules fully replace the default graph instead of extending it. Required when `preset` is `"custom"`. |
120
+ | `customRules` | `array` | `[]` | Array of custom phase dependency rules. Only used when `preset` is `"custom"`. |
121
+ | `gates` | `array` | `[]` | Array of custom phase gate definitions. See [gates\[\]](#gates-custom-phase-gates) below. Optional; defaults to empty. |
122
+ | `storyReflection` | `object` | preset-based | See [storyReflection](#storyreflection-inception--product-gate) below. Omit entirely for zero-config defaults per preset. |
123
+
124
+ ##### Phase Dependency Presets
125
+
126
+ | Preset | Phase 3 Gates | storyReflection default | Use Case |
127
+ |------------|---------------|-------------------------------------------------------------------------|----------------------------------------------------|
128
+ | `full` | All gates | **Enabled** -- `logical_design.md` + `domain_model.md` required, `uiux_design.md` optional | AIDLC full ceremony; mission-critical systems |
129
+ | `standard` | Core gates | **Enabled** -- `logical_design.md` required, `domain_model.md` optional | Production development with moderate rigor |
130
+ | `minimal` | None | **Disabled** | Prototyping / exploration (trade-off: no reflection enforcement) |
131
+ | `custom` | User-defined | User-defined (zero or explicit `mappings`) | Full control via `customRules` and `storyReflection.mappings` |
132
+
133
+ > `"default"` is accepted as an alias for `"full"` so existing `phasegate.config.json` files keep working after the upgrade.
134
+
135
+ #### `gates[]` (custom phase gates)
136
+
137
+ `gates[]` lets a project declare **additional phase gates** that fire when a write targets specific file globs. Each gate is checked at the pre-tool-use hook (and via `check-phase-gate` CLI) and blocks the write if its preconditions are not met.
138
+
139
+ `gates[]` is typically combined with `preset: "custom"` and `override: true` when the project wants full control over the phase dependency graph. It is also valid to layer a small number of gates on top of `preset: "custom"` without replacing the full graph.
140
+
141
+ **Validation is fail-fast**: a malformed `gates[]` entry (e.g. `level: 99`, unknown dependency) causes `loadResolvedConfig()` to exit with code `2` and prints `Invalid phasegate.config.json: ...` to stderr. The same error surfaces as a `blocker` in the hook path.
142
+
143
+ ##### Gate definition schema
144
+
145
+ Each entry in `gates[]` is an object with:
146
+
147
+ | Field | Type | Required | Description |
148
+ |-------------------|------------|----------|-------------------------------------------------------------------------------------------------------------------|
149
+ | `name` | `string` | yes | Unique gate identifier. Must match `^[a-z][a-z0-9-]*$`. |
150
+ | `level` | `integer` | yes | Phase level this gate belongs to. One of `1`, `2`, `3`. |
151
+ | `requires` | `object[]` | yes | Required artifacts. Each entry is `{ "path": "<glob or path>", "required": <boolean> }`. |
152
+ | `blocks` | `string[]` | yes | Glob patterns of files the gate guards. A write targeting any matching file triggers this gate. |
153
+ | `dependsOn` | `string[]` | yes | Names of other gates that must pass first. Forms a DAG; cycles are rejected at load time. |
154
+ | `storyAnnotation` | `object` | no | `{ "required": <boolean>, "tag": "<tag-name>" }`. When `required: true`, matched files must contain the tag (e.g. `@story-id H01-01`). Only valid when `level: 3`. |
155
+
156
+ **Rules:**
157
+
158
+ - `name` must be unique across the whole `gates[]` array.
159
+ - `level` is restricted to `1`, `2`, or `3`. `level: 99` or similar is a schema violation.
160
+ - `dependsOn` must reference existing gate names and must not form a cycle.
161
+ - `storyAnnotation` may only appear on `level: 3` gates (schema-enforced).
162
+ - `blocks` uses picomatch glob syntax (e.g. `"src/**/*.ts"`, `"scripts/harness/order/**"`).
163
+
164
+ ##### Example 1 — single level-3 story gate
165
+
166
+ Enforce that any write under `scripts/harness/order/**` carries an `@story-id` annotation:
167
+
168
+ ```jsonc
169
+ {
170
+ "phaseDependencies": {
171
+ "preset": "custom",
172
+ "override": true,
173
+ "customRules": [],
174
+ "gates": [
175
+ {
176
+ "name": "order-story-impl",
177
+ "level": 3,
178
+ "requires": [
179
+ { "path": "docs/product/user_stories.md", "required": true }
180
+ ],
181
+ "blocks": ["scripts/harness/order/**/*.ts"],
182
+ "dependsOn": [],
183
+ "storyAnnotation": { "required": true, "tag": "@story-id" }
184
+ }
185
+ ]
186
+ }
187
+ }
188
+ ```
189
+
190
+ ##### Example 2 — diamond DAG with multiple chains
191
+
192
+ Two level-1 gates feed into a level-2 aggregate, which gates a level-3 implementation:
193
+
194
+ ```jsonc
195
+ {
196
+ "phaseDependencies": {
197
+ "preset": "custom",
198
+ "override": true,
199
+ "customRules": [],
200
+ "gates": [
201
+ {
202
+ "name": "logical-design",
203
+ "level": 1,
204
+ "requires": [
205
+ { "path": "docs/product/construction/{unit}/logical_design.md", "required": true }
206
+ ],
207
+ "blocks": [],
208
+ "dependsOn": []
209
+ },
210
+ {
211
+ "name": "domain-model",
212
+ "level": 1,
213
+ "requires": [
214
+ { "path": "docs/product/construction/{unit}/domain_model.md", "required": true }
215
+ ],
216
+ "blocks": [],
217
+ "dependsOn": []
218
+ },
219
+ {
220
+ "name": "tdd-plan",
221
+ "level": 2,
222
+ "requires": [
223
+ { "path": "docs/inception/{unit}/{storyId}/tdd_implementation_plan.md", "required": true }
224
+ ],
225
+ "blocks": [],
226
+ "dependsOn": ["logical-design", "domain-model"]
227
+ },
228
+ {
229
+ "name": "story-impl",
230
+ "level": 3,
231
+ "requires": [],
232
+ "blocks": ["scripts/harness/**/*.ts"],
233
+ "dependsOn": ["tdd-plan"],
234
+ "storyAnnotation": { "required": true, "tag": "@story-id" }
235
+ }
236
+ ]
237
+ }
238
+ }
239
+ ```
240
+
241
+ ##### Example 3 — minimal level-1 gate (no storyAnnotation)
242
+
243
+ Block commits that touch a protected path unless a design artifact exists — no story-id enforcement:
244
+
245
+ ```jsonc
246
+ {
247
+ "phaseDependencies": {
248
+ "preset": "custom",
249
+ "override": true,
250
+ "customRules": [],
251
+ "gates": [
252
+ {
253
+ "name": "schema-guard",
254
+ "level": 1,
255
+ "requires": [
256
+ { "path": "docs/schema/migration-notes.md", "required": true }
257
+ ],
258
+ "blocks": ["db/migrations/**/*.sql"],
259
+ "dependsOn": []
260
+ }
261
+ ]
262
+ }
263
+ }
264
+ ```
265
+
266
+ #### `storyReflection` (inception -> product gate)
267
+
268
+ `storyReflection` enforces that every US / issue under `docs/inception/{unit}/{storyId}/` has been **cascaded into the accumulating product design documents** (`docs/product/construction/{unit}/`) before source code under `src/{unit}/` or `scripts/harness/{unit}/` can be written or edited.
269
+
270
+ The check fires at the pre-tool-use hook and blocks `Write`/`Edit` (and their Bash equivalents such as `cat > file`, `tee`, heredoc, `sed -i`, `cp`, `mv`, `touch`) whenever an inception design exists but its `@story-id` is not reflected in the corresponding product file.
271
+
272
+ **Zero-config**: omitting the `storyReflection` block, or specifying it without `mappings`, applies the preset's built-in mappings automatically.
273
+
274
+ | Sub-field | Type | Default | Description |
275
+ |-------------|------------|-------------------------|------------------------------------------------------------------------------|
276
+ | `enabled` | `boolean` | preset-dependent | Master switch. `full` / `standard` default to `true`; `minimal` defaults to `false`. |
277
+ | `mappings` | `array` | preset-dependent | Array of inception -> product file mappings. Omit to use the preset default. |
278
+
279
+ Each mapping entry:
280
+
281
+ | Field | Type | Description |
282
+ |-------------|-----------|-----------------------------------------------------------------------------|
283
+ | `inception` | `string` | Template path, e.g. `"docs/inception/{unit}/{storyId}/logical_design.md"`. |
284
+ | `product` | `string` | Template path, e.g. `"docs/product/construction/{unit}/logical_design.md"`.|
285
+ | `required` | `boolean` | When `true`, missing reflection blocks the write. When `false`, it is tolerated (optional mapping). |
286
+
287
+ ##### Preset defaults (hard-coded)
288
+
289
+ **`full`** -- AIDLC recommended (product-accumulated design documents only; test designs are out of scope because they live per-US inside `inception/`):
290
+
291
+ ```jsonc
292
+ [
293
+ { "inception": "docs/inception/{unit}/{storyId}/logical_design.md",
294
+ "product": "docs/product/construction/{unit}/logical_design.md",
295
+ "required": true },
296
+ { "inception": "docs/inception/{unit}/{storyId}/domain_model.md",
297
+ "product": "docs/product/construction/{unit}/domain_model.md",
298
+ "required": true },
299
+ { "inception": "docs/inception/{unit}/{storyId}/uiux_design.md",
300
+ "product": "docs/product/construction/{unit}/uiux_design.md",
301
+ "required": false }
302
+ ]
303
+ ```
304
+
305
+ **`standard`**:
306
+
307
+ ```jsonc
308
+ [
309
+ { "inception": "docs/inception/{unit}/{storyId}/logical_design.md",
310
+ "product": "docs/product/construction/{unit}/logical_design.md",
311
+ "required": true },
312
+ { "inception": "docs/inception/{unit}/{storyId}/domain_model.md",
313
+ "product": "docs/product/construction/{unit}/domain_model.md",
314
+ "required": false }
315
+ ]
316
+ ```
317
+
318
+ **`minimal`**: `enabled: false`. No storyReflection checking.
319
+
320
+ ##### Custom mappings example
321
+
322
+ Override the preset defaults only when your project needs a different policy:
323
+
324
+ ```jsonc
325
+ {
326
+ "phaseDependencies": {
327
+ "preset": "standard",
328
+ "storyReflection": {
329
+ "enabled": true,
330
+ "mappings": [
331
+ { "inception": "docs/inception/{unit}/{storyId}/logical_design.md",
332
+ "product": "docs/product/construction/{unit}/logical_design.md",
333
+ "required": true }
334
+ ]
335
+ }
336
+ }
337
+ }
338
+ ```
339
+
340
+ ##### How the check fires
341
+
342
+ 1. `Write` / `Edit` (or a Bash write such as `cat > src/order/foo.ts`) targets a source file under a Unit.
343
+ 2. `WriteTargetScope` resolves the `@unit` annotation (comma-separated and multi-line `@unit` are both supported; **all** listed units are checked).
344
+ 3. For each unit, every `storyId` directory under `docs/inception/{unit}/` is enumerated.
345
+ 4. For each required mapping, the pre-tool-use hook checks that the target product document contains `@story-id {storyId}`.
346
+ 5. Any missing reflection produces a `STORY_REFLECTION` block reason with a fix hint that points to the `cascade-updater` skill and [ADR-013](../ADR/ADR-013-story-reflection-gate.md).
347
+
348
+ ##### Passing the gate
349
+
350
+ `cascade-updater` is the **standard means of passing the storyReflection gate**: run it to propagate the new US / issue design into the accumulating product documents. Manual editing of the product file with an appended `@story-id` tag is also accepted.
351
+
352
+ Quick Mode with `relaxedGates: ["phase-gate"]` relaxes `storyReflection` as well (see [Quick Mode](#quick-mode)). L1 and L2 `metadata` / `test-quality` checks remain fully enforced.
116
353
 
117
354
  #### `planningMode`
118
355
 
@@ -72,7 +72,7 @@ Use /quick-implementor skill for version changes in package.json.
72
72
  - Provides immediate feedback on violations
73
73
 
74
74
  ### Stop (before session end)
75
- - Runs `harness:complete-check` (L2-L4 full validation)
75
+ - Runs `phasegate:complete-check` (L2-L4 full validation)
76
76
  - Session end is held if checks are not all green
77
77
 
78
78
  ## Optional Shell Script Hooks
@@ -33,7 +33,7 @@ npm install
33
33
  ### 1. Initialize
34
34
 
35
35
  ```bash
36
- npx harness init --name <project-name>
36
+ npx phasegate init --name <project-name>
37
37
  ```
38
38
 
39
39
  This deploys 28 skills to `.claude/skills/` and generates `phasegate.config.json`.
@@ -62,14 +62,14 @@ Run `/product-architect` to begin the AIDLC process.
62
62
 
63
63
  ```bash
64
64
  npm update phasegate
65
- npx harness update-skills
65
+ npx phasegate update-skills
66
66
  ```
67
67
 
68
68
  ## Recommended .gitignore additions
69
69
 
70
70
  ```
71
71
  node_modules/
72
- .claude/skills/ # regenerated by npx harness init
72
+ .claude/skills/ # regenerated by npx phasegate init
73
73
  dist/
74
74
  reports/
75
75
  .harness/
@@ -78,7 +78,7 @@ reports/
78
78
  ## Verify Installation
79
79
 
80
80
  ```bash
81
- npx harness --version
82
- npx harness lint
83
- npm run harness:status
81
+ npx phasegate --version
82
+ npx phasegate lint
83
+ npm run phasegate:status
84
84
  ```
@@ -31,7 +31,7 @@ The Hooks Engine validates agent hook configuration and enforces completion gate
31
31
  **Command:**
32
32
 
33
33
  ```bash
34
- npx harness validate --layer L0
34
+ npx phasegate validate --layer L0
35
35
  ```
36
36
 
37
37
  ---
@@ -68,7 +68,7 @@ L1 rules run in real-time as code is written. They are implemented as Biome AST
68
68
  **Command:**
69
69
 
70
70
  ```bash
71
- npx harness lint
71
+ npx phasegate lint
72
72
  ```
73
73
 
74
74
  ---
@@ -86,7 +86,7 @@ L2 validators run before every commit. They enforce process discipline and test
86
86
  **Command:**
87
87
 
88
88
  ```bash
89
- npx harness validate --layer L2
89
+ npx phasegate validate --layer L2
90
90
  ```
91
91
 
92
92
  ---
@@ -105,7 +105,7 @@ L3 validators run in the CI/CD pipeline before a merge is permitted. They cover
105
105
  **Command:**
106
106
 
107
107
  ```bash
108
- npx harness validate --layer L3
108
+ npx phasegate validate --layer L3
109
109
  ```
110
110
 
111
111
  ---
@@ -123,7 +123,7 @@ L4 validators run on a weekly schedule. They detect slow-moving drift that accum
123
123
  **Command:**
124
124
 
125
125
  ```bash
126
- npx harness validate --layer L4
126
+ npx phasegate validate --layer L4
127
127
  ```
128
128
 
129
129
  ---
@@ -1,6 +1,6 @@
1
1
  # Skills Overview
2
2
 
3
- Phasegate provides 28 skills covering the full AIDLC (AI-Driven Development Life Cycle). Skills are deployed to `.claude/skills/` by `npx harness init` and invoked as slash commands in AI agent sessions.
3
+ Phasegate provides 28 skills covering the full AIDLC (AI-Driven Development Life Cycle). Skills are deployed to `.claude/skills/` by `npx phasegate init` and invoked as slash commands in AI agent sessions.
4
4
 
5
5
  ## AIDLC Process — Skill Execution Order
6
6
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "phasegate",
3
- "version": "0.15.0",
3
+ "version": "0.31.0",
4
4
  "packageManager": "pnpm@10.30.1",
5
5
  "description": "Phasegate — AI-agnostic quality defense toolkit. Enforces structural integrity between design intent and code.",
6
6
  "license": "Apache-2.0",
@@ -26,7 +26,7 @@
26
26
  },
27
27
  "type": "module",
28
28
  "files": [
29
- "bin/harness",
29
+ "bin/phasegate",
30
30
  "scripts/harness/**/*.ts",
31
31
  "!scripts/harness/__tests__/**",
32
32
  "scripts/harness/**/*.json",
@@ -40,23 +40,25 @@
40
40
  "CHANGELOG.md"
41
41
  ],
42
42
  "bin": {
43
- "harness": "./bin/harness"
43
+ "phasegate": "./bin/phasegate"
44
44
  },
45
45
  "scripts": {
46
- "harness": "npx tsx scripts/harness/main.ts",
47
- "harness:status": "npx tsx scripts/harness/main.ts harness:status",
48
- "harness:enable": "npx tsx scripts/harness/main.ts enable-feature",
49
- "harness:disable": "npx tsx scripts/harness/main.ts disable-feature",
50
- "harness:check-phase": "npx tsx scripts/harness/main.ts harness:check-phase",
51
- "harness:check-ready": "npx tsx scripts/harness/main.ts harness:check-ready",
52
- "test": "vitest run --config scripts/harness/__tests__/vitest.config.ts"
46
+ "phasegate": "npx tsx scripts/harness/main.ts",
47
+ "phasegate:status": "npx tsx scripts/harness/main.ts harness:status",
48
+ "phasegate:enable": "npx tsx scripts/harness/main.ts enable-feature",
49
+ "phasegate:disable": "npx tsx scripts/harness/main.ts disable-feature",
50
+ "phasegate:check-phase": "npx tsx scripts/harness/main.ts harness:check-phase",
51
+ "phasegate:check-ready": "npx tsx scripts/harness/main.ts harness:check-ready",
52
+ "test": "vitest run --config scripts/harness/__tests__/vitest.config.forks.ts && vitest run --config scripts/harness/__tests__/vitest.config.ts"
53
53
  },
54
54
  "dependencies": {
55
55
  "ajv": "^8.18.0",
56
+ "picomatch": "^4.0.4",
56
57
  "tsx": "^4.0.0"
57
58
  },
58
59
  "devDependencies": {
59
60
  "@biomejs/biome": "^2.4.7",
61
+ "@types/picomatch": "^4.0.0",
60
62
  "@types/node": "^25.3.5",
61
63
  "typescript": "^5.0.0",
62
64
  "vitest": "^3.0.0"
@@ -1,3 +1,4 @@
1
+ // @layer domain
1
2
  import type { ADR } from '../aggregates/adr.js';
2
3
  import type { AdrBody } from '../value-objects/adr-body.js';
3
4
  import type { AdrFrontmatter } from '../value-objects/adr-frontmatter.js';
@@ -1,3 +1,4 @@
1
+ // @layer domain
1
2
  import type { AdrFrontmatter } from '../value-objects/adr-frontmatter.js';
2
3
 
3
4
  export interface AdrFrontmatterParserPort {
@@ -1,3 +1,4 @@
1
+ // @layer domain
1
2
  import type { ADR } from '../aggregates/adr.js';
2
3
  import type { AdrId } from '../value-objects/adr-id.js';
3
4
  import type { AdrStatus } from '../value-objects/adr-status.js';
@@ -5,11 +5,11 @@
5
5
  const ALLOWED_STATUSES = ['Proposed', 'Accepted', 'Deprecated', 'Superseded'] as const;
6
6
  type AdrStatusValue = (typeof ALLOWED_STATUSES)[number];
7
7
 
8
- const TRANSITIONS: Readonly<Record<AdrStatusValue, readonly AdrStatusValue[]>> = Object.freeze({
9
- Proposed: Object.freeze(['Accepted', 'Deprecated']),
10
- Accepted: Object.freeze(['Deprecated', 'Superseded']),
11
- Deprecated: Object.freeze(['Proposed']),
12
- Superseded: Object.freeze([]),
8
+ const TRANSITIONS = Object.freeze({
9
+ Proposed: Object.freeze(['Accepted', 'Deprecated'] as const),
10
+ Accepted: Object.freeze(['Deprecated', 'Superseded'] as const),
11
+ Deprecated: Object.freeze(['Proposed'] as const),
12
+ Superseded: Object.freeze([] as const),
13
13
  });
14
14
 
15
15
  export class InvalidAdrStatusError extends Error {
@@ -52,7 +52,7 @@ export class AdrStatus {
52
52
  }
53
53
 
54
54
  canTransitionTo(target: AdrStatus): boolean {
55
- return TRANSITIONS[this.value].includes(target.value);
55
+ return (TRANSITIONS[this.value] as readonly string[]).includes(target.value);
56
56
  }
57
57
 
58
58
  equals(other: AdrStatus): boolean {
@@ -11,8 +11,10 @@ export interface HandlePreToolUseInput {
11
11
  export interface HandlePreToolUseOutput {
12
12
  shouldBlock: boolean;
13
13
  blockedFilePath?: string;
14
- blockReason?: 'PROTECTED_FILE' | 'PHASE_GATE';
14
+ blockReason?: 'PROTECTED_FILE' | 'PHASE_GATE' | 'STORY_REFLECTION';
15
15
  error?: { message: string };
16
16
  phaseGateBlockers?: string[];
17
+ storyReflectionBlockers?: string[];
18
+ storyReflectionWarnings?: string[];
17
19
  nextAction?: string;
18
20
  }
@@ -9,15 +9,17 @@
9
9
 
10
10
  import { AsyncHookToCliTranslator } from '../../domain/services/hook-to-cli-translator.js';
11
11
  import { HookEvent } from '../../domain/value-objects/hook-event.js';
12
- import { ProtectedFileList } from '../../domain/value-objects/protected-file-list.js';
13
12
  import type { BlockMetadata } from '../../domain/value-objects/hook-translation-result.js';
14
13
  import type { ConfigQueryPort } from '../../domain/ports/config-query-port.js';
15
14
  import type { PhaseGateQueryPort } from '../../domain/ports/phase-gate-query-port.js';
15
+ import type { StoryReflectionQueryPort } from '../../domain/ports/story-reflection-query-port.js';
16
+ import { WriteTargetScope } from '../../domain/value-objects/write-target-scope.js';
16
17
  import type { HandlePreToolUseInput, HandlePreToolUseOutput } from '../dto/handle-pre-tool-use-dto.js';
17
18
 
18
19
  export interface HandlePreToolUseUseCasePorts {
19
20
  configQueryPort: ConfigQueryPort;
20
21
  phaseGateQueryPort: PhaseGateQueryPort;
22
+ storyReflectionQueryPort?: StoryReflectionQueryPort;
21
23
  }
22
24
 
23
25
  export class HandlePreToolUseInputValidationError extends Error {
@@ -29,11 +31,17 @@ export class HandlePreToolUseInputValidationError extends Error {
29
31
  }
30
32
 
31
33
  export class HandlePreToolUseUseCase {
34
+ private static readonly WRITE_TOOLS: ReadonlySet<string> = new Set([
35
+ 'Write', 'Edit', 'NotebookEdit', 'str_replace_editor',
36
+ ]);
37
+
32
38
  private readonly translator: AsyncHookToCliTranslator;
33
39
  private readonly configQueryPort: ConfigQueryPort;
40
+ private readonly storyReflectionQueryPort?: StoryReflectionQueryPort;
34
41
 
35
42
  constructor(ports: HandlePreToolUseUseCasePorts) {
36
43
  this.configQueryPort = ports.configQueryPort;
44
+ this.storyReflectionQueryPort = ports.storyReflectionQueryPort;
37
45
  this.translator = new AsyncHookToCliTranslator({
38
46
  configQueryPort: ports.configQueryPort,
39
47
  reentryGuard: { isActive: () => false } as never,
@@ -71,7 +79,39 @@ export class HandlePreToolUseUseCase {
71
79
  };
72
80
  }
73
81
 
74
- return { shouldBlock: false };
82
+ const scope = this.resolveStoryReflectionScope(input);
83
+ if (scope === null || this.storyReflectionQueryPort === undefined) {
84
+ return { shouldBlock: false };
85
+ }
86
+
87
+ const reflectionResult = await this.storyReflectionQueryPort.checkReflection(scope.unitId!);
88
+
89
+ if (reflectionResult.skipped || reflectionResult.passed) {
90
+ return { shouldBlock: false };
91
+ }
92
+
93
+ return HandlePreToolUseUseCase.buildStoryReflectionBlockOutput(
94
+ input.targetFilePaths[0],
95
+ reflectionResult.blockers,
96
+ reflectionResult.warnings,
97
+ );
98
+ }
99
+
100
+ private resolveStoryReflectionScope(input: HandlePreToolUseInput): WriteTargetScope | null {
101
+ if (!HandlePreToolUseUseCase.WRITE_TOOLS.has(input.toolName)) {
102
+ return null;
103
+ }
104
+
105
+ const projectPaths = this.configQueryPort.getProjectPaths();
106
+
107
+ for (const targetFilePath of input.targetFilePaths) {
108
+ const scope = WriteTargetScope.fromPath(targetFilePath, projectPaths);
109
+ if (scope?.level === 3 && scope.unitId !== undefined) {
110
+ return scope;
111
+ }
112
+ }
113
+
114
+ return null;
75
115
  }
76
116
 
77
117
  private static readonly LEVEL_LABELS: Record<number, string> = {
@@ -129,7 +169,7 @@ export class HandlePreToolUseUseCase {
129
169
  {
130
170
  pattern: /(?:^|\/)harness\.config\.json$/,
131
171
  message: (fp) =>
132
- `保護ファイルへの書き込みがブロックされました: ${fp}\nハーネス設定は CLI 経由で変更してください: npx harness config ...`,
172
+ `保護ファイルへの書き込みがブロックされました: ${fp}\nハーネス設定は CLI 経由で変更してください: npx phasegate config ...`,
133
173
  },
134
174
  {
135
175
  pattern: /(?:^|\/)\.claude\/settings\.json$/,
@@ -161,4 +201,70 @@ export class HandlePreToolUseUseCase {
161
201
  error: { message },
162
202
  };
163
203
  }
204
+
205
+ private static buildStoryReflectionBlockOutput(
206
+ blockedFilePath: string | undefined,
207
+ blockers: readonly string[],
208
+ warnings: readonly string[],
209
+ ): HandlePreToolUseOutput {
210
+ return {
211
+ shouldBlock: true,
212
+ blockedFilePath,
213
+ blockReason: 'STORY_REFLECTION',
214
+ error: {
215
+ message: HandlePreToolUseUseCase.buildStoryReflectionErrorMessage(blockers),
216
+ },
217
+ storyReflectionBlockers: [...blockers],
218
+ storyReflectionWarnings: [...warnings],
219
+ };
220
+ }
221
+
222
+ private static buildStoryReflectionErrorMessage(blockers: readonly string[]): string {
223
+ const firstBlocker = blockers[0];
224
+ const details = firstBlocker === undefined
225
+ ? null
226
+ : HandlePreToolUseUseCase.extractStoryReflectionDetails(firstBlocker);
227
+ const lines: string[] = [];
228
+
229
+ if (details !== null) {
230
+ lines.push(`[L2-STORY-REFLECTION] ${details.productPath} に`);
231
+ lines.push(`@story-id ${details.storyId} が反映されていません。`);
232
+ lines.push('');
233
+ } else {
234
+ lines.push('[L2-STORY-REFLECTION] product 文書に @story-id が反映されていません。');
235
+ lines.push('');
236
+ }
237
+
238
+ for (const blocker of blockers) {
239
+ lines.push(`- ${blocker}`);
240
+ }
241
+
242
+ lines.push('');
243
+ lines.push('修正方法:');
244
+ lines.push(' 1. cascade-updater を実行して product 文書を更新');
245
+ lines.push(
246
+ ` 2. または手動で該当 product 文書に @story-id ${details?.storyId ?? '<STORY-ID>'} を追加`,
247
+ );
248
+ lines.push('');
249
+ lines.push('参照: ADR-XXX');
250
+
251
+ return lines.join('\n');
252
+ }
253
+
254
+ private static extractStoryReflectionDetails(
255
+ blocker: string,
256
+ ): { productPath: string; storyId: string } | null {
257
+ const productPathMatch = blocker.match(/docs\/product\/construction\/[^\s]+\.md/);
258
+ const storyIdMatch = blocker.match(/@story-id\s+([A-Z][\w-]*-\d+)|\b([A-Z][\w-]*-\d+)\b/);
259
+ const storyId = storyIdMatch?.[1] ?? storyIdMatch?.[2];
260
+
261
+ if (productPathMatch === null || storyId === undefined) {
262
+ return null;
263
+ }
264
+
265
+ return {
266
+ productPath: productPathMatch[0],
267
+ storyId,
268
+ };
269
+ }
164
270
  }
@@ -68,7 +68,7 @@ export class HandleStopUseCase {
68
68
  await this.reentryGuardStatePort.writeActive();
69
69
 
70
70
  try {
71
- const cliResult = await this.cliExecutorPort.execute('harness:complete-check', []);
71
+ const cliResult = await this.cliExecutorPort.execute('phasegate:complete-check', []);
72
72
  return {
73
73
  executed: true,
74
74
  cliResult,
@@ -8,5 +8,7 @@ export type HookType = 'pre-tool-use' | 'post-tool-use' | 'stop';
8
8
  export interface ConfigQueryPort {
9
9
  isHookEnabled(hookType: HookType): Promise<boolean>;
10
10
  getProtectedFilePatterns(): Promise<string[]>;
11
+ getProtectedFileExclusions(): Promise<string[]>;
12
+ getRelaxedGates(): Promise<readonly string[]>;
11
13
  getProjectPaths(): ProjectPaths;
12
14
  }