phasegate 0.283.0 → 0.335.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +16 -0
- package/docs/ADR/017-warning-severity-aggregation.md +17 -0
- package/docs/ADR/038-config-state-operation-permission-policy.md +78 -0
- package/docs/ADR/039-hook-observable-state-as-authorization-unit.md +74 -0
- package/docs/ADR/040-quick-mode-config-via-preset-resolution.md +66 -0
- package/docs/guide/cli-reference.md +89 -7
- package/docs/guide/configuration.md +43 -2
- package/docs/guide/layer-model.md +2 -0
- package/docs/guide/quick-vs-full-mode.md +63 -3
- package/docs/guide/troubleshooting.md +37 -0
- package/docs/templates/agent-context/CLAUDE.md.template.md +6 -6
- package/package.json +2 -2
- package/scripts/harness/agent-integration/application/dto/handle-pre-tool-use-dto.ts +5 -1
- package/scripts/harness/agent-integration/application/usecases/handle-pre-tool-use-usecase.ts +108 -20
- package/scripts/harness/agent-integration/domain/services/bash-write-target-extractor.ts +215 -5
- package/scripts/harness/agent-integration/domain/value-objects/protected-file-list.ts +5 -0
- package/scripts/harness/agent-integration/infrastructure/adapters/file-system-full-mode-session-query-adapter.ts +75 -23
- package/scripts/harness/agent-integration/infrastructure/adapters/harness-config-config-query-adapter.ts +18 -3
- package/scripts/harness/agent-integration/infrastructure/adapters/quick-mode-full-mode-requirement-adapter.ts +15 -1
- package/scripts/harness/agent-integration/presentation/pre-tool-use-hook.ts +57 -9
- package/scripts/harness/ci-governance/application/dto/scaffold-inception-input.ts +9 -0
- package/scripts/harness/ci-governance/application/dto/scaffold-inception-output.ts +13 -0
- package/scripts/harness/ci-governance/application/usecases/list-templates-usecase.ts +30 -0
- package/scripts/harness/ci-governance/application/usecases/scaffold-inception-usecase.ts +63 -0
- package/scripts/harness/ci-governance/application/usecases/show-template-usecase.ts +39 -0
- package/scripts/harness/ci-governance/composition-root.ts +57 -5
- package/scripts/harness/ci-governance/domain/ports/inception-doc-writer-port.ts +19 -0
- package/scripts/harness/ci-governance/domain/ports/inception-template-repository-port.ts +16 -0
- package/scripts/harness/ci-governance/domain/ports/template-catalog-port.ts +23 -0
- package/scripts/harness/ci-governance/domain/services/claude-md-composer.ts +20 -11
- package/scripts/harness/ci-governance/domain/value-objects/inception-doc-kind.ts +109 -0
- package/scripts/harness/ci-governance/domain/value-objects/template-catalog-entry.ts +53 -0
- package/scripts/harness/ci-governance/domain/value-objects/template-name.ts +50 -0
- package/scripts/harness/ci-governance/infrastructure/adapters/file-system-inception-doc-writer-adapter.ts +42 -0
- package/scripts/harness/ci-governance/infrastructure/adapters/file-system-inception-template-repository-adapter.ts +32 -0
- package/scripts/harness/ci-governance/infrastructure/adapters/file-system-template-catalog-adapter.ts +60 -0
- package/scripts/harness/ci-governance/presentation/handlers/check-repetition-handler.ts +10 -2
- package/scripts/harness/ci-governance/presentation/handlers/scaffold-inception-handler.ts +101 -0
- package/scripts/harness/ci-governance/presentation/handlers/templates-handler.ts +103 -0
- package/scripts/harness/config-foundation/domain/harness-config.ts +12 -0
- package/scripts/harness/config-foundation/infrastructure/presets/minimal.json +3 -3
- package/scripts/harness/config-foundation/infrastructure/presets/standard.json +3 -3
- package/scripts/harness/config-foundation/infrastructure/presets/strict.json +3 -3
- package/scripts/harness/config-foundation/infrastructure/schemas/harness-config-v2.schema.json +44 -1
- package/scripts/harness/config-foundation/infrastructure/schemas/harness-config-v3.schema.json +42 -1
- package/scripts/harness/harness-api/domain/services/command-dispatch-service.ts +12 -3
- package/scripts/harness/harness-api/domain/value-objects/ci-check-result.ts +2 -22
- package/scripts/harness/harness-api/domain/value-objects/known-harness-commands.ts +3 -1
- package/scripts/harness/harness-error/application/dto/create-harness-error-input.ts +3 -1
- package/scripts/harness/harness-error/application/dto/harness-error-contract.ts +3 -1
- package/scripts/harness/harness-error/application/mappers/harness-error-contract-mapper.ts +9 -17
- package/scripts/harness/harness-error/application/usecases/create-harness-error-use-case.ts +7 -7
- package/scripts/harness/harness-error/domain/services/harness-error-factory.ts +30 -33
- package/scripts/harness/harness-error/domain/value-objects/error-definition.ts +28 -17
- package/scripts/harness/harness-error/domain/value-objects/harness-error.ts +30 -9
- package/scripts/harness/harness-error/domain/value-objects/remediation-type.ts +30 -0
- package/scripts/harness/harness-error/infrastructure/registry/l2-error-definitions.ts +44 -29
- package/scripts/harness/harness-error/infrastructure/registry/l3-error-definitions.ts +44 -27
- package/scripts/harness/harness-error/infrastructure/registry/l4-error-definitions.ts +47 -32
- package/scripts/harness/installation/application/checks/claude-context-missing-check.ts +13 -7
- package/scripts/harness/installation/application/checks/config-status-check.ts +52 -0
- package/scripts/harness/installation/application/checks/husky-pre-commit-missing-check.ts +6 -0
- package/scripts/harness/installation/application/ports/config-status-probe-port.ts +9 -0
- package/scripts/harness/installation/application/usecases/run-doctor-diagnostics.ts +30 -8
- package/scripts/harness/installation/application/usecases/run-install.ts +44 -11
- package/scripts/harness/installation/application/usecases/run-reconcile.ts +44 -11
- package/scripts/harness/installation/composition-root.ts +13 -3
- package/scripts/harness/installation/domain/check-id.ts +2 -0
- package/scripts/harness/installation/domain/config-status.ts +17 -0
- package/scripts/harness/installation/domain/ports/heuristic-check.ts +10 -1
- package/scripts/harness/installation/infrastructure/adapters/config-status-probe-adapter.ts +79 -0
- package/scripts/harness/installation/presentation/cli/doctor-handler.ts +6 -1
- package/scripts/harness/installation/presentation/formatters/diagnostic-report-formatter.ts +19 -5
- package/scripts/harness/integrations/pre-commit.ts +17 -3
- package/scripts/harness/main.ts +159 -21
- package/scripts/harness/phase-dependency-model/application/services/evidence-bundle-assembler.ts +2 -1
- package/scripts/harness/phase-dependency-model/domain/ports/plan-document-reader-port.ts +12 -0
- package/scripts/harness/phase-dependency-model/infrastructure/filesystem/markdown-plan-document-reader.ts +64 -33
- package/scripts/harness/phase2-extensions/presentation/handlers/check-freshness-handler.ts +17 -9
- package/scripts/harness/quick-mode/application/ports/file-existence-port.ts +15 -0
- package/scripts/harness/quick-mode/application/usecases/classify-change-category-usecase.ts +60 -22
- package/scripts/harness/quick-mode/composition-root.ts +25 -15
- package/scripts/harness/quick-mode/domain/errors/quick-mode-config-error.ts +19 -0
- package/scripts/harness/quick-mode/domain/services/quick-mode-judgment-engine.ts +116 -18
- package/scripts/harness/quick-mode/domain/value-objects/category-override-rules.ts +147 -0
- package/scripts/harness/quick-mode/domain/value-objects/change-category.ts +33 -0
- package/scripts/harness/quick-mode/domain/value-objects/quick-mode-config.ts +31 -10
- package/scripts/harness/quick-mode/index.ts +7 -1
- package/scripts/harness/quick-mode/infrastructure/adapters/fs-file-existence-adapter.ts +38 -0
- package/scripts/harness/quick-mode/infrastructure/adapters/harness-config-quick-mode-config-adapter.ts +83 -32
- package/scripts/harness/skill-quality/infrastructure/adapters/file-system-requirement-test-matrix-adapter.ts +51 -8
- package/scripts/harness/skill-quality/presentation/handlers/check-coverage-handler.ts +13 -6
- package/scripts/harness/traceability-model/domain/value-objects/work-item-frontmatter.ts +5 -1
- package/scripts/harness/traceability-model/infrastructure/gateways/file-system-work-item-identity-gateway.ts +6 -1
- package/scripts/harness/traceability-model/infrastructure/gateways/file-system-work-item-status-gateway.ts +15 -2
- package/scripts/harness/validator-system/application/use-cases/aggregate-validation-results-usecase.ts +11 -14
- package/scripts/harness/validator-system/application/use-cases/run-l3-validators-usecase.ts +8 -0
- package/scripts/harness/validator-system/domain/services/effective-severity-policy.ts +39 -0
- package/scripts/harness/validator-system/domain/value-objects/consistency-report.ts +6 -4
- package/scripts/harness/validator-system/domain/value-objects/drift-report.ts +12 -7
- package/scripts/harness/validator-system/domain/value-objects/validation-result.ts +11 -3
- package/scripts/harness/validator-system/infrastructure/adapters/file-system-security-pattern-scanner-adapter.ts +20 -17
- package/scripts/harness/validator-system/infrastructure/adapters/phase-dependency-phase-gate-policy-adapter.ts +35 -14
- package/scripts/harness/validator-system/infrastructure/adapters/traceability-metadata-policy-adapter.ts +13 -8
- package/scripts/harness/validator-system/presentation/formatters/agent-validation-result-formatter.ts +19 -10
- package/skills/product-architect/SKILL.md +19 -0
- package/skills/quick-implementor/SKILL.md +19 -0
- package/skills/story-mapper/SKILL.md +11 -0
- package/skills/story-writer/SKILL.md +11 -0
- package/skills/unit-designer/SKILL.md +11 -0
- package/templates/product_overview.template.md +85 -0
- package/templates/product_overview_plan.template.md +55 -0
- package/templates/story_mapping_plan.template.md +61 -0
- package/templates/story_writer_plan.template.md +61 -0
- package/templates/unit_design_plan.template.md +63 -0
|
@@ -5,21 +5,22 @@
|
|
|
5
5
|
* エラー定義値オブジェクト
|
|
6
6
|
* エラーコードごとの正規定義(タイトル、カテゴリ、severity、ADR/fix_example要否)を不変で保持する
|
|
7
7
|
*/
|
|
8
|
-
import { InvalidErrorDefinitionError } from
|
|
9
|
-
import type { AdrRef } from
|
|
10
|
-
import type { ErrorCode } from
|
|
11
|
-
import type { FixExample } from
|
|
12
|
-
import type {
|
|
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
|
-
|
|
|
16
|
-
|
|
|
17
|
-
|
|
|
18
|
-
|
|
|
19
|
-
|
|
|
20
|
-
|
|
|
21
|
-
|
|
|
22
|
-
|
|
|
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
|
-
|
|
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
|
|
9
|
-
import type { ErrorCode } from
|
|
10
|
-
import type { FixExample } from
|
|
11
|
-
import type
|
|
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:
|
|
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
|
|
6
|
-
import { ErrorCode } from
|
|
7
|
-
import { ErrorDefinition } from
|
|
8
|
-
import { FixExample } from
|
|
9
|
-
import { Severity } from
|
|
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:
|
|
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(
|
|
34
|
+
defaultSeverity: Severity.create("error"),
|
|
26
35
|
adrRefRequired: true,
|
|
27
|
-
defaultAdrRef: AdrRef.create(
|
|
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:
|
|
40
|
-
title:
|
|
41
|
-
category:
|
|
42
|
-
ownerValidatorId:
|
|
43
|
-
defaultFixExample:
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
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:
|
|
51
|
-
title:
|
|
52
|
-
category:
|
|
53
|
-
ownerValidatorId:
|
|
54
|
-
defaultFixExample:
|
|
55
|
-
|
|
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:
|
|
59
|
-
title:
|
|
60
|
-
category:
|
|
61
|
-
ownerValidatorId:
|
|
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
|
|
6
|
-
import { ErrorCode } from
|
|
7
|
-
import { ErrorDefinition } from
|
|
8
|
-
import { FixExample } from
|
|
9
|
-
import { Severity } from
|
|
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:
|
|
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(
|
|
31
|
+
defaultSeverity: Severity.create("error"),
|
|
23
32
|
adrRefRequired: true,
|
|
24
|
-
defaultAdrRef: AdrRef.create(
|
|
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:
|
|
34
|
-
title:
|
|
35
|
-
category:
|
|
36
|
-
ownerValidatorId:
|
|
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:
|
|
41
|
-
title:
|
|
42
|
-
category:
|
|
43
|
-
ownerValidatorId:
|
|
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:
|
|
49
|
-
title:
|
|
50
|
-
category:
|
|
51
|
-
ownerValidatorId:
|
|
52
|
-
defaultFixExample:
|
|
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:
|
|
56
|
-
title:
|
|
57
|
-
category:
|
|
58
|
-
ownerValidatorId:
|
|
72
|
+
code: "L3-004",
|
|
73
|
+
title: "要件とテストのトレーサビリティが不足している",
|
|
74
|
+
category: "consistency",
|
|
75
|
+
ownerValidatorId: "nyquist",
|
|
59
76
|
defaultFixExample: 'const storyId = "H06-01";',
|
|
60
77
|
}),
|
|
61
78
|
]);
|
|
@@ -3,73 +3,88 @@
|
|
|
3
3
|
* @unit harness-error
|
|
4
4
|
* @work-item-id WI-156
|
|
5
5
|
*/
|
|
6
|
-
import { AdrRef } from
|
|
7
|
-
import { ErrorCode } from
|
|
8
|
-
import { ErrorDefinition } from
|
|
9
|
-
import { FixExample } from
|
|
10
|
-
import { Severity } from
|
|
6
|
+
import { AdrRef } from "../../domain/value-objects/adr-ref.js";
|
|
7
|
+
import { ErrorCode } from "../../domain/value-objects/error-code.js";
|
|
8
|
+
import { ErrorDefinition } from "../../domain/value-objects/error-definition.js";
|
|
9
|
+
import { FixExample } from "../../domain/value-objects/fix-example.js";
|
|
10
|
+
import { Severity } from "../../domain/value-objects/severity.js";
|
|
11
11
|
|
|
12
12
|
function createDefinition(input: {
|
|
13
13
|
code: string;
|
|
14
14
|
title: string;
|
|
15
|
-
category:
|
|
15
|
+
category:
|
|
16
|
+
| "phase_gate"
|
|
17
|
+
| "architecture"
|
|
18
|
+
| "dependency"
|
|
19
|
+
| "quality"
|
|
20
|
+
| "security"
|
|
21
|
+
| "performance"
|
|
22
|
+
| "consistency"
|
|
23
|
+
| "metadata";
|
|
16
24
|
ownerValidatorId: string;
|
|
17
25
|
defaultFixExample: string;
|
|
26
|
+
defaultRemediationType?: "mechanical" | "ai-assisted" | "manual";
|
|
18
27
|
}): ErrorDefinition {
|
|
19
28
|
return ErrorDefinition.create({
|
|
20
29
|
code: ErrorCode.create(input.code),
|
|
21
30
|
title: input.title,
|
|
22
31
|
category: input.category,
|
|
23
|
-
defaultSeverity: Severity.create(
|
|
32
|
+
defaultSeverity: Severity.create("warning"),
|
|
24
33
|
adrRefRequired: true,
|
|
25
|
-
defaultAdrRef: AdrRef.create(
|
|
34
|
+
defaultAdrRef: AdrRef.create("ADR-004"),
|
|
26
35
|
fixExampleRequired: true,
|
|
27
36
|
defaultFixExample: FixExample.create(input.defaultFixExample),
|
|
28
37
|
ownerValidatorId: input.ownerValidatorId,
|
|
38
|
+
defaultRemediationType: input.defaultRemediationType ?? null,
|
|
29
39
|
});
|
|
30
40
|
}
|
|
31
41
|
|
|
32
42
|
export const L4_ERROR_DEFINITIONS = Object.freeze([
|
|
33
43
|
createDefinition({
|
|
34
|
-
code:
|
|
35
|
-
title:
|
|
36
|
-
category:
|
|
37
|
-
ownerValidatorId:
|
|
44
|
+
code: "L4-001",
|
|
45
|
+
title: "設計と実装の乖離が検出された",
|
|
46
|
+
category: "consistency",
|
|
47
|
+
ownerValidatorId: "drift-detect",
|
|
38
48
|
defaultFixExample: 'const actual = "align implementation with design";',
|
|
49
|
+
// WI-335: design drift の解消は設計意図の理解が必要で機械適用不能だが、
|
|
50
|
+
// AI エージェントが設計文書を読んで自己修正できる(ai-assisted)。
|
|
51
|
+
defaultRemediationType: "ai-assisted",
|
|
39
52
|
}),
|
|
40
53
|
createDefinition({
|
|
41
|
-
code:
|
|
42
|
-
title:
|
|
43
|
-
category:
|
|
44
|
-
ownerValidatorId:
|
|
54
|
+
code: "L4-002",
|
|
55
|
+
title: "文書間の整合性が崩れている",
|
|
56
|
+
category: "consistency",
|
|
57
|
+
ownerValidatorId: "consistency-check",
|
|
45
58
|
defaultFixExample: 'const actual = "synchronize documentation";',
|
|
59
|
+
// WI-335: 文書間整合の回復は「どちらの記述が正か」の判断を伴う(ai-assisted)。
|
|
60
|
+
defaultRemediationType: "ai-assisted",
|
|
46
61
|
}),
|
|
47
62
|
createDefinition({
|
|
48
|
-
code:
|
|
49
|
-
title:
|
|
50
|
-
category:
|
|
51
|
-
ownerValidatorId:
|
|
63
|
+
code: "L4-003",
|
|
64
|
+
title: "未使用コードが検出された",
|
|
65
|
+
category: "consistency",
|
|
66
|
+
ownerValidatorId: "dead-code",
|
|
52
67
|
defaultFixExample: 'const actual = "remove unused export";',
|
|
53
68
|
}),
|
|
54
69
|
createDefinition({
|
|
55
|
-
code:
|
|
56
|
-
title:
|
|
57
|
-
category:
|
|
58
|
-
ownerValidatorId:
|
|
70
|
+
code: "L4-004",
|
|
71
|
+
title: "設計ドキュメントの鮮度が閾値を超過した",
|
|
72
|
+
category: "consistency",
|
|
73
|
+
ownerValidatorId: "doc-freshness",
|
|
59
74
|
defaultFixExample: 'const actual = "review or refresh stale design document";',
|
|
60
75
|
}),
|
|
61
76
|
createDefinition({
|
|
62
|
-
code:
|
|
63
|
-
title:
|
|
64
|
-
category:
|
|
65
|
-
ownerValidatorId:
|
|
77
|
+
code: "L4-005",
|
|
78
|
+
title: "設計ドキュメント内のポインタ参照が解決できない",
|
|
79
|
+
category: "consistency",
|
|
80
|
+
ownerValidatorId: "pointer-validation",
|
|
66
81
|
defaultFixExample: 'const actual = "fix unresolved document pointer";',
|
|
67
82
|
}),
|
|
68
83
|
createDefinition({
|
|
69
|
-
code:
|
|
70
|
-
title:
|
|
71
|
-
category:
|
|
72
|
-
ownerValidatorId:
|
|
84
|
+
code: "L4-006",
|
|
85
|
+
title: "スキルカタログ数とドキュメント宣言が一致しない",
|
|
86
|
+
category: "consistency",
|
|
87
|
+
ownerValidatorId: "skill-catalog-drift",
|
|
73
88
|
defaultFixExample: 'const actual = "update skill count declarations with the skill catalog";',
|
|
74
89
|
}),
|
|
75
90
|
]);
|
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
// @unit installation
|
|
2
2
|
// @layer application
|
|
3
3
|
// @work-item-id WI-215
|
|
4
|
+
// @work-item-id WI-343
|
|
4
5
|
|
|
5
6
|
import type { FileInspectorPort } from "../ports/file-inspector-port.js";
|
|
6
|
-
import type { HeuristicCheck } from "../../domain/ports/heuristic-check.js";
|
|
7
|
+
import type { HeuristicCheck, HeuristicCheckContext } from "../../domain/ports/heuristic-check.js";
|
|
7
8
|
import type { DiagnosticFinding } from "../../domain/diagnostic-finding.js";
|
|
8
9
|
import { createFinding, projectPath } from "./check-utils.js";
|
|
9
10
|
|
|
@@ -15,20 +16,25 @@ export class ClaudeContextMissingCheck implements HeuristicCheck {
|
|
|
15
16
|
private readonly projectTarget = "CLAUDE.md";
|
|
16
17
|
private readonly legacyTarget = ".claude/CLAUDE.local.md";
|
|
17
18
|
|
|
18
|
-
async run(
|
|
19
|
+
async run(
|
|
20
|
+
projectRoot: string,
|
|
21
|
+
inspector: FileInspectorPort,
|
|
22
|
+
context?: HeuristicCheckContext,
|
|
23
|
+
): Promise<DiagnosticFinding | null> {
|
|
19
24
|
const content = await inspector.readText(projectPath(projectRoot, this.target));
|
|
20
|
-
if (content?.includes(MARKDOWN_BEGIN) === true &&
|
|
25
|
+
if (content?.includes(MARKDOWN_BEGIN) === true && /phasegate/i.test(content)) return null;
|
|
21
26
|
const projectContent = await inspector.readText(projectPath(projectRoot, this.projectTarget));
|
|
22
|
-
if (projectContent?.includes(MARKDOWN_BEGIN) === true &&
|
|
27
|
+
if (projectContent?.includes(MARKDOWN_BEGIN) === true && /phasegate/i.test(projectContent)) return null;
|
|
23
28
|
|
|
24
29
|
const legacyContent = await inspector.readText(projectPath(projectRoot, this.legacyTarget));
|
|
30
|
+
const target = context?.installationMode === "project" ? this.projectTarget : this.target;
|
|
25
31
|
return createFinding({
|
|
26
32
|
checkId: this.checkId,
|
|
27
33
|
severity: "red",
|
|
28
|
-
target
|
|
29
|
-
message: legacyContent
|
|
34
|
+
target,
|
|
35
|
+
message: legacyContent !== null && /phasegate/i.test(legacyContent)
|
|
30
36
|
? ".claude/CLAUDE.local.md は Claude Code の documented discovery path ではありません"
|
|
31
|
-
:
|
|
37
|
+
: `${target} に runtime-visible PhaseGate context がありません`,
|
|
32
38
|
repairMode: "mechanical",
|
|
33
39
|
});
|
|
34
40
|
}
|