phasegate 0.152.1 → 0.152.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (25) hide show
  1. package/CHANGELOG.md +12 -0
  2. package/README.md +22 -9
  3. package/docs/guide/cli-reference.md +58 -16
  4. package/docs/guide/configuration.md +17 -2
  5. package/docs/guide/hooks-integration.md +8 -0
  6. package/docs/guide/layer-model.md +23 -5
  7. package/package.json +1 -1
  8. package/scripts/harness/ci-governance/infrastructure/adapters/validator-id-registry-adapter.ts +1 -1
  9. package/scripts/harness/config-foundation/domain/harness-config.ts +1 -0
  10. package/scripts/harness/harness-api/infrastructure/adapters/harness-config-query-adapter.ts +1 -0
  11. package/scripts/harness/main.ts +1 -0
  12. package/scripts/harness/phase-dependency-model/domain/values/artifact.ts +1 -0
  13. package/scripts/harness/phase2-extensions/infrastructure/adapters/git-log-document-age-adapter.ts +1 -0
  14. package/scripts/harness/phase2-extensions/infrastructure/adapters/git-log-initial-creation-age-adapter.ts +1 -0
  15. package/scripts/harness/setup/skill-deployer.ts +2 -0
  16. package/scripts/harness/skill-quality/infrastructure/adapters/git-commit-executor-adapter.ts +1 -0
  17. package/scripts/harness/traceability-model/composition-root.ts +1 -0
  18. package/scripts/harness/traceability-model/domain/ports/work-item-migration-source-port.ts +1 -0
  19. package/scripts/harness/traceability-model/domain/services/work-item-migration-planner.ts +1 -0
  20. package/scripts/harness/traceability-model/infrastructure/gateways/file-system-work-item-migration-source-gateway.ts +1 -0
  21. package/scripts/harness/traceability-model/infrastructure/gateways/markdown-story-catalog-gateway.ts +1 -0
  22. package/scripts/harness/validator-system/infrastructure/adapters/ast-performance-scanner-adapter.ts +1 -0
  23. package/scripts/harness/validator-system/infrastructure/adapters/file-system-security-pattern-scanner-adapter.ts +1 -0
  24. package/scripts/harness/validator-system/infrastructure/adapters/import-graph-source-analysis-adapter.ts +5 -2
  25. package/scripts/harness/validator-system/infrastructure/adapters/markdown-design-document-adapter.ts +1 -0
package/CHANGELOG.md CHANGED
@@ -7,6 +7,18 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
7
7
 
8
8
  ## [Unreleased]
9
9
 
10
+ ## [0.152.3] - 2026-05-12
11
+
12
+ ### Fixed
13
+
14
+ - **Historical WI status closure / WI-012 / WI-027 / WI-035 / WI-036 / WI-085 / WI-086 / WI-087 / WI-088 / WI-089 / WI-090 / WI-091 / WI-092 / WI-093 / WI-096** — completes missing product reflection and implementation traceability evidence for the remaining targeted historical WI backlog, then applies derived statuses for fix/chore items so the target set no longer reports stale.
15
+
16
+ ## [0.152.2] - 2026-05-12
17
+
18
+ ### Fixed
19
+
20
+ - **WI status evidence closure / WI-119 / WI-120 / WI-121 / WI-127 / WI-128** — adds missing implementation/test traceability annotations and applies derived WI statuses so the remaining G1/G5 backlog items no longer report stale or reflected-only status.
21
+
10
22
  ## [0.152.1] - 2026-05-12
11
23
 
12
24
  ### Fixed
package/README.md CHANGED
@@ -492,40 +492,53 @@ Because Codex's native `apply_patch` tool is routed through an internal `ApplyPa
492
492
 
493
493
  ## CLI Reference
494
494
 
495
+ <!-- @work-item-id WI-150 -->
496
+
495
497
  ```bash
496
498
  npx phasegate <command> [options]
497
499
  ```
498
500
 
501
+ README keeps only the entry points most users need. The full public/compatibility/internal catalog, including commands shown by `phasegate --help`, lives in [CLI Reference](docs/guide/cli-reference.md).
502
+
499
503
  | Command | Description |
500
504
  |---|---|
501
- | `init --name <name>` | Legacy-compatible bootstrap for new projects: deploy skills, generate config, and optionally add hooks/CI. Prefer `install` when the project may already have hooks, scripts, or CI files. |
502
- | `install --dry-run` / `--apply` | Idempotently merge PhaseGate into the current project, preserve existing user content, add package scripts/devDependency, and write `.phasegate/manifest.json`. |
503
- | `doctor` | Diagnose silent or partial installations and report repair hints (`--json`, `--strict`, `--report-out <path>`). |
505
+ | `init --name <name>` | Legacy-compatible bootstrap for new projects. Supports `--skills <core\|all>`, `--agent <claude\|codex\|both>`, `--with-husky`, `--with-ci`, and `--yes`. Prefer `install` when the project may already have hooks, scripts, or CI files. |
506
+ | `install --dry-run` / `--apply` | Idempotently merge PhaseGate into the current project, preserve existing user content, add package scripts/devDependency, and write `.phasegate/manifest.json`. Use `--force` only for managed-file replacement. |
507
+ | `doctor` | Diagnose silent or partial installations (`--json`, `--strict`, `--report-out <path>`). `--report-out` is an explicit file path, not `reporting.outputDir`. |
504
508
  | `uninstall --dry-run` / `--apply` | Remove PhaseGate-managed files and managed blocks using `.phasegate/manifest.json`, preserving user content. |
505
509
  | `reconcile --dry-run` / `--apply` | Update PhaseGate-managed files to the current package templates and refresh manifest hashes. |
506
- | `lint` | Run L1 Biome AST checks |
507
- | `validate --layer <L1-L4\|all>` | Run validators for specified layer (`--layer L0` prints runtime hook guidance; explicit L4 runs even when scheduled L4 is disabled) |
508
- | `ci-check` | Full CI check (L2-L4; disabled L4 is reported as skipped) |
510
+ | `lint` / `phasegate:lint` | Run L1 Biome AST checks. The `phasegate:*` form is a binary subcommand, not an npm script unless `package.json` defines it locally. |
511
+ | `validate --layer <L1-L4\|all>` | Run validators for the specified layer (`--layer L0` prints runtime hook guidance). `--fail-on-warning` / `--no-fail-on-warning` override config. |
512
+ | `ci-check` | Full CI check (L2-L4; disabled L4 is reported as skipped). Supports `--quick`, `--fail-on-reject`, `--dry-run`, and `--files`. |
509
513
  | `ci:generate-template --type <aidlc-gate\|consistency-check\|pre-commit\|agent-context-refresh> --render` | Render the bundled CI/hook template to stdout |
510
514
  | `ci:auto-refresh-agent-context --dry-run` / `--apply` | Refresh AGENTS.md pointers and CLAUDE.md standard sections |
511
515
  | `refresh-claude-md --dry-run` / `--apply` | Refresh only CLAUDE.md while preserving the user-owned section |
512
516
  | `p2:check-agent-context` | Check AGENTS.md / CLAUDE.md freshness |
513
517
  | `update-skills` | Compatibility alias for `reconcile` |
514
- | `phasegate:status` | Display overall harness health summary |
518
+ | `phasegate:status --json` | Display overall harness health summary, including configuration, cached artifact, and live validation state where available |
519
+ | `phasegate:detect-drift --json` | Design/code drift summary. Drift findings are advisory unless strict warning handling is enabled. |
515
520
  | `work-items:status --dry-run` / `--apply` | Derive WI status from artifacts and optionally update stale `description.md` frontmatter. Apply refuses downgrades unless `--allow-downgrade` is supplied. |
516
521
  | `phasegate:check-phase --unit <id>` | Check current phase for a Unit |
517
522
  | `check-change-category --paths <csv>` | Classify changed files into Quick Mode categories and report whether Full Mode is required (`--format json`, `--fail-on-full-required`) |
518
523
  | `baseline` | Create `.phasegate/baseline.json` snapshot for Phase A-2 retrofit grandfather (`--dry-run`, `--force`, `--paths <glob,glob,...>`, `--json`). `baseline.enabled` defaults to `true` since v0.71.0. |
519
524
  | `scaffold-design --unit <id> --phase <logical\|domain\|uiux\|unit-test\|it-test>` | Generate minimum viable design doc from `templates/*.template.md` into `docs/product/construction/{unit}/*.md` (`--force`, `--json`). Materializes the `scaffold: ...` line emitted by phase-gate errors. |
525
+ | `scaffold-wi <unit> <type>` | Create `docs/inception/{unit}/WI-XXX/description.md` using the next free WI number. |
526
+ | `emit-agent-rules` | Print the AGENTS.md / CLAUDE.md WI workflow rules block. |
520
527
  | `list-errors --layer <L0-L4>` | List error definitions with fix examples |
521
- | `hook <pre-tool-use\|post-tool-use\|stop>` | Run a Claude Code hook (reads JSON from stdin) |
528
+ | `hook <pre-tool-use\|post-tool-use\|stop\|session-start\|user-prompt-submit>` | Run an agent hook (reads JSON from stdin; session-start/user-prompt-submit write JSON context) |
522
529
  | `pre-commit` | Run L2 pre-commit validators on staged files |
523
530
  | `bypass:audit --base <ref> [--head <ref>]` | Replay pre-commit validation over a push/CI range and require structured bypass evidence for gate failures |
524
531
  | `delegate-sonnet [...args]` | Delegate task to Sonnet 4.6 (transparent wrapper) |
525
532
  | `migrate work-items --dry-run` / `--apply` | Migrate legacy `ISSUE-XXX` / `H{NN}-{NN}` directories under `docs/inception/` to the unified `WI-XXX` layout (frontmatter `type` / `legacy_id` / `affects` injected). Sequential allocator skips numbers already used by existing WIs. See [CLI Reference -- Work Item Migration](docs/guide/cli-reference.md#work-item-migration). |
526
533
  | `migrate --schema v3` | Upgrade `phasegate.config.json` to v3 schema by adding the `architecture` key (idempotent). |
527
534
 
528
- See the [Japanese README](README.ja.md) for the complete CLI reference.
535
+ ### L4 warnings and strictness
536
+
537
+ <!-- @work-item-id WI-151 -->
538
+
539
+ Standard projects keep `layers.L4.enabled: false`; `validate --layer all` and `phasegate:ci-check` report disabled L4 validators as skipped. Explicit `validate --layer L4` runs the scheduled validators on demand. Warning-only L4 drift/consistency/dead-code findings remain advisory unless `validate.failOnWarning: true`, the `strict` preset, or `--fail-on-warning` is used. Use that strict mode only after the project has real drift keys, consistency targets, pointer/freshness ownership, and semantic drift coverage.
540
+
541
+ See the [CLI Reference](docs/guide/cli-reference.md) for the complete catalog and the [Japanese README](README.ja.md) for Japanese-language onboarding.
529
542
 
530
543
  ---
531
544
 
@@ -6,22 +6,42 @@ Entry point:
6
6
  npx phasegate <command> [options]
7
7
  ```
8
8
 
9
+ <!-- @work-item-id WI-150 -->
10
+
11
+ Command names in this document are split into three surfaces:
12
+
13
+ | Surface | How to run | Contract |
14
+ |---|---|---|
15
+ | Binary subcommand | `npx phasegate <command>` | Public CLI shipped by the package. This includes `phasegate:*` compatibility subcommands shown by `phasegate --help`. |
16
+ | npm script | `npm run <script>` / `pnpm <script>` | Only available when the consuming project's `package.json` defines that script. The package itself currently defines `phasegate`, `phasegate:status`, `phasegate:enable`, `phasegate:disable`, `phasegate:check-phase`, `phasegate:check-ready`, and `harness:*` aliases. |
17
+ | Internal / compatibility | `npx phasegate <command>` | Supported for migration, dogfooding, or legacy workflows; prefer the canonical command listed in the description when one exists. |
18
+
9
19
  ---
10
20
 
11
21
  ## Setup
12
22
 
13
23
  | Command | Description |
14
24
  |---|---|
15
- | `init --name <name>` | Legacy-compatible bootstrap for new projects: deploy skills, generate config, and optionally add hooks/CI |
16
- | `install --dry-run` / `--apply` | Idempotently merge PhaseGate into an existing project, preserve user content, add package scripts/devDependency, and write `.phasegate/manifest.json` |
17
- | `doctor` | Diagnose silent or partial installations and report repair hints (`--json`, `--strict`, `--report-out <path>`) |
18
- | `uninstall --dry-run` / `--apply` | Remove PhaseGate-managed files and managed blocks using `.phasegate/manifest.json` |
19
- | `reconcile --dry-run` / `--apply` | Update PhaseGate-managed files to current package templates and refresh manifest hashes |
20
- | `update-skills` | Compatibility alias for `reconcile` |
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>`, `--with-husky`, `--with-ci`, `--yes`. |
26
+ | `install --dry-run` / `--apply` | Idempotently merge PhaseGate into an existing project, preserve user content, add package scripts/devDependency, and write `.phasegate/manifest.json`. `--force` replaces managed targets after backup. |
27
+ | `doctor` | Diagnose silent or partial installations and report repair hints (`--json`, `--strict`, `--report-out <path>`). `--report-out` writes exactly to the supplied path, not to `reporting.outputDir`. |
28
+ | `uninstall --dry-run` / `--apply` | Remove PhaseGate-managed files and managed blocks using `.phasegate/manifest.json`; `--force` handles managed conflict cases. |
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
+ | `update-skills` | Compatibility alias for `reconcile`; use `reconcile` for new automation. |
31
+ | `scaffold-wi <unit> <type>` | Create `docs/inception/{unit}/WI-XXX/description.md` using the next free WI number. |
32
+ | `emit-agent-rules` | Print the AGENTS.md / CLAUDE.md WI workflow rules block. |
21
33
  | `list-features` | List available features |
22
34
  | `enable-feature <name>` | Enable a feature |
23
35
  | `disable-feature <name>` | Disable a feature |
24
36
 
37
+ ### Setup JSON and report outputs
38
+
39
+ <!-- @work-item-id WI-158 -->
40
+
41
+ Setup lifecycle commands support JSON for automation where shown by help: `install --json`, `reconcile --json`, `uninstall --json`, and `doctor --json`. `doctor --report-out <path>` persists the doctor JSON payload to that exact path. Relative paths are resolved from the project root; absolute paths are used as-is.
42
+
43
+ This is separate from `reporting.outputDir`. The configured report directory is used by phase-dependency / phase-gate reporting, while regression-suite result files are fixed under `reports/regression/` and status/drift JSON is emitted to stdout.
44
+
25
45
  ---
26
46
 
27
47
  ## Quality Checks
@@ -29,8 +49,8 @@ npx phasegate <command> [options]
29
49
  | Command | Options | Description |
30
50
  |---|---|---|
31
51
  | `lint` | `--target <path>` `--json` | L1 Biome AST check |
32
- | `validate` | `--layer L1\|L2\|L3\|L4\|all` `--unit <name>` `--format human\|agent\|ci` | L2-L4 validators |
33
- | `ci-check` | `--quick` `--fail-on-reject` `--dry-run` `--files` | Full CI check (L2-L4) |
52
+ | `validate` | `--layer L0\|L1\|L2\|L3\|L4\|all` `--unit <name>` `--format human\|agent\|ci` `--fail-on-warning` `--no-fail-on-warning` `--no-l4` | Validators. `--layer L0` prints runtime hook guidance. Explicit `--layer L4` runs L4 on demand; `all` and CI-style execution honor disabled L4 unless overridden by command-specific behavior. |
53
+ | `ci-check` | `--quick` `--fail-on-reject` `--dry-run` `--files` | Full CI check (L2-L4). `--quick` applies Quick Mode relaxation policy, `--fail-on-reject` turns a rejected quick decision into a failing exit, `--dry-run` reports without enforcing, and `--files` supplies the changed-file set. |
34
54
  | `validate-metadata <files>` | | Validate implementation metadata |
35
55
  | `check-phase-gate` | `--level 1\|2\|3` | Phase gate check |
36
56
 
@@ -258,7 +278,9 @@ unit-scoped WI(H-ID 由来)の reflection check でも継続認識される
258
278
 
259
279
  ## Harness API
260
280
 
261
- Commands exposed as npm scripts (`npm run <command>`).
281
+ <!-- @work-item-id WI-150 -->
282
+
283
+ The following are binary subcommands (`npx phasegate <command>`). Do not assume they are npm scripts unless the consuming project defines a matching `package.json` script. In this package, only `phasegate:status`, `phasegate:check-ready`, and `phasegate:check-phase` are currently exposed as package scripts among the `phasegate:*` commands.
262
284
 
263
285
  | Command | Options | Description |
264
286
  |---|---|---|
@@ -270,6 +292,23 @@ Commands exposed as npm scripts (`npm run <command>`).
270
292
  | `phasegate:lint` | `--target <path>` `--json` | Lint via harness-api |
271
293
  | `phasegate:complete-check` | `--json` | L2-L4 full check |
272
294
  | `phasegate:impact-analysis` | `<storyId>` `--json` | Story impact analysis |
295
+ | `phasegate:generate-matrix` | `--requirements <path>` `--tests <path>` `--out <path>` `--json` | Generate the requirement-test matrix |
296
+
297
+ ### Status and drift JSON semantics
298
+
299
+ <!-- @work-item-id WI-151 -->
300
+
301
+ `phasegate:status --json` is intended for humans, CI, and agents that need to distinguish configured intent from observed results. Layer entries may include:
302
+
303
+ | Key | Meaning | How to use it |
304
+ |---|---|---|
305
+ | `configurationState` | Whether the layer is enabled by resolved config (`enabled` / `disabled`) | Use this to explain why a layer should run or be skipped. |
306
+ | `cachedArtifactState` | Whether a previously generated artifact/report is present (`present` / `missing`) | Use this to decide whether a report needs to be generated before relying on cached evidence. `missing` means no artifact exists; it is not the same as a validator limitation. |
307
+ | `liveValidationState` | Result of the current live check (`pass` / `fail` / `skipped`) | Use this as the current gate signal. `skipped` usually follows disabled configuration. |
308
+
309
+ `phasegate:detect-drift --json` returns drift findings from live design/code comparison. A finding with a real mismatch is different from a validator `limitation`: `missing` means expected evidence or artifacts were absent, while `limitation` means the validator cannot currently prove the condition and should be treated as advisory until coverage is improved.
310
+
311
+ L4 warning findings fail the process only when warning strictness is enabled (`validate.failOnWarning: true`, the `strict` preset, or `--fail-on-warning`). `--no-fail-on-warning` forces advisory behavior for the current command.
273
312
 
274
313
  ---
275
314
 
@@ -334,15 +373,17 @@ ISSUE-005 P3-10 で明確化された境界:
334
373
 
335
374
  ## Regression Tests
336
375
 
376
+ <!-- @work-item-id WI-150, WI-158 -->
377
+
337
378
  | Command | Description |
338
379
  |---|---|
339
- | `regression:run-k-requirements` | K1-K15 non-negotiable requirements |
340
- | `regression:run-gng-gate` | Go/No-Go Gate 3 quality conditions |
341
- | `regression:run-agent-guard` | Agent-independence guard |
342
- | `regression:run-k14-k15` | K14/K15 regression |
343
- | `regression:configure-ci-gate` | Configure CI gate |
344
- | `regression:analyze-migration` | Analyze v0 test migration |
345
- | `regression:migrate-v0-tests` | Execute v0 test migration |
380
+ | `regression:run-k-requirements` | K1-K15 non-negotiable requirements. Writes suite result JSON under fixed `reports/regression/`. |
381
+ | `regression:run-gng-gate` | Go/No-Go Gate 3 quality conditions. Writes suite result JSON under fixed `reports/regression/`. |
382
+ | `regression:run-agent-guard` | Agent-independence guard. Writes suite result JSON under fixed `reports/regression/`. |
383
+ | `regression:run-k14-k15` | K14/K15 regression. Writes suite result JSON under fixed `reports/regression/`. |
384
+ | `regression:configure-ci-gate` | Configure CI gate (`--suites <ids>`, `--threshold <n>`). |
385
+ | `regression:analyze-migration` | Analyze v0 test migration (`--dry-run`). |
386
+ | `regression:migrate-v0-tests` | Execute v0 test migration (`--confirm`). |
346
387
 
347
388
  ---
348
389
 
@@ -362,6 +403,7 @@ ISSUE-005 P3-10 で明確化された境界:
362
403
  | `p2:check-freshness` | `--pattern <glob>` `--dry-run` `--format text\|json` | Compatibility entry point for L4-004 doc freshness; canonical L4 execution is `validate --layer L4` |
363
404
  | `p2:validate-pointers` | `--include-urls` `--format text\|json` | Compatibility entry point for L4-005 pointer validation; canonical L4 execution is `validate --layer L4` |
364
405
  | `p2:generate-e2e-template` | `--phase <phase>` `--output <path>` | Generate E2E test template |
406
+ | `p2:check-initial-creation` | `--pattern <glob>` `--format text\|json` | Compatibility detector for long-lived `initial_creation: true` docs. |
365
407
 
366
408
  ### `phasegate:generate-matrix`
367
409
 
@@ -420,10 +420,23 @@ Quick Mode with `relaxedGates: ["phase-gate"]` relaxes `storyReflection` as well
420
420
 
421
421
  #### `reporting`
422
422
 
423
+ <!-- @work-item-id WI-158 -->
424
+
423
425
  | Sub-field | Type | Default | Description |
424
426
  |-------------|----------|-------------|-------------------------------------------------------|
425
427
  | `format` | `string` | `"json"` | Output format for validation reports. |
426
- | `outputDir` | `string` | `"reports"` | Directory where reports are written. |
428
+ | `outputDir` | `string` | `"reports"` | Configured report directory used by phase-gate / story-reflection reporting paths and status-derived phase dependency output. |
429
+
430
+ `reporting.outputDir` is not a blanket sink for every command that writes a file:
431
+
432
+ | Producer | Output path contract |
433
+ |---|---|
434
+ | Phase dependency / phase-gate reporting | Uses resolved `reporting.outputDir`; if no config can be read by the story-reflection provider, the legacy fallback is `.harness/reports`. |
435
+ | `doctor --report-out <path>` | Writes exactly to `<path>` relative to the project root, or to the absolute path supplied. It does not derive a path from `reporting.outputDir`. |
436
+ | `phasegate:status --json` / `phasegate:detect-drift --json` | Writes to stdout. Redirect explicitly if a persisted report is needed. |
437
+ | `regression:*` suites | Write CI gate result JSON under fixed `reports/regression/`; this is a regression-suite contract and currently does not consult `reporting.outputDir`. |
438
+
439
+ Use `reports/` as the canonical default for project-visible reports. Treat `.harness/reports` as a legacy fallback used only where the phase-dependency provider has no resolved config.
427
440
 
428
441
  #### `validate` (severity policy, ADR-017 / WI-094)
429
442
 
@@ -548,6 +561,8 @@ If you move your design documents to a non-default location, update `paths` acco
548
561
 
549
562
  **How paths flow into the L2 phase-gate validator (since v0.117.0 / WI-085):**
550
563
 
564
+ <!-- @work-item-id WI-149 -->
565
+
551
566
  `STANDARD_PHASE_NODES` / `FULL_PHASE_NODES` / `MINIMAL_PHASE_NODES` express artifact locations using two placeholders, expanded at validation time from `paths`:
552
567
 
553
568
  | Placeholder | Resolved from | Default |
@@ -555,7 +570,7 @@ If you move your design documents to a non-default location, update `paths` acco
555
570
  | `{designDocsRoot}` | `paths.designDocs` | `docs/product/construction` |
556
571
  | `{inceptionDocsRoot}` | `paths.inceptionDocs` | `docs/inception` |
557
572
 
558
- Setting `paths.designDocs` to `mydocs/product/construction` makes the L2 phase-gate require `mydocs/product/construction/{unit}/domain_model.md` instead of the default. Default values match the v0.115.0 layout for full backward compatibility.
573
+ Setting `paths.designDocs` to `mydocs/product/construction` makes the L2 phase-gate require `mydocs/product/construction/{unit}/domain_model.md` instead of the default. This setting points to the construction subtree, not the broader product root; product-wide artifacts under `docs/product/` stay literal unless you define a custom `phaseDependencies.gates[]` preset. Default values match the v0.115.0 layout for full backward compatibility.
559
574
 
560
575
  **Out of scope (paths handled by literal references):**
561
576
 
@@ -94,6 +94,14 @@ Use /quick-implementor skill for version changes in package.json.
94
94
  - By default, the hook exits with the inner CLI's exit code, which Claude Code shows as a transcript warning but does not turn-block on.
95
95
  - Set `agentIntegration.stopHook.enforce: true` in `phasegate.config.json` to enable **strict mode**: on Complete Check failure, the hook emits `{"decision":"block","reason":"Complete Check failed (exitCode=N)"}` on stdout and exits with code 2, hard-blocking Claude Code's turn end. Reentry-detection still exits 0 regardless of this setting. See `docs/guide/configuration.md` `agentIntegration` section for details.
96
96
 
97
+ ## Git hook metadata validation
98
+
99
+ <!-- @work-item-id WI-149 -->
100
+
101
+ When installed with Husky, `.husky/pre-commit` invokes `npx phasegate pre-commit`. That path runs the same L2 pre-commit contract used by CI and includes staged Markdown metadata validation in addition to implementation metadata checks. In practice, staged `docs/inception/**/description.md` files are checked for WI frontmatter shape, `docs/product/**` reflection updates are checked for `@work-item-id WI-XXX`, and staged implementation/test files are checked for source metadata.
102
+
103
+ `validate-metadata <files>` remains available as a direct metadata command, but the public pre-commit contract for users is `phasegate pre-commit`; do not wire a separate Markdown metadata hook unless you have a project-specific reason.
104
+
97
105
  ## Optional Shell Script Hooks
98
106
 
99
107
  Additional hooks can be placed in `.claude/scripts/`:
@@ -102,13 +102,17 @@ npx phasegate lint
102
102
 
103
103
  ## L2: Pre-commit Validators
104
104
 
105
+ <!-- @work-item-id WI-151 -->
106
+
105
107
  L2 validators run before every commit. They enforce process discipline and test quality standards.
106
108
 
107
- | Validator | Description |
108
- |-----------|-------------|
109
- | **phase-gate** | Enforces design-before-implementation order. Code changes to `scripts/harness/` are blocked unless the corresponding design documents exist in `docs/product/construction/`. |
110
- | **metadata** | Verifies completeness of source file annotations: `@unit`, `@layer`, `@US-XXX`, and `@story` |
111
- | **test-quality** | Enforces test authoring standards through a runner-independent semantic model: AAA pattern (Arrange/Act/Assert), named Act observation, single-act-per-test, assertion strength, lifecycle/E2E exceptions, and no domain/internal mocking in domain layer tests |
109
+ | Validator | ID | Description |
110
+ |-----------|----|-------------|
111
+ | **phase-gate** | L2-001 | Enforces design-before-implementation order. Code changes to `scripts/harness/` are blocked unless the corresponding design documents exist in `docs/product/construction/` or the configured `paths.designDocs` root. |
112
+ | **metadata** | L2-002 | Verifies completeness of source file annotations such as `@unit`, `@layer`, and story/WI metadata. |
113
+ | **test-quality** | L2-003 | Enforces test authoring standards through a runner-independent semantic model: AAA pattern, named Act observation, single-act-per-test, assertion strength, lifecycle/E2E exceptions, and no domain/internal mocking in domain layer tests. |
114
+ | **cli-e2e-test-existence** | L2-013 | Checks that public CLI commands have corresponding CLI/e2e coverage or an explicit documented reason for compatibility/internal handling. |
115
+ | **work-item-status-staleness** | L2-014 | Compares `description.md` frontmatter status with derived artifact evidence and reports stale WI status. |
112
116
 
113
117
  **Command:**
114
118
 
@@ -139,6 +143,8 @@ npx phasegate validate --layer L3
139
143
 
140
144
  ## L4: Scheduled Validators
141
145
 
146
+ <!-- @work-item-id WI-151 -->
147
+
142
148
  L4 validators are designed to run on a weekly schedule and detect slow-moving drift that accumulates over time.
143
149
 
144
150
  > **Status**: L4 is **disabled by default** (`layers.L4.enabled: false` in `phasegate.config.json`). Projects opt in by flipping the flag and scheduling the command via CI cron (see `ci:generate-template --type consistency-check --render`). Implementation-wise the validators listed below are functional; the default-off state is a conservative rollout choice, not a missing feature. @work-item-id WI-128
@@ -163,6 +169,18 @@ npx phasegate validate --layer L4
163
169
 
164
170
  Use a weekly cron such as `0 9 * * 1` for the generated consistency-check workflow. Standard projects normally keep L4 default-off and run the scheduled audit as advisory. Strict projects may opt into `layers.L4.enabled: true` and `failOnWarning` behavior when L4 warnings should block promotion. @work-item-id WI-128
165
171
 
172
+ ### Status and drift states
173
+
174
+ `phasegate:status --json` separates three ideas that should not be collapsed in CI or agent logic:
175
+
176
+ | State key | Meaning |
177
+ |---|---|
178
+ | `configurationState` | The resolved config intent for the layer or check. Disabled configuration means the layer should be skipped in aggregate execution. |
179
+ | `cachedArtifactState` | Whether a persisted artifact/report exists. `missing` means no report artifact is available; it is not proof that validation failed. |
180
+ | `liveValidationState` | The current live execution result: pass, fail, or skipped. This is the gate signal to use for current decisions. |
181
+
182
+ For drift output, treat `missing` and `limitation` differently. `missing` means expected product docs, pointers, reports, or code evidence are absent. `limitation` means the current detector cannot prove the condition even though inputs may exist; keep those findings advisory until detector coverage is improved.
183
+
166
184
  ### Drift-detect design pointers
167
185
 
168
186
  L4-001 normally matches design headings to code exports by name. When a heading intentionally maps to a differently named implementation file, add a pointer directly under the heading:
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "phasegate",
3
- "version": "0.152.1",
3
+ "version": "0.152.5",
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",
@@ -1,6 +1,6 @@
1
1
  // @unit ci-governance
2
2
  // @layer infrastructure
3
- // @work-item-id WI-124
3
+ // @work-item-id WI-124 / WI-128
4
4
 
5
5
  import type { ValidatorIdRegistryPort } from '../../domain/ports/validator-id-registry-port.js';
6
6
  import { buildDefaultRegistry } from '../../../validator-system/composition-root.js';
@@ -1,6 +1,7 @@
1
1
  /**
2
2
  * @layer domain
3
3
  * @unit config-foundation
4
+ * @work-item-id WI-012
4
5
  */
5
6
  import { ConfigFoundationDomainError } from './errors/config-foundation-domain-error.js';
6
7
  import { ConfigValidationError } from './errors/config-validation-error.js';
@@ -1,6 +1,7 @@
1
1
  // @layer infrastructure
2
2
  // @unit harness-api
3
3
  // @work-item-id WI-123
4
+ // @work-item-id WI-096
4
5
  // harness-config-query-adapter.ts — HarnessConfigQueryAdapter
5
6
 
6
7
  import * as fs from 'node:fs/promises';
@@ -1,6 +1,7 @@
1
1
  /**
2
2
  * @unit harness-api
3
3
  * @layer presentation
4
+ * @work-item-id WI-090 / WI-091
4
5
  * @work-item-id WI-113 / WI-142
5
6
  *
6
7
  * Phasegate CLI エントリポイント。
@@ -1,6 +1,7 @@
1
1
  /**
2
2
  * @layer domain
3
3
  * @unit phase-dependency-model
4
+ * @work-item-id WI-085
4
5
  */
5
6
  import path from 'node:path';
6
7
 
@@ -1,6 +1,7 @@
1
1
  /**
2
2
  * @layer infrastructure
3
3
  * @unit phase2-extensions
4
+ * @work-item-id WI-035
4
5
  */
5
6
  import { execFileSync } from 'node:child_process';
6
7
  import * as fs from 'node:fs/promises';
@@ -1,6 +1,7 @@
1
1
  /**
2
2
  * @layer infrastructure
3
3
  * @unit phase2-extensions
4
+ * @work-item-id WI-035
4
5
  */
5
6
  import { execFileSync } from 'node:child_process';
6
7
  import * as fs from 'node:fs/promises';
@@ -1,5 +1,7 @@
1
1
  // @unit harness-api
2
2
  // @layer infrastructure
3
+ // @work-item-id WI-086 / WI-087
4
+ // @work-item-id WI-127
3
5
  // Note: import.meta.url を使わず、呼び出し元 (main.ts) がパスを解決して渡す設計。
4
6
 
5
7
  import { promises as fs } from "node:fs";
@@ -1,6 +1,7 @@
1
1
  /**
2
2
  * @layer infrastructure
3
3
  * @unit skill-quality
4
+ * @work-item-id WI-036
4
5
  */
5
6
  import { execFileSync } from 'node:child_process';
6
7
  import type { CommitExecutorPort } from '../../domain/ports/commit-executor-port.js';
@@ -1,6 +1,7 @@
1
1
  /**
2
2
  * @layer application
3
3
  * @unit traceability-model
4
+ * @work-item-id WI-093
4
5
  *
5
6
  * traceability-model ユニットの Composition Root。
6
7
  * 全コンポーネントを生成・配線し、外部に公開するハンドラー群を返す。
@@ -1,5 +1,6 @@
1
1
  // @unit traceability-model
2
2
  // @layer domain
3
+ // @work-item-id WI-027
3
4
 
4
5
  import type { LegacyIssueDirectory } from "../value-objects/work-item-migration-candidate.js";
5
6
 
@@ -1,5 +1,6 @@
1
1
  // @unit traceability-model
2
2
  // @layer domain
3
+ // @work-item-id WI-027
3
4
 
4
5
  import type {
5
6
  LegacyIssueDirectory,
@@ -1,5 +1,6 @@
1
1
  // @unit traceability-model
2
2
  // @layer infrastructure
3
+ // @work-item-id WI-027
3
4
 
4
5
  import * as fs from "node:fs";
5
6
  import { readdir, readFile } from "node:fs/promises";
@@ -1,6 +1,7 @@
1
1
  /**
2
2
  * @layer infrastructure
3
3
  * @unit traceability-model
4
+ * @work-item-id WI-093
4
5
  *
5
6
  * user_stories.md を読み込み StoryCatalogPort を実装するゲートウェイ
6
7
  */
@@ -1,6 +1,7 @@
1
1
  /**
2
2
  * @layer infrastructure
3
3
  * @unit validator-system
4
+ * @work-item-id WI-121
4
5
  *
5
6
  * AstPerformanceScannerAdapter — PerformanceScannerPort実装
6
7
  * TypeScript Compiler API によるループ内 await 検出 + ファイルサイズチェック(L3-002)
@@ -1,6 +1,7 @@
1
1
  /**
2
2
  * @layer infrastructure
3
3
  * @unit validator-system
4
+ * @work-item-id WI-120
4
5
  *
5
6
  * FileSystemSecurityPatternScannerAdapter — SecurityPatternScannerPort実装
6
7
  */
@@ -1,6 +1,7 @@
1
1
  /**
2
2
  * @layer infrastructure
3
3
  * @unit validator-system
4
+ * @work-item-id WI-119
4
5
  *
5
6
  * ImportGraphSourceAnalysisAdapter — SourceAnalysisPort実装
6
7
  */
@@ -19,9 +20,11 @@ const EXPORT_LIST_PATTERN = /export\s+(?:type\s+)?\{([^}]+)\}/g;
19
20
 
20
21
  export class ImportGraphSourceAnalysisAdapter implements SourceAnalysisPort {
21
22
  private readonly root: string;
23
+ private readonly includeExcludedFiles: boolean;
22
24
 
23
- constructor(root: string = HARNESS_ROOT) {
25
+ constructor(root: string = HARNESS_ROOT, options: { includeExcludedFiles?: boolean } = {}) {
24
26
  this.root = root;
27
+ this.includeExcludedFiles = options.includeExcludedFiles ?? false;
25
28
  }
26
29
 
27
30
  async getImportGraph(): Promise<ImportGraphData> {
@@ -34,7 +37,7 @@ export class ImportGraphSourceAnalysisAdapter implements SourceAnalysisPort {
34
37
  try {
35
38
  const content = await readFile(filePath, 'utf8');
36
39
  const exports = extractExports(content);
37
- const excludedReason = classifyDeadCodeExclusion(filePath);
40
+ const excludedReason = this.includeExcludedFiles ? undefined : classifyDeadCodeExclusion(filePath);
38
41
  nodes.push({
39
42
  filePath,
40
43
  exports,
@@ -1,6 +1,7 @@
1
1
  /**
2
2
  * @layer infrastructure
3
3
  * @unit validator-system
4
+ * @work-item-id WI-091
4
5
  * @work-item-id WI-117, WI-118
5
6
  *
6
7
  * MarkdownDesignDocumentAdapter — DesignDocumentPort実装