phasegate 0.135.0 → 0.137.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 +26 -0
- package/README.ja.md +7 -5
- package/README.md +7 -4
- package/docs/guide/cli-reference.md +3 -0
- package/docs/templates/agent-context/CLAUDE.md.template.md +29 -0
- package/docs/templates/ci/agent-context-refresh.yml +59 -0
- package/docs/templates/ci/aidlc-gate.yml +97 -0
- package/docs/templates/ci/consistency-check.yml +117 -0
- package/docs/templates/hooks/commit-msg +13 -0
- package/docs/templates/hooks/pre-commit +62 -0
- package/package.json +2 -1
- package/scripts/harness/ci-governance/application/dto/check-agent-context-input.ts +8 -0
- package/scripts/harness/ci-governance/application/dto/check-agent-context-output.ts +17 -0
- package/scripts/harness/ci-governance/application/dto/refresh-agent-context-input.ts +8 -0
- package/scripts/harness/ci-governance/application/dto/refresh-agent-context-output.ts +15 -0
- package/scripts/harness/ci-governance/application/dto/refresh-claude-md-input.ts +8 -0
- package/scripts/harness/ci-governance/application/dto/refresh-claude-md-output.ts +13 -0
- package/scripts/harness/ci-governance/application/usecases/check-agent-context-usecase.ts +48 -0
- package/scripts/harness/ci-governance/application/usecases/refresh-agent-context-usecase.ts +31 -0
- package/scripts/harness/ci-governance/application/usecases/refresh-claude-md-usecase.ts +73 -0
- package/scripts/harness/ci-governance/composition-root.ts +23 -1
- package/scripts/harness/ci-governance/domain/aggregates/ci-template.ts +1 -1
- package/scripts/harness/ci-governance/domain/ports/agent-context-document-port.ts +17 -0
- package/scripts/harness/ci-governance/domain/services/claude-md-composer.ts +39 -0
- package/scripts/harness/ci-governance/domain/services/template-generator.ts +1 -0
- package/scripts/harness/ci-governance/domain/types/template-type.ts +2 -1
- package/scripts/harness/ci-governance/infrastructure/adapters/agent-context-file-adapter.ts +55 -0
- package/scripts/harness/ci-governance/infrastructure/adapters/yaml-template-renderer-adapter.ts +16 -31
- package/scripts/harness/ci-governance/presentation/handlers/check-agent-context-handler.ts +33 -0
- package/scripts/harness/ci-governance/presentation/handlers/generate-ci-template-handler.ts +19 -1
- package/scripts/harness/ci-governance/presentation/handlers/refresh-agent-context-handler.ts +44 -0
- package/scripts/harness/ci-governance/presentation/handlers/refresh-claude-md-handler.ts +38 -0
- package/scripts/harness/main.ts +57 -8
- package/scripts/harness/setup/skill-deployer.ts +52 -2
- package/scripts/harness/traceability-model/domain/value-objects/work-item-frontmatter.ts +3 -1
- package/scripts/harness/validator-system/infrastructure/adapters/phase-dependency-phase-gate-policy-adapter.ts +4 -0
package/CHANGELOG.md
CHANGED
|
@@ -7,6 +7,32 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
7
7
|
|
|
8
8
|
## [Unreleased]
|
|
9
9
|
|
|
10
|
+
## [0.137.0] - 2026-05-09
|
|
11
|
+
|
|
12
|
+
### Added
|
|
13
|
+
|
|
14
|
+
- **WI-032 — AGENTS.md / CLAUDE.md auto-refresh pipeline** — `ci:auto-refresh-agent-context --dry-run|--apply|--json` を追加し、lesson artifact 由来の AGENTS.md pointer 更新と CLAUDE.md 標準セクション更新を 1 コマンドで実行できるようにした。
|
|
15
|
+
- `refresh-claude-md --dry-run|--apply|--json` を追加し、CLAUDE.md の user-owned section を保持しながら bundled template から標準セクションを再生成。
|
|
16
|
+
- `p2:check-agent-context --threshold-days <n> --json` を追加し、AGENTS.md / CLAUDE.md の鮮度を検査可能にした。
|
|
17
|
+
- `docs/templates/ci/agent-context-refresh.yml` を追加し、`ci:generate-template --type agent-context-refresh --render` と `phasegate init --with-ci` で配布可能にした。
|
|
18
|
+
- PhaseGate 自身にも `.github/workflows/agent-context-refresh.yml` を追加し、週次 refresh PR を作成する構成にした。
|
|
19
|
+
|
|
20
|
+
## [0.136.0] - 2026-05-09
|
|
21
|
+
|
|
22
|
+
### Added
|
|
23
|
+
|
|
24
|
+
- **WI-031 — CI template の二系統統一 + `phasegate init --with-ci`** — `ci:generate-template --render` が bundled template を正本として stdout に出力するようにし、`phasegate init --with-ci` で `.github/workflows/aidlc-gate.yml` と `.github/workflows/consistency-check.yml` を opt-in 配置できるようにした。
|
|
25
|
+
- `docs/templates/ci/{aidlc-gate,consistency-check}.yml` と `docs/templates/hooks/pre-commit` を render の正本に統一。
|
|
26
|
+
- `consistency-check` の cron と GitHub Issue 自動作成 logic が CLI render と bundled template で一致。
|
|
27
|
+
- 既存 workflow は上書きせず skipped として扱い、新規 config 作成時は `ci.enabled: true` を保存。
|
|
28
|
+
- `docs/templates/**` を npm package 同梱対象に追加。
|
|
29
|
+
|
|
30
|
+
### Fixed
|
|
31
|
+
|
|
32
|
+
- **WI-031 / WI-097 — inception 配下の WI ID 重複を解消** — `_cross/WI-031` と `agent-integration/WI-031` が別内容で同一 ID を持っていたため、H11-04 由来の agent-integration 側を `WI-097` に再採番した。
|
|
33
|
+
- `legacy_id: H11-04` は維持し、agent-integration の product docs に `@work-item-id WI-097` を追記。
|
|
34
|
+
- 再発防止の follow-up として `WI-106`(inception 全体での WI ID 重複防止)を起票。
|
|
35
|
+
|
|
10
36
|
## [0.135.0] - 2026-05-09
|
|
11
37
|
|
|
12
38
|
### Added
|
package/README.ja.md
CHANGED
|
@@ -70,7 +70,7 @@ Node.js >= 18, npm >= 9, TypeScript 5.x
|
|
|
70
70
|
npm install --save-dev phasegate
|
|
71
71
|
|
|
72
72
|
# 2. プロジェクトを初期化
|
|
73
|
-
npx phasegate init --name my-project --with-husky
|
|
73
|
+
npx phasegate init --name my-project --with-husky --with-ci
|
|
74
74
|
|
|
75
75
|
# 3. AI agent を起動して /product-architect から始める
|
|
76
76
|
claude
|
|
@@ -87,6 +87,7 @@ claude
|
|
|
87
87
|
- `docs/principles/*.md` — アーキテクチャ哲学・テスト規約(immutable)
|
|
88
88
|
- `docs/folder_management_rules.md` — ドキュメント配置ルール(**正本**)
|
|
89
89
|
- `--with-husky` を付けると `.husky/pre-commit` ・ `.husky/commit-msg` も配置
|
|
90
|
+
- `--with-ci` を付けると `.github/workflows/aidlc-gate.yml` ・ `.github/workflows/consistency-check.yml` ・ `.github/workflows/agent-context-refresh.yml` も配置
|
|
90
91
|
|
|
91
92
|
**`init` が生成しないもの**(後で skill が作る):
|
|
92
93
|
|
|
@@ -282,7 +283,7 @@ npx phasegate <command> [options]
|
|
|
282
283
|
|
|
283
284
|
| コマンド | 説明 |
|
|
284
285
|
|---|---|
|
|
285
|
-
| `init --name <name>` | 初期化(skills/config/hooks 配置)。`--agent claude\|codex\|both`、`--with-husky`、`--preset <full\|standard\|minimal\|custom>` |
|
|
286
|
+
| `init --name <name>` | 初期化(skills/config/hooks 配置)。`--agent claude\|codex\|both`、`--with-husky`、`--with-ci`、`--preset <full\|standard\|minimal\|custom>` |
|
|
286
287
|
| `update-skills` | スキルを最新版に再デプロイ |
|
|
287
288
|
| `lint` | L1 Biome AST チェック |
|
|
288
289
|
| `validate --layer <L1\|L2\|L3\|L4\|all>` | 指定レイヤーのバリデータ実行(`--format human\|agent\|ci`) |
|
|
@@ -295,7 +296,10 @@ npx phasegate <command> [options]
|
|
|
295
296
|
| `phasegate:detect-drift` | 設計-コード乖離レポート |
|
|
296
297
|
| `migrate work-items --dry-run` / `--apply` | 既存リポジトリの旧 `ISSUE-XXX` / `H{NN}-{NN}` directory を WI 統一レイアウト(`_cross/{WI-XXX}/` / `{unit}/{WI-XXX}/`)へ移行。frontmatter(`type` / `severity` / `legacy_id` / `affects`)を自動注入。冪等。`--json` で CI/スクリプト連携可。詳細: [Work Item Migration](docs/guide/cli-reference.md#work-item-migration) |
|
|
297
298
|
| `migrate --schema v3` | `phasegate.config.json` を v3 schema へ昇格(`architecture` キー追加) |
|
|
298
|
-
| `ci:generate-template --type <aidlc-gate\|pre-commit\|consistency-check>` | CI/CD テンプレート生成(`--render`
|
|
299
|
+
| `ci:generate-template --type <aidlc-gate\|pre-commit\|consistency-check\|agent-context-refresh>` | CI/CD テンプレート生成(`--render` で bundled template を stdout 出力) |
|
|
300
|
+
| `ci:auto-refresh-agent-context --dry-run` / `--apply` | AGENTS.md pointer と CLAUDE.md 標準セクションを更新 |
|
|
301
|
+
| `refresh-claude-md --dry-run` / `--apply` | user section を保持して CLAUDE.md だけを更新 |
|
|
302
|
+
| `p2:check-agent-context` | AGENTS.md / CLAUDE.md の鮮度を検査 |
|
|
299
303
|
| `list-errors --layer <L0-L4>` | エラー定義一覧 |
|
|
300
304
|
| `hook <pre-tool-use\|post-tool-use\|stop>` | agent hook を起動(stdin から JSON) |
|
|
301
305
|
| `pre-commit` | L2 pre-commit バリデータをステージファイルに適用 |
|
|
@@ -451,8 +455,6 @@ reports/
|
|
|
451
455
|
|
|
452
456
|
| Work Item | 内容 |
|
|
453
457
|
|---|---|
|
|
454
|
-
| **[WI-031](docs/inception/_cross/WI-031/description.md)** | CI template の二系統統一 + `phasegate init --with-ci` |
|
|
455
|
-
| **[WI-032](docs/inception/_cross/WI-032/description.md)** | AGENTS.md / CLAUDE.md auto-refresh パイプライン |
|
|
456
458
|
| **[WI-033](docs/inception/_cross/WI-033/description.md)** | `doc-freshness` / `pointer-validation` を L4 validator に昇格 |
|
|
457
459
|
|
|
458
460
|
L3 Nyquist Validation の `requirement-test-matrix.json` 自動生成はまだ未自動化です。現時点では手動セットアップで利用できます。
|
package/README.md
CHANGED
|
@@ -71,7 +71,7 @@ Node.js >= 18, npm >= 9, TypeScript 5.x
|
|
|
71
71
|
npm install --save-dev phasegate
|
|
72
72
|
|
|
73
73
|
# 2. Initialize the project
|
|
74
|
-
npx phasegate init --name my-project --with-husky
|
|
74
|
+
npx phasegate init --name my-project --with-husky --with-ci
|
|
75
75
|
|
|
76
76
|
# 3. Start your AI agent and begin with product design
|
|
77
77
|
claude
|
|
@@ -86,6 +86,7 @@ claude
|
|
|
86
86
|
- `.claude/settings.json` and/or `.codex/hooks.json` hook configuration
|
|
87
87
|
- `docs/principles/*.md` and `docs/folder_management_rules.md`
|
|
88
88
|
- `.husky/pre-commit` and `.husky/commit-msg` when `--with-husky` is passed
|
|
89
|
+
- `.github/workflows/aidlc-gate.yml`, `.github/workflows/consistency-check.yml`, and `.github/workflows/agent-context-refresh.yml` when `--with-ci` is passed
|
|
89
90
|
|
|
90
91
|
`init` intentionally does **not** create `docs/inception/` work item directories or `docs/product/` design documents. Those are produced later by skills such as `/product-architect`, `/domain-designer`, and `/logical-designer`. That is the core contract: no design, no code.
|
|
91
92
|
|
|
@@ -463,10 +464,14 @@ npx phasegate <command> [options]
|
|
|
463
464
|
|
|
464
465
|
| Command | Description |
|
|
465
466
|
|---|---|
|
|
466
|
-
| `init --name <name>` | Initialize project, deploy skills, generate config |
|
|
467
|
+
| `init --name <name>` | Initialize project, deploy skills, generate config. Use `--with-ci` to deploy GitHub Actions workflows. |
|
|
467
468
|
| `lint` | Run L1 Biome AST checks |
|
|
468
469
|
| `validate --layer <L2-L4\|all>` | Run validators for specified layer (`--layer L0` prints runtime hook guidance) |
|
|
469
470
|
| `ci-check` | Full CI check (L2-L4) |
|
|
471
|
+
| `ci:generate-template --type <aidlc-gate\|consistency-check\|pre-commit\|agent-context-refresh> --render` | Render the bundled CI/hook template to stdout |
|
|
472
|
+
| `ci:auto-refresh-agent-context --dry-run` / `--apply` | Refresh AGENTS.md pointers and CLAUDE.md standard sections |
|
|
473
|
+
| `refresh-claude-md --dry-run` / `--apply` | Refresh only CLAUDE.md while preserving the user-owned section |
|
|
474
|
+
| `p2:check-agent-context` | Check AGENTS.md / CLAUDE.md freshness |
|
|
470
475
|
| `update-skills` | Update skills to latest version |
|
|
471
476
|
| `phasegate:status` | Display overall harness health summary |
|
|
472
477
|
| `phasegate:check-phase --unit <id>` | Check current phase for a Unit |
|
|
@@ -512,8 +517,6 @@ The main path is ready for project use, but a few documented behaviors still req
|
|
|
512
517
|
|
|
513
518
|
| Work Item | Title | Why it matters |
|
|
514
519
|
|---|---|---|
|
|
515
|
-
| **[WI-031](docs/inception/_cross/WI-031/description.md)** | CI template unification + `phasegate init --with-ci` | Today the bundled YAML and the `ci:generate-template` output diverge (different cron schedule, only the bundled one creates GitHub Issues). `phasegate init` does not deploy the workflow, so L4 only runs after the user manually copies the file. WI-031 unifies the two paths and adds an opt-in deploy flag. |
|
|
516
|
-
| **[WI-032](docs/inception/_cross/WI-032/description.md)** | AGENTS.md / CLAUDE.md auto-refresh pipeline | `ci:migrate-agents-md` exists as a one-shot CLI but there is no scheduled job, and CLAUDE.md is fully hand-maintained. WI-032 adds an `auto-refresh-agent-context` workflow plus a template-driven CLAUDE.md regenerator that preserves user-owned sections. |
|
|
517
520
|
| **[WI-033](docs/inception/_cross/WI-033/description.md)** | Promote `doc-freshness` / `pointer-validation` to L4 validators | Both capabilities exist as `p2:check-freshness` / `p2:validate-pointers` CLI commands but are not registered as L4 validators, so `validate --layer L4` skips them. WI-033 plumbs them through `validator-system` so they run via the standard L4 path and presets. |
|
|
518
521
|
|
|
519
522
|
`requirement-test-matrix.json` auto-generation for L3 Nyquist Validation is not automated yet; see the L3 guide for the current manual setup.
|
|
@@ -321,6 +321,9 @@ ISSUE-005 P3-10 で明確化された境界:
|
|
|
321
321
|
|---|---|---|
|
|
322
322
|
| `ci:generate-template` | `--preset <id>` `--type <type>` `--render` `--json` | Generate CI/CD template |
|
|
323
323
|
| `ci:migrate-agents-md` | `--dry-run` `--validate-only` `--json` | Migrate AGENTS.md to pointer format |
|
|
324
|
+
| `ci:auto-refresh-agent-context` | `--dry-run` `--apply` `--json` | Refresh AGENTS.md pointers and CLAUDE.md standard sections |
|
|
325
|
+
| `refresh-claude-md` | `--dry-run` `--apply` `--json` | Refresh CLAUDE.md while preserving the user-owned section |
|
|
326
|
+
| `p2:check-agent-context` | `--threshold-days <n>` `--json` | Check AGENTS.md / CLAUDE.md freshness |
|
|
324
327
|
| `ci:check-repetition` | `--code <errorCode>` `--reset` `--json` | Detect repetitive errors |
|
|
325
328
|
|
|
326
329
|
---
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
# CLAUDE.md
|
|
2
|
+
|
|
3
|
+
## 必読ドキュメント
|
|
4
|
+
|
|
5
|
+
- `docs/folder_management_rules.md`
|
|
6
|
+
- `docs/principles/architecture-philosophy.md`
|
|
7
|
+
- `docs/principles/testing-rules.md`
|
|
8
|
+
|
|
9
|
+
## PhaseGate Commands
|
|
10
|
+
|
|
11
|
+
{{PHASEGATE_COMMANDS}}
|
|
12
|
+
|
|
13
|
+
## Phase Presets
|
|
14
|
+
|
|
15
|
+
{{PHASEGATE_PRESETS}}
|
|
16
|
+
|
|
17
|
+
## Skills
|
|
18
|
+
|
|
19
|
+
{{PHASEGATE_SKILLS}}
|
|
20
|
+
|
|
21
|
+
## User Section
|
|
22
|
+
|
|
23
|
+
<!-- phasegate:user-section:start -->
|
|
24
|
+
{{PHASEGATE_USER_SECTION}}
|
|
25
|
+
<!-- phasegate:user-section:end -->
|
|
26
|
+
|
|
27
|
+
## Agent Context Refresh
|
|
28
|
+
|
|
29
|
+
Run `phasegate ci:auto-refresh-agent-context --dry-run` to preview updates and `phasegate ci:auto-refresh-agent-context --apply` to write AGENTS.md / CLAUDE.md.
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
# Phasegate — Agent context refresh workflow
|
|
2
|
+
#
|
|
3
|
+
# 使い方:
|
|
4
|
+
# このファイルを .github/workflows/agent-context-refresh.yml にコピーして使用する。
|
|
5
|
+
#
|
|
6
|
+
# 実行タイミング: 毎週火曜 04:00 UTC(手動トリガーも可)
|
|
7
|
+
# 実行内容:
|
|
8
|
+
# 1. AGENTS.md pointer refresh
|
|
9
|
+
# 2. CLAUDE.md standard section refresh
|
|
10
|
+
# 3. 変更検出時: refresh branch を push して PR を作成
|
|
11
|
+
|
|
12
|
+
name: Agent Context Refresh
|
|
13
|
+
|
|
14
|
+
on:
|
|
15
|
+
schedule:
|
|
16
|
+
- cron: '0 4 * * 2'
|
|
17
|
+
workflow_dispatch:
|
|
18
|
+
|
|
19
|
+
jobs:
|
|
20
|
+
refresh-agent-context:
|
|
21
|
+
name: Refresh AGENTS.md and CLAUDE.md
|
|
22
|
+
runs-on: ubuntu-latest
|
|
23
|
+
permissions:
|
|
24
|
+
contents: write
|
|
25
|
+
pull-requests: write
|
|
26
|
+
|
|
27
|
+
steps:
|
|
28
|
+
- name: Checkout
|
|
29
|
+
uses: actions/checkout@v4
|
|
30
|
+
|
|
31
|
+
- name: Setup Node.js
|
|
32
|
+
uses: actions/setup-node@v4
|
|
33
|
+
with:
|
|
34
|
+
node-version: '20'
|
|
35
|
+
cache: 'pnpm'
|
|
36
|
+
|
|
37
|
+
- name: Install pnpm
|
|
38
|
+
uses: pnpm/action-setup@v4
|
|
39
|
+
with:
|
|
40
|
+
version: 9
|
|
41
|
+
|
|
42
|
+
- name: Install dependencies
|
|
43
|
+
run: pnpm install --frozen-lockfile
|
|
44
|
+
|
|
45
|
+
- name: Refresh agent context
|
|
46
|
+
run: pnpm run harness ci:auto-refresh-agent-context --apply
|
|
47
|
+
|
|
48
|
+
- name: Create pull request
|
|
49
|
+
uses: peter-evans/create-pull-request@v6
|
|
50
|
+
with:
|
|
51
|
+
branch: phasegate/agent-context-refresh
|
|
52
|
+
title: 'chore: refresh agent context'
|
|
53
|
+
commit-message: 'chore: refresh agent context'
|
|
54
|
+
body: |
|
|
55
|
+
Automated AGENTS.md / CLAUDE.md refresh generated by PhaseGate.
|
|
56
|
+
labels: |
|
|
57
|
+
aidlc
|
|
58
|
+
agent-context
|
|
59
|
+
automated
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
# Phasegate — PR検証ワークフロー
|
|
2
|
+
#
|
|
3
|
+
# 使い方:
|
|
4
|
+
# このファイルを .github/workflows/aidlc-gate.yml にコピーして使用する。
|
|
5
|
+
#
|
|
6
|
+
# 実行タイミング: Pull Request(open / synchronize / reopen)
|
|
7
|
+
# 実行内容:
|
|
8
|
+
# 1. harness:lint — L1 Biome AST ルール検証
|
|
9
|
+
# 2. harness:ci-check — L3 CI バリデータ(security / performance / coverage / nyquist)
|
|
10
|
+
# 3. 失敗時: PR にエラーサマリーをコメント
|
|
11
|
+
|
|
12
|
+
name: AIDLC Quality Gate
|
|
13
|
+
|
|
14
|
+
on:
|
|
15
|
+
pull_request:
|
|
16
|
+
types: [opened, synchronize, reopened]
|
|
17
|
+
|
|
18
|
+
jobs:
|
|
19
|
+
harness-gate:
|
|
20
|
+
name: Harness Quality Gate
|
|
21
|
+
runs-on: ubuntu-latest
|
|
22
|
+
permissions:
|
|
23
|
+
pull-requests: write # PRコメント書き込みに必要
|
|
24
|
+
|
|
25
|
+
steps:
|
|
26
|
+
- name: Checkout
|
|
27
|
+
uses: actions/checkout@v4
|
|
28
|
+
|
|
29
|
+
- name: Setup Node.js
|
|
30
|
+
uses: actions/setup-node@v4
|
|
31
|
+
with:
|
|
32
|
+
node-version: '20'
|
|
33
|
+
cache: 'pnpm'
|
|
34
|
+
|
|
35
|
+
- name: Install pnpm
|
|
36
|
+
uses: pnpm/action-setup@v4
|
|
37
|
+
with:
|
|
38
|
+
version: 9
|
|
39
|
+
|
|
40
|
+
- name: Install dependencies
|
|
41
|
+
run: pnpm install --frozen-lockfile
|
|
42
|
+
|
|
43
|
+
# L1: Biome AST ルール
|
|
44
|
+
- name: L1 Lint (Biome AST)
|
|
45
|
+
id: lint
|
|
46
|
+
run: |
|
|
47
|
+
set +e
|
|
48
|
+
RESULT=$(pnpm run harness lint --json 2>&1)
|
|
49
|
+
EXIT_CODE=$?
|
|
50
|
+
echo "result<<EOF" >> $GITHUB_OUTPUT
|
|
51
|
+
echo "$RESULT" >> $GITHUB_OUTPUT
|
|
52
|
+
echo "EOF" >> $GITHUB_OUTPUT
|
|
53
|
+
echo "exit_code=$EXIT_CODE" >> $GITHUB_OUTPUT
|
|
54
|
+
exit $EXIT_CODE
|
|
55
|
+
|
|
56
|
+
# L3: CI バリデータ(security / performance / coverage / nyquist)
|
|
57
|
+
- name: L3 CI Check
|
|
58
|
+
id: ci_check
|
|
59
|
+
if: always()
|
|
60
|
+
run: |
|
|
61
|
+
set +e
|
|
62
|
+
RESULT=$(pnpm run harness harness:ci-check --json 2>&1)
|
|
63
|
+
EXIT_CODE=$?
|
|
64
|
+
echo "result<<EOF" >> $GITHUB_OUTPUT
|
|
65
|
+
echo "$RESULT" >> $GITHUB_OUTPUT
|
|
66
|
+
echo "EOF" >> $GITHUB_OUTPUT
|
|
67
|
+
echo "exit_code=$EXIT_CODE" >> $GITHUB_OUTPUT
|
|
68
|
+
exit $EXIT_CODE
|
|
69
|
+
|
|
70
|
+
# 失敗時のみ PR にコメント
|
|
71
|
+
- name: Post failure comment
|
|
72
|
+
if: failure()
|
|
73
|
+
uses: actions/github-script@v7
|
|
74
|
+
with:
|
|
75
|
+
script: |
|
|
76
|
+
const lintResult = `${{ steps.lint.outputs.result }}`;
|
|
77
|
+
const ciResult = `${{ steps.ci_check.outputs.result }}`;
|
|
78
|
+
const lintFailed = '${{ steps.lint.outputs.exit_code }}' !== '0';
|
|
79
|
+
const ciFailed = '${{ steps.ci_check.outputs.exit_code }}' !== '0';
|
|
80
|
+
|
|
81
|
+
let body = '## ❌ AIDLC Quality Gate — 失敗\n\n';
|
|
82
|
+
|
|
83
|
+
if (lintFailed) {
|
|
84
|
+
body += '### L1 Lint エラー\n```json\n' + lintResult + '\n```\n\n';
|
|
85
|
+
}
|
|
86
|
+
if (ciFailed) {
|
|
87
|
+
body += '### L3 CI Check エラー\n```json\n' + ciResult + '\n```\n\n';
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
body += '---\n> 修正方法は各 `HarnessError.suggestion` および `HarnessError.fix_example` を参照してください。';
|
|
91
|
+
|
|
92
|
+
github.rest.issues.createComment({
|
|
93
|
+
issue_number: context.issue.number,
|
|
94
|
+
owner: context.repo.owner,
|
|
95
|
+
repo: context.repo.repo,
|
|
96
|
+
body,
|
|
97
|
+
});
|
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
# Phasegate — 週次整合性チェックワークフロー
|
|
2
|
+
#
|
|
3
|
+
# 使い方:
|
|
4
|
+
# このファイルを .github/workflows/consistency-check.yml にコピーして使用する。
|
|
5
|
+
#
|
|
6
|
+
# 実行タイミング: 毎週月曜 09:00 UTC(手動トリガーも可)
|
|
7
|
+
# 実行内容:
|
|
8
|
+
# 1. harness:detect-drift — L4 設計⇔コード乖離検出(drift-detect)
|
|
9
|
+
# 2. harness:complete-check — L4 全バリデータ(drift-detect / consistency-check / dead-code)
|
|
10
|
+
# 3. 乖離検出時: GitHub Issue を自動作成
|
|
11
|
+
|
|
12
|
+
name: AIDLC Consistency Check (Weekly)
|
|
13
|
+
|
|
14
|
+
on:
|
|
15
|
+
schedule:
|
|
16
|
+
- cron: '0 9 * * 1' # 毎週月曜 09:00 UTC
|
|
17
|
+
workflow_dispatch: # 手動トリガー
|
|
18
|
+
|
|
19
|
+
jobs:
|
|
20
|
+
consistency-check:
|
|
21
|
+
name: L4 Consistency & Drift Check
|
|
22
|
+
runs-on: ubuntu-latest
|
|
23
|
+
permissions:
|
|
24
|
+
issues: write # Issue 自動作成に必要
|
|
25
|
+
|
|
26
|
+
steps:
|
|
27
|
+
- name: Checkout
|
|
28
|
+
uses: actions/checkout@v4
|
|
29
|
+
|
|
30
|
+
- name: Setup Node.js
|
|
31
|
+
uses: actions/setup-node@v4
|
|
32
|
+
with:
|
|
33
|
+
node-version: '20'
|
|
34
|
+
cache: 'pnpm'
|
|
35
|
+
|
|
36
|
+
- name: Install pnpm
|
|
37
|
+
uses: pnpm/action-setup@v4
|
|
38
|
+
with:
|
|
39
|
+
version: 9
|
|
40
|
+
|
|
41
|
+
- name: Install dependencies
|
|
42
|
+
run: pnpm install --frozen-lockfile
|
|
43
|
+
|
|
44
|
+
# L4-001: Drift Detection(設計⇔コード双方向乖離)
|
|
45
|
+
- name: L4 Drift Detection
|
|
46
|
+
id: drift
|
|
47
|
+
run: |
|
|
48
|
+
set +e
|
|
49
|
+
RESULT=$(pnpm run harness harness:detect-drift --json 2>&1)
|
|
50
|
+
EXIT_CODE=$?
|
|
51
|
+
echo "result<<EOF" >> $GITHUB_OUTPUT
|
|
52
|
+
echo "$RESULT" >> $GITHUB_OUTPUT
|
|
53
|
+
echo "EOF" >> $GITHUB_OUTPUT
|
|
54
|
+
echo "exit_code=$EXIT_CODE" >> $GITHUB_OUTPUT
|
|
55
|
+
exit 0 # Issue作成のため常に続行
|
|
56
|
+
|
|
57
|
+
# L4: 全バリデータ(drift-detect + consistency-check + dead-code)
|
|
58
|
+
- name: L4 Complete Check
|
|
59
|
+
id: complete
|
|
60
|
+
run: |
|
|
61
|
+
set +e
|
|
62
|
+
RESULT=$(pnpm run harness harness:complete-check --json 2>&1)
|
|
63
|
+
EXIT_CODE=$?
|
|
64
|
+
echo "result<<EOF" >> $GITHUB_OUTPUT
|
|
65
|
+
echo "$RESULT" >> $GITHUB_OUTPUT
|
|
66
|
+
echo "EOF" >> $GITHUB_OUTPUT
|
|
67
|
+
echo "exit_code=$EXIT_CODE" >> $GITHUB_OUTPUT
|
|
68
|
+
exit 0 # Issue作成のため常に続行
|
|
69
|
+
|
|
70
|
+
# 乖離が検出された場合のみ Issue を作成
|
|
71
|
+
- name: Create issue on drift detected
|
|
72
|
+
if: |
|
|
73
|
+
steps.drift.outputs.exit_code != '0' ||
|
|
74
|
+
steps.complete.outputs.exit_code != '0'
|
|
75
|
+
uses: actions/github-script@v7
|
|
76
|
+
with:
|
|
77
|
+
script: |
|
|
78
|
+
const driftResult = `${{ steps.drift.outputs.result }}`;
|
|
79
|
+
const completeResult = `${{ steps.complete.outputs.result }}`;
|
|
80
|
+
const driftFailed = '${{ steps.drift.outputs.exit_code }}' !== '0';
|
|
81
|
+
const completeFailed = '${{ steps.complete.outputs.exit_code }}' !== '0';
|
|
82
|
+
|
|
83
|
+
const today = new Date().toISOString().slice(0, 10);
|
|
84
|
+
let body = `## 🔍 AIDLC 整合性チェック結果 — ${today}\n\n`;
|
|
85
|
+
body += '> 週次スケジュール実行により設計⇔コードの乖離が検出されました。\n\n';
|
|
86
|
+
|
|
87
|
+
if (driftFailed) {
|
|
88
|
+
body += '### L4-001 Drift Detection\n```json\n' + driftResult + '\n```\n\n';
|
|
89
|
+
}
|
|
90
|
+
if (completeFailed) {
|
|
91
|
+
body += '### L4 Complete Check\n```json\n' + completeResult + '\n```\n\n';
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
body += '---\n';
|
|
95
|
+
body += '### 対処方法\n';
|
|
96
|
+
body += '1. 乖離の内容を確認し、設計文書またはコードのどちらを修正すべきか判断\n';
|
|
97
|
+
body += '2. `cascade-updater` スキルで設計文書を更新、または実装を修正\n';
|
|
98
|
+
body += '3. `pnpm run harness harness:detect-drift` で再検証して乖離が解消されたことを確認\n';
|
|
99
|
+
|
|
100
|
+
github.rest.issues.create({
|
|
101
|
+
owner: context.repo.owner,
|
|
102
|
+
repo: context.repo.repo,
|
|
103
|
+
title: `[AIDLC] 設計⇔コード乖離検出 (${today})`,
|
|
104
|
+
body,
|
|
105
|
+
labels: ['aidlc', 'drift-detected', 'automated'],
|
|
106
|
+
});
|
|
107
|
+
|
|
108
|
+
- name: Summary
|
|
109
|
+
run: |
|
|
110
|
+
DRIFT_CODE="${{ steps.drift.outputs.exit_code }}"
|
|
111
|
+
COMPLETE_CODE="${{ steps.complete.outputs.exit_code }}"
|
|
112
|
+
if [ "$DRIFT_CODE" = "0" ] && [ "$COMPLETE_CODE" = "0" ]; then
|
|
113
|
+
echo "✅ 設計⇔コード整合性: 問題なし"
|
|
114
|
+
else
|
|
115
|
+
echo "❌ 乖離を検出しました。GitHub Issue を確認してください。"
|
|
116
|
+
exit 1
|
|
117
|
+
fi
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
#!/usr/bin/env sh
|
|
2
|
+
# PhaseGate commit-msg hook template.
|
|
3
|
+
#
|
|
4
|
+
# Usage:
|
|
5
|
+
# 1. Copy this file to .husky/commit-msg
|
|
6
|
+
# 2. chmod +x .husky/commit-msg
|
|
7
|
+
#
|
|
8
|
+
# The hook validates commit-message trailers that require access to the final
|
|
9
|
+
# commit message, such as `Work-Item: WI-XXX` for WI document changes.
|
|
10
|
+
|
|
11
|
+
. "$(dirname -- "$0")/_/husky.sh"
|
|
12
|
+
|
|
13
|
+
npx phasegate commit-msg "$1"
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
#!/usr/bin/env sh
|
|
2
|
+
# GSDLC Quality Harness — Pre-commit Hook テンプレート
|
|
3
|
+
#
|
|
4
|
+
# 使い方:
|
|
5
|
+
# 1. このファイルを .husky/pre-commit にコピーする
|
|
6
|
+
# 2. chmod +x .husky/pre-commit
|
|
7
|
+
# 3. pnpm add --save-dev husky && npx husky install
|
|
8
|
+
#
|
|
9
|
+
# 実行内容:
|
|
10
|
+
# L1: Biome AST ルール(require-unit-comment, no-layer-violation など 8ルール)
|
|
11
|
+
# L2: Pre-commit バリデータ(phase-gate / metadata / test-quality)
|
|
12
|
+
#
|
|
13
|
+
# ⚠️ Quick Mode の場合は HARNESS_QUICK_MODE=1 を設定してコミットする:
|
|
14
|
+
# HARNESS_QUICK_MODE=1 git commit -m "fix: ..."
|
|
15
|
+
|
|
16
|
+
. "$(dirname -- "$0")/_/husky.sh"
|
|
17
|
+
|
|
18
|
+
HARNESS_CMD="npx tsx scripts/harness/main.ts"
|
|
19
|
+
|
|
20
|
+
echo "🔍 AIDLC Quality Gate (Pre-commit)"
|
|
21
|
+
echo "──────────────────────────────────"
|
|
22
|
+
|
|
23
|
+
# -----------------------------------------------------------------------
|
|
24
|
+
# L1: Biome AST ルール
|
|
25
|
+
# -----------------------------------------------------------------------
|
|
26
|
+
echo "▶ L1 Lint (Biome AST)..."
|
|
27
|
+
$HARNESS_CMD lint
|
|
28
|
+
L1_EXIT=$?
|
|
29
|
+
|
|
30
|
+
if [ $L1_EXIT -ne 0 ]; then
|
|
31
|
+
echo ""
|
|
32
|
+
echo "❌ L1 Lint が失敗しました。"
|
|
33
|
+
echo " 修正してから再度コミットしてください。"
|
|
34
|
+
echo " 詳細: pnpm run harness lint"
|
|
35
|
+
exit 1
|
|
36
|
+
fi
|
|
37
|
+
echo "✅ L1 Lint: passed"
|
|
38
|
+
|
|
39
|
+
# -----------------------------------------------------------------------
|
|
40
|
+
# L2: Pre-commit バリデータ
|
|
41
|
+
# -----------------------------------------------------------------------
|
|
42
|
+
# Quick Mode では phase-gate をスキップ
|
|
43
|
+
if [ "${HARNESS_QUICK_MODE:-0}" = "1" ]; then
|
|
44
|
+
echo "▶ L2 Validators (Quick Mode: phase-gate スキップ)..."
|
|
45
|
+
$HARNESS_CMD check-phase-gate --skip-phase-gate
|
|
46
|
+
else
|
|
47
|
+
echo "▶ L2 Validators (phase-gate / metadata / test-quality)..."
|
|
48
|
+
$HARNESS_CMD check-phase-gate
|
|
49
|
+
fi
|
|
50
|
+
L2_EXIT=$?
|
|
51
|
+
|
|
52
|
+
if [ $L2_EXIT -ne 0 ]; then
|
|
53
|
+
echo ""
|
|
54
|
+
echo "❌ L2 Validators が失敗しました。"
|
|
55
|
+
echo " 修正してから再度コミットしてください。"
|
|
56
|
+
echo " 詳細: pnpm run harness check-phase-gate"
|
|
57
|
+
exit 1
|
|
58
|
+
fi
|
|
59
|
+
echo "✅ L2 Validators: passed"
|
|
60
|
+
|
|
61
|
+
echo "──────────────────────────────────"
|
|
62
|
+
echo "✅ AIDLC Quality Gate: passed"
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "phasegate",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.137.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": "MIT",
|
|
@@ -38,6 +38,7 @@
|
|
|
38
38
|
"docs/contracts/**",
|
|
39
39
|
"docs/principles/**",
|
|
40
40
|
"docs/guide/**",
|
|
41
|
+
"docs/templates/**",
|
|
41
42
|
"docs/folder_management_rules.md",
|
|
42
43
|
"LICENSE",
|
|
43
44
|
"CHANGELOG.md"
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @layer application
|
|
3
|
+
* @unit ci-governance
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
export interface AgentContextFreshnessFinding {
|
|
7
|
+
readonly path: string;
|
|
8
|
+
readonly status: 'pass' | 'error';
|
|
9
|
+
readonly ageInDays: number | null;
|
|
10
|
+
readonly message: string;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
export interface CheckAgentContextOutput {
|
|
14
|
+
readonly passed: boolean;
|
|
15
|
+
readonly thresholdDays: number;
|
|
16
|
+
readonly findings: readonly AgentContextFreshnessFinding[];
|
|
17
|
+
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @layer application
|
|
3
|
+
* @unit ci-governance
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import type { MigrateAgentsMdOutput } from './migrate-agents-md-output.js';
|
|
7
|
+
import type { RefreshClaudeMdOutput } from './refresh-claude-md-output.js';
|
|
8
|
+
|
|
9
|
+
export interface RefreshAgentContextOutput {
|
|
10
|
+
readonly success: boolean;
|
|
11
|
+
readonly applied: boolean;
|
|
12
|
+
readonly agentsMd: MigrateAgentsMdOutput;
|
|
13
|
+
readonly claudeMd: RefreshClaudeMdOutput;
|
|
14
|
+
readonly errors: Array<{ code: string; message: string }>;
|
|
15
|
+
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @layer application
|
|
3
|
+
* @unit ci-governance
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
export interface RefreshClaudeMdOutput {
|
|
7
|
+
readonly success: boolean;
|
|
8
|
+
readonly path: string;
|
|
9
|
+
readonly changed: boolean;
|
|
10
|
+
readonly applied: boolean;
|
|
11
|
+
readonly preview: string;
|
|
12
|
+
readonly errors: Array<{ code: string; message: string }>;
|
|
13
|
+
}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @layer application
|
|
3
|
+
* @unit ci-governance
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import type { AgentContextDocumentPort } from '../../domain/ports/agent-context-document-port.js';
|
|
7
|
+
import type { CheckAgentContextInput } from '../dto/check-agent-context-input.js';
|
|
8
|
+
import type { AgentContextFreshnessFinding, CheckAgentContextOutput } from '../dto/check-agent-context-output.js';
|
|
9
|
+
|
|
10
|
+
const AGENT_CONTEXT_PATHS = ['AGENTS.md', 'CLAUDE.md'] as const;
|
|
11
|
+
const DEFAULT_THRESHOLD_DAYS = 30;
|
|
12
|
+
|
|
13
|
+
export class CheckAgentContextUseCase {
|
|
14
|
+
constructor(private readonly documentPort: AgentContextDocumentPort) {}
|
|
15
|
+
|
|
16
|
+
async execute(input: CheckAgentContextInput): Promise<CheckAgentContextOutput> {
|
|
17
|
+
const thresholdDays = input.thresholdDays ?? DEFAULT_THRESHOLD_DAYS;
|
|
18
|
+
const findings: AgentContextFreshnessFinding[] = [];
|
|
19
|
+
|
|
20
|
+
for (const path of AGENT_CONTEXT_PATHS) {
|
|
21
|
+
const stat = await this.documentPort.statProjectFile(path);
|
|
22
|
+
if (!stat.exists) {
|
|
23
|
+
findings.push({
|
|
24
|
+
path,
|
|
25
|
+
status: 'error',
|
|
26
|
+
ageInDays: null,
|
|
27
|
+
message: `${path} does not exist`,
|
|
28
|
+
});
|
|
29
|
+
continue;
|
|
30
|
+
}
|
|
31
|
+
const stale = stat.ageInDays !== null && stat.ageInDays > thresholdDays;
|
|
32
|
+
findings.push({
|
|
33
|
+
path,
|
|
34
|
+
status: stale ? 'error' : 'pass',
|
|
35
|
+
ageInDays: stat.ageInDays,
|
|
36
|
+
message: stale
|
|
37
|
+
? `${path} is older than ${thresholdDays} days`
|
|
38
|
+
: `${path} is fresh`,
|
|
39
|
+
});
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
return {
|
|
43
|
+
passed: findings.every((finding) => finding.status === 'pass'),
|
|
44
|
+
thresholdDays,
|
|
45
|
+
findings,
|
|
46
|
+
};
|
|
47
|
+
}
|
|
48
|
+
}
|