phasegate 0.222.0 → 0.254.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 (108) hide show
  1. package/CHANGELOG.md +51 -1
  2. package/README.ja.md +28 -1
  3. package/README.md +27 -0
  4. package/docs/ADR/001-l1-biome-editor-time-enforcement.md +2 -0
  5. package/docs/ADR/015-architecture-preset.md +2 -0
  6. package/docs/ADR/031-world-model-ownership-and-corpus-lifecycle.md +155 -0
  7. package/docs/ADR/032-world-node-identity.md +198 -0
  8. package/docs/ADR/033-world-snapshot-canonicalization.md +246 -0
  9. package/docs/ADR/034-world-constraint-semantics.md +218 -0
  10. package/docs/ADR/035-world-adoption-baseline-and-waiver.md +341 -0
  11. package/docs/ADR/036-world-model-and-doc-freshness.md +169 -0
  12. package/docs/ADR/037-world-cli-and-output-contract.md +398 -0
  13. package/docs/contracts/requirement-test-matrix.schema.json +15 -0
  14. package/docs/contracts/world-baseline.schema.json +35 -0
  15. package/docs/contracts/world-constraints.schema.json +56 -0
  16. package/docs/contracts/world-debts.schema.json +32 -0
  17. package/docs/contracts/world-obligation-report.schema.json +259 -0
  18. package/docs/contracts/world-waivers.schema.json +32 -0
  19. package/docs/guide/cli-reference.md +34 -0
  20. package/package.json +1 -1
  21. package/scripts/harness/attestation/application/ports/sha256-capability.ts +25 -0
  22. package/scripts/harness/attestation/composition-root.ts +14 -4
  23. package/scripts/harness/attestation/index.ts +6 -1
  24. package/scripts/harness/attestation/infrastructure/adapters/node-crypto-content-hasher-adapter.ts +6 -6
  25. package/scripts/harness/attestation/infrastructure/adapters/node-crypto-sha256-capability.ts +19 -0
  26. package/scripts/harness/harness-api/domain/value-objects/known-harness-commands.ts +4 -1
  27. package/scripts/harness/main.ts +107 -1
  28. package/scripts/harness/nyquist-validation/application/dto/generate-matrix-output.ts +11 -0
  29. package/scripts/harness/nyquist-validation/application/usecases/check-ac-coverage-gate-usecase.ts +6 -0
  30. package/scripts/harness/nyquist-validation/application/usecases/generate-requirement-test-matrix-usecase.ts +8 -4
  31. package/scripts/harness/nyquist-validation/domain/entities/story-mapping.ts +29 -2
  32. package/scripts/harness/nyquist-validation/domain/services/ac-coverage-gate-policy.ts +28 -0
  33. package/scripts/harness/nyquist-validation/infrastructure/adapters/markdown-requirement-source-adapter.ts +71 -4
  34. package/scripts/harness/nyquist-validation/infrastructure/schema/matrix-schema-loader.ts +4 -0
  35. package/scripts/harness/traceability-model/application/dto/traceability-world-read-dto.ts +67 -0
  36. package/scripts/harness/traceability-model/application/facades/traceability-world-read-facade.ts +372 -0
  37. package/scripts/harness/traceability-model/application/ports/traceability-world-read-source-port.ts +61 -0
  38. package/scripts/harness/traceability-model/composition-root.ts +21 -5
  39. package/scripts/harness/traceability-model/index.ts +17 -6
  40. package/scripts/harness/traceability-model/infrastructure/adapters/file-system-traceability-world-read-adapter.ts +223 -0
  41. package/scripts/harness/traceability-model/infrastructure/parsers/story-catalog-parser.ts +86 -8
  42. package/scripts/harness/world-model/application/dto/world-inspection-dto.ts +43 -0
  43. package/scripts/harness/world-model/application/dto/world-obligation-report-dto.ts +54 -0
  44. package/scripts/harness/world-model/application/dto/world-resolved-config-input.ts +62 -0
  45. package/scripts/harness/world-model/application/ports/obligation-report-writer-port.ts +7 -0
  46. package/scripts/harness/world-model/application/ports/world-control-declaration-repository-port.ts +57 -0
  47. package/scripts/harness/world-model/application/ports/world-fact-source-port.ts +17 -0
  48. package/scripts/harness/world-model/application/usecases/build-snapshot-use-case.ts +111 -0
  49. package/scripts/harness/world-model/application/usecases/derive-obligations-use-case.ts +155 -0
  50. package/scripts/harness/world-model/application/usecases/derive-world-obligations-use-case.ts +144 -0
  51. package/scripts/harness/world-model/application/usecases/inspect-world-use-case.ts +74 -0
  52. package/scripts/harness/world-model/application/usecases/pin-constraint-endpoint-use-case.ts +139 -0
  53. package/scripts/harness/world-model/composition-root.ts +218 -0
  54. package/scripts/harness/world-model/domain/entities/constraint-record.ts +148 -0
  55. package/scripts/harness/world-model/domain/entities/control-declarations.ts +274 -0
  56. package/scripts/harness/world-model/domain/entities/edge.ts +41 -0
  57. package/scripts/harness/world-model/domain/entities/extraction-diagnostic.ts +60 -0
  58. package/scripts/harness/world-model/domain/entities/snapshot.ts +75 -0
  59. package/scripts/harness/world-model/domain/entities/world-node.ts +210 -0
  60. package/scripts/harness/world-model/domain/ports/world-hashing-port.ts +8 -0
  61. package/scripts/harness/world-model/domain/services/canonical-json-serializer.ts +113 -0
  62. package/scripts/harness/world-model/domain/services/constraint-evaluator.ts +486 -0
  63. package/scripts/harness/world-model/domain/services/obligation-derivation-service.ts +199 -0
  64. package/scripts/harness/world-model/domain/services/policy-inputs-digest-deriver.ts +66 -0
  65. package/scripts/harness/world-model/domain/services/snapshot-root-deriver.ts +218 -0
  66. package/scripts/harness/world-model/domain/services/text-content-normalizer.ts +30 -0
  67. package/scripts/harness/world-model/domain/services/violation-fingerprint-deriver.ts +183 -0
  68. package/scripts/harness/world-model/domain/value-objects/artifact-kind.ts +58 -0
  69. package/scripts/harness/world-model/domain/value-objects/change-provenance.ts +137 -0
  70. package/scripts/harness/world-model/domain/value-objects/corpus-role.ts +57 -0
  71. package/scripts/harness/world-model/domain/value-objects/declared-key.ts +35 -0
  72. package/scripts/harness/world-model/domain/value-objects/evaluation-id.ts +41 -0
  73. package/scripts/harness/world-model/domain/value-objects/explicit-constraint-relation.ts +53 -0
  74. package/scripts/harness/world-model/domain/value-objects/explicit-node-alias.ts +30 -0
  75. package/scripts/harness/world-model/domain/value-objects/node-pin.ts +34 -0
  76. package/scripts/harness/world-model/domain/value-objects/path-key.ts +103 -0
  77. package/scripts/harness/world-model/domain/value-objects/sha256-digest.ts +39 -0
  78. package/scripts/harness/world-model/domain/value-objects/violation-fingerprint.ts +36 -0
  79. package/scripts/harness/world-model/domain/value-objects/wcr-rule-id.ts +59 -0
  80. package/scripts/harness/world-model/domain/value-objects/world-node-id.ts +222 -0
  81. package/scripts/harness/world-model/index.ts +22 -0
  82. package/scripts/harness/world-model/infrastructure/adapters/adr-fact-extractor.ts +27 -0
  83. package/scripts/harness/world-model/infrastructure/adapters/assembled-world-fact-source.ts +17 -0
  84. package/scripts/harness/world-model/infrastructure/adapters/attestation-fact-extractor.ts +288 -0
  85. package/scripts/harness/world-model/infrastructure/adapters/attestation-sha256-world-hashing-adapter.ts +15 -0
  86. package/scripts/harness/world-model/infrastructure/adapters/composite-design-fact-source.ts +23 -0
  87. package/scripts/harness/world-model/infrastructure/adapters/design-corpus-fact-extractor.ts +285 -0
  88. package/scripts/harness/world-model/infrastructure/adapters/design-fact-extraction.ts +63 -0
  89. package/scripts/harness/world-model/infrastructure/adapters/file-system-obligation-report-writer-adapter.ts +37 -0
  90. package/scripts/harness/world-model/infrastructure/adapters/file-system-world-control-repository-adapters.ts +330 -0
  91. package/scripts/harness/world-model/infrastructure/adapters/integrity-manifest-fact-extractor.ts +101 -0
  92. package/scripts/harness/world-model/infrastructure/adapters/json-fact-extractor-support.ts +151 -0
  93. package/scripts/harness/world-model/infrastructure/adapters/markdown-design-fact-extractor.ts +493 -0
  94. package/scripts/harness/world-model/infrastructure/adapters/matrix-fact-extractor.ts +283 -0
  95. package/scripts/harness/world-model/infrastructure/adapters/product-fact-extractor.ts +29 -0
  96. package/scripts/harness/world-model/infrastructure/adapters/proposal-fact-extractor.ts +29 -0
  97. package/scripts/harness/world-model/infrastructure/adapters/runtime-fact-extraction.ts +19 -0
  98. package/scripts/harness/world-model/infrastructure/adapters/source-metadata-fact-extractor.ts +22 -0
  99. package/scripts/harness/world-model/infrastructure/adapters/test-reference-source-fact-extractor.ts +22 -0
  100. package/scripts/harness/world-model/infrastructure/adapters/traceability-design-fact-adapter.ts +112 -0
  101. package/scripts/harness/world-model/infrastructure/adapters/traceability-world-read-facade-merger.ts +38 -0
  102. package/scripts/harness/world-model/infrastructure/adapters/type-script-source-fact-extractor.ts +236 -0
  103. package/scripts/harness/world-model/infrastructure/adapters/unit-fact-extractor.ts +71 -0
  104. package/scripts/harness/world-model/infrastructure/adapters/world-control-declaration-mapper.ts +383 -0
  105. package/scripts/harness/world-model/presentation/cli/world-command-support.ts +60 -0
  106. package/scripts/harness/world-model/presentation/cli/world-derive-command-handler.ts +105 -0
  107. package/scripts/harness/world-model/presentation/cli/world-inspect-command-handler.ts +194 -0
  108. package/scripts/harness/world-model/presentation/cli/world-pin-command-handler.ts +100 -0
@@ -0,0 +1,259 @@
1
+ {
2
+ "$schema": "https://json-schema.org/draft/2020-12/schema",
3
+ "$id": "https://phasegate.dev/contracts/world-obligation-report.schema.json",
4
+ "title": "PhaseGate World obligation report",
5
+ "type": "object",
6
+ "additionalProperties": false,
7
+ "required": [
8
+ "schemaVersion",
9
+ "evaluationId",
10
+ "rulesetVersion",
11
+ "policyInputsDigest",
12
+ "structuralObligations",
13
+ "repaidBaselineEntries",
14
+ "declaredSemanticDebts",
15
+ "policyDiagnostics",
16
+ "summary"
17
+ ],
18
+ "properties": {
19
+ "schemaVersion": { "const": "phasegate-world-obligation-report/v1" },
20
+ "evaluationId": {
21
+ "type": "string",
22
+ "pattern": "^pgw:v1:evaluation:sha256:[0-9a-f]{64}$"
23
+ },
24
+ "rulesetVersion": { "type": "string", "minLength": 1 },
25
+ "policyInputsDigest": {
26
+ "type": "string",
27
+ "pattern": "^sha256:[0-9a-f]{64}$"
28
+ },
29
+ "structuralObligations": {
30
+ "type": "array",
31
+ "items": { "$ref": "#/$defs/structuralObligation" }
32
+ },
33
+ "repaidBaselineEntries": {
34
+ "type": "array",
35
+ "items": { "$ref": "#/$defs/repaidBaselineEntry" }
36
+ },
37
+ "declaredSemanticDebts": {
38
+ "type": "array",
39
+ "items": { "$ref": "#/$defs/semanticDebt" }
40
+ },
41
+ "policyDiagnostics": {
42
+ "type": "array",
43
+ "items": { "$ref": "#/$defs/policyDiagnostic" }
44
+ },
45
+ "summary": {
46
+ "type": "object",
47
+ "additionalProperties": false,
48
+ "required": [
49
+ "structuralObligations",
50
+ "repaidBaselineEntries",
51
+ "declaredSemanticDebts",
52
+ "policyDiagnostics"
53
+ ],
54
+ "properties": {
55
+ "structuralObligations": { "type": "integer", "minimum": 0 },
56
+ "repaidBaselineEntries": { "type": "integer", "minimum": 0 },
57
+ "declaredSemanticDebts": { "type": "integer", "minimum": 0 },
58
+ "policyDiagnostics": { "type": "integer", "minimum": 0 }
59
+ }
60
+ }
61
+ },
62
+ "$defs": {
63
+ "jsonValue": {
64
+ "oneOf": [
65
+ { "type": "null" },
66
+ { "type": "boolean" },
67
+ { "type": "number" },
68
+ { "type": "string" },
69
+ {
70
+ "type": "array",
71
+ "items": { "$ref": "#/$defs/jsonValue" }
72
+ },
73
+ {
74
+ "type": "object",
75
+ "additionalProperties": { "$ref": "#/$defs/jsonValue" }
76
+ }
77
+ ]
78
+ },
79
+ "pin": {
80
+ "oneOf": [
81
+ { "type": "null" },
82
+ {
83
+ "type": "object",
84
+ "additionalProperties": false,
85
+ "required": ["nodeId", "contentDigest"],
86
+ "properties": {
87
+ "nodeId": { "type": "string", "pattern": "^pgw:v1:.+" },
88
+ "contentDigest": {
89
+ "type": "string",
90
+ "pattern": "^sha256:[0-9a-f]{64}$"
91
+ }
92
+ }
93
+ }
94
+ ]
95
+ },
96
+ "subject": {
97
+ "type": "object",
98
+ "additionalProperties": false,
99
+ "required": ["endpointRole", "nodeIds"],
100
+ "properties": {
101
+ "endpointRole": {
102
+ "enum": ["claimant", "premise", "both", "declaration", "global"]
103
+ },
104
+ "nodeIds": {
105
+ "type": "array",
106
+ "items": { "type": "string", "pattern": "^pgw:v1:.+" }
107
+ }
108
+ }
109
+ },
110
+ "waiver": {
111
+ "oneOf": [
112
+ { "type": "null" },
113
+ {
114
+ "type": "object",
115
+ "additionalProperties": false,
116
+ "required": ["waiverId", "reason", "expiresOn", "workItemId"],
117
+ "properties": {
118
+ "waiverId": { "type": "string", "pattern": "^pgw:v1:waiver:.+" },
119
+ "reason": { "type": "string", "minLength": 1 },
120
+ "expiresOn": {
121
+ "type": "string",
122
+ "pattern": "^[0-9]{4}-[0-9]{2}-[0-9]{2}$"
123
+ },
124
+ "workItemId": { "type": "string", "pattern": "^WI-[0-9]+$" }
125
+ }
126
+ }
127
+ ]
128
+ },
129
+ "structuralObligation": {
130
+ "type": "object",
131
+ "additionalProperties": false,
132
+ "required": [
133
+ "violationFingerprint",
134
+ "ruleId",
135
+ "constraintId",
136
+ "factType",
137
+ "subject",
138
+ "claimantPin",
139
+ "premisePin",
140
+ "expected",
141
+ "observed",
142
+ "classification",
143
+ "waiver"
144
+ ],
145
+ "properties": {
146
+ "violationFingerprint": {
147
+ "type": "string",
148
+ "pattern": "^pgw:v1:violation-fingerprint:sha256:[0-9a-f]{64}$"
149
+ },
150
+ "ruleId": { "type": "string", "pattern": "^WCR-[0-9]{3}$" },
151
+ "constraintId": {
152
+ "oneOf": [
153
+ { "type": "null" },
154
+ { "type": "string", "pattern": "^pgw:v1:constraint:.+" }
155
+ ]
156
+ },
157
+ "factType": {
158
+ "oneOf": [
159
+ { "type": "null" },
160
+ {
161
+ "enum": ["references", "depends-on", "refines", "content-equals"]
162
+ }
163
+ ]
164
+ },
165
+ "subject": { "$ref": "#/$defs/subject" },
166
+ "claimantPin": { "$ref": "#/$defs/pin" },
167
+ "premisePin": { "$ref": "#/$defs/pin" },
168
+ "expected": {
169
+ "type": "object",
170
+ "additionalProperties": { "$ref": "#/$defs/jsonValue" }
171
+ },
172
+ "observed": {
173
+ "type": "object",
174
+ "additionalProperties": { "$ref": "#/$defs/jsonValue" }
175
+ },
176
+ "classification": {
177
+ "enum": [
178
+ "adopted-legacy",
179
+ "new-structural",
180
+ "invalid-declaration",
181
+ "waived"
182
+ ]
183
+ },
184
+ "waiver": { "$ref": "#/$defs/waiver" }
185
+ }
186
+ },
187
+ "repaidBaselineEntry": {
188
+ "type": "object",
189
+ "additionalProperties": false,
190
+ "required": [
191
+ "violationFingerprint",
192
+ "ruleId",
193
+ "constraintId",
194
+ "classification",
195
+ "disposition"
196
+ ],
197
+ "properties": {
198
+ "violationFingerprint": {
199
+ "type": "string",
200
+ "pattern": "^pgw:v1:violation-fingerprint:sha256:[0-9a-f]{64}$"
201
+ },
202
+ "ruleId": { "type": "string", "pattern": "^WCR-[0-9]{3}$" },
203
+ "constraintId": {
204
+ "oneOf": [
205
+ { "type": "null" },
206
+ { "type": "string", "pattern": "^pgw:v1:constraint:.+" }
207
+ ]
208
+ },
209
+ "classification": { "const": "repaid" },
210
+ "disposition": { "const": "cleanup-required" }
211
+ }
212
+ },
213
+ "semanticDebt": {
214
+ "type": "object",
215
+ "additionalProperties": false,
216
+ "required": [
217
+ "schemaVersion",
218
+ "debtId",
219
+ "kind",
220
+ "title",
221
+ "reason",
222
+ "ownerUnit",
223
+ "introducedByWorkItemId",
224
+ "references"
225
+ ],
226
+ "properties": {
227
+ "schemaVersion": { "const": "phasegate-world-debts/v1" },
228
+ "debtId": { "type": "string", "pattern": "^pgw:v1:semantic-debt:.+" },
229
+ "kind": { "const": "semantic" },
230
+ "title": { "type": "string", "minLength": 1 },
231
+ "reason": { "type": "string", "minLength": 1 },
232
+ "ownerUnit": { "type": "string", "minLength": 1 },
233
+ "introducedByWorkItemId": {
234
+ "type": "string",
235
+ "pattern": "^WI-[0-9]+$"
236
+ },
237
+ "references": {
238
+ "type": "array",
239
+ "items": { "type": "string", "pattern": "^pgw:v1:.+" }
240
+ }
241
+ }
242
+ },
243
+ "policyDiagnostic": {
244
+ "type": "object",
245
+ "additionalProperties": false,
246
+ "required": ["code", "subjectId", "details"],
247
+ "properties": {
248
+ "code": { "type": "string", "pattern": "^[a-z][a-z0-9-]*$" },
249
+ "subjectId": {
250
+ "oneOf": [{ "type": "null" }, { "type": "string", "minLength": 1 }]
251
+ },
252
+ "details": {
253
+ "type": "object",
254
+ "additionalProperties": { "$ref": "#/$defs/jsonValue" }
255
+ }
256
+ }
257
+ }
258
+ }
259
+ }
@@ -0,0 +1,32 @@
1
+ {
2
+ "$schema": "https://json-schema.org/draft/2020-12/schema",
3
+ "$id": "https://phasegate.dev/contracts/world-waivers.schema.json",
4
+ "title": "PhaseGate World waivers",
5
+ "type": "object",
6
+ "additionalProperties": false,
7
+ "required": ["schemaVersion", "waivers"],
8
+ "properties": {
9
+ "schemaVersion": { "const": "phasegate-world-waivers/v1" },
10
+ "waivers": {
11
+ "type": "array",
12
+ "items": {
13
+ "type": "object",
14
+ "additionalProperties": false,
15
+ "required": ["waiverId", "violationFingerprint", "reason", "expiresOn", "workItemId", "renewalOf"],
16
+ "properties": {
17
+ "waiverId": { "type": "string", "pattern": "^pgw:v1:waiver:[a-z][a-z0-9]*(?:[._-][a-z0-9]+)*$" },
18
+ "violationFingerprint": { "type": "string", "pattern": "^pgw:v1:violation-fingerprint:sha256:[0-9a-f]{64}$" },
19
+ "reason": { "type": "string", "minLength": 1 },
20
+ "expiresOn": { "type": "string", "pattern": "^[0-9]{4}-[0-9]{2}-[0-9]{2}$" },
21
+ "workItemId": { "type": "string", "pattern": "^WI-[0-9]+$" },
22
+ "renewalOf": {
23
+ "oneOf": [
24
+ { "type": "null" },
25
+ { "type": "string", "pattern": "^pgw:v1:waiver:[a-z][a-z0-9]*(?:[._-][a-z0-9]+)*$" }
26
+ ]
27
+ }
28
+ }
29
+ }
30
+ }
31
+ }
32
+ }
@@ -325,6 +325,40 @@ L4 warning findings fail the process only when warning strictness is enabled (`v
325
325
 
326
326
  ---
327
327
 
328
+ ## World Model
329
+
330
+ <!-- @work-item-id WI-299 -->
331
+
332
+ World Model コマンド(ADR-037)。設計文書・ソース・テスト・matrix・attestation を型付き事実グラフとして抽出し、pin された制約を両端点対称に再評価して義務を導出する。明示実行は config に依存せず常に可能(`world.enabled` は既定 `false` で、将来の L2/L3 ゲート統合のみを制御。validator ID `L2-017` / `L3-008` は予約済み・未登録)。
333
+
334
+ | Command | Options | Description |
335
+ |---|---|---|
336
+ | `world:inspect` | `--format human\|json` `--json` | Read-only World snapshot(node / edge / 抽出 diagnostics)を構築・表示。宣言も report も書かない |
337
+ | `world:pin` | `--constraint <id>`(`pgw:v1:constraint` ID, 必須) `--endpoint <claimant\|premise>`(必須) `--apply` `--format human\|json` `--json` | 制約端点の現在 digest をプレビュー。`--apply` で `phasegate.world-constraints.json` を atomic に更新 |
338
+ | `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
+ ### Exit code
341
+
342
+ | Exit | 意味 |
343
+ |---|---|
344
+ | 0 | クリーン(`world:derive` では adopted-legacy / waived / declared debt のみで blocking なし) |
345
+ | 1 | blocking な finding あり(`world:inspect` は抽出 diagnostics あり、`world:derive` は新規違反・期限切れ waiver 等) |
346
+ | 2 | 契約エラー(未知の control-file schema、不正な引数など) |
347
+
348
+ ### 制御ファイルと出力
349
+
350
+ | File | Role |
351
+ |---|---|
352
+ | `phasegate.world-constraints.json` | pin された制約宣言(`world:pin --apply` が更新する唯一の mutation 経路) |
353
+ | `phasegate.world-baseline.json` | 既存違反の adoption baseline(閉じた集合・縮小のみ。同一 ruleset での追加は拒否) |
354
+ | `phasegate.world-waivers.json` | 単一 fingerprint 単位の waiver(理由 / 期限 / Work Item 必須) |
355
+ | `phasegate.world-debts.json` | 宣言済み semantic debt(import として表示され、「再発見」はしない) |
356
+ | `.harness/world-obligations.json` | `world:derive --write` の永続 report。**導出結果のキャッシュに過ぎず**、手編集・削除しても再導出の判定は変わらない |
357
+
358
+ JSON 出力は envelope `phasegate-world-cli/v1` に包まれ、同一 checkout での 2 回実行は byte-identical(決定性契約)。schema は `docs/contracts/world-*.schema.json` を参照。
359
+
360
+ ---
361
+
328
362
  ## ADR Management
329
363
 
330
364
  | Command | Options | Description |
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "phasegate",
3
- "version": "0.222.0",
3
+ "version": "0.254.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",
@@ -0,0 +1,25 @@
1
+ // @unit attestation
2
+ // @layer application
3
+ // @work-item-id WI-286
4
+
5
+ /**
6
+ * Unit境界を越えて受け渡すplain SHA-256 digest。
7
+ *
8
+ * 64桁lowercase hexのruntime invariantはproviderと各consumer-local VOが検証する。
9
+ * attestation domainのDigestはこのpublic contractへ露出しない。
10
+ */
11
+ export type Sha256DigestString = `sha256:${string}`;
12
+
13
+ /**
14
+ * Raw bytesをSHA-256するattestation public capability。
15
+ */
16
+ export interface Sha256Capability {
17
+ hashBytes(bytes: Uint8Array): Sha256DigestString;
18
+ }
19
+
20
+ /**
21
+ * Unicode normalizationを行わず、TextEncoderのUTF-8 bytesをpublic capabilityへ渡す。
22
+ */
23
+ export function hashUtf8(capability: Sha256Capability, text: string): Sha256DigestString {
24
+ return capability.hashBytes(new TextEncoder().encode(text));
25
+ }
@@ -10,16 +10,18 @@
10
10
  import { execFile } from "node:child_process";
11
11
  import { promisify } from "node:util";
12
12
  import { AttestationRecordMapper } from "./application/mappers/attestation-record-mapper.js";
13
+ import type { Sha256Capability } from "./application/ports/sha256-capability.js";
13
14
  import { ProduceAttestationUseCase } from "./application/usecases/produce-attestation-usecase.js";
14
15
  import { VerifyAttestationUseCase } from "./application/usecases/verify-attestation-usecase.js";
15
- import { GranularityDerivationService } from "./domain/services/granularity-derivation-service.js";
16
16
  import { AcBoundScopeService } from "./domain/services/ac-bound-scope-service.js";
17
+ import { GranularityDerivationService } from "./domain/services/granularity-derivation-service.js";
17
18
  import { CiCheckGateResultAdapter } from "./infrastructure/adapters/ci-check-gate-result-adapter.js";
19
+ import { ConfigAcBoundAllowlistAdapter } from "./infrastructure/adapters/config-ac-bound-allowlist-adapter.js";
18
20
  import { FileSystemAttestationRepositoryAdapter } from "./infrastructure/adapters/file-system-attestation-repository-adapter.js";
19
- import { FileSystemSourceDigesterAdapter } from "./infrastructure/adapters/file-system-source-digester-adapter.js";
20
21
  import { FileSystemMatrixSourceAdapter } from "./infrastructure/adapters/file-system-matrix-source-adapter.js";
21
- import { ConfigAcBoundAllowlistAdapter } from "./infrastructure/adapters/config-ac-bound-allowlist-adapter.js";
22
+ import { FileSystemSourceDigesterAdapter } from "./infrastructure/adapters/file-system-source-digester-adapter.js";
22
23
  import { NodeCryptoContentHasherAdapter } from "./infrastructure/adapters/node-crypto-content-hasher-adapter.js";
24
+ import { NodeCryptoSha256Capability } from "./infrastructure/adapters/node-crypto-sha256-capability.js";
23
25
  import { AttestHandler } from "./presentation/handlers/attest-handler.js";
24
26
  import { VerifyAttestationHandler } from "./presentation/handlers/verify-attestation-handler.js";
25
27
 
@@ -41,13 +43,21 @@ export interface AttestationModuleOptions {
41
43
  readonly clock?: () => Date;
42
44
  }
43
45
 
46
+ /**
47
+ * Unit非依存のplain SHA-256 public capabilityを生成する。
48
+ */
49
+ export function createSha256Capability(): Sha256Capability {
50
+ return new NodeCryptoSha256Capability();
51
+ }
52
+
44
53
  /**
45
54
  * attestation Unit のモジュールを組み立てる。
46
55
  * @param rootDir プロジェクトルート(source digest / repository の baseDir)。
47
56
  */
48
57
  export function createAttestationModule(rootDir: string, options?: AttestationModuleOptions): AttestationModule {
49
58
  // Infrastructure adapters
50
- const hasher = new NodeCryptoContentHasherAdapter();
59
+ const sha256Capability = createSha256Capability();
60
+ const hasher = new NodeCryptoContentHasherAdapter(sha256Capability);
51
61
  const sourceDigester = new FileSystemSourceDigesterAdapter(rootDir);
52
62
  const gateResultSource = new CiCheckGateResultAdapter({ mainTsPath: options?.mainTsPath });
53
63
  const repository = new FileSystemAttestationRepositoryAdapter(rootDir);
@@ -5,9 +5,14 @@
5
5
  // Public DTO types
6
6
  export type { AttestationDocument } from "./application/dto/attestation-document.js";
7
7
  export type { VerifyAttestationOutput } from "./application/dto/verify-attestation-output.js";
8
+ export {
9
+ hashUtf8,
10
+ type Sha256Capability,
11
+ type Sha256DigestString,
12
+ } from "./application/ports/sha256-capability.js";
8
13
  export type { AttestationModule, AttestationModuleOptions } from "./composition-root.js";
9
14
  // Composition Root
10
- export { createAttestationModule } from "./composition-root.js";
15
+ export { createAttestationModule, createSha256Capability } from "./composition-root.js";
11
16
  export type { AttestHandlerArgs, AttestHandlerResult } from "./presentation/handlers/attest-handler.js";
12
17
  // Presentation Handlers
13
18
  export { AttestHandler } from "./presentation/handlers/attest-handler.js";
@@ -1,18 +1,18 @@
1
1
  // @unit attestation
2
2
  // @layer infrastructure
3
3
 
4
- import { createHash } from "node:crypto";
4
+ import { hashUtf8, type Sha256Capability } from "../../application/ports/sha256-capability.js";
5
5
  import type { ContentHasherPort } from "../../domain/ports/content-hasher-port.js";
6
6
  import { Digest } from "../../domain/value-objects/digest.js";
7
+ import { NodeCryptoSha256Capability } from "./node-crypto-sha256-capability.js";
7
8
 
8
9
  /**
9
- * ContentHasherPort node:crypto 実装。
10
- * canonical payload / source content の sha256 を `sha256:<64hex>` Digest として返す。
11
- * installation の node-crypto-hash-adapter をミラーし、アルゴリズムは sha256 に固定する。
10
+ * Public Sha256Capabilityをattestation-local ContentHasherPortへ変換するadapter。
12
11
  */
13
12
  export class NodeCryptoContentHasherAdapter implements ContentHasherPort {
13
+ constructor(private readonly capability: Sha256Capability = new NodeCryptoSha256Capability()) {}
14
+
14
15
  sha256(content: string): Digest {
15
- const hex = createHash("sha256").update(content, "utf8").digest("hex");
16
- return Digest.fromSha256Hex(hex);
16
+ return Digest.create(hashUtf8(this.capability, content));
17
17
  }
18
18
  }
@@ -0,0 +1,19 @@
1
+ // @unit attestation
2
+ // @layer infrastructure
3
+ // @work-item-id WI-286
4
+
5
+ import { createHash } from "node:crypto";
6
+ import type { Sha256Capability, Sha256DigestString } from "../../application/ports/sha256-capability.js";
7
+
8
+ /**
9
+ * Attestation public SHA-256 capabilityのNode.js実装。
10
+ *
11
+ * 既存NodeCryptoContentHasherAdapterからprimitiveを移動し、
12
+ * World向けにnode:crypto call siteを増やさない。
13
+ */
14
+ export class NodeCryptoSha256Capability implements Sha256Capability {
15
+ hashBytes(bytes: Uint8Array): Sha256DigestString {
16
+ const hex = createHash("sha256").update(bytes).digest("hex");
17
+ return `sha256:${hex}`;
18
+ }
19
+ }
@@ -1,6 +1,6 @@
1
1
  // @unit harness-api
2
2
  // @layer domain
3
- // @work-item-id WI-250
3
+ // @work-item-id WI-250, WI-291, WI-296
4
4
  // known-harness-commands.ts — CLI 実サーフェスの canonical 既知コマンド一覧
5
5
  //
6
6
  // main.ts の CLI dispatch(`switch (command)`)が受理する全トップレベルコマンド名の
@@ -87,4 +87,7 @@ export const KNOWN_HARNESS_COMMANDS: readonly string[] = Object.freeze([
87
87
  "validate-fix",
88
88
  "validate-metadata",
89
89
  "work-items:status",
90
+ "world:derive",
91
+ "world:inspect",
92
+ "world:pin",
90
93
  ]);
@@ -21,6 +21,7 @@
21
21
  * @work-item-id WI-213
22
22
  * @work-item-id WI-217
23
23
  * @work-item-id WI-219
24
+ * @work-item-id WI-291
24
25
  *
25
26
  * Phasegate CLI エントリポイント。
26
27
  * 各Unitの Composition Root からハンドラーを取得し、コマンドに応じてディスパッチする。
@@ -92,6 +93,12 @@ import {
92
93
  import { createSkillQualityHandlers } from "./skill-quality/composition-root.js";
93
94
  import { createTraceabilityModelModule } from "./traceability-model/composition-root.js";
94
95
  import { createValidatorSystemModule } from "./validator-system/composition-root.js";
96
+ import {
97
+ createWorldModelModule,
98
+ WorldDeriveCommandHandler,
99
+ WorldInspectCommandHandler,
100
+ WorldPinCommandHandler,
101
+ } from "./world-model/index.js";
95
102
 
96
103
  /**
97
104
  * main.ts (scripts/harness/main.ts) から2階層上がパッケージルート。
@@ -232,6 +239,9 @@ Commands:
232
239
  phasegate:generate-matrix Generate requirement-test matrix (--requirements, --tests, --out, --json)
233
240
  phasegate:attest Produce a signed-attestation record of ci-check (--out <path>, --require-pass, --mode <unsigned-poc|signed>, --json)
234
241
  phasegate:verify-attestation Verify an attestation record's integrity (<file>, --json)
242
+ world:inspect Inspect the read-only World snapshot (--format human|json, --json)
243
+ world:pin Preview or apply an endpoint pin (--constraint, --endpoint, --apply)
244
+ world:derive Derive obligations (--write, --out, --format human|json, --json)
235
245
 
236
246
  Gate semantics:
237
247
  phasegate:complete-check Gate: lint + all validators; exits 1 on failure
@@ -780,6 +790,35 @@ Options:
780
790
  "phasegate:check-ready": `Usage: phasegate phasegate:check-ready
781
791
 
782
792
  Check whether the harness is ready (config valid, hooks deployed).`,
793
+ "world:inspect": `Usage: phasegate world:inspect [options]
794
+
795
+ Inspect the read-only World snapshot without writing declarations or generated reports.
796
+
797
+ Options:
798
+ --format <human|json> Output format (default: human)
799
+ --json Alias for --format json
800
+ --help, -h Show this help`,
801
+ "world:pin": `Usage: phasegate world:pin --constraint <id> --endpoint <claimant|premise> [options]
802
+
803
+ Preview a current endpoint digest. Use --apply to atomically update phasegate.world-constraints.json.
804
+
805
+ Options:
806
+ --constraint <id> pgw:v1:constraint ID
807
+ --endpoint <role> claimant or premise
808
+ --apply Atomically apply the candidate
809
+ --format <human|json> Output format (default: human)
810
+ --json Alias for --format json
811
+ --help, -h Show this help`,
812
+ "world:derive": `Usage: phasegate world:derive [options]
813
+
814
+ Derive the immutable World obligation report. Default mode is pure and read-only.
815
+
816
+ Options:
817
+ --write Persist the raw obligation report
818
+ --out <path> Override report path (requires --write)
819
+ --format <human|json> Output format (default: human)
820
+ --json Alias for --format json
821
+ --help, -h Show this help`,
783
822
  "phasegate:complete-check": `Usage: phasegate phasegate:complete-check
784
823
 
785
824
  Run completion check (used by Stop hook). Validates phase-gate, metadata, and test-quality.`,
@@ -1838,6 +1877,21 @@ async function loadResolvedConfig(): Promise<HarnessConfigV2 | undefined> {
1838
1877
  }
1839
1878
  }
1840
1879
 
1880
+ async function loadWorldResolvedConfig() {
1881
+ try {
1882
+ const configModule = createConfigFoundationModule();
1883
+ const result = await configModule.usecases.loadResolvedConfigUseCase.execute();
1884
+ return {
1885
+ designDocsRoot: result.config.paths.designDocs,
1886
+ inceptionRoot: result.config.paths.inceptionDocs,
1887
+ requirementMatrixPath: result.config.layers.L3.requirementMatrixPath,
1888
+ };
1889
+ } catch (error) {
1890
+ if (error instanceof ConfigNotFoundError) return undefined;
1891
+ throw error;
1892
+ }
1893
+ }
1894
+
1841
1895
  async function main(): Promise<void> {
1842
1896
  const args = process.argv.slice(2);
1843
1897
  const command = args[0];
@@ -1865,7 +1919,7 @@ async function main(): Promise<void> {
1865
1919
  const json = hasFlag(args, "--json");
1866
1920
 
1867
1921
  // Cross-unit wiring: 設定を先に解決し、各Unit に注入する
1868
- const resolvedConfig = await loadResolvedConfig();
1922
+ const resolvedConfig = command.startsWith("world:") ? undefined : await loadResolvedConfig();
1869
1923
 
1870
1924
  try {
1871
1925
  switch (command) {
@@ -2664,6 +2718,58 @@ async function main(): Promise<void> {
2664
2718
  break;
2665
2719
  }
2666
2720
 
2721
+ // ── world-model ──
2722
+ case "world:inspect": {
2723
+ let handler: WorldInspectCommandHandler;
2724
+ try {
2725
+ handler = createWorldModelModule({
2726
+ rootDir,
2727
+ resolvedConfig: await loadWorldResolvedConfig(),
2728
+ }).worldInspectCommandHandler;
2729
+ } catch (error) {
2730
+ handler = WorldInspectCommandHandler.fromFailure(error);
2731
+ }
2732
+ const result = await handler.execute(args.slice(1));
2733
+ if (result.stdout.length > 0) process.stdout.write(result.stdout);
2734
+ if (result.stderr.length > 0) process.stderr.write(result.stderr);
2735
+ process.exitCode = result.exitCode;
2736
+ return;
2737
+ }
2738
+
2739
+ case "world:pin": {
2740
+ let handler: WorldPinCommandHandler;
2741
+ try {
2742
+ handler = createWorldModelModule({
2743
+ rootDir,
2744
+ resolvedConfig: await loadWorldResolvedConfig(),
2745
+ }).worldPinCommandHandler;
2746
+ } catch (error) {
2747
+ handler = WorldPinCommandHandler.fromFailure(error);
2748
+ }
2749
+ const result = await handler.execute(args.slice(1));
2750
+ if (result.stdout.length > 0) process.stdout.write(result.stdout);
2751
+ if (result.stderr.length > 0) process.stderr.write(result.stderr);
2752
+ process.exitCode = result.exitCode;
2753
+ return;
2754
+ }
2755
+
2756
+ case "world:derive": {
2757
+ let handler: WorldDeriveCommandHandler;
2758
+ try {
2759
+ handler = createWorldModelModule({
2760
+ rootDir,
2761
+ resolvedConfig: await loadWorldResolvedConfig(),
2762
+ }).worldDeriveCommandHandler;
2763
+ } catch (error) {
2764
+ handler = WorldDeriveCommandHandler.fromFailure(error);
2765
+ }
2766
+ const result = await handler.execute(args.slice(1));
2767
+ if (result.stdout.length > 0) process.stdout.write(result.stdout);
2768
+ if (result.stderr.length > 0) process.stderr.write(result.stderr);
2769
+ process.exitCode = result.exitCode;
2770
+ return;
2771
+ }
2772
+
2667
2773
  // ── phase-dependency-model ──
2668
2774
  case "check-phase-gate": {
2669
2775
  const phaseConfig = resolvedConfig ? toPhaseConfigSection(resolvedConfig) : undefined;