phasegate 0.315.0 → 0.340.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 +4 -0
- package/README.ja.md +22 -9
- package/README.md +28 -17
- package/docs/ADR/038-config-state-operation-permission-policy.md +5 -2
- 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/ADR/041-non-excludable-agent-trust-roots.md +68 -0
- package/docs/guide/antigravity-integration.md +26 -0
- package/docs/guide/cli-reference.md +93 -11
- package/docs/guide/codex-integration.md +44 -107
- package/docs/guide/configuration.md +43 -2
- package/docs/guide/grok-integration.md +26 -0
- package/docs/guide/hooks-integration.md +27 -4
- package/docs/guide/installation.md +4 -2
- package/docs/guide/quick-vs-full-mode.md +36 -1
- package/docs/guide/setup-artifacts.md +4 -4
- package/docs/guide/skills-overview.md +1 -1
- package/package.json +2 -2
- package/scripts/harness/agent-integration/application/dto/handle-pre-tool-use-dto.ts +6 -2
- package/scripts/harness/agent-integration/application/dto/normalized-pre-tool-use-request.ts +32 -0
- package/scripts/harness/agent-integration/application/usecases/handle-pre-tool-use-usecase.ts +17 -9
- package/scripts/harness/agent-integration/domain/ports/full-mode-requirement-query-port.ts +3 -1
- package/scripts/harness/agent-integration/domain/services/apply-patch-write-target-extractor.ts +98 -0
- package/scripts/harness/agent-integration/domain/services/bash-write-target-extractor.ts +196 -54
- package/scripts/harness/agent-integration/domain/value-objects/hook-translation-result.ts +1 -1
- package/scripts/harness/agent-integration/domain/value-objects/protected-file-list.ts +39 -17
- package/scripts/harness/agent-integration/infrastructure/adapters/quick-mode-full-mode-requirement-adapter.ts +15 -1
- package/scripts/harness/agent-integration/presentation/phasegate-status-context.ts +1 -1
- package/scripts/harness/agent-integration/presentation/post-tool-use-hook.ts +1 -0
- package/scripts/harness/agent-integration/presentation/pre-tool-use-hook.ts +129 -73
- package/scripts/harness/agent-integration/presentation/pre-tool-use-payload-normalizer.ts +228 -0
- package/scripts/harness/agent-integration/presentation/pre-tool-use-response-renderer.ts +38 -0
- 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 +55 -3
- 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/value-objects/inception-doc-kind.ts +109 -0
- package/scripts/harness/ci-governance/domain/value-objects/integrity-target.ts +2 -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/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 +2 -2
- package/scripts/harness/config-foundation/infrastructure/presets/standard.json +2 -2
- package/scripts/harness/config-foundation/infrastructure/presets/strict.json +2 -2
- 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/value-objects/known-harness-commands.ts +3 -1
- package/scripts/harness/installation/application/checks/antigravity-hook-missing-check.ts +79 -0
- package/scripts/harness/installation/application/checks/codex-hook-missing-check.ts +70 -6
- package/scripts/harness/installation/application/checks/grok-hook-missing-check.ts +79 -0
- package/scripts/harness/installation/application/checks/husky-runtime-inactive-check.ts +33 -0
- package/scripts/harness/installation/application/named-hook-json.ts +17 -0
- package/scripts/harness/installation/application/operator-notice.ts +42 -0
- package/scripts/harness/installation/application/usecases/run-doctor-diagnostics.ts +18 -7
- package/scripts/harness/installation/application/usecases/run-install.ts +152 -52
- package/scripts/harness/installation/application/usecases/run-reconcile.ts +86 -10
- package/scripts/harness/installation/application/usecases/run-uninstall.ts +149 -25
- package/scripts/harness/installation/composition-root.ts +10 -0
- package/scripts/harness/installation/domain/agent-target.ts +39 -0
- package/scripts/harness/installation/domain/check-id.ts +5 -0
- package/scripts/harness/installation/domain/husky-runtime-state.ts +34 -0
- package/scripts/harness/installation/domain/ports/git-hooks-runtime-probe.ts +9 -0
- package/scripts/harness/installation/domain/repair-table.ts +5 -0
- package/scripts/harness/installation/infrastructure/adapters/git-hooks-runtime-probe-adapter.ts +62 -0
- package/scripts/harness/installation/presentation/cli/install-handler.ts +23 -4
- package/scripts/harness/installation/presentation/cli/reconcile-handler.ts +7 -1
- package/scripts/harness/installation/presentation/formatters/diagnostic-report-formatter.ts +27 -0
- package/scripts/harness/main.ts +202 -51
- 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 +4 -1
- package/scripts/harness/quick-mode/application/dto/change-category-classification-contract.ts +1 -1
- package/scripts/harness/quick-mode/application/dto/quick-mode-eligibility-contract.ts +1 -1
- package/scripts/harness/quick-mode/application/usecases/classify-change-category-usecase.ts +3 -1
- 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 +59 -19
- package/scripts/harness/quick-mode/domain/types/rejection-rule.ts +1 -1
- 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/harness-config-quick-mode-config-adapter.ts +83 -32
- package/scripts/harness/regression-suite/infrastructure/adapters/vitest-test-runner-adapter.ts +13 -3
- package/skills/product-architect/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/.agents/hooks.json +16 -0
- package/templates/.claude/scripts/analyze-errors-hook.sh +2 -2
- package/templates/.claude/settings.json +5 -3
- package/templates/.codex/hooks.json +2 -2
- 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
|
@@ -22,12 +22,12 @@ Command names in this document are split into three surfaces:
|
|
|
22
22
|
|
|
23
23
|
| Command | Description |
|
|
24
24
|
|---|---|
|
|
25
|
-
| `init --name <name>` | Legacy-compatible bootstrap for new projects: deploy skills, generate config, and optionally add hooks/CI. Options: `--preset <full\|standard\|minimal\|custom>`, `--skills <core\|all>`, `--agent <claude\|codex\|both>`, `--workflow <standard\|strict>`, `--language <language>`, `--with-husky`, `--with-ci`, `--yes`. `--language` writes `project.languages: ["<language>"]`; omitted language keeps the TypeScript-compatible default. <!-- @work-item-id WI-212 --> |
|
|
26
|
-
| `install --dry-run` / `--apply` | Idempotently merge PhaseGate into an existing project, preserve user content, add package scripts/devDependency, create selected
|
|
27
|
-
| `doctor` | Diagnose silent or partial installations and report repair hints (`--json`, `--strict`, `--agent <claude\|codex\|both>`, `--report-out <path>`).
|
|
25
|
+
| `init --name <name>` | Legacy-compatible bootstrap for new projects: deploy skills, generate config, and optionally add hooks/CI. Options: `--preset <full\|standard\|minimal\|custom>`, `--skills <core\|all>`, `--agent <claude\|codex\|both\|grok\|antigravity\|all>`, `--workflow <standard\|strict>`, `--language <language>`, `--with-husky`, `--with-ci`, `--yes`. `--language` writes `project.languages: ["<language>"]`; omitted language keeps the TypeScript-compatible default. <!-- @work-item-id WI-212, WI-385 --> |
|
|
26
|
+
| `install --dry-run` / `--apply` | Idempotently merge PhaseGate into an existing project, preserve user content, add package scripts/devDependency, create selected context/hooks, and write `.phasegate/manifest.json`. `--agent <claude\|codex\|both\|grok\|antigravity\|all>` selects runtime targets; `both` remains Claude + Codex and `all` selects every supported runtime. `--force` replaces managed targets after backup. <!-- @work-item-id WI-385 --> |
|
|
27
|
+
| `doctor` | Diagnose silent or partial installations and report repair hints (`--json`, `--strict`, `--agent <claude\|codex\|both\|grok\|antigravity\|all>`, `--report-out <path>`). Grok scope checks compatible matcher/timeout and emits trust guidance; Antigravity scope checks named schema/matcher/timeout and emits the CLI-only boundary. <!-- @work-item-id WI-385 --> |
|
|
28
28
|
| `uninstall --dry-run` / `--apply` | Remove PhaseGate-managed files and managed blocks using `.phasegate/manifest.json`; `--force` handles managed conflict cases. |
|
|
29
29
|
| `reconcile --dry-run` / `--apply` | Update PhaseGate-managed files to current package templates and refresh manifest hashes; `--force` allows managed-file replacement with backup. |
|
|
30
|
-
| `setup:agent` | Agent-readable setup planner and optional apply path. Options: `--intent <minimal\|recommended\|strict\|ci-only\|agent-hooks\|retrofit>`, `--agent <claude\|codex\|both>`, `--workflow <standard\|strict>`, `--with-husky`, `--with-ci`, `--dry-run`, `--apply`, `--json`. <!-- @work-item-id WI-172 --> |
|
|
30
|
+
| `setup:agent` | Agent-readable setup planner and optional apply path. Options: `--intent <minimal\|recommended\|strict\|ci-only\|agent-hooks\|retrofit>`, `--agent <claude\|codex\|both\|grok\|antigravity\|all>`, `--workflow <standard\|strict>`, `--with-husky`, `--with-ci`, `--dry-run`, `--apply`, `--json`. <!-- @work-item-id WI-172, WI-385 --> |
|
|
31
31
|
| `config:plan` | Agent-readable configuration change planner. Options: `--intent <l4-strict\|codex-hooks\|ci-fail-on-warning\|baseline-reset\|quick-mode-strict\|quick-mode-relax\|retrofit-bootstrap\|planning-mode-relax>`, `--dry-run`, `--apply`, `--json`. <!-- @work-item-id WI-173 --> <!-- @work-item-id WI-201 --> <!-- @work-item-id WI-204 --> |
|
|
32
32
|
| `session begin` / `session end` | Hook-visible Full Mode session manager. Use `session begin --mode full --unit <unit> --work-item <WI-XXX> --reason <text> --duration <ttl>` before implementation that must touch Quick Mode disallowed categories, and `session end --work-item <WI-XXX>` after completion. <!-- @work-item-id WI-206 --> |
|
|
33
33
|
| `update-skills` | Compatibility alias for `reconcile`; use `reconcile` for new automation. |
|
|
@@ -127,7 +127,7 @@ npx phasegate baseline --paths "scripts/harness/**/*.ts,src/**/*.ts"
|
|
|
127
127
|
|
|
128
128
|
| Command | Options | Description |
|
|
129
129
|
|---|---|---|
|
|
130
|
-
| `scaffold-design` | `--unit <id>` `--phase <logical\|domain\|uiux\|unit-test\|it-test>` `--force` `--json` | `templates/*.template.md` を読み取り `{{unit}}` を `--unit` 値で置換して `
|
|
130
|
+
| `scaffold-design` | `--unit <id>` `--phase <logical\|domain\|uiux\|unit-test\|it-test>` `--force` `--json` | `templates/*.template.md` を読み取り `{{unit}}` を `--unit` 値で置換して `{paths.designDocs}/{unit}/*.md` を生成する。既存ファイルは `--force` なしでは保護(exit 2)。|
|
|
131
131
|
|
|
132
132
|
### `scaffold-design` の使い方
|
|
133
133
|
|
|
@@ -146,21 +146,103 @@ npx phasegate scaffold-design --unit harness-api --phase logical --force
|
|
|
146
146
|
npx phasegate scaffold-design --unit harness-api --phase logical --json
|
|
147
147
|
```
|
|
148
148
|
|
|
149
|
-
|
|
149
|
+
生成先と対応テンプレ(生成先の `docs/product/construction` 部分は
|
|
150
|
+
`phasegate.config.json` の `paths.designDocs` に追従する。WI-369 以前は
|
|
151
|
+
ハードコードされており、`paths.designDocs` を移設した PJ では scaffold 先と
|
|
152
|
+
フェーズゲートの検査先がズレていた):
|
|
150
153
|
|
|
151
154
|
| `--phase` | 生成先 | テンプレ |
|
|
152
155
|
|---|---|---|
|
|
153
|
-
| `logical` | `
|
|
154
|
-
| `domain` | `
|
|
155
|
-
| `uiux` | `
|
|
156
|
-
| `unit-test` | `
|
|
157
|
-
| `it-test` | `
|
|
156
|
+
| `logical` | `{paths.designDocs}/{unit}/logical_design.md` | `templates/logical_design.template.md` |
|
|
157
|
+
| `domain` | `{paths.designDocs}/{unit}/domain_model.md` | `templates/domain_model.template.md` |
|
|
158
|
+
| `uiux` | `{paths.designDocs}/{unit}/uiux_design.md` | `templates/uiux_design.template.md` |
|
|
159
|
+
| `unit-test` | `{paths.designDocs}/{unit}/unit_test_design.md` | `templates/unit_test_design.template.md` |
|
|
160
|
+
| `it-test` | `{paths.designDocs}/{unit}/it_test_design.md` | `templates/it_test_design.template.md` |
|
|
158
161
|
|
|
159
162
|
exit code は `0` = 生成成功 / 上書き成功、`2` = 既存ファイルあり(`--force` 無)
|
|
160
163
|
または引数不正。
|
|
161
164
|
|
|
162
165
|
---
|
|
163
166
|
|
|
167
|
+
## Scaffold Inception (Phase Gate Level-1 Templates)
|
|
168
|
+
|
|
169
|
+
| Command | Options | Description |
|
|
170
|
+
|---|---|---|
|
|
171
|
+
| `scaffold-inception` | `--kind <doc-kind>` `--dry-run`(既定)/ `--apply` `--force` `--json` | L2 の Level-1 フェーズゲートが要求する inception plan 文書と `product_overview.md` の雛形を生成する。既存ファイルは `--force` なしでは保護(exit 2)。|
|
|
172
|
+
|
|
173
|
+
WI-368(GitHub issue #42)で導入。`scaffold-design` は `--unit` を必須とする
|
|
174
|
+
construction 文書専用で、unit 軸を持たない `_shared/*_plan.md` や product 直下の
|
|
175
|
+
文書を表現できないため、別コマンドとして分離している。
|
|
176
|
+
|
|
177
|
+
```bash
|
|
178
|
+
# 何がどこに生成されるかを確認(既定は dry-run)
|
|
179
|
+
npx phasegate scaffold-inception --kind product-overview-plan
|
|
180
|
+
|
|
181
|
+
# 実際に書き込む
|
|
182
|
+
npx phasegate scaffold-inception --kind product-overview-plan --apply
|
|
183
|
+
npx phasegate scaffold-inception --kind product-overview --apply
|
|
184
|
+
|
|
185
|
+
# 既存ファイルを意図的に上書き
|
|
186
|
+
npx phasegate scaffold-inception --kind product-overview-plan --apply --force
|
|
187
|
+
```
|
|
188
|
+
|
|
189
|
+
生成先と対応テンプレ:
|
|
190
|
+
|
|
191
|
+
| `--kind` | 生成先 | テンプレ |
|
|
192
|
+
|---|---|---|
|
|
193
|
+
| `product-overview-plan` | `{paths.inceptionDocs}/_shared/product_overview_plan.md` | `templates/product_overview_plan.template.md` |
|
|
194
|
+
| `product-overview` | `{paths.designDocs}/../product_overview.md` | `templates/product_overview.template.md` |
|
|
195
|
+
| `story-writer-plan` | `{paths.inceptionDocs}/_shared/story_writer_plan.md` | `templates/story_writer_plan.template.md` |
|
|
196
|
+
| `story-mapping-plan` | `{paths.inceptionDocs}/_shared/story_mapping_plan.md` | `templates/story_mapping_plan.template.md` |
|
|
197
|
+
| `unit-design-plan` | `{paths.inceptionDocs}/_shared/unit_design_plan.md` | `templates/unit_design_plan.template.md` |
|
|
198
|
+
|
|
199
|
+
### テンプレート = ゲート合格保証
|
|
200
|
+
|
|
201
|
+
plan テンプレートは QA セクション見出しを必ず含むため、`--apply` の生成物は
|
|
202
|
+
**無編集のまま** `planningMode: "interactive"`(既定)の Level-1 ゲートを通る。
|
|
203
|
+
この性質はラウンドトリップテストで機械的に検証されている。
|
|
204
|
+
|
|
205
|
+
`planningMode: "embedded-qa"` では `[Question]` と `[Answer]` の個数一致に加え
|
|
206
|
+
`[Answer]` に本文があることが要求されるため、生成直後の雛形は**通らない**。
|
|
207
|
+
これは意図した挙動であり、テンプレートが人間の承認証跡を偽造しないための境界。
|
|
208
|
+
|
|
209
|
+
### スコープ外の doc-kind
|
|
210
|
+
|
|
211
|
+
`user_stories.md` / `user_story_mapping.md` / `units/{unit}_unit.md` /
|
|
212
|
+
`units/integration_contract.md` と、unit スコープの plan 文書
|
|
213
|
+
(`{unit}/domain_model_plan.md` 等、Level-2 ゲート)は未収録。段階投入とする。
|
|
214
|
+
|
|
215
|
+
---
|
|
216
|
+
|
|
217
|
+
## Templates (Bundled Template Access)
|
|
218
|
+
|
|
219
|
+
| Command | Options | Description |
|
|
220
|
+
|---|---|---|
|
|
221
|
+
| `templates list` | `--json` | 同梱テンプレート名を一覧表示する。|
|
|
222
|
+
| `templates show <name>` | — | テンプレート本文を stdout に出力する。|
|
|
223
|
+
|
|
224
|
+
WI-367(GitHub issue #42)で導入。consumer プロジェクトでは phasegate は
|
|
225
|
+
`node_modules/phasegate/templates/` に入り、エージェントの sandbox が
|
|
226
|
+
`node_modules` の Read を deny していると **テンプレート実体に到達できない**。
|
|
227
|
+
`skills list` / `skills info` と同型の stdout 経路でこれを解消する。
|
|
228
|
+
|
|
229
|
+
```bash
|
|
230
|
+
npx phasegate templates list
|
|
231
|
+
npx phasegate templates show product_overview_plan
|
|
232
|
+
|
|
233
|
+
# 生成物としてそのまま保存できる(本文以外を混ぜない)
|
|
234
|
+
npx phasegate templates show logical_design > docs/product/construction/foo/logical_design.md
|
|
235
|
+
```
|
|
236
|
+
|
|
237
|
+
`<name>` は同梱テンプレートの catalog(`templates/` の readdir 結果)と
|
|
238
|
+
**完全一致照合**する。ユーザー入力文字列がパス構成要素になる経路を持たないため、
|
|
239
|
+
`../../package.json` のようなパスは exit 2 で拒否され内容も出力されない。
|
|
240
|
+
|
|
241
|
+
exit code は `0` = 成功、`2` = name 未指定 / 不正な name / 未知の name /
|
|
242
|
+
未知のサブコマンド。
|
|
243
|
+
|
|
244
|
+
---
|
|
245
|
+
|
|
164
246
|
## Work Item Migration
|
|
165
247
|
|
|
166
248
|
`docs/inception/` 配下の work item directory を **統一 `WI-XXX` レイアウト**へ移行する CLI。
|
|
@@ -1,56 +1,32 @@
|
|
|
1
1
|
# Codex CLI Integration
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
<!-- @work-item-id WI-384 -->
|
|
4
|
+
|
|
5
|
+
Phasegate supports OpenAI Codex CLI through project-local command hooks. Codex rust-v0.124.0 or newer is required for native `apply_patch` coverage; hooks are stable and enabled by default in those releases.
|
|
4
6
|
|
|
5
7
|
## Setup
|
|
6
8
|
|
|
7
|
-
|
|
9
|
+
Install or reconcile the managed Codex artifacts:
|
|
8
10
|
|
|
9
11
|
```bash
|
|
10
|
-
|
|
11
|
-
npx phasegate
|
|
12
|
-
|
|
13
|
-
# 2. Enable the Codex CLI feature flag manually
|
|
14
|
-
codex features enable hooks
|
|
15
|
-
```
|
|
16
|
-
|
|
17
|
-
For dual-agent projects (Claude + Codex), use `--agent both`.
|
|
18
|
-
|
|
19
|
-
Responsibility split:
|
|
20
|
-
|
|
21
|
-
- `phasegate init --agent codex` sets up **project-local artifacts** such as `phasegate.config.json`, `skills/`, `.codex/hooks.json`, and `.codex/skills`
|
|
22
|
-
- `codex features enable hooks` updates the **Codex CLI user environment** and is intentionally left as a manual step
|
|
23
|
-
|
|
24
|
-
### Manual setup
|
|
25
|
-
|
|
26
|
-
Alternatively, set up Codex integration manually:
|
|
27
|
-
|
|
28
|
-
#### 1. Enable hooks in Codex config
|
|
29
|
-
|
|
30
|
-
Add to `~/.codex/config.toml` (or project `.codex/config.toml`):
|
|
31
|
-
|
|
32
|
-
```toml
|
|
33
|
-
[features]
|
|
34
|
-
hooks = true
|
|
12
|
+
npx phasegate install --agent codex --with-husky --apply
|
|
13
|
+
npx phasegate doctor --agent codex
|
|
35
14
|
```
|
|
36
15
|
|
|
37
|
-
|
|
16
|
+
Use `--agent both` for projects shared with Claude Code. After `.codex/hooks.json` is created or changed, open `/hooks` in Codex and trust the current hook definition hash. Trust is stored outside the project and cannot be verified by Phasegate, so install, reconcile, and doctor print an operator notice.
|
|
38
17
|
|
|
39
|
-
|
|
18
|
+
The deprecated `phasegate init --agent codex` path remains available and prints the same minimum-version and re-trust guidance.
|
|
40
19
|
|
|
41
|
-
|
|
42
|
-
mkdir -p .codex
|
|
43
|
-
cp node_modules/phasegate/templates/.codex/hooks.json .codex/hooks.json
|
|
44
|
-
```
|
|
20
|
+
### Manual configuration
|
|
45
21
|
|
|
46
|
-
|
|
22
|
+
The canonical matcher is `Bash|apply_patch` for both events:
|
|
47
23
|
|
|
48
24
|
```json
|
|
49
25
|
{
|
|
50
26
|
"hooks": {
|
|
51
27
|
"PreToolUse": [
|
|
52
28
|
{
|
|
53
|
-
"matcher": "Bash",
|
|
29
|
+
"matcher": "Bash|apply_patch",
|
|
54
30
|
"hooks": [
|
|
55
31
|
{
|
|
56
32
|
"type": "command",
|
|
@@ -62,7 +38,7 @@ Or merge the following into your existing `.codex/hooks.json`:
|
|
|
62
38
|
],
|
|
63
39
|
"PostToolUse": [
|
|
64
40
|
{
|
|
65
|
-
"matcher": "Bash",
|
|
41
|
+
"matcher": "Bash|apply_patch",
|
|
66
42
|
"hooks": [
|
|
67
43
|
{
|
|
68
44
|
"type": "command",
|
|
@@ -71,97 +47,58 @@ Or merge the following into your existing `.codex/hooks.json`:
|
|
|
71
47
|
}
|
|
72
48
|
]
|
|
73
49
|
}
|
|
74
|
-
],
|
|
75
|
-
"Stop": [
|
|
76
|
-
{
|
|
77
|
-
"hooks": [
|
|
78
|
-
{
|
|
79
|
-
"type": "command",
|
|
80
|
-
"command": "npx phasegate hook stop",
|
|
81
|
-
"statusMessage": "phasegate: completion check",
|
|
82
|
-
"timeout": 30
|
|
83
|
-
}
|
|
84
|
-
]
|
|
85
|
-
}
|
|
86
50
|
]
|
|
87
51
|
}
|
|
88
52
|
}
|
|
89
53
|
```
|
|
90
54
|
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
Because Codex's native `apply_patch` tool does not trigger hooks (see [Codex's limitation](#known-limitations)), the pre-commit layer is the primary defense for apply_patch-based edits. Install via husky:
|
|
94
|
-
|
|
95
|
-
```bash
|
|
96
|
-
npx phasegate init --with-husky # or rerun init with this flag
|
|
97
|
-
```
|
|
98
|
-
|
|
99
|
-
## Defense Layers in Codex
|
|
100
|
-
|
|
101
|
-
Compared to Claude Code, the enforcement timing is shifted for `apply_patch`-based edits. Coverage is equivalent overall but arrives at different stages.
|
|
55
|
+
`Write` and `Edit` aliases are not included in the Codex-specific template. `apply_patch` is the canonical upstream tool name.
|
|
102
56
|
|
|
103
|
-
|
|
104
|
-
|---|---|---|
|
|
105
|
-
| Bash-based file writes (`sed -i`, `tee`, heredoc) | `PreToolUse(Bash)` — hard block | `PreToolUse(Bash)` — hard block (same) |
|
|
106
|
-
| Bash-invoked `apply_patch <<'PATCH'` | `PreToolUse(Bash)` — hard block | `PreToolUse(Bash)` — hard block (via Wave 1 `apply_patch` heredoc detection) |
|
|
107
|
-
| **Native `apply_patch` tool calls** | `PreToolUse(Write\|Edit)` — hard block | ⚠️ **Not intercepted by hooks** — deferred to pre-commit |
|
|
108
|
-
| Protected file writes | hook — immediate block | hook (Bash path) + pre-commit (commit path) |
|
|
109
|
-
| Phase-gate enforcement | hook — immediate block | hook (Bash path) + pre-commit (commit path) |
|
|
110
|
-
| Post-edit formatter / lint | `PostToolUse(Write\|Edit)` | `PostToolUse(Bash)` (partial) |
|
|
111
|
-
| Session completion check | `Stop` hook | `Stop` hook (same) |
|
|
57
|
+
## Coverage
|
|
112
58
|
|
|
113
|
-
|
|
59
|
+
| Edit path | Pre-edit hard block | Post-edit lint | Commit-time backstop |
|
|
60
|
+
|---|---|---|---|
|
|
61
|
+
| Shell writes (`sed -i`, `tee`, heredoc, `cat >`) | ✅ `PreToolUse(Bash)` | ✅ `PostToolUse(Bash)` | ✅ L2 pre-commit |
|
|
62
|
+
| Bash-invoked `apply_patch <<'PATCH'` | ✅ parsed by `BashWriteTargetExtractor` | ✅ `PostToolUse(Bash)` | ✅ L2 pre-commit |
|
|
63
|
+
| Native `apply_patch` Update/Add/Delete/Move to | ✅ `PreToolUse(apply_patch)` | ✅ `PostToolUse(apply_patch)` | ✅ L2 pre-commit |
|
|
114
64
|
|
|
115
|
-
|
|
65
|
+
For native patches, Phasegate reads raw patch text from `tool_input.command`, preserves directive order, and maps Update/Add/Delete to MODIFY/CREATE/DELETE. An Update followed by `*** Move to:` adds the source as MODIFY and the destination as CREATE. All targets join the existing protected-file, phase-gate, story-reflection, and Quick/Full Mode checks. One violating target denies the whole patch before editing.
|
|
116
66
|
|
|
117
|
-
|
|
67
|
+
PostToolUse intentionally does not parse patch targets again. It sends the event through the existing fast lint path.
|
|
118
68
|
|
|
119
|
-
|
|
69
|
+
## Hook result contract
|
|
120
70
|
|
|
121
|
-
|
|
71
|
+
- Deny: exit 2 with non-empty stderr.
|
|
72
|
+
- Continue: exit 0 with empty stdout. Informational stderr is allowed.
|
|
73
|
+
- Phasegate does not emit `permissionDecision: "ask"` because that path can fail open.
|
|
74
|
+
- Phasegate does not emit an `allow` response without `updatedInput`.
|
|
75
|
+
- Missing `tool_input.command` or a patch without `*** Begin Patch` fails closed.
|
|
122
76
|
|
|
123
|
-
|
|
124
|
-
- Violations surface at **pre-commit time** instead
|
|
125
|
-
- Feedback is delayed relative to the Claude Code experience
|
|
77
|
+
## Layered defense and residual risk
|
|
126
78
|
|
|
127
|
-
|
|
79
|
+
Command hooks are a fast path. They can be skipped until the updated definition is trusted, and project code cannot inspect Codex's external trust store. Keep `.husky/pre-commit` and CI enabled: L2 remains the commit-time backstop and CI remains the authoritative re-check.
|
|
128
80
|
|
|
129
|
-
|
|
81
|
+
Codex CLI 0.144.5 still exposes `unified_exec`, whose interception coverage is incomplete. Commands routed through an unobserved `unified_exec` path may bypass the edit-time hook; L2 pre-commit and CI remain the fallback for that residual risk.
|
|
130
82
|
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
### Windows is not supported
|
|
134
|
-
|
|
135
|
-
Codex hooks themselves do not support Windows. Phasegate follows the same constraint.
|
|
136
|
-
|
|
137
|
-
### `unified_exec` interception is incomplete
|
|
138
|
-
|
|
139
|
-
Codex documents that the newer `unified_exec` mechanism has incomplete interception. Commands routed through `unified_exec` may bypass hooks. Phasegate falls back to pre-commit for any such bypass.
|
|
140
|
-
|
|
141
|
-
## Recommended Workflow
|
|
142
|
-
|
|
143
|
-
1. **Enable all three layers**: Codex hooks + pre-commit hook + CI validation
|
|
144
|
-
2. **Commit frequently** to catch native apply_patch violations early
|
|
145
|
-
3. **Review the coverage matrix** above so you understand which edits are hard-blocked vs caught later
|
|
83
|
+
Windows Codex hooks and Codex versions older than 0.124.0 are not supported by this integration.
|
|
146
84
|
|
|
147
85
|
## Troubleshooting
|
|
148
86
|
|
|
149
|
-
###
|
|
150
|
-
|
|
151
|
-
- Verify `hooks = true` is set in `config.toml`
|
|
152
|
-
- Verify `.codex/hooks.json` is in the project root or `~/.codex/`
|
|
153
|
-
- Run `codex --version` to ensure you're on a version that supports hooks
|
|
154
|
-
|
|
155
|
-
### False positives on Bash hooks
|
|
87
|
+
### Native apply_patch is not intercepted
|
|
156
88
|
|
|
157
|
-
|
|
89
|
+
1. Run `codex --version` and confirm 0.124.0 or newer.
|
|
90
|
+
2. Confirm both matchers in `.codex/hooks.json` are `Bash|apply_patch`.
|
|
91
|
+
3. Run `npx phasegate doctor --agent codex`.
|
|
92
|
+
4. Run `npx phasegate reconcile --apply` if doctor reports stale wiring.
|
|
93
|
+
5. Open `/hooks` and trust the current definition hash.
|
|
158
94
|
|
|
159
|
-
###
|
|
95
|
+
### A patch is denied
|
|
160
96
|
|
|
161
|
-
|
|
97
|
+
Read stderr for the blocked path and recovery guidance. Full Mode changes require an active `phasegate session begin --mode full ...` authorization. Malformed or target-less native patches are denied rather than silently allowed.
|
|
162
98
|
|
|
163
|
-
## See
|
|
99
|
+
## See also
|
|
164
100
|
|
|
165
|
-
- [
|
|
166
|
-
- [
|
|
167
|
-
- [Codex
|
|
101
|
+
- [Hooks Integration](./hooks-integration.md)
|
|
102
|
+
- [Layer Model](./layer-model.md)
|
|
103
|
+
- [OpenAI Codex hooks documentation](https://developers.openai.com/codex/hooks)
|
|
104
|
+
- [openai/codex PR #18391](https://github.com/openai/codex/pull/18391)
|
|
@@ -41,7 +41,8 @@ The plan identifies target fields, managed artifacts, commands, validation, risk
|
|
|
41
41
|
"mixedCategories": true,
|
|
42
42
|
"newDomainFile": true,
|
|
43
43
|
"apiContractChange": true
|
|
44
|
-
}
|
|
44
|
+
},
|
|
45
|
+
"categoryOverrides": {} // Optional. e.g. { "docs": ["results/**", "notes/**"] }
|
|
45
46
|
},
|
|
46
47
|
"phaseDependencies": {
|
|
47
48
|
"preset": "standard", // "full" | "standard" | "minimal" | "custom" ("default" -> "full")
|
|
@@ -198,10 +199,13 @@ The five layers are:
|
|
|
198
199
|
|
|
199
200
|
| Sub-field | Type | Default | Description |
|
|
200
201
|
|------------------------|------------|-----------------------------------------|-----------------------------------------------------------------------------|
|
|
201
|
-
| `allowedCategories` | `string[]` | `["bugfix", "docs", "test", "config"]` | Change categories permitted under Quick Mode. Any category outside this list requires the full `story-implementor` workflow. |
|
|
202
|
+
| `allowedCategories` | `string[]` | `["bugfix", "docs", "test", "config"]` | Change categories permitted under Quick Mode. Any category outside this list requires the full `story-implementor` workflow. **Enum** — only `bugfix`, `docs`, `test`, `config`, `feature`, `domain`, `api` are accepted; anything else is a config error. |
|
|
202
203
|
| `maintainedLayers` | `string[]` | `["L1", "L2-002", "L2-003", "L2-014", "L3-001"]` | Exact validator IDs that remain enforced in Quick Mode. `L1` is the only layer shorthand; `L2` is not expanded. |
|
|
203
204
|
| `relaxedGates` | `string[]` | `["L2-001", "L3-002", "L3-003", "L3-004", "L4"]` | Validators/layers relaxed by Quick Mode. `L4` means all L4 validators are skipped. |
|
|
204
205
|
| `fullModeRequiredWhen` | `object` | all flags `true` | Conditions that force a Quick Mode change to escalate to the full `/story-implementor` flow. See below. |
|
|
206
|
+
| `categoryOverrides` | `object` | `{}` | Maps a change category to a list of globs, so project-specific paths land in a category the built-in table cannot infer. See below. |
|
|
207
|
+
|
|
208
|
+
The defaults above come from the defense preset declared in `project.preset`; Quick Mode resolves its effective settings through the same preset resolution as the rest of the config (ADR-040). Sub-fields you declare in `phasegate.config.json` replace the preset value for that sub-field only (arrays are replaced wholesale, not merged); sub-fields you omit keep the preset value. All three shipped presets (`minimal` / `standard` / `strict`) currently declare the same Quick Mode values, so switching the defense preset does not change Quick Mode strength today. <!-- @work-item-id WI-377 -->
|
|
205
209
|
|
|
206
210
|
##### `fullModeRequiredWhen`
|
|
207
211
|
|
|
@@ -217,6 +221,43 @@ Introduced in ISSUE-006 Story A (v0.63.0) and wired into the pre-tool-use hook b
|
|
|
217
221
|
|
|
218
222
|
Set a flag to `false` only when the project intentionally accepts the risk of merging that category of change without the design ceremony -- e.g. an early-stage prototype where new domain files are expected to churn.
|
|
219
223
|
|
|
224
|
+
##### `allowedCategories` is an enum
|
|
225
|
+
|
|
226
|
+
<!-- @work-item-id WI-373 -->
|
|
227
|
+
|
|
228
|
+
`allowedCategories` accepts only the seven `ChangeCategory` values. A misspelling such as `"typoo"` is rejected as a config error rather than silently ignored, and case is not normalised — `"Docs"` is an error, not an alias for `"docs"`, because classification keys are always lowercase and a normalised spelling would only hide the same dead setting.
|
|
229
|
+
|
|
230
|
+
If the quickMode section is invalid, the pre-tool-use hook fails **closed**: writes are blocked with an explicit "quickMode 設定が不正なため" reason until the config is fixed. (A *missing* config still fails open, so greenfield adoption is unaffected.)
|
|
231
|
+
|
|
232
|
+
##### `categoryOverrides`
|
|
233
|
+
|
|
234
|
+
<!-- @work-item-id WI-372 -->
|
|
235
|
+
|
|
236
|
+
```jsonc
|
|
237
|
+
{
|
|
238
|
+
"quickMode": {
|
|
239
|
+
"categoryOverrides": {
|
|
240
|
+
"docs": ["results/**", "notes/**"]
|
|
241
|
+
}
|
|
242
|
+
}
|
|
243
|
+
}
|
|
244
|
+
```
|
|
245
|
+
|
|
246
|
+
Keys are the seven `ChangeCategory` values; values are lists of globs matched against project-relative POSIX paths. Supported syntax is `**` (crosses `/`), `*` (does not cross `/`), and `?` (one non-`/` character); brace expansion and negation are not supported.
|
|
247
|
+
|
|
248
|
+
| Rule | Behaviour |
|
|
249
|
+
|------|-----------|
|
|
250
|
+
| Precedence | Overrides are evaluated **before** the built-in classification table, so an explicit declaration beats inference. |
|
|
251
|
+
| Downgrade guard | A path the built-in rules classify as `domain` or `api` cannot be moved to a lower-risk category; an override may only raise the risk. |
|
|
252
|
+
| Valid keys | All seven categories, including `domain` / `api` / `feature`. Assigning a path to those *hardens* the gate, since they sit outside the default `allowedCategories`. |
|
|
253
|
+
| Rejection rules | `NEW_DOMAIN` and `API_CONTRACT` remain path-based and ignore overrides entirely. Only `MIXED_CHANGES` uses the override-adjusted category. |
|
|
254
|
+
| Ties | If two categories match the same path, the higher-risk one wins, so the result never depends on JSON key order. |
|
|
255
|
+
|
|
256
|
+
Overrides apply identically to the pre-tool-use hook, `check-change-category`, and `ci-check --quick`. Leaving `categoryOverrides` unset reproduces the pre-existing classification exactly. See [Quick vs Full Mode](quick-vs-full-mode.md#overriding-the-table-for-project-specific-paths) for worked reasoning.
|
|
257
|
+
|
|
258
|
+
<!-- @work-item-id WI-380 -->
|
|
259
|
+
`categoryOverrides` goes through the same preset resolution as the other Quick Mode sub-fields (ADR-040), and merges one level deeper than they do: the merge unit is the **category key**, not the whole object. None of the three shipped presets declares `categoryOverrides`, so today whatever you write in `phasegate.config.json` is the effective value verbatim. If a preset does declare it, a category you also declare replaces that category's glob list wholesale, while categories you leave out keep the preset's globs.
|
|
260
|
+
|
|
220
261
|
<!-- @work-item-id WI-159 -->
|
|
221
262
|
Quick Mode uses exact validator IDs for `maintainedLayers`. To keep all L2 validators active, list `L2-001`, `L2-002`, `L2-003`, `L2-013`, `L2-014`, and `L2-015` explicitly. The default keeps metadata, test-quality, work-item status, and security checks active while skipping phase-gate, CLI E2E coverage, contract traceability coverage, performance, coverage, nyquist, and L4 scheduled validators.
|
|
222
263
|
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
# Grok Build Integration
|
|
2
|
+
|
|
3
|
+
<!-- @work-item-id WI-385 -->
|
|
4
|
+
|
|
5
|
+
Phasegate uses Grok Build's Claude-compatible project hook scanner. It manages `.claude/settings.json` as the single hook source and deliberately does not create `.grok/hooks`, avoiding duplicate invocation.
|
|
6
|
+
|
|
7
|
+
Minimum supported runtime: the hook-capable Grok CLI 1.0.0 series, which is the series used to verify this integration. If hooks appear to be silently inactive, run `grok inspect` and confirm the project hook is loaded and trusted in `/hooks`.
|
|
8
|
+
|
|
9
|
+
## Setup
|
|
10
|
+
|
|
11
|
+
```bash
|
|
12
|
+
npx phasegate install --agent grok --with-husky --apply
|
|
13
|
+
npx phasegate doctor --agent grok
|
|
14
|
+
```
|
|
15
|
+
|
|
16
|
+
The managed PreToolUse entries collectively match `Bash|Write|Edit|apply_patch`; each Phasegate command has an explicit 30-second timeout. Grok otherwise defaults a hook to 5 seconds and fails open when the hook times out or crashes, so the distributed timeout gives Phasegate enough time to inspect a write while L2 pre-commit remains the backstop. `run_terminal_command`, `search_replace`, `write`, and `apply_patch` camelCase payloads are normalized to the existing Bash/Write/Edit/patch pipeline. Grok truncates tool input at 128 KB; a truncated command or patch is denied because the full target set cannot be proven. A direct tool with a complete path can still be checked.
|
|
17
|
+
|
|
18
|
+
## Result contract
|
|
19
|
+
|
|
20
|
+
- Deny writes top-level `{ "decision": "deny", "reason": ... }` and Claude-compatible `hookSpecificOutput` to stdout, writes the reason to stderr, and exits 2.
|
|
21
|
+
- Allow exits 0 with empty stdout and does not override permission.
|
|
22
|
+
- Agent/model fields and the selected install target are not authorization inputs.
|
|
23
|
+
|
|
24
|
+
## Trust and residual risk
|
|
25
|
+
|
|
26
|
+
Project hooks can be skipped before trust is approved, and Phasegate cannot inspect Grok's external trust state. Run `grok inspect`, open `/hooks`, and approve with `--trust` or `/hooks-trust`. Keep L2 pre-commit and CI enabled because timeout/crash remains fail-open even with the explicit 30-second limit. The canonical path key for every future Grok `write` variant remains runtime-controlled; unknown supported-write shapes fail closed rather than silently allowing.
|
|
@@ -6,17 +6,28 @@ Phasegate integrates natively with Claude Code through its hooks system. This en
|
|
|
6
6
|
|
|
7
7
|
For new or existing projects, prefer `npx phasegate install --dry-run` followed by `npx phasegate install --apply` so existing hook JSON is merged instead of replaced. Manual editing is still possible, but then `phasegate doctor` may report missing managed targets until the expected PhaseGate entries, skill links, Husky scripts, CI workflow, and manifest are present. See [Setup Artifacts](setup-artifacts.md). <!-- @work-item-id WI-152 --> <!-- @work-item-id WI-169 -->
|
|
8
8
|
|
|
9
|
-
|
|
9
|
+
### Manual hook configuration
|
|
10
|
+
|
|
11
|
+
If structured install is unavailable, use the same packaged commands and timeout as the distributed `.claude/settings.json`:
|
|
10
12
|
|
|
11
13
|
```jsonc
|
|
12
14
|
{
|
|
13
15
|
"hooks": {
|
|
14
16
|
"PreToolUse": [
|
|
17
|
+
{
|
|
18
|
+
"matcher": "Bash|apply_patch",
|
|
19
|
+
"hooks": [{
|
|
20
|
+
"type": "command",
|
|
21
|
+
"command": "npx phasegate hook pre-tool-use",
|
|
22
|
+
"timeout": 30
|
|
23
|
+
}]
|
|
24
|
+
},
|
|
15
25
|
{
|
|
16
26
|
"matcher": "Write|Edit",
|
|
17
27
|
"hooks": [{
|
|
18
28
|
"type": "command",
|
|
19
|
-
"command": "npx
|
|
29
|
+
"command": "npx phasegate hook pre-tool-use",
|
|
30
|
+
"timeout": 30
|
|
20
31
|
}]
|
|
21
32
|
}
|
|
22
33
|
],
|
|
@@ -25,7 +36,7 @@ Add the following to `.claude/settings.json`:
|
|
|
25
36
|
"matcher": "Write|Edit",
|
|
26
37
|
"hooks": [{
|
|
27
38
|
"type": "command",
|
|
28
|
-
"command": "npx
|
|
39
|
+
"command": "npx phasegate hook post-tool-use"
|
|
29
40
|
}]
|
|
30
41
|
}
|
|
31
42
|
],
|
|
@@ -34,7 +45,7 @@ Add the following to `.claude/settings.json`:
|
|
|
34
45
|
"matcher": "",
|
|
35
46
|
"hooks": [{
|
|
36
47
|
"type": "command",
|
|
37
|
-
"command": "npx
|
|
48
|
+
"command": "npx phasegate hook stop"
|
|
38
49
|
}]
|
|
39
50
|
}
|
|
40
51
|
]
|
|
@@ -42,6 +53,18 @@ Add the following to `.claude/settings.json`:
|
|
|
42
53
|
}
|
|
43
54
|
```
|
|
44
55
|
|
|
56
|
+
## Runtime coverage matrix
|
|
57
|
+
|
|
58
|
+
<!-- @work-item-id WI-385 -->
|
|
59
|
+
|
|
60
|
+
| Runtime payload | Managed source | Pre-edit deny output | Coverage boundary |
|
|
61
|
+
|---|---|---|---|
|
|
62
|
+
| Claude / Codex flat snake_case | `.claude/settings.json` / `.codex/hooks.json` | empty stdout, stderr, exit 2 | Existing contract unchanged |
|
|
63
|
+
| Grok flat camelCase | Claude-compatible `.claude/settings.json` | top-level deny plus `hookSpecificOutput`, stderr, exit 2 | Trust must be checked with `grok inspect` / `/hooks` |
|
|
64
|
+
| Antigravity nested `toolCall` | named `.agents/hooks.json` | top-level `decision` / `reason`, stderr, exit 2 | Hard block supported for `agy` CLI only |
|
|
65
|
+
|
|
66
|
+
All allow paths keep stdout empty and do not override runtime permission. Malformed, ambiguous, truncated command/patch, or supported write tools without extractable targets fail closed. L2 pre-commit and CI remain the backstops for untrusted/skipped hooks, Antigravity IDE/desktop, and unverified timeout/crash behavior.
|
|
67
|
+
|
|
45
68
|
## Hook Behaviors
|
|
46
69
|
|
|
47
70
|
### Responsibility Separation (important)
|
|
@@ -36,7 +36,7 @@ npm install
|
|
|
36
36
|
npx phasegate init --name <project-name>
|
|
37
37
|
```
|
|
38
38
|
|
|
39
|
-
This deploys 29 skills to `skills/`, creates the agent-facing skill links (
|
|
39
|
+
This deploys 29 skills to `skills/`, creates the selected agent-facing skill links (`.claude/skills/`, `.codex/skills/`, or `.agents/skills/`), and generates `phasegate.config.json`.
|
|
40
40
|
|
|
41
41
|
`init` is the legacy-compatible bootstrap path for new projects. It also runs the structured install path for the selected agent target so `CLAUDE.md` and/or `AGENTS.md` receive a PhaseGate managed section. Use `install` when the project may already have hooks, package scripts, or CI files that should be preserved. <!-- @work-item-id WI-174 -->
|
|
42
42
|
|
|
@@ -56,7 +56,9 @@ npx phasegate install --apply
|
|
|
56
56
|
npx phasegate doctor
|
|
57
57
|
```
|
|
58
58
|
|
|
59
|
-
`install --dry-run` reports whether each target will be created, merged, skipped, or refused. `install --apply` performs the merge, adds package scripts and the `phasegate` devDependency, deploys selected bundled skills to root `skills/`, creates `.claude/skills
|
|
59
|
+
`install --dry-run` reports whether each target will be created, merged, skipped, or refused. `install --apply` performs the merge, adds package scripts and the `phasegate` devDependency, deploys selected bundled skills to root `skills/`, creates the selected `.claude/skills`, `.codex/skills`, and `.agents/skills` links, writes `CLAUDE.md` / `AGENTS.md` managed sections for selected agent targets, writes `.github/workflows/phasegate-aidlc-gate.yml` when CI is enabled, and records managed entries in `.phasegate/manifest.json`. Husky hook targets (`.husky/*`) and the GitHub Actions target are opt-in, matching `init` and `setup:agent`: pass `--with-husky` and/or `--with-ci` to include them — without these flags `install` does not touch `.husky/` or `.github/workflows/`. <!-- @work-item-id WI-316 --> Existing skills catalogs are merged: PhaseGate refreshes only bundled skill directories selected by `--skills core|all` and preserves user-owned skills. See [Setup Artifacts](setup-artifacts.md) for the full managed target, generated artifact, runtime state, legacy artifact, and user-level setting inventory. <!-- @work-item-id WI-152 --> <!-- @work-item-id WI-169 --> <!-- @work-item-id WI-174 --> <!-- @work-item-id WI-216 -->
|
|
60
|
+
|
|
61
|
+
Agent targets are `claude | codex | both | grok | antigravity | all`. `both` is backward-compatible Claude + Codex. Grok shares `.claude/settings.json` and `.claude/skills`, receives `AGENTS.md` without Claude-only `CLAUDE.md`, and does not receive `.grok/hooks`. Antigravity receives `.agents/hooks.json`, `.agents/skills`, and `AGENTS.md`. `all` installs Claude, Codex, and Antigravity surfaces, with Grok covered once by the Claude-compatible hook. <!-- @work-item-id WI-385 -->
|
|
60
62
|
|
|
61
63
|
For personal evaluation inside a team-owned repository:
|
|
62
64
|
|
|
@@ -77,6 +77,7 @@ The classifier is **path-based, not intent-based**. It never reads your commit m
|
|
|
77
77
|
|
|
78
78
|
| Order | Match | Category |
|
|
79
79
|
|---|---|---|
|
|
80
|
+
| 0 | `quickMode.categoryOverrides` glob match (see below) | the configured category |
|
|
80
81
|
| 1 | `*.config.json`, `*.config.ts`, `phasegate.config.json` | `config` |
|
|
81
82
|
| 2 | `.github/workflows/*.yml`, `.github/workflows/*.yaml` | `config` |
|
|
82
83
|
| 3 | Repo-root bootstrap files: `.gitignore`, `.gitattributes`, `.editorconfig`, `.npmrc`, `.nvmrc`, `tsconfig.json`, `tsconfig.*.json`, anything under `.husky/` | `config` |
|
|
@@ -96,6 +97,38 @@ Two consequences worth internalising:
|
|
|
96
97
|
|
|
97
98
|
When the hook blocks a write, the message now names the deciding category and change kind per path (`foo.ts (category=feature, changeKind=CREATE)`), and — for `bugfix` / `docs` / `test` / `config` blocks — points at `allowedCategories` and `config:plan --intent quick-mode-relax` rather than at `/story-implementor`. <!-- @work-item-id WI-352 --> <!-- @work-item-id WI-354 -->
|
|
98
99
|
|
|
100
|
+
### Overriding the table for project-specific paths
|
|
101
|
+
|
|
102
|
+
<!-- @work-item-id WI-372 -->
|
|
103
|
+
|
|
104
|
+
The built-in table has no knowledge of your project's own conventions. A directory such as `results/` or `notes/` holds documents, but the classifier sees an unknown path: `MODIFY` falls through to `bugfix`, and `CREATE` falls through to `feature` — a category that cannot be added to `allowedCategories` at all, so the write is permanently Full Mode.
|
|
105
|
+
|
|
106
|
+
`quickMode.categoryOverrides` maps a category to a list of globs:
|
|
107
|
+
|
|
108
|
+
```jsonc
|
|
109
|
+
{
|
|
110
|
+
"quickMode": {
|
|
111
|
+
"allowedCategories": ["bugfix", "docs", "test", "config"],
|
|
112
|
+
"categoryOverrides": {
|
|
113
|
+
"docs": ["results/**", "notes/**"]
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
Four rules govern how overrides interact with the table above:
|
|
120
|
+
|
|
121
|
+
1. **Overrides are evaluated first — order 0 in the table.** They are an explicit declaration about your repository, so they beat inference. Without this, `notes/deploy.config.json` would still be caught by rule 1 and the setting would look broken.
|
|
122
|
+
2. **Overrides cannot downgrade `domain` or `api`.** If the built-in rules classify a path as `domain` (rule 7) or `api` (rule 5), an override may only raise the risk, never lower it. `{"docs": ["scripts/**"]}` will *not* turn a domain file into a doc. The weakening vector is closed by construction, not by convention.
|
|
123
|
+
3. **All seven categories are valid override keys**, including `domain`, `api`, and `feature`. Assigning a path to one of those only makes the gate harder to pass, since they sit outside the default `allowedCategories` — it is a hardening lever, e.g. `{"domain": ["packages/core/**"]}`.
|
|
124
|
+
4. **`NEW_DOMAIN` and `API_CONTRACT` still apply.** The three rejection rules stay path-based and ignore overrides entirely, so a misconfigured override cannot let a new domain file or a port/adapter change slip through. Only `MIXED_CHANGES` consumes the override-adjusted category.
|
|
125
|
+
|
|
126
|
+
If two override categories match the same path, the higher-risk one wins, so the result never depends on JSON key order.
|
|
127
|
+
|
|
128
|
+
Supported glob syntax is deliberately small: `**` (crosses `/`), `*` (does not cross `/`), and `?` (one non-`/` character). Brace expansion and negation are not supported. Patterns are matched against project-relative POSIX paths.
|
|
129
|
+
|
|
130
|
+
Overrides apply identically to all three consumers — the PreToolUse hook, `check-change-category`, and `ci-check --quick` — because they share one config load. With `categoryOverrides` unset the classification is exactly what it was before the feature existed.
|
|
131
|
+
|
|
99
132
|
### Dry-running the classifier
|
|
100
133
|
|
|
101
134
|
Use `check-change-category` to evaluate an arbitrary file list without actually starting an implementation:
|
|
@@ -193,7 +226,9 @@ Stop, commit nothing, and re-launch `/story-implementor`. Don't try to "finish i
|
|
|
193
226
|
Not by emptying the list — `allowedCategories: []` is rejected as invalid config (`allowedCategories must not be empty`), so it breaks the hook rather than tightening it. Narrow it instead: `allowedCategories: ["docs"]` routes effectively everything through Full Mode while staying valid. Alternatively, leave the categories as-is and set every `quickMode.fullModeRequiredWhen.*` flag to `true` (the default) so any non-trivial scope automatically escalates.
|
|
194
227
|
|
|
195
228
|
**Q. Can I add custom categories?**
|
|
196
|
-
No. `allowedCategories` accepts only values from a fixed enum — the seven `ChangeCategory` values `bugfix`, `docs`, `test`, `config`, `feature`, `domain`, `api`. The default allow-list is the first four; the remaining three exist so that a project can *deliberately* widen the gate (rarely a good idea), not so you can invent a new label.
|
|
229
|
+
No. `allowedCategories` accepts only values from a fixed enum — the seven `ChangeCategory` values `bugfix`, `docs`, `test`, `config`, `feature`, `domain`, `api`. The default allow-list is the first four; the remaining three exist so that a project can *deliberately* widen the gate (rarely a good idea), not so you can invent a new label. The enum is enforced by both the config schema and `QuickModeConfig`, so a misspelling is a loud config error, not a setting that quietly never matches. <!-- @work-item-id WI-373 -->
|
|
230
|
+
|
|
231
|
+
What you *can* customise is which paths map to which of those seven categories — see [Overriding the table for project-specific paths](#overriding-the-table-for-project-specific-paths). If your workflow needs a category outside the enum, that is evidence the change is probably Full Mode material.
|
|
197
232
|
|
|
198
233
|
---
|
|
199
234
|
|