phasegate 0.254.0 → 0.283.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (82) hide show
  1. package/CHANGELOG.md +60 -0
  2. package/README.ja.md +6 -3
  3. package/README.md +6 -3
  4. package/docs/contracts/attestation-v2.schema.json +110 -0
  5. package/docs/guide/cli-reference.md +12 -1
  6. package/docs/guide/configuration.md +56 -0
  7. package/docs/guide/installation.md +1 -1
  8. package/docs/templates/ci/aidlc-gate.yml +60 -2
  9. package/package.json +2 -2
  10. package/scripts/harness/agent-integration/application/dto/open-world-obligations-context-dto.ts +30 -0
  11. package/scripts/harness/agent-integration/application/ports/world-obligations-query-port.ts +30 -0
  12. package/scripts/harness/agent-integration/application/usecases/get-open-world-obligations-context-usecase.ts +66 -0
  13. package/scripts/harness/agent-integration/infrastructure/adapters/harness-config-config-query-adapter.ts +30 -27
  14. package/scripts/harness/agent-integration/infrastructure/adapters/world-model-open-obligations-query-adapter.ts +58 -0
  15. package/scripts/harness/agent-integration/presentation/post-tool-use-hook.ts +29 -16
  16. package/scripts/harness/agent-integration/presentation/session-start-hook.ts +37 -1
  17. package/scripts/harness/agent-integration/presentation/stop-hook.ts +35 -26
  18. package/scripts/harness/agent-integration/presentation/world-obligations-session-context.ts +60 -0
  19. package/scripts/harness/attestation/application/dto/attestation-document.ts +17 -4
  20. package/scripts/harness/attestation/application/mappers/attestation-record-mapper.ts +55 -4
  21. package/scripts/harness/attestation/application/ports/world-snapshot-root-provider.ts +10 -0
  22. package/scripts/harness/attestation/application/usecases/produce-attestation-usecase.ts +33 -7
  23. package/scripts/harness/attestation/composition-root.ts +5 -0
  24. package/scripts/harness/attestation/domain/entities/attestation-record.ts +37 -2
  25. package/scripts/harness/attestation/index.ts +7 -1
  26. package/scripts/harness/attestation/presentation/handlers/attest-handler.ts +5 -2
  27. package/scripts/harness/config-foundation/application/mappers/validator-system-config-mapper.ts +40 -9
  28. package/scripts/harness/config-foundation/application/mappers/world-model-config-mapper.ts +15 -0
  29. package/scripts/harness/config-foundation/domain/harness-config.ts +70 -87
  30. package/scripts/harness/config-foundation/domain/services/preset-resolution-service.ts +80 -88
  31. package/scripts/harness/config-foundation/domain/value-objects/project-config.ts +34 -18
  32. package/scripts/harness/config-foundation/domain/value-objects/world-config.ts +198 -0
  33. package/scripts/harness/config-foundation/index.ts +14 -15
  34. package/scripts/harness/config-foundation/infrastructure/presets/minimal.json +24 -0
  35. package/scripts/harness/config-foundation/infrastructure/presets/standard.json +24 -0
  36. package/scripts/harness/config-foundation/infrastructure/presets/strict.json +24 -0
  37. package/scripts/harness/config-foundation/infrastructure/repositories/file-system-config-repository.ts +27 -18
  38. package/scripts/harness/config-foundation/infrastructure/schemas/harness-config-v2.schema.json +84 -8
  39. package/scripts/harness/config-foundation/infrastructure/schemas/harness-config-v3.schema.json +84 -8
  40. package/scripts/harness/harness-api/domain/ports/config-query-port.ts +11 -1
  41. package/scripts/harness/harness-api/domain/services/command-dispatch-service.ts +125 -86
  42. package/scripts/harness/harness-api/domain/services/status-derivation-service.ts +31 -21
  43. package/scripts/harness/harness-api/domain/value-objects/ci-check-result.ts +18 -4
  44. package/scripts/harness/harness-api/domain/value-objects/harness-status-summary.ts +23 -8
  45. package/scripts/harness/harness-api/infrastructure/adapters/biome-ast-engine-lint-adapter.ts +4 -4
  46. package/scripts/harness/harness-api/infrastructure/adapters/harness-config-query-adapter.ts +79 -34
  47. package/scripts/harness/installation/application/usecases/run-install.ts +199 -51
  48. package/scripts/harness/installation/application/usecases/run-reconcile.ts +277 -69
  49. package/scripts/harness/installation/domain/deployment-manifest.ts +43 -0
  50. package/scripts/harness/integrations/pre-commit.ts +169 -27
  51. package/scripts/harness/main.ts +200 -136
  52. package/scripts/harness/traceability-model/application/dto/changed-design-fragment-dto.ts +31 -0
  53. package/scripts/harness/traceability-model/application/facades/design-change-read-facade.ts +14 -0
  54. package/scripts/harness/traceability-model/application/ports/staged-design-change-source-port.ts +9 -0
  55. package/scripts/harness/traceability-model/composition-root.ts +5 -0
  56. package/scripts/harness/traceability-model/index.ts +9 -0
  57. package/scripts/harness/traceability-model/infrastructure/adapters/git-staged-design-change-adapter.ts +155 -0
  58. package/scripts/harness/validator-system/application/use-cases/run-l2-validators-usecase.ts +31 -0
  59. package/scripts/harness/validator-system/application/use-cases/run-l3-validators-usecase.ts +57 -6
  60. package/scripts/harness/validator-system/composition-root.ts +25 -7
  61. package/scripts/harness/validator-system/domain/ports/ac-coverage-policy-port.ts +10 -1
  62. package/scripts/harness/validator-system/domain/ports/world-constraint-admission-policy-port.ts +28 -0
  63. package/scripts/harness/validator-system/domain/ports/world-constraint-rederivation-policy-port.ts +11 -0
  64. package/scripts/harness/validator-system/domain/services/design-change-declaration-policy.ts +75 -0
  65. package/scripts/harness/validator-system/domain/services/world-constraint-admission-service.ts +78 -0
  66. package/scripts/harness/validator-system/domain/services/world-constraint-rederivation-service.ts +76 -0
  67. package/scripts/harness/validator-system/domain/value-objects/validator-id.ts +4 -0
  68. package/scripts/harness/validator-system/infrastructure/adapters/harness-config-validator-config-adapter.ts +126 -18
  69. package/scripts/harness/validator-system/infrastructure/adapters/nyquist-ac-coverage-policy-adapter.ts +49 -20
  70. package/scripts/harness/validator-system/infrastructure/adapters/world-model-constraint-admission-adapter.ts +56 -0
  71. package/scripts/harness/validator-system/infrastructure/adapters/world-model-constraint-rederivation-adapter.ts +56 -0
  72. package/scripts/harness/world-model/application/dto/pinned-design-endpoint-dto.ts +19 -0
  73. package/scripts/harness/world-model/application/dto/world-resolved-config-input.ts +92 -27
  74. package/scripts/harness/world-model/application/dto/world-snapshot-root-dto.ts +8 -0
  75. package/scripts/harness/world-model/application/facades/pinned-design-endpoint-facade.ts +63 -0
  76. package/scripts/harness/world-model/application/facades/world-snapshot-root-facade.ts +19 -0
  77. package/scripts/harness/world-model/application/usecases/derive-world-obligations-use-case.ts +3 -1
  78. package/scripts/harness/world-model/composition-root.ts +62 -33
  79. package/scripts/harness/world-model/index.ts +11 -0
  80. package/scripts/harness/world-model/infrastructure/adapters/attestation-fact-extractor.ts +48 -13
  81. package/scripts/harness/world-model/infrastructure/adapters/file-system-world-control-repository-adapters.ts +6 -4
  82. package/scripts/harness/world-model/presentation/cli/world-derive-command-handler.ts +6 -2
package/CHANGELOG.md CHANGED
@@ -7,8 +7,68 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
7
7
 
8
8
  ## [Unreleased]
9
9
 
10
+ ### Fixed
11
+
12
+ - **WI-328 — 実効言語と出所を phasegate:status に表示(GitHub #39 残課題)** — WI-319/320 の言語自動検出の結果がどこにも表示されず、どの validator が有効/SKIP になるか知る術がなかった。`phasegate:status` の JSON に `languages: { effective, source }`(source = `declared` / `detected` / `fallback`)を追加。解決ロジックは validator-system の `resolveProjectLanguages()`(WI-319 の検出テーブル)に一本化して再利用し、validator の有効/SKIP 判定と必ず同じ結果を表示する。ConfigQueryPort への追加は optional メソッドで後方互換。
13
+
14
+ - **WI-327 — 最小 config(project のみ)で動作可能に** — 手書き `phasegate.config.json` のスキーマが top-level 8 項目を required とし、`{"project": {"name": ..., "preset": ...}}` の最小構成で L1-001 が連発していた。プリセット解決(`PresetResolutionService.deepMerge`)は省略セクションの補完を既に完備していたため、v3 **と v2**(architecture キーなしの最小 config は v2 検証に振られる)の top-level required を `["project"]` に緩和し、型定義を実態に一致させた。**検証は弱めていない**: セクション内の required・型・enum・additionalProperties は不変で、書かれているが不正なキーは従来どおりエラー(spawn E2E で exit 2 を固定)。最小 config の解決結果がプリセット定義と一致することも統合テストで固定。
15
+
16
+ - **WI-326 — install フラグ状態を manifest に永続化(GitHub #36 残課題)** — `--with-husky` / `--with-ci` / personal の install 時オプションが `.phasegate/manifest.json` に記録されず、後の reconcile が「全 target 対象」を仮定して opt-out したはずの Husky / CI workflow を追加し直す食い違いがあった。manifest に optional `installationFlags` を追加して install(apply)時に実効フラグを記録し、reconcile は明示指定 > manifest 記録 > 従来挙動の優先順で target を構成する。フィールドを持たない旧 manifest は推測せず従来挙動のまま(load / save round-trip のバイト互換もテストで固定)。
17
+
18
+ - **WI-324 — フレッシュプロジェクトで L3-004 を SKIP に(オンボーディング阻害の解消)** — phasegate 導入直後(story 未作成・requirement-test-matrix 未生成)でも L3-004 が「マトリクス不在」で fail-closed FAIL になり導入体験を阻害していた。「matrix 不在 かつ StoryCatalog(user_stories.md)の story ゼロ」の場合のみ skipWithReason(WI-317 の L3-003 と同表現)で透過 SKIP に変更。**story が 1 件でも存在するのに matrix 不在なら従来どおり fail-closed**(あるべき matrix の消失事故は見逃さない)。story 数の取得に失敗した場合も判定不能として fail-closed 側に倒す。
19
+
20
+ - **WI-323 — 非ゲート hook の payload フィールド欠落を fail-open 化(GitHub #40 残課題)** — stop hook が stdin payload の `session_id` 欠落で exit 2 になり、WI-314 の「hook は開発フローを止めない」方針と不整合だった。stop(`SESSION_ID_MISSING`)と post-tool-use(`TOOL_NAME_MISSING`)を警告 + hook-skip-event 記録 + exit 0 の fail-open に変更。**pre-tool-use の `tool_name` 欠落 exit 2 は書き込みゲートのため意図的に fail-closed を維持**し、回帰ガードテストで固定。usecase 契約(空 sessionId エラー)は presentation 入口ガード方式で不変。
21
+
22
+ - **WI-322 — config なし fallback の coverageThreshold 90 を opt-out の 0 に修正(GitHub #37 残課題)** — WI-317 で「カバレッジゲートはオプトイン、0 = 正規の opt-out」と定義したのに、config なし環境で使われる validator-system の `DEFAULT_CONFIG` fallback が `coverageThreshold: 90` のままで、config を持たない環境だけ勝手に 90% が強制される矛盾を解消。fallback のみの変更でプリセット定義(minimal / standard / strict)は不変。fallback 経由で L3-003 が透過 SKIP になることを回帰テストで固定。
23
+
24
+ - **WI-321 — complete-check の JSON 出力に warning 詳細を含める(GitHub #38 残課題)** — `phasegate:complete-check` が warning を `summary.warnings` の件数のみで返し、どの validator のどんな warning かが出力に含まれなかった非対称を修正。ci-check case と同じく `CiCheckResult` を data ペイロードとして pass / fail 双方で返す(`data.validatorResults[].validatorId / errors[]`)。validator 結果 0 件時は従来どおり data なし。判定ロジック・exit code・lint 合流は不変。
25
+
26
+ - **WI-325 — load 経路の JSON パース失敗が "Failed to persist" と誤表示される問題を修正** — `FileSystemConfigRepository.load()` の JSON 構文エラーが書き込み用の `ConfigPersistenceError`("Failed to persist config")で送出され、読み込み失敗なのに永続化失敗と誤解させるメッセージになっていた。`ConfigParseError extends ConfigPersistenceError` を新設して load 経路を "Failed to parse config JSON" に分離。サブクラス化により main.ts の `instanceof ConfigPersistenceError` fail-open 判定(WI-314)は無変更で互換維持。save 経路は従来どおり。
27
+
28
+ - **WI-320 — 言語自動検出を実 CLI 経路で有効化(GitHub #39 フォローアップ)** — WI-319 の検出は adapter に実装されたが、実 CLI では preset 解決(`preset-resolution-service`)・mapper・`ProjectConfig` VO の 3 箇所が未宣言時に `["typescript"]` を注入するため dead code だった(シナリオ検証で発見)。「未宣言」シグナルを resolved config から adapter まで生存させ、純 Python リポジトリで L3-003 が unsupported-language SKIP になることを実 CLI spawn の E2E で固定。宣言時の挙動・検証は不変。
29
+
30
+ - **WI-319 — project.languages のファイルシステム自動検出(GitHub #39)** — `project.languages` 未宣言時に無条件で `["typescript"]` へフォールバックし、純 Python プロジェクトでも TS 専用 validator(L3-002 / L3-003 / L4-003)が既定で走っていた問題を修正。マーカーファイル(python: pyproject.toml 等 / go.mod / Cargo.toml / pom.xml / Gemfile / composer.json、typescript: tsconfig.json または package.json の typescript 依存のみ — phasegate 導入時の package.json を誤検出しないため存在自体は根拠にしない)から検出し、config 宣言は引き続き最優先、検出ゼロ時は従来どおり typescript フォールバック。
31
+
32
+ - **WI-318 — complete-check に severity-aware 集約を適用(GitHub #38)** — `phasegate:complete-check` が validator の生の `passed` だけを見ており、warning-only failure でも exit 1 になって `validate` / `ci-check` と乖離していた。Stop hook が叩くのは complete-check のため、L2-016 の `ungated-legacy` マーカー(error→可視 warning 降格)が実質無効化されていた。ci-check と同一の `CiCheckResult.fromResults()`(ADR-017 / WI-260 の `isEffectivelyPassed`)を通す集約に修正し、warning 件数を summary に反映。skipped validator が fail 扱いされる潜在バグも同時に解消。lint fail → exit 1 の合流は不変。
33
+
34
+ - **WI-317 — coverageThreshold の opt-out を到達可能に(GitHub #37)** — L3-003 実装は「カバレッジゲートはオプトイン」と明記しつつ、opt-out 手段(`null`)がスキーマで拒否され、`0` を設定してもレポート不在で fail-closed FAIL になる矛盾があった。ドメイン VO `L3Config.hasCoverageGate()` の「threshold > 0 でのみ有効」の意図に run-l3 を揃え、`coverageThreshold: 0`(および null)を正規の opt-out として SKIP にした(minimal preset の 0 も本来の opt-out として機能)。レポート不在 FAIL の suggestion に (a) カバレッジ付き実行 (b) `coverageThreshold: 0` での opt-out (c) 非 JS/TS プロジェクトの `project.languages` 宣言、の 3 択を案内する。
35
+
36
+ - **WI-316 — install の `--with-husky` / `--with-ci` dead flag を修正(GitHub #36)** — install コマンドがこの 2 フラグを一度も読まず、`--personal` なしでは常に `.husky/*` と `.github/workflows/phasegate-aidlc-gate.yml` を書き込んでいた。ヘルプ記載・`init` / `setup:agent` と同じ opt-in(フラグ明示時のみ書き込み)に配線を揃え、CLI 統合テストとドキュメントで固定した。usecase のプログラマティック契約(既定 true)は不変。
37
+
38
+ - **WI-315 — install / reconcile が CLAUDE.md の user-section を上書きする問題を修正(GitHub #35)** — CLAUDE.md テンプレートは user-section が managed-section の内側にあるため、`install --apply` / `reconcile` の managed block 置換がユーザー自身の記述を placeholder で消失させていた。merge 時に既存 user-section 本文を抽出して新 block に再注入する方式で保持するようにした(AGENTS.md の既存挙動は不変)。併せて、ユーザー本文が `String.replace` の置換文字列として `$` シーケンス解釈される潜在破損を replacer 関数で封じた。
39
+
40
+ - **WI-314 — 不正 config の hook / doctor 自己修復デッドロック解消(GitHub #40)** — スキーマ違反の `phasegate.config.json` が dispatch 上流の fail-closed で全コマンドを exit 2 にし、pre-tool-use hook 経由で Bash / Write / Edit を全遮断して config 自身の修復も不能になる問題を修正。`hook` / `doctor` は警告 + 既定設定で続行する fail-open とし(診断・自己修復経路の常時確保)、`validate` / `ci-check` 等の検査系は復旧手順の案内付きで fail-closed を維持。hook 内部 adapter の素 `JSON.parse` throw も同様に fail-open 化し、構文破壊 JSON での再デッドロックを塞いだ。gated スコープへの書き込みは phase-gate 判定が引き続き fail-closed でブロックする。
41
+
42
+ - **WI-313 — typescript peer range を `<7.0.0` に制限(GitHub #34)** — peer 自動インストールで typescript@7 が解決されると classic compiler API(`ts.ScriptTarget` 等)が存在せず全コマンドが `Cannot read properties of undefined (reading 'ESNext')` でクラッシュする問題を修正。TypeScript 7 系を peer range で弾き、packaging contract テストで range を固定した。
43
+
44
+ - **WI-312 — coverage-producing CI gate** — production workflowとbundled `aidlc-gate`がL3-003実行前に`coverage/coverage-summary.json`を生成せず、clean checkoutでcoverageThresholdに対してfail-closedとなる既存欠陥を修正。self-repoはcoverage付きunit / integrationとcoverage対象外E2Eを各1回だけ実行してplain full suiteの二重実行を避け、threads開始時にもforks blobを保持して両poolをmergeする。templateは採用projectの`coverage` scriptをpackage manager別に必須実行し、test / coverage → matrix → World derive二重一致 → L3 → attestation → integrityの順序を維持する。
45
+
46
+ - **WI-311 — hermetic CI-facing harness integration tests** — GitHub Actionsのtest-before-matrix順序で、real lint integrationとCLI E2Eがself-repo cwd、coverage、untracked requirement matrixを暗黙のPASS入力としていた既存欠陥を修正。lint adapterへ明示rootを注入してtracked minimal workspaceだけを実scanし、`phasegate:ci-check --json`とlegacy `complete-check`はL3 / Worldを明示無効化したtemp configで公開command契約を検証する。productionのfail-closedとCI gate順序は変更しない。
47
+
48
+ - **WI-310 — hermetic large-stdout CLI regression** — WI-308の64 KiB超assertionがuntracked requirement matrixとself-repoの604 adopted-legacy warningsへ依存していた欠陥を修正。tracked World-enabled configを使うtemp corpusに160組のduplicate fragment IDを生成し、CIのtest-before-matrix順序でも`validate --layer L2 --format json` / `--json`が決定的に64 KiBを超えて完全parseできる契約へ置換した。
49
+
50
+ - **WI-309 — WI-305 validator domain reflection repair** — `DesignChangeDeclarationPolicy`を実装・配線しながらvalidator-system `domain_model.md`へのWI-305累積反映を欠落させ、story reflection corpusが検出したbaseline外違反を正規に解消。exact `corpusRole + DeclaredKey`照合、pinned change限定、Work-Item trailer intersection、unique sorted finding、local fast-path / L3 authority境界を実コードどおり記録し、baseline / allowlistには触れていない。
51
+
52
+ - **WI-308 — CLI large stdout drain** — self-repoのWorld enforcement有効化により`validate --layer L2 --json`が604件のadopted-legacy warningを含む64 KiB超のJSONとなり、`console.log`直後の`process.exit`がpipe bufferをdrainせず末尾を切断する回帰を修正。direct stdout resultを返す全top-level CLI経路を共通graceful exitへ統合し、warningを省略せず任意サイズの完全な出力と既存exit codeを維持する。64 KiB超を必須条件とするprocess E2Eで`--format json` / `--json`双方を固定し、同E2E fileの全subprocess caseへ明示60秒timeoutを適用した。
53
+
10
54
  ### Added
11
55
 
56
+ - **WI-307 / H17-19 — World production-ready CI / template regression(WM-24)** — self-repo CIをtest → requirement-test matrix生成 → pure `world:derive --json`二重byte一致 → authoritative L3 → attestation v2 produce / verify → integrity verifyのtrust chainへ整列。保存obligation reportをCI入力にせず、runner tempの二出力とv2 evidenceだけを比較・検証する。bundled `aidlc-gate`はconfig JSONをfail-closedで読み、`world.enabled:true`の場合だけmatrix後のderive二重一致を実行するため、false / absentの採用projectは既存L3契約を維持する。regression-suiteにactual processの3 `world:*` command、`phasegate-world-cli/v1` envelope、exit 0 / 1 / 2、CI source order、package surfaceのcontract testを追加。README / README.ja / CLI guideを登録済み`L2-017` / `L3-008`、bounded SessionStart、attestation v2 root pin、self-repo dogfood有効のproduction仕様へ更新し、H17-19を同一着地でrequiredとして登録した。Phase CのCI統合により、warning-only validatorの`passed:false`とaggregate `allPassed:true`が同時に公開される潜在矛盾を顕在化。harness-apiのpublic ci-check projectionで同一`failOnWarning` policyをper-validator結果にも適用し、warning diagnosticsを保持したまま既定時は`passed:true`、strict時は`passed:false`へ一貫させ、attestation INV-1を緩和せずv2 smokeを成立させた。
57
+
58
+ - **WI-306 / H17-18 — Attestation v2 World snapshot root pin(WM-23)** — `phasegate-attestation/v2` / `https://phasegate.dev/attestation/gate-run/v2`を追加し、World canonical `corpusRoot`を必須`worldSnapshotRoot`としてattestationDigestのcanonical payloadへ封印する。fragment / node個別digestは保存せず、published `attestation-v2.schema.json`もroot一件だけを許可する。attestation applicationはconsumer-owned plain root providerだけを受け、top-level harness compositionがworld-model public `WorldSnapshotRootFacade`からrootを注入するため、attestation→world-model importを作らない。provider未配線のprogrammatic produceと全v1 verifyは無期限互換のv1を維持し、schema / predicate / root presence mismatchやprovider failureはv1へdowngradeせずfail-closed。World owner projectionはv1 / v2を受理しながらv2 root self-referenceをcorpus projectionから除外する。v1 / v2 produce→verify、root改竄、published schema、projection determinismをtestで固定し、H17-18を同一着地でrequiredとして登録した。
59
+
60
+ - **WI-305 / H17-17 — Design change declaration / reflection hook(WM-22)** — commit-msg経路へpin済み設計fragmentの変更宣言checkを追加。traceability-modelのpublic plain DTO facadeがGit index / HEADから内容の変わったexplicit product / inception fragmentだけをrole、DeclaredKey、path、change kind、sorted `@work-item-id`、明示`@world-reflects`付きで観測し、world-modelのpublic facadeがconstraint repositoryを露出せずclaimant / premiseのexplicit fragment pinだけを投影する。validator-system policyは両者をrole + keyでendpoint-symmetricに突合し、pin済み変更fragmentのWork Item集合とcommitの`Work-Item: WI-NNN` trailerに共通IDがない場合だけnon-bypassableでblockする。unpinned / legacy whole-file / ADR / source変更へblocking面を広げず、`world.enabled:false`ではproviderを呼ばず従来挙動を維持。Git / control observation不能はfixed code warningへfail-openし、local hookは偽造可能なfast-path、authoritative trust rootはL3-008であることを出力する。H17-17を同一着地で`planned -> required`として登録し、changed fragment / pin projection / matching・mismatch・unavailable contractをunit / Git fixture testで固定した。
61
+
62
+ - **WI-304 / H17-16 — SessionStart open World obligations summary(WM-21)** — agent-integrationのSessionStart経路へconsumer-owned `WorldObligationsQueryPort`、plain context DTO、priority / adopted-count usecase、bounded presentationを追加。infrastructure adapterはworld-model public `createWorldModelModule`だけを消費し、保存済み`.harness/world-obligations.json`を読まず`writeReport:false`でcurrent corpusからpure deriveする。`new-structural` / `invalid-declaration` / expired waiverをcleanup-required / waivedより先にstable keyで表示し、adopted-legacyは個別列挙せず件数一行へ集約。World sectionはconfig値にかかわらず最大5件 / 2000 Unicode scalar、entry途中切断なし、決定的省略行を保証し、reason / diagnostic details / corpus prose / full reportをpromptへ中継しない。`world.enabled:false`またはsession summary無効時はquery未実行・非表示、config / derive不能時はrepository由来reasonを含まない固定一行warningへfail-openしてhook exit 0を維持する。self-repo E2Eで604 adopted-legacyが一行だけになりfingerprint本文を注入しないことを固定し、H17-16を同一着地で`planned -> required`へ進めた。
63
+
64
+ - **WI-303 — self-repo World enforcement 有効化(dogfood)** — CP-4 合格を受け `phasegate.config.json` に `world.enabled: true` を設定。以後 self-repo の L2 は L2-017(constraint admission fast-path)、L3 は L3-008(authoritative re-derivation)を実際に実行する。604 件の adopted-legacy baseline は非 blocking warning として可視化され、新規構造違反・不正宣言は fail-closed。実測コストは両ゲート合計 2 秒未満。
65
+
66
+ - **WI-302 / H17-15 — L3-008 authoritative World constraint re-derivation(WM-20)** — ADR-030のCI trust rootとADR-035 / ADR-037のnon-authoritative generated report contractを執行し、`L3-008 world-constraint-rederivation`をValidatorId、default registry、RunL3、composition-rootへ登録。専用consumer-owned port / service / infrastructure adapterが呼出しごとにworld-model public compositionをfresh構築し、current corpusとversioned constraints / baseline / waiver / debtから`writeReport:false`で義務を独立再導出する。`.harness/world-obligations.json`のreader / cache / pathを依存に持たず、report absent / forged / unsupported-version / deletedでobservationとblocking結果が不変であることをreal filesystem fixtureで固定した。validator-system policyは`new-structural` / `invalid-declaration`と全derive diagnosticをfingerprint・WCR rule付きerrorとしてfail-closed、`adopted-legacy` / active waiverをwarningとして可視non-blockingにする。base fixtureはPASSし、new unpinned claim / duplicate IDを既存mutation manifestのexact fingerprint、unknown schemaをauthoritative diagnosticとして検証。resolved `world.enabled:false`ではL3-008を明示skip、trueの場合だけ実行し、self-repo config自体は変更していない。H17-15を同一着地で`planned -> required`へ進め、enforceable MVPのL2 local / L3 authoritative dual pathを完成した。
67
+
68
+ - **WI-301 / H17-14 — L2-017 World constraint admission fast-path(WM-19)** — ADR-037で予約した`L2-017 world-constraint-admission`をValidatorId、default registry、RunL2、composition-rootへ登録。config-foundationのresolved `world.enabled`をautomatic gate selectionとして消費し、false / absentではdefinitionを残した明示skip、trueの場合だけworld-model public facadeからpure `deriveWorldObligationsUseCase`を実行する。validator-system所有のpolicy serviceは`new-structural` / `invalid-declaration`とconstraint document admission failureをerrorとしてfail-closedにし、`adopted-legacy` / active waiverをfingerprint・WCR rule付きwarningとして可視化する。validなnew claim / pin自体はblockせず、保存obligation reportは入力にしない。HarnessErrorはlocal fast-pathが偽造可能でauthoritative判定は後続L3 clean-corpus re-derivationであると明記。fixtureでunpinned claim / malformed schemaのfail-closed、new pin finding、baseline採用後のlegacy non-blocking、disabled時のport非実行を固定した。self-repo `world.enabled`はfalseのまま、L3-008は未登録。H17-14を同一着地で`planned -> required`へ進めた。
69
+
70
+ - **WI-300 / H17-13 — World config surface と resolved mapping(WM-18)** — `phasegate.config.json` v2 / v3へADR-037のtop-level `world` contractを追加し、corpus roots / selection、matrix・attestation・integrity inputs、constraints・baseline・waivers・debts declarations、obligation report、session-start limitをschema / domain Value Objectでfail-closed検証する。absolute / backslash / traversal path、cross-role root overlap、case-fold collision、unknown field、範囲外limitを拒否。minimal / standard / strictは全てcanonical defaultsと`world.enabled:false`を持ち、explicit `world:*` commandは引き続き常時実行可能。preset resolutionはnested overrideをmergeし、World field省略時だけlegacy design / inception / matrix pathを継承する。dedicated `toWorldModelConfig()`をpublic mapping boundaryとして追加し、mainから完全plain DTOをWorld compositionへ注入。複数root、custom provider / control / output pathをextractor、repository、writerへ配線し、corpus digestからoutput / session / gate enablementを除外した。validator-system mapperにもWM-19 / WM-20用World projectionを渡すが、`L2-017` / `L3-008`は未登録のまま維持。H17-13を同一着地で`planned -> required`として登録し、configuration guideとaffected Unit設計を更新した。
71
+
12
72
  - **WI-299 — World Model のユーザー向けドキュメント反映** — README.md / README.ja.md に World Model 節(端点対称な制約再評価、`world:inspect` / `world:pin` / `world:derive`、immutable obligation report、adoption baseline、fail-closed 新規違反、CLI-only の現状スコープ)と Core Capabilities 行・CLI 表エントリを追加。`docs/guide/cli-reference.md` に World Model 節(options / exit code 0-1-2 / 制御ファイル 4 種 + `.harness/world-obligations.json` / `phasegate-world-cli/v1` envelope / `world.enabled` 既定 false と L2-017 / L3-008 予約の明記)を新設。README.ja footer の版表記を現行へ更新。
13
73
 
14
74
  - **WI-298 / H17-12 — Self-repo World adoption baseline と dogfood smoke(WM-17)** — final tracked corpus、H17-12 AC-bound smoke、再生成matrix、skill-quality semantic debt reflectionを含むcheckoutをbaselineなしで二重deriveし、serialized bytesとunique fingerprint集合の一致を確認。initial structural violationは実測604件で、全件implicit global TestReference ID duplicateの`WCR-005`、WCR-001 / explicit constraint finding / waiver / malformed policy inputは0件だった。candidate evaluation / corpus / constraint rootsをprovenanceに持つ604-entry closed `phasegate.world-baseline.json`を`adoptedByWorkItemId: WI-298`で採用し、same-ruleset追記禁止・返済削除onlyを明記。skill-quality coverage reportのungated attestation gapを`pgw:v1:semantic-debt:skill-quality.coverage-attestation-legacy`として`phasegate.world-debts.json`へ一件宣言し、既存`@coverage-gating`と`@world-semantic-debt`を併存させてL2-016を変更せず別collectionへimportした。self-repo smokeはmatrix再生成後の`world:derive --json`二重実行をbyte-identical、baseline=current fingerprint集合、604件全て`adopted-legacy`、new / repaid / policy diagnostic 0、semantic debt 1、exit 0として固定。H17-12を`planned -> required`へ進め、Phase B機能MVPを完成した。
package/README.ja.md CHANGED
@@ -189,7 +189,7 @@ npx phasegate reconcile --apply
189
189
  | **HarnessError 形式** | 全エラーに ADR 参照 + 修正例が含まれ、AI が自己修正できる |
190
190
  | **Baseline (retrofit)** | 既存リポジトリ導入時、`baseline` snapshot に登録した既存ファイルは構造的に編集されるまで gate 対象外 |
191
191
  | **カスタム gate** | AIDLC 以外のプロジェクトでも schema-first など独自の前提条件を設定できる |
192
- | **World Model (CLI)** | 設計文書・ソース・テスト・matrix・attestation を型付き事実グラフに抽出し、制約の両端点を pin して義務を決定的に再導出(`world:inspect` / `world:pin` / `world:derive`) |
192
+ | **World Model** | 設計文書・ソース・テスト・matrix・attestationを型付き事実グラフへ抽出。決定的`world:*` CLI、L2 fast-path、L3 authoritative再導出、bounded SessionStart、attestation v2 root pinを提供 |
193
193
 
194
194
  ---
195
195
 
@@ -260,7 +260,7 @@ Phasegate はプロンプトインジェクションを独立した新規脅威
260
260
 
261
261
  phasegate のゲートは従来一方向でした: 書き込み時にコードを設計と照合する。**World Model**([ADR-031](docs/ADR/031-world-model-ownership-and-corpus-lifecycle.md)〜[037](docs/ADR/037-world-cli-and-output-contract.md))はこの制約面を**端点対称**にします。設計文書・ソースメタデータ・テスト・requirement-test matrix・attestation を型付き・content-addressed な事実グラフとして抽出し、pin された制約は**どちらの端点が変わっても**再評価されます — 設計文書を編集すれば、それを根拠として主張していたコード側に可視の義務が生まれます(逆方向だけではなく)。
262
262
 
263
- 3 コマンドを提供します(明示実行は常に可能。`phasegate.config.json` の `world.enabled` は既定 `false` で、将来のゲート統合のみを制御します):
263
+ 3 コマンドは常に明示実行できます。`world.enabled` の product 既定値は `false` で、有効化すると登録済み L2/L3 統合が動きます。このリポジトリでは dogfood のため有効です。
264
264
 
265
265
  ```bash
266
266
  npx phasegate world:inspect --json # 決定的な read-only snapshot: node / edge / 抽出 diagnostics
@@ -274,8 +274,11 @@ npx phasegate world:derive --json # 制約評価から obligation report を
274
274
  - **新規違反は初日から fail-closed。** 既存違反は閉じた・人間レビュー可能な baseline(`phasegate.world-baseline.json`)として採用され、縮小のみ許されます(同一 ruleset での追加は拒否)。
275
275
  - **既知の意味的ギャップは宣言するもので「再発見」しない。** explicit debt は `phasegate.world-debts.json` に宣言し import として表示。waiver(`phasegate.world-waivers.json`)は fingerprint / 理由 / 期限 / Work Item が必須です。
276
276
  - **決定性は契約。** 同一 checkout での 2 回実行は byte-identical な JSON を出力します。
277
+ - **enforcement は二つの信頼レベルを持つ。** `L2-017` は偽造可能な local fast-path、`L3-008` は current corpus から authoritative に再導出し、`.harness/world-obligations.json`を信頼しません。adopted legacy は可視・非blocking、新規構造違反や不正宣言はfail-closedです。
278
+ - **agent context はbounded。** SessionStartは最大5件 / 2000文字でopen itemを表示し、adopted legacyは件数だけに集約。導出不能時は固定warningへfail-openします。
279
+ - **evidenceはroot一件だけをpinする。** attestation v2はfragment digestを複製せず`worldSnapshotRoot`をgate-run evidenceへ封印し、v1 produce / verify互換も維持します。
277
280
 
278
- 現在のスコープは **CLI のみ**です: validator ID L2-017 / L3-008 は予約済みですが pre-commit / CI ゲートへの登録は未実施で、将来フェーズとして管理しています。
281
+ World enforcementはproduction統合済みです。`L2-017` / `L3-008`は登録済み、bundled CI gateはWorld有効projectで決定的deriveを条件付き実行し、このリポジトリはfull dogfood pathを実行します。
279
282
 
280
283
  ---
281
284
 
package/README.md CHANGED
@@ -173,7 +173,7 @@ npx phasegate reconcile --apply
173
173
  | **Agent-readable HarnessError output** | Gives AI agents the reason, missing artifacts, references, and examples needed to self-correct |
174
174
  | **Retrofit baseline** | Lets existing repositories adopt Phasegate gradually by grandfathering unchanged files |
175
175
  | **Configurable gates** | Supports AIDLC defaults or custom gates such as schema-first API development |
176
- | **World Model (CLI)** | Extracts design docs, source, tests, matrices, and attestations into a typed fact graph, pins constraints between endpoints, and deterministically re-derives obligations (`world:inspect` / `world:pin` / `world:derive`) |
176
+ | **World Model** | Extracts design docs, source, tests, matrices, and attestations into a typed fact graph; deterministic `world:*` commands, L2 fast-path, L3 authoritative re-derivation, bounded SessionStart context, and attestation v2 root pinning |
177
177
 
178
178
  ---
179
179
 
@@ -240,7 +240,7 @@ Five components implement this posture:
240
240
 
241
241
  Phasegate's gates historically pointed one way: code is checked against design at write time. The **World Model** (per [ADR-031](docs/ADR/031-world-model-ownership-and-corpus-lifecycle.md)–[037](docs/ADR/037-world-cli-and-output-contract.md)) makes that constraint surface **endpoint-symmetric**: design documents, source metadata, tests, the requirement-test matrix, and attestations are extracted into a typed, content-addressed fact graph, and a pinned constraint is re-evaluated whenever *either* endpoint changes — so editing a design document creates visible obligations on the code that claimed it, not just the other way around.
242
242
 
243
- Three commands (always runnable explicitly; `world.enabled` in `phasegate.config.json` defaults to `false` and only governs future gate integration):
243
+ Three commands are always runnable explicitly. The product default for `world.enabled` is `false`; enabling it activates the registered L2/L3 integrations. This repository enables it for dogfooding.
244
244
 
245
245
  ```bash
246
246
  npx phasegate world:inspect --json # deterministic read-only snapshot: nodes, edges, extraction diagnostics
@@ -254,8 +254,11 @@ Design commitments that keep it honest:
254
254
  - **New violations fail closed from day one.** Pre-existing violations are adopted into a closed, human-reviewable baseline (`phasegate.world-baseline.json`) that can only shrink; same-ruleset additions are rejected.
255
255
  - **Known semantic gaps are declared, never "rediscovered."** Explicit debts live in `phasegate.world-debts.json` and are displayed as imports; waivers (`phasegate.world-waivers.json`) require a fingerprint, reason, expiry, and Work Item.
256
256
  - **Determinism is a contract.** Double runs over the same checkout produce byte-identical JSON output.
257
+ - **Enforcement has two trust levels.** `L2-017` is a forgeable local fast-path; `L3-008` authoritatively re-derives from the current corpus and never trusts `.harness/world-obligations.json`. Adopted legacy remains visible and non-blocking; new structural or malformed declarations fail closed.
258
+ - **Agent context is bounded.** SessionStart shows at most five open items within 2,000 characters, summarizes adopted legacy as a count, and fails open with a fixed warning if derivation is unavailable.
259
+ - **Evidence pins one root.** Attestation v2 seals `worldSnapshotRoot` in gate-run evidence without copying fragment digests; v1 produce/verify compatibility remains available.
257
260
 
258
- Current scope is **CLI-only**: validator IDs L2-017 / L3-008 are reserved but not yet registered into pre-commit/CI gating, which is tracked as a future phase.
261
+ World enforcement is production-integrated: `L2-017` and `L3-008` are registered, the bundled CI gate conditionally runs deterministic derivation for World-enabled projects, and this repository runs the full dogfood path.
259
262
 
260
263
  ---
261
264
 
@@ -0,0 +1,110 @@
1
+ {
2
+ "$schema": "https://json-schema.org/draft/2020-12/schema",
3
+ "$id": "https://phasegate.dev/contracts/attestation-v2.schema.json",
4
+ "title": "PhaseGate attestation v2",
5
+ "type": "object",
6
+ "additionalProperties": false,
7
+ "required": [
8
+ "schemaVersion",
9
+ "predicateType",
10
+ "subject",
11
+ "inputs",
12
+ "granularity",
13
+ "acBoundScope",
14
+ "worldSnapshotRoot",
15
+ "metadata",
16
+ "signature"
17
+ ],
18
+ "properties": {
19
+ "schemaVersion": { "const": "phasegate-attestation/v2" },
20
+ "predicateType": { "const": "https://phasegate.dev/attestation/gate-run/v2" },
21
+ "worldSnapshotRoot": { "$ref": "#/$defs/digest" },
22
+ "subject": {
23
+ "type": "object",
24
+ "additionalProperties": false,
25
+ "required": ["command", "gateResult", "validatorSet"],
26
+ "properties": {
27
+ "command": { "type": "string", "minLength": 1 },
28
+ "gateResult": { "enum": ["pass", "fail"] },
29
+ "validatorSet": {
30
+ "type": "array",
31
+ "items": {
32
+ "type": "object",
33
+ "additionalProperties": false,
34
+ "required": ["validatorId", "passed", "skipped"],
35
+ "properties": {
36
+ "validatorId": { "type": "string", "minLength": 1 },
37
+ "passed": { "type": "boolean" },
38
+ "skipped": { "type": "boolean" }
39
+ }
40
+ }
41
+ }
42
+ }
43
+ },
44
+ "inputs": {
45
+ "type": "object",
46
+ "additionalProperties": false,
47
+ "required": ["digestAlgorithm", "sources", "inputDigest"],
48
+ "properties": {
49
+ "digestAlgorithm": { "const": "sha256" },
50
+ "sources": {
51
+ "type": "array",
52
+ "items": {
53
+ "type": "object",
54
+ "additionalProperties": false,
55
+ "required": ["path", "digest"],
56
+ "properties": {
57
+ "path": { "type": "string", "minLength": 1 },
58
+ "digest": { "$ref": "#/$defs/digest" }
59
+ }
60
+ }
61
+ },
62
+ "inputDigest": { "$ref": "#/$defs/digest" }
63
+ }
64
+ },
65
+ "granularity": {
66
+ "type": "object",
67
+ "additionalProperties": false,
68
+ "required": ["traceability"],
69
+ "properties": {
70
+ "traceability": {
71
+ "type": "object",
72
+ "additionalProperties": false,
73
+ "required": ["validator", "level", "claim", "knownLimitations"],
74
+ "properties": {
75
+ "validator": { "type": "string", "minLength": 1 },
76
+ "level": { "enum": ["file", "ac"] },
77
+ "claim": { "type": "string" },
78
+ "knownLimitations": { "type": "array", "items": { "type": "string" } }
79
+ }
80
+ }
81
+ }
82
+ },
83
+ "acBoundScope": { "type": "array", "items": { "type": "string" } },
84
+ "metadata": {
85
+ "type": "object",
86
+ "additionalProperties": false,
87
+ "required": ["producedAt", "producer", "gitCommit"],
88
+ "properties": {
89
+ "producedAt": { "type": "string", "minLength": 1 },
90
+ "producer": { "type": "string", "minLength": 1 },
91
+ "gitCommit": { "type": ["string", "null"] }
92
+ }
93
+ },
94
+ "signature": {
95
+ "type": "object",
96
+ "additionalProperties": false,
97
+ "required": ["mode", "attestationDigest", "algorithm", "keyId", "value"],
98
+ "properties": {
99
+ "mode": { "enum": ["unsigned-poc", "signed"] },
100
+ "attestationDigest": { "$ref": "#/$defs/digest" },
101
+ "algorithm": { "type": ["string", "null"] },
102
+ "keyId": { "type": ["string", "null"] },
103
+ "value": { "type": ["string", "null"] }
104
+ }
105
+ }
106
+ },
107
+ "$defs": {
108
+ "digest": { "type": "string", "pattern": "^sha256:[0-9a-f]{64}$" }
109
+ }
110
+ }
@@ -328,8 +328,9 @@ L4 warning findings fail the process only when warning strictness is enabled (`v
328
328
  ## World Model
329
329
 
330
330
  <!-- @work-item-id WI-299 -->
331
+ <!-- @work-item-id WI-307 -->
331
332
 
332
- World Model コマンド(ADR-037)。設計文書・ソース・テスト・matrix・attestation を型付き事実グラフとして抽出し、pin された制約を両端点対称に再評価して義務を導出する。明示実行は config に依存せず常に可能(`world.enabled` は既定 `false` で、将来の L2/L3 ゲート統合のみを制御。validator ID `L2-017` / `L3-008` は予約済み・未登録)。
333
+ World Model コマンド(ADR-037)。設計文書・ソース・テスト・matrix・attestation を型付き事実グラフとして抽出し、pin された制約を両端点対称に再評価して義務を導出する。明示実行は config に依存せず常に可能。`world.enabled` のproduct既定値は`false`で、trueの場合に登録済み`L2-017` / `L3-008`とSessionStart integrationを有効化する。phasegate self-repoはdogfoodのためtrueである。
333
334
 
334
335
  | Command | Options | Description |
335
336
  |---|---|---|
@@ -337,6 +338,16 @@ World Model コマンド(ADR-037)。設計文書・ソース・テスト・m
337
338
  | `world:pin` | `--constraint <id>`(`pgw:v1:constraint` ID, 必須) `--endpoint <claimant\|premise>`(必須) `--apply` `--format human\|json` `--json` | 制約端点の現在 digest をプレビュー。`--apply` で `phasegate.world-constraints.json` を atomic に更新 |
338
339
  | `world:derive` | `--write` `--out <path>`(`--write` 必須) `--format human\|json` `--json` | immutable な obligation report を再導出。既定は pure・read-only。`--write` で raw report を `.harness/world-obligations.json`(untracked)へ永続化 |
339
340
 
341
+ ### Automatic integration
342
+
343
+ | Surface | Contract |
344
+ |---|---|
345
+ | `L2-017 world-constraint-admission` | local fast-path。new / changed constraintのmalformed、新規pin / unpinned claimをfail-closed。adopted-legacyはwarningのみ。local resultは偽造可能でauthorityではない |
346
+ | `L3-008 world-constraint-rederivation` | current corpusとversioned control inputからauthoritativeにpure再導出。保存`.harness/world-obligations.json`は読まず、改竄・削除で結果が変わらない |
347
+ | SessionStart | blocking相当を優先して最大5件 / 2000 Unicode scalar。adopted-legacyは件数一行、全文やreasonをpromptへ注入しない。derive不能は固定warningへfail-open |
348
+ | Attestation v2 | `phasegate-attestation/v2`がcanonical`worldSnapshotRoot`一件をpin。fragment digest collectionは保存しない。既存v1のproduce / verify互換を維持 |
349
+ | Bundled `aidlc-gate` | `world.enabled:true`のprojectでmatrix生成後にpure deriveを二回実行してbyte一致を確認し、その後L3を実行。false / absentではWorld段階だけをskip |
350
+
340
351
  ### Exit code
341
352
 
342
353
  | Exit | 意味 |
@@ -76,6 +76,36 @@ The plan identifies target fields, managed artifacts, commands, validation, risk
76
76
  "format": "json",
77
77
  "outputDir": "reports"
78
78
  },
79
+ "world": {
80
+ "enabled": false,
81
+ "corpus": {
82
+ "productRoots": ["docs/product"],
83
+ "inceptionRoots": ["docs/inception"],
84
+ "adrRoots": ["docs/ADR"],
85
+ "sourceRoots": ["scripts/harness"],
86
+ "include": ["**/*"],
87
+ "exclude": []
88
+ },
89
+ "inputs": {
90
+ "matrixPath": ".harness/requirement-test-matrix.json",
91
+ "attestationPath": ".harness/attestation.json",
92
+ "integrityManifestPath": "phasegate.integrity.json"
93
+ },
94
+ "declarations": {
95
+ "constraintsPath": "phasegate.world-constraints.json",
96
+ "baselinePath": "phasegate.world-baseline.json",
97
+ "waiversPath": "phasegate.world-waivers.json",
98
+ "debtsPath": "phasegate.world-debts.json"
99
+ },
100
+ "output": {
101
+ "obligationReportPath": ".harness/world-obligations.json"
102
+ },
103
+ "sessionStart": {
104
+ "enabled": true,
105
+ "maxItems": 5,
106
+ "maxChars": 2000
107
+ }
108
+ },
79
109
  "preCommit": {
80
110
  "implementationExtensions": [".ts"]
81
111
  },
@@ -115,6 +145,8 @@ The `strict` preset also enables:
115
145
  - `bundleSizeLimit` -- 500 KB default cap
116
146
  - `deadCodeGC` -- automatic dead-code garbage collection
117
147
 
148
+ All three presets resolve the same World Model defaults with `world.enabled: false`. This switch controls future automatic L2/L3 and hook integration; it does not disable explicit `world:inspect`, `world:pin`, or `world:derive` commands. Enabling automatic World gates remains an explicit rollout decision. <!-- @work-item-id WI-300 -->
149
+
118
150
  ---
119
151
 
120
152
  ### Field Reference
@@ -216,6 +248,30 @@ Example for Python and TypeScript:
216
248
 
217
249
  The metadata validators read `@unit` and `@layer` with language-agnostic regular expressions, so Python `# @unit api` and Go `// @unit api` style comments are both valid as long as the file extension is included here.
218
250
 
251
+ #### `world`
252
+
253
+ <!-- @work-item-id WI-300 -->
254
+
255
+ `world` configures the World Model read corpus and reviewed control inputs. It is available in both v2 and v3 config schemas. Nested fields may be omitted and are resolved from the selected preset.
256
+
257
+ | Field | Default | Meaning |
258
+ |---|---|---|
259
+ | `enabled` | `false` | Enables future automatic validator/hook integration; explicit `world:*` commands remain available |
260
+ | `corpus.productRoots` | `["docs/product"]` | Canonical product corpus roots |
261
+ | `corpus.inceptionRoots` | `["docs/inception"]` | Proposal/delta corpus roots |
262
+ | `corpus.adrRoots` | `["docs/ADR"]` | ADR corpus roots |
263
+ | `corpus.sourceRoots` | `["scripts/harness"]` | Source/test corpus roots |
264
+ | `corpus.include` / `exclude` | `["**/*"]` / `[]` | Versioned selection patterns |
265
+ | `inputs.matrixPath` | `.harness/requirement-test-matrix.json` | Matrix owner projection input |
266
+ | `inputs.attestationPath` | `.harness/attestation.json` | Attestation evidence input |
267
+ | `inputs.integrityManifestPath` | `phasegate.integrity.json` | Integrity declaration input |
268
+ | `declarations.*Path` | `phasegate.world-{constraints,baseline,waivers,debts}.json` | Git-reviewed external declarations |
269
+ | `output.obligationReportPath` | `.harness/world-obligations.json` | Generated, non-authoritative report path |
270
+ | `sessionStart.enabled` | `true` | Allows the bounded World summary when session integration is installed |
271
+ | `sessionStart.maxItems` / `maxChars` | `5` / `2000` | Summary caps; valid ranges are 1–20 and 1–8000 |
272
+
273
+ All paths are project-relative POSIX paths. Absolute paths, backslashes, `.` / `..` segments, cross-role corpus root overlap, and case-fold collisions are rejected. When the matching World field is omitted, legacy `paths.designDocs`, `paths.inceptionDocs`, and `layers.L3.requirementMatrixPath` remain compatible inputs. A present but invalid `world` section fails closed; it is never replaced with defaults silently.
274
+
219
275
  #### `phase2Extensions`
220
276
 
221
277
  <!-- @work-item-id WI-170 -->
@@ -56,7 +56,7 @@ 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` and `.codex/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`. 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 -->
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` and `.codex/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
60
 
61
61
  For personal evaluation inside a team-owned repository:
62
62
 
@@ -7,8 +7,11 @@
7
7
  # 実行内容:
8
8
  # 1. bypass:audit — bypass trailer / evidence 監査
9
9
  # 2. phasegate lint — L1 Biome AST ルール検証
10
- # 3. phasegate:ci-check L3 CI バリデータ(security / performance / coverage / nyquist)
11
- # 4. 失敗時: PR にエラーサマリーをコメント
10
+ # 3. package coverage script を実行し、L3-003 の入力を生成
11
+ # 4. requirement-test matrix をcurrent testsから再生成
12
+ # 5. world.enabled=true の場合、world:derive を2回実行してbyte一致を検証
13
+ # 6. phasegate:ci-check — L3 CI バリデータ(security / performance / coverage / nyquist / World)
14
+ # 7. 失敗時: PR にエラーサマリーをコメント
12
15
 
13
16
  name: AIDLC Quality Gate
14
17
 
@@ -77,6 +80,61 @@ jobs:
77
80
  echo "exit_code=$EXIT_CODE" >> $GITHUB_OUTPUT
78
81
  exit $EXIT_CODE
79
82
 
83
+ # L3-003 is fail-closed when coverageThreshold is configured but the
84
+ # report is absent. The adopting project owns this script and must emit
85
+ # coverage/coverage-summary.json; package-manager selection follows the
86
+ # lockfile used during dependency installation above.
87
+ - name: Test and generate coverage
88
+ shell: bash
89
+ run: |
90
+ set -euo pipefail
91
+ node -e "const scripts=require('./package.json').scripts ?? {}; if (!scripts.coverage) { throw new Error('phasegate aidlc-gate requires package.json scripts.coverage to generate coverage/coverage-summary.json'); }"
92
+ if [ -f pnpm-lock.yaml ]; then
93
+ pnpm run coverage
94
+ elif [ -f yarn.lock ]; then
95
+ yarn coverage
96
+ else
97
+ npm run coverage
98
+ fi
99
+
100
+ # L3-004 consumes the generated requirement-test matrix. Always rebuild it
101
+ # from this checkout instead of trusting a stale or persisted artifact.
102
+ - name: Generate requirement-test matrix
103
+ if: always()
104
+ run: npx phasegate phasegate:generate-matrix
105
+
106
+ # Automatic World integration is selected only by an explicit true value.
107
+ # Missing/false keeps existing projects compatible; invalid JSON is a hard
108
+ # configuration error and must not be laundered into a disabled result.
109
+ - name: Detect World Model enablement
110
+ id: world_config
111
+ if: always()
112
+ shell: bash
113
+ run: |
114
+ set -euo pipefail
115
+ ENABLED=$(node --input-type=module <<'NODE'
116
+ import { existsSync, readFileSync } from 'node:fs';
117
+ if (!existsSync('phasegate.config.json')) {
118
+ process.stdout.write('false');
119
+ } else {
120
+ const config = JSON.parse(readFileSync('phasegate.config.json', 'utf8'));
121
+ process.stdout.write(config.world?.enabled === true ? 'true' : 'false');
122
+ }
123
+ NODE
124
+ )
125
+ echo "enabled=$ENABLED" >> "$GITHUB_OUTPUT"
126
+
127
+ - name: World derive determinism
128
+ if: steps.world_config.outputs.enabled == 'true'
129
+ shell: bash
130
+ run: |
131
+ set -euo pipefail
132
+ FIRST="$RUNNER_TEMP/phasegate-world-first.json"
133
+ SECOND="$RUNNER_TEMP/phasegate-world-second.json"
134
+ npx phasegate world:derive --json > "$FIRST"
135
+ npx phasegate world:derive --json > "$SECOND"
136
+ cmp --silent "$FIRST" "$SECOND"
137
+
80
138
  # L3: CI バリデータ(security / performance / coverage / nyquist)
81
139
  - name: L3 CI Check
82
140
  id: ci_check
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "phasegate",
3
- "version": "0.254.0",
3
+ "version": "0.283.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",
@@ -78,7 +78,7 @@
78
78
  "vitest": "^3.0.0"
79
79
  },
80
80
  "peerDependencies": {
81
- "typescript": ">=5.0.0"
81
+ "typescript": ">=5.0.0 <7.0.0"
82
82
  },
83
83
  "peerDependenciesMeta": {
84
84
  "typescript": {
@@ -0,0 +1,30 @@
1
+ // @unit agent-integration
2
+ // @layer application
3
+ // @work-item-id WI-304
4
+
5
+ export type OpenWorldObligationClassification =
6
+ | "new-structural"
7
+ | "invalid-declaration"
8
+ | "expired-waiver"
9
+ | "policy-diagnostic"
10
+ | "cleanup-required"
11
+ | "waived";
12
+
13
+ export interface OpenWorldObligationContextItemDto {
14
+ readonly kind: "structural" | "cleanup-required" | "policy-diagnostic";
15
+ readonly classification: OpenWorldObligationClassification;
16
+ readonly ruleId: string | null;
17
+ readonly constraintId: string | null;
18
+ readonly violationFingerprint: string | null;
19
+ readonly subjectId: string | null;
20
+ readonly policyCode?: string | null;
21
+ }
22
+
23
+ export type OpenWorldObligationsContextDto =
24
+ | { readonly status: "disabled" }
25
+ | { readonly status: "unavailable" }
26
+ | {
27
+ readonly status: "available";
28
+ readonly entries: readonly OpenWorldObligationContextItemDto[];
29
+ readonly adoptedLegacyCount: number;
30
+ };
@@ -0,0 +1,30 @@
1
+ // @unit agent-integration
2
+ // @layer application
3
+ // @work-item-id WI-304
4
+
5
+ export type QueriedWorldObligationClassification =
6
+ | "adopted-legacy"
7
+ | "new-structural"
8
+ | "invalid-declaration"
9
+ | "expired-waiver"
10
+ | "policy-diagnostic"
11
+ | "cleanup-required"
12
+ | "waived";
13
+
14
+ export interface QueriedWorldObligationEntry {
15
+ readonly kind: "structural" | "cleanup-required" | "policy-diagnostic";
16
+ readonly classification: QueriedWorldObligationClassification;
17
+ readonly ruleId: string | null;
18
+ readonly constraintId: string | null;
19
+ readonly violationFingerprint: string | null;
20
+ readonly subjectId?: string | null;
21
+ readonly policyCode?: string | null;
22
+ }
23
+
24
+ export type WorldObligationsQueryResult =
25
+ | { readonly status: "available"; readonly entries: readonly QueriedWorldObligationEntry[] }
26
+ | { readonly status: "unavailable" };
27
+
28
+ export interface WorldObligationsQueryPort {
29
+ query(): Promise<WorldObligationsQueryResult>;
30
+ }
@@ -0,0 +1,66 @@
1
+ // @unit agent-integration
2
+ // @layer application
3
+ // @work-item-id WI-304
4
+
5
+ import type {
6
+ OpenWorldObligationContextItemDto,
7
+ OpenWorldObligationsContextDto,
8
+ } from "../dto/open-world-obligations-context-dto.js";
9
+ import type { QueriedWorldObligationEntry, WorldObligationsQueryPort } from "../ports/world-obligations-query-port.js";
10
+
11
+ interface Dependencies {
12
+ readonly worldObligationsQueryPort: WorldObligationsQueryPort;
13
+ }
14
+
15
+ const priority = (entry: OpenWorldObligationContextItemDto): number => {
16
+ if (entry.classification === "new-structural" || entry.classification === "invalid-declaration") return 0;
17
+ if (entry.classification === "expired-waiver" || entry.classification === "policy-diagnostic") return 1;
18
+ if (entry.classification === "cleanup-required") return 2;
19
+ return 3;
20
+ };
21
+
22
+ const stableKey = (entry: OpenWorldObligationContextItemDto): string =>
23
+ [
24
+ priority(entry).toString().padStart(2, "0"),
25
+ entry.ruleId ?? "",
26
+ entry.constraintId ?? "",
27
+ entry.violationFingerprint ?? "",
28
+ entry.subjectId ?? "",
29
+ entry.policyCode ?? "",
30
+ ].join("\u0000");
31
+
32
+ type DisplayableQueriedEntry = QueriedWorldObligationEntry & {
33
+ readonly classification: Exclude<QueriedWorldObligationEntry["classification"], "adopted-legacy">;
34
+ };
35
+
36
+ const isDisplayable = (entry: QueriedWorldObligationEntry): entry is DisplayableQueriedEntry =>
37
+ entry.classification !== "adopted-legacy";
38
+
39
+ const toContextItem = (entry: DisplayableQueriedEntry): OpenWorldObligationContextItemDto => ({
40
+ kind: entry.kind,
41
+ classification: entry.classification,
42
+ ruleId: entry.ruleId,
43
+ constraintId: entry.constraintId,
44
+ violationFingerprint: entry.violationFingerprint,
45
+ subjectId: entry.subjectId ?? null,
46
+ policyCode: entry.policyCode ?? null,
47
+ });
48
+
49
+ export class GetOpenWorldObligationsContextUseCase {
50
+ constructor(private readonly dependencies: Dependencies) {}
51
+
52
+ async execute(input: { readonly enabled: boolean }): Promise<OpenWorldObligationsContextDto> {
53
+ if (!input.enabled) return { status: "disabled" };
54
+
55
+ const result = await this.dependencies.worldObligationsQueryPort.query();
56
+ if (result.status === "unavailable") return { status: "unavailable" };
57
+
58
+ const adoptedLegacyCount = result.entries.filter((entry) => entry.classification === "adopted-legacy").length;
59
+ const entries = result.entries
60
+ .filter(isDisplayable)
61
+ .map(toContextItem)
62
+ .sort((left, right) => (stableKey(left) < stableKey(right) ? -1 : stableKey(left) > stableKey(right) ? 1 : 0));
63
+
64
+ return { status: "available", entries: Object.freeze(entries), adoptedLegacyCount };
65
+ }
66
+ }