phasegate 0.283.0 → 0.315.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 (71) hide show
  1. package/CHANGELOG.md +16 -0
  2. package/docs/ADR/017-warning-severity-aggregation.md +17 -0
  3. package/docs/ADR/038-config-state-operation-permission-policy.md +78 -0
  4. package/docs/guide/layer-model.md +2 -0
  5. package/docs/guide/quick-vs-full-mode.md +28 -3
  6. package/docs/guide/troubleshooting.md +37 -0
  7. package/docs/templates/agent-context/CLAUDE.md.template.md +6 -6
  8. package/package.json +1 -1
  9. package/scripts/harness/agent-integration/application/usecases/handle-pre-tool-use-usecase.ts +98 -18
  10. package/scripts/harness/agent-integration/domain/services/bash-write-target-extractor.ts +25 -3
  11. package/scripts/harness/agent-integration/infrastructure/adapters/file-system-full-mode-session-query-adapter.ts +75 -23
  12. package/scripts/harness/agent-integration/infrastructure/adapters/harness-config-config-query-adapter.ts +18 -3
  13. package/scripts/harness/agent-integration/presentation/pre-tool-use-hook.ts +51 -6
  14. package/scripts/harness/ci-governance/composition-root.ts +2 -2
  15. package/scripts/harness/ci-governance/domain/services/claude-md-composer.ts +20 -11
  16. package/scripts/harness/ci-governance/presentation/handlers/check-repetition-handler.ts +10 -2
  17. package/scripts/harness/config-foundation/infrastructure/presets/minimal.json +1 -1
  18. package/scripts/harness/config-foundation/infrastructure/presets/standard.json +1 -1
  19. package/scripts/harness/config-foundation/infrastructure/presets/strict.json +1 -1
  20. package/scripts/harness/harness-api/domain/services/command-dispatch-service.ts +12 -3
  21. package/scripts/harness/harness-api/domain/value-objects/ci-check-result.ts +2 -22
  22. package/scripts/harness/harness-error/application/dto/create-harness-error-input.ts +3 -1
  23. package/scripts/harness/harness-error/application/dto/harness-error-contract.ts +3 -1
  24. package/scripts/harness/harness-error/application/mappers/harness-error-contract-mapper.ts +9 -17
  25. package/scripts/harness/harness-error/application/usecases/create-harness-error-use-case.ts +7 -7
  26. package/scripts/harness/harness-error/domain/services/harness-error-factory.ts +30 -33
  27. package/scripts/harness/harness-error/domain/value-objects/error-definition.ts +28 -17
  28. package/scripts/harness/harness-error/domain/value-objects/harness-error.ts +30 -9
  29. package/scripts/harness/harness-error/domain/value-objects/remediation-type.ts +30 -0
  30. package/scripts/harness/harness-error/infrastructure/registry/l2-error-definitions.ts +44 -29
  31. package/scripts/harness/harness-error/infrastructure/registry/l3-error-definitions.ts +44 -27
  32. package/scripts/harness/harness-error/infrastructure/registry/l4-error-definitions.ts +47 -32
  33. package/scripts/harness/installation/application/checks/claude-context-missing-check.ts +13 -7
  34. package/scripts/harness/installation/application/checks/config-status-check.ts +52 -0
  35. package/scripts/harness/installation/application/checks/husky-pre-commit-missing-check.ts +6 -0
  36. package/scripts/harness/installation/application/ports/config-status-probe-port.ts +9 -0
  37. package/scripts/harness/installation/application/usecases/run-doctor-diagnostics.ts +30 -8
  38. package/scripts/harness/installation/application/usecases/run-install.ts +44 -11
  39. package/scripts/harness/installation/application/usecases/run-reconcile.ts +44 -11
  40. package/scripts/harness/installation/composition-root.ts +13 -3
  41. package/scripts/harness/installation/domain/check-id.ts +2 -0
  42. package/scripts/harness/installation/domain/config-status.ts +17 -0
  43. package/scripts/harness/installation/domain/ports/heuristic-check.ts +10 -1
  44. package/scripts/harness/installation/infrastructure/adapters/config-status-probe-adapter.ts +79 -0
  45. package/scripts/harness/installation/presentation/cli/doctor-handler.ts +6 -1
  46. package/scripts/harness/installation/presentation/formatters/diagnostic-report-formatter.ts +19 -5
  47. package/scripts/harness/integrations/pre-commit.ts +17 -3
  48. package/scripts/harness/main.ts +57 -9
  49. package/scripts/harness/phase-dependency-model/infrastructure/filesystem/markdown-plan-document-reader.ts +60 -32
  50. package/scripts/harness/phase2-extensions/presentation/handlers/check-freshness-handler.ts +17 -9
  51. package/scripts/harness/quick-mode/application/ports/file-existence-port.ts +15 -0
  52. package/scripts/harness/quick-mode/application/usecases/classify-change-category-usecase.ts +60 -22
  53. package/scripts/harness/quick-mode/composition-root.ts +25 -15
  54. package/scripts/harness/quick-mode/domain/services/quick-mode-judgment-engine.ts +72 -3
  55. package/scripts/harness/quick-mode/infrastructure/adapters/fs-file-existence-adapter.ts +38 -0
  56. package/scripts/harness/skill-quality/infrastructure/adapters/file-system-requirement-test-matrix-adapter.ts +51 -8
  57. package/scripts/harness/skill-quality/presentation/handlers/check-coverage-handler.ts +13 -6
  58. package/scripts/harness/traceability-model/domain/value-objects/work-item-frontmatter.ts +5 -1
  59. package/scripts/harness/traceability-model/infrastructure/gateways/file-system-work-item-identity-gateway.ts +6 -1
  60. package/scripts/harness/traceability-model/infrastructure/gateways/file-system-work-item-status-gateway.ts +15 -2
  61. package/scripts/harness/validator-system/application/use-cases/aggregate-validation-results-usecase.ts +11 -14
  62. package/scripts/harness/validator-system/application/use-cases/run-l3-validators-usecase.ts +8 -0
  63. package/scripts/harness/validator-system/domain/services/effective-severity-policy.ts +39 -0
  64. package/scripts/harness/validator-system/domain/value-objects/consistency-report.ts +6 -4
  65. package/scripts/harness/validator-system/domain/value-objects/drift-report.ts +12 -7
  66. package/scripts/harness/validator-system/domain/value-objects/validation-result.ts +11 -3
  67. package/scripts/harness/validator-system/infrastructure/adapters/file-system-security-pattern-scanner-adapter.ts +20 -17
  68. package/scripts/harness/validator-system/infrastructure/adapters/phase-dependency-phase-gate-policy-adapter.ts +35 -14
  69. package/scripts/harness/validator-system/infrastructure/adapters/traceability-metadata-policy-adapter.ts +13 -8
  70. package/scripts/harness/validator-system/presentation/formatters/agent-validation-result-formatter.ts +19 -10
  71. package/skills/quick-implementor/SKILL.md +19 -0
@@ -5,33 +5,36 @@
5
5
  * HarnessErrorFactory ドメインサービス
6
6
  * ErrorDefinitionRegistry と Domain ポートを組み合わせて HarnessError を生成する唯一の入口
7
7
  */
8
- import { AdrReferenceNotFoundError } from '../errors/adr-reference-not-found-error.js';
9
- import { EmptyMessageError } from '../errors/empty-message-error.js';
10
- import { EmptySuggestionError } from '../errors/empty-suggestion-error.js';
11
- import { InvalidFixExampleError } from '../errors/invalid-fix-example-error.js';
12
- import { MissingAdrRefError } from '../errors/missing-adr-ref-error.js';
13
- import { MissingFixExampleError } from '../errors/missing-fix-example-error.js';
14
- import type { AdrExistenceCheckerPort } from '../ports/adr-existence-checker-port.js';
15
- import type { FixExampleValidatorPort } from '../ports/fix-example-validator-port.js';
16
- import { AdrRef } from '../value-objects/adr-ref.js';
17
- import { ErrorCode } from '../value-objects/error-code.js';
18
- import { FixExample } from '../value-objects/fix-example.js';
19
- import { HarnessError } from '../value-objects/harness-error.js';
20
- import { Severity } from '../value-objects/severity.js';
21
- import type { ErrorDefinitionRegistry } from './error-definition-registry.js';
22
- import type { SeverityContractEnforcer } from './severity-contract-enforcer.js';
8
+ import { AdrReferenceNotFoundError } from "../errors/adr-reference-not-found-error.js";
9
+ import { EmptyMessageError } from "../errors/empty-message-error.js";
10
+ import { EmptySuggestionError } from "../errors/empty-suggestion-error.js";
11
+ import { InvalidFixExampleError } from "../errors/invalid-fix-example-error.js";
12
+ import { MissingAdrRefError } from "../errors/missing-adr-ref-error.js";
13
+ import { MissingFixExampleError } from "../errors/missing-fix-example-error.js";
14
+ import type { AdrExistenceCheckerPort } from "../ports/adr-existence-checker-port.js";
15
+ import type { FixExampleValidatorPort } from "../ports/fix-example-validator-port.js";
16
+ import { AdrRef } from "../value-objects/adr-ref.js";
17
+ import { ErrorCode } from "../value-objects/error-code.js";
18
+ import { FixExample } from "../value-objects/fix-example.js";
19
+ import { HarnessError } from "../value-objects/harness-error.js";
20
+ import type { RemediationType } from "../value-objects/remediation-type.js";
21
+ import { Severity } from "../value-objects/severity.js";
22
+ import type { ErrorDefinitionRegistry } from "./error-definition-registry.js";
23
+ import type { SeverityContractEnforcer } from "./severity-contract-enforcer.js";
23
24
 
24
25
  export interface CreateHarnessErrorParams {
25
26
  readonly code: string;
26
27
  readonly message: string;
27
28
  readonly suggestion: string;
28
29
  readonly validatorId: string;
29
- readonly requestedSeverity?: 'error' | 'warning';
30
+ readonly requestedSeverity?: "error" | "warning";
30
31
  readonly adrRef?: string | null;
31
32
  readonly fixExample?: string | null;
32
33
  readonly suggestedSkill?: string | null;
33
34
  readonly scaffoldCommand?: string | null;
34
35
  readonly templatePath?: string | null;
36
+ /** WI-335: suggestion の修復方式分類。省略時は ErrorDefinition の既定に従う。 */
37
+ readonly remediationType?: RemediationType | null;
35
38
  }
36
39
 
37
40
  export interface HarnessErrorFactoryDeps {
@@ -68,18 +71,14 @@ export class HarnessErrorFactory {
68
71
  const definition = this.registry.getDefinition(errorCode);
69
72
 
70
73
  // 3. severity 解決
71
- const requestedSeverity = input.requestedSeverity
72
- ? Severity.create(input.requestedSeverity)
73
- : undefined;
74
- const effectiveSeverity =
75
- this.severityContractEnforcer.resolveEffectiveSeverity(
76
- requestedSeverity,
77
- definition.defaultSeverity
78
- );
74
+ const requestedSeverity = input.requestedSeverity ? Severity.create(input.requestedSeverity) : undefined;
75
+ const effectiveSeverity = this.severityContractEnforcer.resolveEffectiveSeverity(
76
+ requestedSeverity,
77
+ definition.defaultSeverity,
78
+ );
79
79
 
80
80
  // 4. ADR 解決
81
- const explicitAdrRef =
82
- input.adrRef != null ? AdrRef.create(input.adrRef) : undefined;
81
+ const explicitAdrRef = input.adrRef != null ? AdrRef.create(input.adrRef) : undefined;
83
82
  const resolvedAdrRef = definition.resolveAdrRef(explicitAdrRef);
84
83
 
85
84
  // 5. ADR 必須チェック
@@ -96,12 +95,8 @@ export class HarnessErrorFactory {
96
95
  }
97
96
 
98
97
  // 7. fix_example 解決
99
- const explicitFixExample =
100
- input.fixExample != null
101
- ? FixExample.create(input.fixExample)
102
- : undefined;
103
- const resolvedFixExample =
104
- definition.resolveFixExample(explicitFixExample);
98
+ const explicitFixExample = input.fixExample != null ? FixExample.create(input.fixExample) : undefined;
99
+ const resolvedFixExample = definition.resolveFixExample(explicitFixExample);
105
100
 
106
101
  // 8. fix_example 必須チェック
107
102
  if (definition.requiresFixExample() && resolvedFixExample === null) {
@@ -117,7 +112,7 @@ export class HarnessErrorFactory {
117
112
  });
118
113
  if (!validationResult.passed) {
119
114
  throw new InvalidFixExampleError(
120
- `fix_example の検証に失敗しました (code=${errorCode.toString()}): ${validationResult.reason}`
115
+ `fix_example の検証に失敗しました (code=${errorCode.toString()}): ${validationResult.reason}`,
121
116
  );
122
117
  }
123
118
  }
@@ -126,6 +121,7 @@ export class HarnessErrorFactory {
126
121
  const resolvedSuggestedSkill = definition.resolveSuggestedSkill(input.suggestedSkill);
127
122
  const resolvedScaffoldCommand = definition.resolveScaffoldCommand(input.scaffoldCommand);
128
123
  const resolvedTemplatePath = definition.resolveTemplatePath(input.templatePath);
124
+ const resolvedRemediationType = definition.resolveRemediationType(input.remediationType);
129
125
 
130
126
  // 11. HarnessError 生成と凍結
131
127
  const harnessError = new HarnessError({
@@ -138,6 +134,7 @@ export class HarnessErrorFactory {
138
134
  suggestedSkill: resolvedSuggestedSkill,
139
135
  scaffoldCommand: resolvedScaffoldCommand,
140
136
  templatePath: resolvedTemplatePath,
137
+ remediationType: resolvedRemediationType,
141
138
  });
142
139
 
143
140
  return Object.freeze(harnessError);
@@ -5,21 +5,22 @@
5
5
  * エラー定義値オブジェクト
6
6
  * エラーコードごとの正規定義(タイトル、カテゴリ、severity、ADR/fix_example要否)を不変で保持する
7
7
  */
8
- import { InvalidErrorDefinitionError } from '../errors/invalid-error-definition-error.js';
9
- import type { AdrRef } from './adr-ref.js';
10
- import type { ErrorCode } from './error-code.js';
11
- import type { FixExample } from './fix-example.js';
12
- import type { Severity } from './severity.js';
8
+ import { InvalidErrorDefinitionError } from "../errors/invalid-error-definition-error.js";
9
+ import type { AdrRef } from "./adr-ref.js";
10
+ import type { ErrorCode } from "./error-code.js";
11
+ import type { FixExample } from "./fix-example.js";
12
+ import type { RemediationType } from "./remediation-type.js";
13
+ import type { Severity } from "./severity.js";
13
14
 
14
15
  export type ErrorDefinitionCategory =
15
- | 'phase_gate'
16
- | 'architecture'
17
- | 'dependency'
18
- | 'quality'
19
- | 'security'
20
- | 'performance'
21
- | 'consistency'
22
- | 'metadata';
16
+ | "phase_gate"
17
+ | "architecture"
18
+ | "dependency"
19
+ | "quality"
20
+ | "security"
21
+ | "performance"
22
+ | "consistency"
23
+ | "metadata";
23
24
 
24
25
  export interface ErrorDefinitionProps {
25
26
  readonly code: ErrorCode;
@@ -34,6 +35,8 @@ export interface ErrorDefinitionProps {
34
35
  readonly defaultSuggestedSkill?: string | null;
35
36
  readonly defaultScaffoldCommand?: string | null;
36
37
  readonly defaultTemplatePath?: string | null;
38
+ /** WI-335: このエラーコードの既定修復方式。未設定(null)は 'manual' 扱い(後方互換)。 */
39
+ readonly defaultRemediationType?: RemediationType | null;
37
40
  }
38
41
 
39
42
  export class ErrorDefinition {
@@ -49,6 +52,7 @@ export class ErrorDefinition {
49
52
  readonly defaultSuggestedSkill: string | null;
50
53
  readonly defaultScaffoldCommand: string | null;
51
54
  readonly defaultTemplatePath: string | null;
55
+ readonly defaultRemediationType: RemediationType | null;
52
56
 
53
57
  private constructor(props: ErrorDefinitionProps) {
54
58
  this.code = props.code;
@@ -63,19 +67,18 @@ export class ErrorDefinition {
63
67
  this.defaultSuggestedSkill = props.defaultSuggestedSkill ?? null;
64
68
  this.defaultScaffoldCommand = props.defaultScaffoldCommand ?? null;
65
69
  this.defaultTemplatePath = props.defaultTemplatePath ?? null;
70
+ this.defaultRemediationType = props.defaultRemediationType ?? null;
66
71
  Object.freeze(this);
67
72
  }
68
73
 
69
74
  static create(props: ErrorDefinitionProps): ErrorDefinition {
70
75
  if (!props.ownerValidatorId || props.ownerValidatorId.trim().length === 0) {
71
- throw new InvalidErrorDefinitionError(
72
- 'ownerValidatorId は空文字であってはなりません。'
73
- );
76
+ throw new InvalidErrorDefinitionError("ownerValidatorId は空文字であってはなりません。");
74
77
  }
75
78
 
76
79
  if (props.defaultAdrRef !== null && !props.adrRefRequired) {
77
80
  throw new InvalidErrorDefinitionError(
78
- 'defaultAdrRef を持つ場合は adrRefRequired を true にしなければなりません。'
81
+ "defaultAdrRef を持つ場合は adrRefRequired を true にしなければなりません。",
79
82
  );
80
83
  }
81
84
 
@@ -128,6 +131,14 @@ export class ErrorDefinition {
128
131
  return this.defaultTemplatePath;
129
132
  }
130
133
 
134
+ /** WI-335: 明示指定を優先し、なければ定義既定の修復方式を返す(未定義は null = 'manual' 扱い)。 */
135
+ resolveRemediationType(explicit?: RemediationType | null): RemediationType | null {
136
+ if (explicit) {
137
+ return explicit;
138
+ }
139
+ return this.defaultRemediationType;
140
+ }
141
+
131
142
  equals(other: ErrorDefinition): boolean {
132
143
  const adrRefEqual =
133
144
  this.defaultAdrRef === null && other.defaultAdrRef === null
@@ -5,14 +5,15 @@
5
5
  * HarnessError 中心モデル(不変値オブジェクト)
6
6
  * 集約を持たず、全属性を不変で保持する値オブジェクトとして設計
7
7
  */
8
- import type { AdrRef } from './adr-ref.js';
9
- import type { ErrorCode } from './error-code.js';
10
- import type { FixExample } from './fix-example.js';
11
- import type { Severity } from './severity.js';
8
+ import type { AdrRef } from "./adr-ref.js";
9
+ import type { ErrorCode } from "./error-code.js";
10
+ import type { FixExample } from "./fix-example.js";
11
+ import { DEFAULT_REMEDIATION_TYPE, type RemediationType } from "./remediation-type.js";
12
+ import type { Severity } from "./severity.js";
12
13
 
13
14
  export interface HarnessErrorContract {
14
15
  readonly code: string;
15
- readonly severity: 'error' | 'warning';
16
+ readonly severity: "error" | "warning";
16
17
  readonly message: string;
17
18
  readonly suggestion: string;
18
19
  readonly adr_ref?: string;
@@ -20,6 +21,7 @@ export interface HarnessErrorContract {
20
21
  readonly suggested_skill?: string;
21
22
  readonly scaffold_command?: string;
22
23
  readonly template_path?: string;
24
+ readonly remediation_type?: RemediationType;
23
25
  }
24
26
 
25
27
  export interface HarnessErrorProps {
@@ -32,6 +34,8 @@ export interface HarnessErrorProps {
32
34
  readonly suggestedSkill?: string | null;
33
35
  readonly scaffoldCommand?: string | null;
34
36
  readonly templatePath?: string | null;
37
+ /** WI-335: suggestion の修復方式分類。未設定(null)は 'manual' 扱い(後方互換)。 */
38
+ readonly remediationType?: RemediationType | null;
35
39
  }
36
40
 
37
41
  export class HarnessError {
@@ -44,6 +48,7 @@ export class HarnessError {
44
48
  readonly suggestedSkill: string | null;
45
49
  readonly scaffoldCommand: string | null;
46
50
  readonly templatePath: string | null;
51
+ readonly remediationType: RemediationType | null;
47
52
 
48
53
  constructor(props: HarnessErrorProps) {
49
54
  this.code = props.code;
@@ -55,6 +60,7 @@ export class HarnessError {
55
60
  this.suggestedSkill = props.suggestedSkill ?? null;
56
61
  this.scaffoldCommand = props.scaffoldCommand ?? null;
57
62
  this.templatePath = props.templatePath ?? null;
63
+ this.remediationType = props.remediationType ?? null;
58
64
  }
59
65
 
60
66
  equals(other: HarnessError): boolean {
@@ -81,7 +87,8 @@ export class HarnessError {
81
87
  fixExampleEqual &&
82
88
  this.suggestedSkill === other.suggestedSkill &&
83
89
  this.scaffoldCommand === other.scaffoldCommand &&
84
- this.templatePath === other.templatePath
90
+ this.templatePath === other.templatePath &&
91
+ this.remediationType === other.remediationType
85
92
  );
86
93
  }
87
94
 
@@ -105,6 +112,21 @@ export class HarnessError {
105
112
  return this.templatePath !== null;
106
113
  }
107
114
 
115
+ /**
116
+ * WI-335: 実効修復方式。未分類は安全側の 'manual' 扱い(機械適用可能と過剰宣言しない)。
117
+ */
118
+ effectiveRemediationType(): RemediationType {
119
+ return this.remediationType ?? DEFAULT_REMEDIATION_TYPE;
120
+ }
121
+
122
+ /**
123
+ * WI-335: suggestion を機械適用すれば必ず解消すると宣言されたエラーか。
124
+ * true のエラーは remediation-round-trip テストで「案内 → 機械適用 → 再実行 → pass」が保証される。
125
+ */
126
+ isMechanicallyRemediable(): boolean {
127
+ return this.effectiveRemediationType() === "mechanical";
128
+ }
129
+
108
130
  toContract(): Readonly<HarnessErrorContract> {
109
131
  const contract: HarnessErrorContract = {
110
132
  code: this.code.toString(),
@@ -112,12 +134,11 @@ export class HarnessError {
112
134
  message: this.message,
113
135
  suggestion: this.suggestion,
114
136
  ...(this.adrRef !== null ? { adr_ref: this.adrRef.toString() } : {}),
115
- ...(this.fixExample !== null
116
- ? { fix_example: this.fixExample.toString() }
117
- : {}),
137
+ ...(this.fixExample !== null ? { fix_example: this.fixExample.toString() } : {}),
118
138
  ...(this.suggestedSkill !== null ? { suggested_skill: this.suggestedSkill } : {}),
119
139
  ...(this.scaffoldCommand !== null ? { scaffold_command: this.scaffoldCommand } : {}),
120
140
  ...(this.templatePath !== null ? { template_path: this.templatePath } : {}),
141
+ ...(this.remediationType !== null ? { remediation_type: this.remediationType } : {}),
121
142
  };
122
143
  return Object.freeze(contract);
123
144
  }
@@ -0,0 +1,30 @@
1
+ /**
2
+ * @layer domain
3
+ * @unit harness-error
4
+ * @work-item-id WI-335
5
+ *
6
+ * RemediationType — suggested action(suggestion)の修復方式分類
7
+ *
8
+ * phasegate の中核価値は「エラー + 次の 1 手」でエージェントの自己修正を駆動することにある。
9
+ * この分類は「案内された 1 手が本当に従えば直るか」を機械保証するための宣言であり、
10
+ * mechanical と宣言されたエラーは往復テスト
11
+ * (scripts/harness/__tests__/integration/validator-system/remediation-round-trip.test.ts)
12
+ * で「エラー → suggestion を機械適用 → 再実行 → pass」が CI 保証される。
13
+ *
14
+ * - mechanical: suggestion の操作を解釈なしで機械適用でき、適用すれば必ず解消する
15
+ * (例: L2-002 の「// @unit を先頭コメントに追加」、
16
+ * L3-003 の「layers.L3.coverageThreshold を 0 に設定して opt-out」)
17
+ * - ai-assisted: 修復に AI/人間の判断・設計理解が必要(例: L4 系の design drift 解消)
18
+ * - manual: 人間の判断が必須(例: L3-001 秘密情報の無効化・ローテーション)。
19
+ * 未分類のエラーも安全側でこの扱いとする(default)
20
+ */
21
+ export type RemediationType = "mechanical" | "ai-assisted" | "manual";
22
+
23
+ /** 未分類エラーの既定値。機械適用可能と過剰宣言しない安全側の値。 */
24
+ export const DEFAULT_REMEDIATION_TYPE: RemediationType = "manual";
25
+
26
+ const VALID_REMEDIATION_TYPES: readonly RemediationType[] = Object.freeze(["mechanical", "ai-assisted", "manual"]);
27
+
28
+ export function isRemediationType(value: unknown): value is RemediationType {
29
+ return typeof value === "string" && (VALID_REMEDIATION_TYPES as readonly string[]).includes(value);
30
+ }
@@ -2,64 +2,79 @@
2
2
  * @layer infrastructure
3
3
  * @unit harness-error
4
4
  */
5
- import { AdrRef } from '../../domain/value-objects/adr-ref.js';
6
- import { ErrorCode } from '../../domain/value-objects/error-code.js';
7
- import { ErrorDefinition } from '../../domain/value-objects/error-definition.js';
8
- import { FixExample } from '../../domain/value-objects/fix-example.js';
9
- import { Severity } from '../../domain/value-objects/severity.js';
5
+ import { AdrRef } from "../../domain/value-objects/adr-ref.js";
6
+ import { ErrorCode } from "../../domain/value-objects/error-code.js";
7
+ import { ErrorDefinition } from "../../domain/value-objects/error-definition.js";
8
+ import { FixExample } from "../../domain/value-objects/fix-example.js";
9
+ import { Severity } from "../../domain/value-objects/severity.js";
10
10
 
11
11
  function createDefinition(input: {
12
12
  code: string;
13
13
  title: string;
14
- category: 'phase_gate' | 'architecture' | 'dependency' | 'quality' | 'security' | 'performance' | 'consistency' | 'metadata';
14
+ category:
15
+ | "phase_gate"
16
+ | "architecture"
17
+ | "dependency"
18
+ | "quality"
19
+ | "security"
20
+ | "performance"
21
+ | "consistency"
22
+ | "metadata";
15
23
  ownerValidatorId: string;
16
24
  defaultFixExample: string;
17
25
  defaultSuggestedSkill?: string;
18
26
  defaultScaffoldCommand?: string;
19
27
  defaultTemplatePath?: string;
28
+ defaultRemediationType?: "mechanical" | "ai-assisted" | "manual";
20
29
  }): ErrorDefinition {
21
30
  return ErrorDefinition.create({
22
31
  code: ErrorCode.create(input.code),
23
32
  title: input.title,
24
33
  category: input.category,
25
- defaultSeverity: Severity.create('error'),
34
+ defaultSeverity: Severity.create("error"),
26
35
  adrRefRequired: true,
27
- defaultAdrRef: AdrRef.create('ADR-002'),
36
+ defaultAdrRef: AdrRef.create("ADR-002"),
28
37
  fixExampleRequired: true,
29
38
  defaultFixExample: FixExample.create(input.defaultFixExample),
30
39
  ownerValidatorId: input.ownerValidatorId,
31
40
  defaultSuggestedSkill: input.defaultSuggestedSkill ?? null,
32
41
  defaultScaffoldCommand: input.defaultScaffoldCommand ?? null,
33
42
  defaultTemplatePath: input.defaultTemplatePath ?? null,
43
+ defaultRemediationType: input.defaultRemediationType ?? null,
34
44
  });
35
45
  }
36
46
 
37
47
  export const L2_ERROR_DEFINITIONS = Object.freeze([
38
48
  createDefinition({
39
- code: 'L2-001',
40
- title: 'Phase Gate の前提条件に違反している',
41
- category: 'phase_gate',
42
- ownerValidatorId: 'phase-gate',
43
- defaultFixExample:
44
- "const requiredPlanPath = 'docs/inception/harness-error/it_test_logic_plan.md';",
45
- defaultSuggestedSkill: '/story-implementor',
46
- defaultScaffoldCommand: 'npx phasegate scaffold-design --unit <unit-id> --phase logical',
47
- defaultTemplatePath: 'templates/logical_design.template.md',
49
+ code: "L2-001",
50
+ title: "Phase Gate の前提条件に違反している",
51
+ category: "phase_gate",
52
+ ownerValidatorId: "phase-gate",
53
+ defaultFixExample: "const requiredPlanPath = 'docs/inception/harness-error/it_test_logic_plan.md';",
54
+ defaultSuggestedSkill: "/story-implementor",
55
+ defaultScaffoldCommand: "npx phasegate scaffold-design --unit <unit-id> --phase logical",
56
+ // WI-356 (issue #29): 旧値 "templates/logical_design.template.md" phasegate 本体の
57
+ // パッケージ内にしか存在せず、導入先 repo からは到達できない到達不能パスだった。
58
+ // hook の block メッセージでこのパスを案内された agent は必ず空振りする。
59
+ // 導入先 repo で実際に読める参照(skill 定義)を指す。skills/ が未配置の
60
+ // personal install 経路でも `npx phasegate skills info <name>` で stdout から読める。
61
+ defaultTemplatePath: "skills/logical-designer/SKILL.md",
48
62
  }),
49
63
  createDefinition({
50
- code: 'L2-002',
51
- title: 'メタデータが不足している',
52
- category: 'metadata',
53
- ownerValidatorId: 'metadata',
54
- defaultFixExample:
55
- '/**\n * @unit harness-error\n * @layer infrastructure\n */\nconst actual = true;',
64
+ code: "L2-002",
65
+ title: "メタデータが不足している",
66
+ category: "metadata",
67
+ ownerValidatorId: "metadata",
68
+ defaultFixExample: "/**\n * @unit harness-error\n * @layer infrastructure\n */\nconst actual = true;",
69
+ // WI-335: suggestion(// @unit / @layer を先頭コメントに追加)は解釈なしで機械適用可能。
70
+ // remediation-round-trip テストで「エラー → 機械適用 → 再実行 → pass」が CI 保証される。
71
+ defaultRemediationType: "mechanical",
56
72
  }),
57
73
  createDefinition({
58
- code: 'L2-003',
59
- title: 'テスト品質規約に違反している',
60
- category: 'quality',
61
- ownerValidatorId: 'test-quality',
62
- defaultFixExample:
63
- "const actual = sut.execute();\nexpect(actual).toBeDefined();",
74
+ code: "L2-003",
75
+ title: "テスト品質規約に違反している",
76
+ category: "quality",
77
+ ownerValidatorId: "test-quality",
78
+ defaultFixExample: "const actual = sut.execute();\nexpect(actual).toBeDefined();",
64
79
  }),
65
80
  ]);
@@ -2,60 +2,77 @@
2
2
  * @layer infrastructure
3
3
  * @unit harness-error
4
4
  */
5
- import { AdrRef } from '../../domain/value-objects/adr-ref.js';
6
- import { ErrorCode } from '../../domain/value-objects/error-code.js';
7
- import { ErrorDefinition } from '../../domain/value-objects/error-definition.js';
8
- import { FixExample } from '../../domain/value-objects/fix-example.js';
9
- import { Severity } from '../../domain/value-objects/severity.js';
5
+ import { AdrRef } from "../../domain/value-objects/adr-ref.js";
6
+ import { ErrorCode } from "../../domain/value-objects/error-code.js";
7
+ import { ErrorDefinition } from "../../domain/value-objects/error-definition.js";
8
+ import { FixExample } from "../../domain/value-objects/fix-example.js";
9
+ import { Severity } from "../../domain/value-objects/severity.js";
10
10
 
11
11
  function createDefinition(input: {
12
12
  code: string;
13
13
  title: string;
14
- category: 'phase_gate' | 'architecture' | 'dependency' | 'quality' | 'security' | 'performance' | 'consistency' | 'metadata';
14
+ category:
15
+ | "phase_gate"
16
+ | "architecture"
17
+ | "dependency"
18
+ | "quality"
19
+ | "security"
20
+ | "performance"
21
+ | "consistency"
22
+ | "metadata";
15
23
  ownerValidatorId: string;
16
24
  defaultFixExample: string;
25
+ defaultRemediationType?: "mechanical" | "ai-assisted" | "manual";
17
26
  }): ErrorDefinition {
18
27
  return ErrorDefinition.create({
19
28
  code: ErrorCode.create(input.code),
20
29
  title: input.title,
21
30
  category: input.category,
22
- defaultSeverity: Severity.create('error'),
31
+ defaultSeverity: Severity.create("error"),
23
32
  adrRefRequired: true,
24
- defaultAdrRef: AdrRef.create('ADR-003'),
33
+ defaultAdrRef: AdrRef.create("ADR-003"),
25
34
  fixExampleRequired: true,
26
35
  defaultFixExample: FixExample.create(input.defaultFixExample),
27
36
  ownerValidatorId: input.ownerValidatorId,
37
+ defaultRemediationType: input.defaultRemediationType ?? null,
28
38
  });
29
39
  }
30
40
 
31
41
  export const L3_ERROR_DEFINITIONS = Object.freeze([
32
42
  createDefinition({
33
- code: 'L3-001',
34
- title: 'セキュリティ上の問題が検出された',
35
- category: 'security',
36
- ownerValidatorId: 'security',
43
+ code: "L3-001",
44
+ title: "セキュリティ上の問題が検出された",
45
+ category: "security",
46
+ ownerValidatorId: "security",
37
47
  defaultFixExample: "const token = process.env.API_TOKEN ?? '';",
48
+ // WI-335: 秘密情報の無効化・ローテーション・保管方式の選定は人間の判断が必須。
49
+ // 「機械適用すれば直る」とは宣言しない(過剰宣言の禁止)。
50
+ defaultRemediationType: "manual",
38
51
  }),
39
52
  createDefinition({
40
- code: 'L3-002',
41
- title: 'パフォーマンス上の問題が検出された',
42
- category: 'performance',
43
- ownerValidatorId: 'performance',
44
- defaultFixExample:
45
- 'const actual = await Promise.all(tasks.map((task) => task()));',
53
+ code: "L3-002",
54
+ title: "パフォーマンス上の問題が検出された",
55
+ category: "performance",
56
+ ownerValidatorId: "performance",
57
+ defaultFixExample: "const actual = await Promise.all(tasks.map((task) => task()));",
46
58
  }),
47
59
  createDefinition({
48
- code: 'L3-003',
49
- title: 'カバレッジ閾値を下回っている',
50
- category: 'quality',
51
- ownerValidatorId: 'coverage',
52
- defaultFixExample: 'const actualCoverage = 0.95;',
60
+ code: "L3-003",
61
+ title: "カバレッジ閾値を下回っている",
62
+ category: "quality",
63
+ ownerValidatorId: "coverage",
64
+ defaultFixExample: "const actualCoverage = 0.95;",
65
+ // WI-335: カバレッジゲートは config の layers.L3.coverageThreshold: 0 で機械的に opt-out
66
+ // できる正規経路を持つ(WI-317 / github#37)。remediation-round-trip テストで
67
+ // 「レポート不在エラー → suggestion の opt-out を機械適用 → 再実行 → SKIP(実効 pass)」を CI 保証。
68
+ // ※ 閾値未達そのもの(テスト追加が必要)を emit する側は ai-assisted を明示指定する。
69
+ defaultRemediationType: "mechanical",
53
70
  }),
54
71
  createDefinition({
55
- code: 'L3-004',
56
- title: '要件とテストのトレーサビリティが不足している',
57
- category: 'consistency',
58
- ownerValidatorId: 'nyquist',
72
+ code: "L3-004",
73
+ title: "要件とテストのトレーサビリティが不足している",
74
+ category: "consistency",
75
+ ownerValidatorId: "nyquist",
59
76
  defaultFixExample: 'const storyId = "H06-01";',
60
77
  }),
61
78
  ]);