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.
- package/CHANGELOG.md +51 -1
- package/README.ja.md +28 -1
- package/README.md +27 -0
- package/docs/ADR/001-l1-biome-editor-time-enforcement.md +2 -0
- package/docs/ADR/015-architecture-preset.md +2 -0
- package/docs/ADR/031-world-model-ownership-and-corpus-lifecycle.md +155 -0
- package/docs/ADR/032-world-node-identity.md +198 -0
- package/docs/ADR/033-world-snapshot-canonicalization.md +246 -0
- package/docs/ADR/034-world-constraint-semantics.md +218 -0
- package/docs/ADR/035-world-adoption-baseline-and-waiver.md +341 -0
- package/docs/ADR/036-world-model-and-doc-freshness.md +169 -0
- package/docs/ADR/037-world-cli-and-output-contract.md +398 -0
- package/docs/contracts/requirement-test-matrix.schema.json +15 -0
- package/docs/contracts/world-baseline.schema.json +35 -0
- package/docs/contracts/world-constraints.schema.json +56 -0
- package/docs/contracts/world-debts.schema.json +32 -0
- package/docs/contracts/world-obligation-report.schema.json +259 -0
- package/docs/contracts/world-waivers.schema.json +32 -0
- package/docs/guide/cli-reference.md +34 -0
- package/package.json +1 -1
- package/scripts/harness/attestation/application/ports/sha256-capability.ts +25 -0
- package/scripts/harness/attestation/composition-root.ts +14 -4
- package/scripts/harness/attestation/index.ts +6 -1
- package/scripts/harness/attestation/infrastructure/adapters/node-crypto-content-hasher-adapter.ts +6 -6
- package/scripts/harness/attestation/infrastructure/adapters/node-crypto-sha256-capability.ts +19 -0
- package/scripts/harness/harness-api/domain/value-objects/known-harness-commands.ts +4 -1
- package/scripts/harness/main.ts +107 -1
- package/scripts/harness/nyquist-validation/application/dto/generate-matrix-output.ts +11 -0
- package/scripts/harness/nyquist-validation/application/usecases/check-ac-coverage-gate-usecase.ts +6 -0
- package/scripts/harness/nyquist-validation/application/usecases/generate-requirement-test-matrix-usecase.ts +8 -4
- package/scripts/harness/nyquist-validation/domain/entities/story-mapping.ts +29 -2
- package/scripts/harness/nyquist-validation/domain/services/ac-coverage-gate-policy.ts +28 -0
- package/scripts/harness/nyquist-validation/infrastructure/adapters/markdown-requirement-source-adapter.ts +71 -4
- package/scripts/harness/nyquist-validation/infrastructure/schema/matrix-schema-loader.ts +4 -0
- package/scripts/harness/traceability-model/application/dto/traceability-world-read-dto.ts +67 -0
- package/scripts/harness/traceability-model/application/facades/traceability-world-read-facade.ts +372 -0
- package/scripts/harness/traceability-model/application/ports/traceability-world-read-source-port.ts +61 -0
- package/scripts/harness/traceability-model/composition-root.ts +21 -5
- package/scripts/harness/traceability-model/index.ts +17 -6
- package/scripts/harness/traceability-model/infrastructure/adapters/file-system-traceability-world-read-adapter.ts +223 -0
- package/scripts/harness/traceability-model/infrastructure/parsers/story-catalog-parser.ts +86 -8
- package/scripts/harness/world-model/application/dto/world-inspection-dto.ts +43 -0
- package/scripts/harness/world-model/application/dto/world-obligation-report-dto.ts +54 -0
- package/scripts/harness/world-model/application/dto/world-resolved-config-input.ts +62 -0
- package/scripts/harness/world-model/application/ports/obligation-report-writer-port.ts +7 -0
- package/scripts/harness/world-model/application/ports/world-control-declaration-repository-port.ts +57 -0
- package/scripts/harness/world-model/application/ports/world-fact-source-port.ts +17 -0
- package/scripts/harness/world-model/application/usecases/build-snapshot-use-case.ts +111 -0
- package/scripts/harness/world-model/application/usecases/derive-obligations-use-case.ts +155 -0
- package/scripts/harness/world-model/application/usecases/derive-world-obligations-use-case.ts +144 -0
- package/scripts/harness/world-model/application/usecases/inspect-world-use-case.ts +74 -0
- package/scripts/harness/world-model/application/usecases/pin-constraint-endpoint-use-case.ts +139 -0
- package/scripts/harness/world-model/composition-root.ts +218 -0
- package/scripts/harness/world-model/domain/entities/constraint-record.ts +148 -0
- package/scripts/harness/world-model/domain/entities/control-declarations.ts +274 -0
- package/scripts/harness/world-model/domain/entities/edge.ts +41 -0
- package/scripts/harness/world-model/domain/entities/extraction-diagnostic.ts +60 -0
- package/scripts/harness/world-model/domain/entities/snapshot.ts +75 -0
- package/scripts/harness/world-model/domain/entities/world-node.ts +210 -0
- package/scripts/harness/world-model/domain/ports/world-hashing-port.ts +8 -0
- package/scripts/harness/world-model/domain/services/canonical-json-serializer.ts +113 -0
- package/scripts/harness/world-model/domain/services/constraint-evaluator.ts +486 -0
- package/scripts/harness/world-model/domain/services/obligation-derivation-service.ts +199 -0
- package/scripts/harness/world-model/domain/services/policy-inputs-digest-deriver.ts +66 -0
- package/scripts/harness/world-model/domain/services/snapshot-root-deriver.ts +218 -0
- package/scripts/harness/world-model/domain/services/text-content-normalizer.ts +30 -0
- package/scripts/harness/world-model/domain/services/violation-fingerprint-deriver.ts +183 -0
- package/scripts/harness/world-model/domain/value-objects/artifact-kind.ts +58 -0
- package/scripts/harness/world-model/domain/value-objects/change-provenance.ts +137 -0
- package/scripts/harness/world-model/domain/value-objects/corpus-role.ts +57 -0
- package/scripts/harness/world-model/domain/value-objects/declared-key.ts +35 -0
- package/scripts/harness/world-model/domain/value-objects/evaluation-id.ts +41 -0
- package/scripts/harness/world-model/domain/value-objects/explicit-constraint-relation.ts +53 -0
- package/scripts/harness/world-model/domain/value-objects/explicit-node-alias.ts +30 -0
- package/scripts/harness/world-model/domain/value-objects/node-pin.ts +34 -0
- package/scripts/harness/world-model/domain/value-objects/path-key.ts +103 -0
- package/scripts/harness/world-model/domain/value-objects/sha256-digest.ts +39 -0
- package/scripts/harness/world-model/domain/value-objects/violation-fingerprint.ts +36 -0
- package/scripts/harness/world-model/domain/value-objects/wcr-rule-id.ts +59 -0
- package/scripts/harness/world-model/domain/value-objects/world-node-id.ts +222 -0
- package/scripts/harness/world-model/index.ts +22 -0
- package/scripts/harness/world-model/infrastructure/adapters/adr-fact-extractor.ts +27 -0
- package/scripts/harness/world-model/infrastructure/adapters/assembled-world-fact-source.ts +17 -0
- package/scripts/harness/world-model/infrastructure/adapters/attestation-fact-extractor.ts +288 -0
- package/scripts/harness/world-model/infrastructure/adapters/attestation-sha256-world-hashing-adapter.ts +15 -0
- package/scripts/harness/world-model/infrastructure/adapters/composite-design-fact-source.ts +23 -0
- package/scripts/harness/world-model/infrastructure/adapters/design-corpus-fact-extractor.ts +285 -0
- package/scripts/harness/world-model/infrastructure/adapters/design-fact-extraction.ts +63 -0
- package/scripts/harness/world-model/infrastructure/adapters/file-system-obligation-report-writer-adapter.ts +37 -0
- package/scripts/harness/world-model/infrastructure/adapters/file-system-world-control-repository-adapters.ts +330 -0
- package/scripts/harness/world-model/infrastructure/adapters/integrity-manifest-fact-extractor.ts +101 -0
- package/scripts/harness/world-model/infrastructure/adapters/json-fact-extractor-support.ts +151 -0
- package/scripts/harness/world-model/infrastructure/adapters/markdown-design-fact-extractor.ts +493 -0
- package/scripts/harness/world-model/infrastructure/adapters/matrix-fact-extractor.ts +283 -0
- package/scripts/harness/world-model/infrastructure/adapters/product-fact-extractor.ts +29 -0
- package/scripts/harness/world-model/infrastructure/adapters/proposal-fact-extractor.ts +29 -0
- package/scripts/harness/world-model/infrastructure/adapters/runtime-fact-extraction.ts +19 -0
- package/scripts/harness/world-model/infrastructure/adapters/source-metadata-fact-extractor.ts +22 -0
- package/scripts/harness/world-model/infrastructure/adapters/test-reference-source-fact-extractor.ts +22 -0
- package/scripts/harness/world-model/infrastructure/adapters/traceability-design-fact-adapter.ts +112 -0
- package/scripts/harness/world-model/infrastructure/adapters/traceability-world-read-facade-merger.ts +38 -0
- package/scripts/harness/world-model/infrastructure/adapters/type-script-source-fact-extractor.ts +236 -0
- package/scripts/harness/world-model/infrastructure/adapters/unit-fact-extractor.ts +71 -0
- package/scripts/harness/world-model/infrastructure/adapters/world-control-declaration-mapper.ts +383 -0
- package/scripts/harness/world-model/presentation/cli/world-command-support.ts +60 -0
- package/scripts/harness/world-model/presentation/cli/world-derive-command-handler.ts +105 -0
- package/scripts/harness/world-model/presentation/cli/world-inspect-command-handler.ts +194 -0
- 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
|
@@ -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 {
|
|
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
|
|
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";
|
package/scripts/harness/attestation/infrastructure/adapters/node-crypto-content-hasher-adapter.ts
CHANGED
|
@@ -1,18 +1,18 @@
|
|
|
1
1
|
// @unit attestation
|
|
2
2
|
// @layer infrastructure
|
|
3
3
|
|
|
4
|
-
import {
|
|
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
|
-
*
|
|
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
|
-
|
|
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
|
]);
|
package/scripts/harness/main.ts
CHANGED
|
@@ -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;
|