phasegate 0.229.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/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,246 @@
|
|
|
1
|
+
---
|
|
2
|
+
adr_id: "033"
|
|
3
|
+
title: "World snapshot canonicalization、version roots、hashing"
|
|
4
|
+
status: Proposed
|
|
5
|
+
date: 2026-07-16
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
# World snapshot canonicalization、version roots、hashing
|
|
9
|
+
|
|
10
|
+
<!-- @work-item-id WI-283 -->
|
|
11
|
+
|
|
12
|
+
## Context
|
|
13
|
+
|
|
14
|
+
World Modelはclean checkoutのcorpusとdeclarationから同じfacts / obligationsを再導出しなければならない。filesystem列挙順、object insertion order、absolute checkout root、clock、generated reportがrootへ混ざると、論理入力が同じでも異なるsnapshotになる。一方、extractor、ruleset、schema、World-relevant resolved configが変われば解釈が変わるため、その差はrootへ反映しなければならない。
|
|
15
|
+
|
|
16
|
+
既存実装には三つの重要な先例と差異がある。
|
|
17
|
+
|
|
18
|
+
- attestation `canonicalStringify`はobject keyを再帰sortし、array orderを保持し、空白なしJSONをUTF-8 SHA-256へ渡す。
|
|
19
|
+
- attestation / ci-governance integrityのfile digesterは`readFile` raw bytesをSHA-256へ渡す。
|
|
20
|
+
- requirement-test-matrixは`generatedAt`を毎回生成し、pretty JSONとして保存するため、保存bytesのhashはsemantic matrix identityにならない。
|
|
21
|
+
|
|
22
|
+
また、既存`NodeCryptoContentHasherAdapter`はattestation-local `ContentHasherPort`と`Digest`を使う。ADR-031によりworld-modelはprovider内部型をimportできず、consumer-owned portを持つ必要がある。ADR-032は`pgw:v1` node IDとPathKeyを確定済みである。
|
|
23
|
+
|
|
24
|
+
## Decision
|
|
25
|
+
|
|
26
|
+
### 1. Leaf digestとthree derived rootsを分離する
|
|
27
|
+
|
|
28
|
+
Artifact / Fragment contentはowner-aware normalization後のbytesをSHA-256し、leaf digest `sha256:<hex>`としてnode factへ入れる。root envelopeはfull proseを重複保持せず、stable node IDs、typed facts、leaf digests、edges、diagnosticsをcanonical JSON化する。
|
|
29
|
+
|
|
30
|
+
三つのderived identityを定義する。
|
|
31
|
+
|
|
32
|
+
#### corpusRoot
|
|
33
|
+
|
|
34
|
+
```text
|
|
35
|
+
sha256(canonicalJson({
|
|
36
|
+
schemaVersion,
|
|
37
|
+
extractorVersion,
|
|
38
|
+
corpusConfigDigest,
|
|
39
|
+
nodes,
|
|
40
|
+
edges,
|
|
41
|
+
extractionDiagnostics
|
|
42
|
+
}))
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
- nodesはNode ID、edgesはtype/from/to/qualifier、diagnosticsはcode/node/path/line/payloadでsortする。
|
|
46
|
+
- constraints / claims / aliases / evaluation findings / obligationsを含めない。
|
|
47
|
+
- Snapshot IDは`pgw:v1:snapshot:<corpusRoot>`。
|
|
48
|
+
|
|
49
|
+
#### constraintRoot
|
|
50
|
+
|
|
51
|
+
```text
|
|
52
|
+
sha256(canonicalJson({
|
|
53
|
+
schemaVersion,
|
|
54
|
+
rulesetVersion,
|
|
55
|
+
constraintConfigDigest,
|
|
56
|
+
constraints,
|
|
57
|
+
explicitClaims,
|
|
58
|
+
aliases,
|
|
59
|
+
declarationDiagnostics
|
|
60
|
+
}))
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
- declarationsはstable IDでsortする。
|
|
64
|
+
- endpointのpinned digestはdeclaration contentなので含める。
|
|
65
|
+
- corpus facts、evaluation output、mutable repayment stateを含めない。
|
|
66
|
+
|
|
67
|
+
#### evaluationId
|
|
68
|
+
|
|
69
|
+
```text
|
|
70
|
+
pgw:v1:evaluation:sha256(
|
|
71
|
+
canonicalJson({
|
|
72
|
+
schemaVersion,
|
|
73
|
+
rulesetVersion,
|
|
74
|
+
corpusRoot,
|
|
75
|
+
constraintRoot,
|
|
76
|
+
evaluationConfigDigest,
|
|
77
|
+
policyInputsDigest
|
|
78
|
+
})
|
|
79
|
+
)
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
外部表現は`pgw:v1:evaluation:sha256:<64 lowercase hex>`。findings、obligations、blocking decision、exit code、reportを含めない。`policyInputsDigest`はADR-035で定義するbaseline / waiver等のimmutable evaluation inputで、未導入時はcanonical empty policy objectのdigestとする。
|
|
83
|
+
|
|
84
|
+
### 2. Canonical JSON contractを固定する
|
|
85
|
+
|
|
86
|
+
- object keyは全階層でECMAScript string ascending orderにsortする。
|
|
87
|
+
- serializerはarray orderを保持する。
|
|
88
|
+
- World-owned set-valued arraysはserializer前にstable ID / canonical tupleでsortする。
|
|
89
|
+
- owner-defined ordered arraysはowner orderを保持する。
|
|
90
|
+
- whitespace、indent、BOM、trailing newlineなし。
|
|
91
|
+
- string escapingとfinite JSON number renderingは`JSON.stringify` semantics。
|
|
92
|
+
- `undefined`, sparse array, function, symbol, bigint, `NaN`, Infinityを拒否し、silent omissionしない。
|
|
93
|
+
- canonical JSON bytesはUTF-8。
|
|
94
|
+
|
|
95
|
+
attestationの既存基本規則と一致させるが、serializerのownershipはworld-modelに置き、attestation domain implementationをimportしない。
|
|
96
|
+
|
|
97
|
+
### 3. Text / bytes normalizationをartifact modeごとに決める
|
|
98
|
+
|
|
99
|
+
#### UTF-8 text / raw prose
|
|
100
|
+
|
|
101
|
+
- strict UTF-8 decode。invalid sequenceをreplacement characterへ変換しない。
|
|
102
|
+
- CRLFとlone CRをLFへnormalizeする。
|
|
103
|
+
- Unicode normalization(NFC / NFD / NFKC / NFKD)は行わない。
|
|
104
|
+
- BOM、trailing whitespace、final newline、zero-width characterを含む他code pointは保持する。
|
|
105
|
+
- normalized stringをUTF-8 encodeしてhashする。
|
|
106
|
+
|
|
107
|
+
したがってline endingだけの差はrootを変えないが、Unicode code point sequence、BOM、whitespace、final newlineの差はrootを変える。
|
|
108
|
+
|
|
109
|
+
#### Structured JSON
|
|
110
|
+
|
|
111
|
+
- strict UTF-8 decode / parse。
|
|
112
|
+
- ownerのversioned schema projectionでsemantic fieldsを選ぶ。
|
|
113
|
+
- object key / string valueへUnicode normalizationを適用しない。
|
|
114
|
+
- object keyをrecursive sortし、semantic set arraysをowner IDでsortする。
|
|
115
|
+
- unknown / unsupported fieldはgeneric name dropせずdiagnostic。
|
|
116
|
+
|
|
117
|
+
#### Binary
|
|
118
|
+
|
|
119
|
+
- extractorがbinaryと明示したartifactだけraw bytesをそのままhashする。
|
|
120
|
+
- extension heuristicだけでtext / binaryを決めない。
|
|
121
|
+
|
|
122
|
+
### 4. Matrix / attestation等generated artifactをowner-aware projectionする
|
|
123
|
+
|
|
124
|
+
genericに`generatedAt`という名前のkeyを全削除しない。各owner adapterがversioned projectionを持つ。
|
|
125
|
+
|
|
126
|
+
- matrix: `generatedAt`を除外。schema version、Story / AC / TestReference semanticsを含め、Story / AC / refsをowner IDsでsortする。
|
|
127
|
+
- attestation: evidence semanticsとverification statusをpublic DTOから観測し、`producedAt`, `gitCommit`, producer package version、signature bytes、attestation self-digest、future `worldSnapshotRoot` self-referenceを除外する。
|
|
128
|
+
- World snapshot / obligation report: extractor input corpusから除外し、self-referenceを作らない。
|
|
129
|
+
- integrity manifest: owner declarationとしてpath / digest semanticsを観測するが、integrityのraw-byte digest contract自体は変更しない。
|
|
130
|
+
|
|
131
|
+
### 5. Path、symlink、case semanticsを固定する
|
|
132
|
+
|
|
133
|
+
- project-relative POSIX PathKeyだけをrootへ入れる。
|
|
134
|
+
- `./` / duplicate separatorをnormalizeし、absolute path、drive letter、backslash、`..`を拒否する。
|
|
135
|
+
- cwd、realpath、temp root、absolute checkout rootを入れない。
|
|
136
|
+
- PathKeyのcaseとUnicode sequenceを保持し、case-sensitiveに比較する。
|
|
137
|
+
- symlinkをfollowしない。link entryとtarget stringをfactとして観測し、target file contentを重複hashしない。
|
|
138
|
+
- broken / cyclic / outside-root symlinkはdiagnosticにし、traversalしない。
|
|
139
|
+
- case-fold collisionはportability diagnosticにし、merge / winner選択しない。
|
|
140
|
+
- filesystem列挙後はPathKeyでsortする。
|
|
141
|
+
|
|
142
|
+
これによりADR-032のpath-based identityを変更せず、異なるabsolute checkoutで同じrootを得る。
|
|
143
|
+
|
|
144
|
+
### 6. Volatile / self / deployment fieldsを明示的に除外する
|
|
145
|
+
|
|
146
|
+
root preimageから除外する:
|
|
147
|
+
|
|
148
|
+
- `generatedAt`, `producedAt`, duration等clock metadata
|
|
149
|
+
- absolute path、cwd、realpath、temp path
|
|
150
|
+
- mtime、inode、PID、host、user
|
|
151
|
+
- git commit
|
|
152
|
+
- package version、`skills/.harness-version`、`deployedAt`等deployment version stamp
|
|
153
|
+
- obligation report、formatter output、persisted repayment state
|
|
154
|
+
- 計算中の`corpusRoot`, Snapshot ID, `constraintRoot`, `evaluationId`
|
|
155
|
+
- attestation self-digest / signatureとfuture `worldSnapshotRoot`
|
|
156
|
+
|
|
157
|
+
除外はowner projectionで明示し、field name一致のgeneric filterは使わない。
|
|
158
|
+
|
|
159
|
+
`schemaVersion`, `extractorVersion`, `rulesetVersion`はsemantic contract versionなので除外しない。
|
|
160
|
+
|
|
161
|
+
### 7. Versionsとrelevant config digestをroot-localに含める
|
|
162
|
+
|
|
163
|
+
- corpusRoot: snapshot `schemaVersion`, `extractorVersion`, `corpusConfigDigest`
|
|
164
|
+
- constraintRoot: constraint `schemaVersion`, `rulesetVersion`, `constraintConfigDigest`
|
|
165
|
+
- evaluationId: evaluation `schemaVersion`, `rulesetVersion`, `evaluationConfigDigest`, `policyInputsDigest`
|
|
166
|
+
|
|
167
|
+
config digestはfull `phasegate.config.json` raw hashではなく、resolved defaults込みのscope-specific DTOをcanonical JSON化したSHA-256とする。
|
|
168
|
+
|
|
169
|
+
- corpus scope: corpus root / include-exclude / extractor options
|
|
170
|
+
- constraint scope: declaration locations / rule parameters
|
|
171
|
+
- evaluation scope: evaluation semanticsを変えるresolved options
|
|
172
|
+
|
|
173
|
+
output directory / format、UI limit、validator-system blocking / severity、unrelated layer configは除外する。config不在時は明示default projectionをhashする。
|
|
174
|
+
|
|
175
|
+
### 8. SHA-256 providerはattestation public facadeに置く
|
|
176
|
+
|
|
177
|
+
hashing capabilityの最終所有先は**attestation public facade**とし、新shared Unitは作らない。
|
|
178
|
+
|
|
179
|
+
public contract:
|
|
180
|
+
|
|
181
|
+
```text
|
|
182
|
+
Sha256Capability.hashBytes(bytes: Uint8Array): "sha256:<64 lowercase hex>"
|
|
183
|
+
```
|
|
184
|
+
|
|
185
|
+
- attestation `Digest`, `ContentHasherPort`, infrastructure classをpublic contractへ露出しない。
|
|
186
|
+
- `hashUtf8` helperが必要なら`TextEncoder`後に`hashBytes`へ委譲する。
|
|
187
|
+
- WM-06で既存`NodeCryptoContentHasherAdapter`の`createHash` primitiveをこのpublic capability implementationへ移動または公開する。
|
|
188
|
+
- attestationはattestation-local adapter、world-modelはworld-model infrastructure adapterからcapabilityを呼び、それぞれlocal Digest VOへ変換する。
|
|
189
|
+
- world-model domainはconsumer-owned `WorldHashingPort`だけに依存する。
|
|
190
|
+
- world-modelからattestation内部Port / VO / adapterをdeep importしない。
|
|
191
|
+
- World導入のための新しい`node:crypto` SHA-256 call siteを増やさない。
|
|
192
|
+
|
|
193
|
+
既存`FileSystemSourceDigesterAdapter`、ci-governance integrity、installationのhash実装を全て統合する作業はWM-06の必須scopeに広げない。
|
|
194
|
+
|
|
195
|
+
### 9. §10の未決事項へ回答する
|
|
196
|
+
|
|
197
|
+
#### Raw prose fragment hashのUnicode normalization
|
|
198
|
+
|
|
199
|
+
**適用しない。** CRLF / CRだけをLFへtransport-normalizeし、それ以外のUnicode code point sequenceを保持したUTF-8 bytesをhashする。NFC / NFDを同一視すると、repositoryが保持する実bytes差を機械が意味的に同一と主張するため採用しない。
|
|
200
|
+
|
|
201
|
+
#### Hashing capabilityの最終所有先
|
|
202
|
+
|
|
203
|
+
**attestation public facadeを採用する。** 既存`NodeCryptoContentHasherAdapter`を唯一のWorld向けprimitiveとしてpublic plain capability化する。新shared contract / Unitは作らず、world-modelとattestationが各consumer-owned port / local Digestへadaptする。
|
|
204
|
+
|
|
205
|
+
## Consequences
|
|
206
|
+
|
|
207
|
+
### Positive
|
|
208
|
+
|
|
209
|
+
- clean checkout、filesystem order、absolute root、JSON key order、LF / CRLFに依存しないrootを得られる。
|
|
210
|
+
- corpus、constraint、evaluationの変更原因をrootで分離できる。
|
|
211
|
+
- generated reportやself digestを入力にする循環を防げる。
|
|
212
|
+
- schema / extractor / ruleset / relevant config変更を明示的にrootへ反映できる。
|
|
213
|
+
- attestation内部domain modelを漏らさず、`node:crypto`実装を増やさずにSHA-256を再利用できる。
|
|
214
|
+
|
|
215
|
+
### Negative / Trade-off
|
|
216
|
+
|
|
217
|
+
- owner artifactごとにversioned semantic projectionとarray sort ruleが必要になる。
|
|
218
|
+
- Unicode normalizationを行わないため、見た目が同じNFC / NFD textは別digestになる。
|
|
219
|
+
- raw integrity digestとWorld normalized text digestは同じfileでも異なる場合がある。
|
|
220
|
+
- attestationがgeneric hashing capabilityのdeployment ownerとなる。
|
|
221
|
+
- version bump disciplineを誤ると異なるextractor / rulesetが同じversionを名乗るリスクがある。
|
|
222
|
+
|
|
223
|
+
## Alternatives
|
|
224
|
+
|
|
225
|
+
- **full file raw bytesを全artifactでhashする** — LF / CRLF、pretty JSON、matrix `generatedAt`でlogical rootが変わるため不採用。
|
|
226
|
+
- **全arrayをgeneric sortする** — ordered process / prose semanticsを壊すため不採用。
|
|
227
|
+
- **Unicode NFCを適用する** — repository byte差を意味的同一と主張するため不採用。
|
|
228
|
+
- **full config raw hashをrootへ入れる** — output / unrelated validator変更でrootが不必要に変わるため不採用。
|
|
229
|
+
- **obligation reportをevaluation inputにする** — derived output改竄で判定を変えられるため不採用。
|
|
230
|
+
- **attestation内部`ContentHasherPort` / `Digest`をworld-modelからimportする** — ADR-031のownership / anti-corruption境界に反するため不採用。
|
|
231
|
+
- **minimal shared hashing Unitを新設する** —primitive一つに新ownershipとproduct lifecycleを追加するコストが現状のpublic facadeより大きいため不採用。
|
|
232
|
+
- **world-model内に新しい`node:crypto` adapterを作る** — SHA-256実装を増やすため不採用。
|
|
233
|
+
|
|
234
|
+
## 関連要件・文書
|
|
235
|
+
|
|
236
|
+
- `docs/inception/_cross/WI-280/delivery_plan.md` §1, §3 WM-03, §7 ADR-033, §8, §10
|
|
237
|
+
- `docs/inception/_cross/WI-281/logical_design.md`
|
|
238
|
+
- `docs/inception/_cross/WI-282/domain_model.md`
|
|
239
|
+
- `docs/inception/_cross/WI-283/description.md`
|
|
240
|
+
- `docs/inception/_cross/WI-283/domain_model.md`
|
|
241
|
+
- `docs/inception/_cross/WI-283/logical_design.md`
|
|
242
|
+
- `docs/inception/_cross/WI-283/unit_test_design.md`
|
|
243
|
+
- ADR-027(成果物駆動の状態導出)
|
|
244
|
+
- ADR-030(attestation canonical payload / integrity)
|
|
245
|
+
- ADR-031(ownership / artifact kind / import direction)
|
|
246
|
+
- ADR-032(World node identity / PathKey / Snapshot ID)
|
|
@@ -0,0 +1,218 @@
|
|
|
1
|
+
---
|
|
2
|
+
adr_id: "034"
|
|
3
|
+
title: "World constraint semantics と endpoint-symmetric evaluation"
|
|
4
|
+
status: Proposed
|
|
5
|
+
date: 2026-07-16
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
# World constraint semantics と endpoint-symmetric evaluation
|
|
9
|
+
|
|
10
|
+
<!-- @work-item-id WI-284 -->
|
|
11
|
+
|
|
12
|
+
## Context
|
|
13
|
+
|
|
14
|
+
World Modelは、canonical snapshot上の明示関係とcontent pinから構造違反を再現可能に導出する必要がある。その際、`claimant depends-on premise`のようなfactには意味方向がある一方、claimantだけでなくpremiseの変更でも同じconstraintを再評価しなければ、前提側のdriftを見落とす。
|
|
15
|
+
|
|
16
|
+
既存`GateGraph`は`dependsOn`を有向辺としてduplicate / unknown dependency / level order / cycleを検査する。L4-001 `DriftDetectionService`はdesign / codeの集合差分を`design→code` / `code→design`として報告し、`SemanticDriftService`は明示`behaviorId`を用いてdesign / code / testを比較する。これらは明示構造の検査という先例だが、stable World node ID、両endpoint digest pin、snapshot identityを持つWorld constraintではない。
|
|
17
|
+
|
|
18
|
+
ADR-031はworld-modelが事実組立とconstraint evaluation、validator-systemがgate / blocking policyを所有すると決定した。ADR-032は`pgw:v1` ID、DeclaredKey、no-winner duplicate、single-hop explicit aliasを決定した。ADR-033はleaf digestと`corpusRoot` / `constraintRoot` / `evaluationId`を分離し、pinned endpoint digestをconstraintRootへ含めると決定した。本ADRはそれらを前提に、v1 constraint semanticsと構造ruleの限界を固定する。
|
|
19
|
+
|
|
20
|
+
## Decision
|
|
21
|
+
|
|
22
|
+
### 1. Typed directed factとendpoint-symmetric evaluationを分離する
|
|
23
|
+
|
|
24
|
+
明示relationは次の順序を持つ。
|
|
25
|
+
|
|
26
|
+
```text
|
|
27
|
+
claimant --factType--> premise
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
- `claimant`は宣言を行い、その整合を主張する側である。
|
|
31
|
+
- `premise`はclaimantの主張が参照する前提側である。
|
|
32
|
+
- v1のconstraint fact typeはexplicit `references`、`depends-on`、`refines`、`content-equals`に限定する。
|
|
33
|
+
- factのreverse edgeを生成せず、fact directionから逆向きの意味を推論しない。
|
|
34
|
+
- `content-equals`のpredicateが数学的に対称でも、claimant / premise orderはdeclaration provenanceとして保持する。
|
|
35
|
+
|
|
36
|
+
evaluationはendpoint-symmetricとする。claimantまたはpremiseのどちらかがchanged candidateになれば同じConstraintを再評価し、両endpointをcurrent snapshotから解決して全applicable ruleを評価する。この対称性は再評価trigger / coverageの性質であり、fact directionを対称化するものではない。
|
|
37
|
+
|
|
38
|
+
incremental schedulingは許可するが、そのserialized evaluation resultは全Constraintを再評価した結果と一致しなければならない。
|
|
39
|
+
|
|
40
|
+
### 2. ConstraintRecordは両endpointをNodePinとして固定する
|
|
41
|
+
|
|
42
|
+
v1 `ConstraintRecord`は次を必須とする。
|
|
43
|
+
|
|
44
|
+
```text
|
|
45
|
+
ConstraintRecord {
|
|
46
|
+
constraintId: pgw:v1:constraint:<DeclaredKey>
|
|
47
|
+
schemaVersion
|
|
48
|
+
factType
|
|
49
|
+
claimant: {
|
|
50
|
+
nodeId: pgw:v1:<node-type>:...
|
|
51
|
+
contentDigest: sha256:<64 lowercase hex>
|
|
52
|
+
}
|
|
53
|
+
premise: {
|
|
54
|
+
nodeId: pgw:v1:<node-type>:...
|
|
55
|
+
contentDigest: sha256:<64 lowercase hex>
|
|
56
|
+
}
|
|
57
|
+
applicableRuleIds: sorted non-empty WCR ID set
|
|
58
|
+
declarationArtifactId
|
|
59
|
+
declarationLocator
|
|
60
|
+
}
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
- `constraintId`はADR-032のDeclaredKey規則に従う。
|
|
64
|
+
- 両NodePinはdeclaration採用時に一意に存在するnodeから作る。missing / duplicate endpointから新規pinを作らない。
|
|
65
|
+
- content digestはADR-033のowner-aware normalization後のleaf digestである。
|
|
66
|
+
- pinは期待値であり、evaluation時にcurrent digestへ自動更新しない。
|
|
67
|
+
- alias解決後のnode ID / locatorはevaluation evidenceへ記録し、ConstraintRecordをmutationしない。
|
|
68
|
+
- `applicableRuleIds`はcanonical ID順にsortする。
|
|
69
|
+
|
|
70
|
+
canonicalized ConstraintRecordとdeclaration diagnosticsはADR-033の`constraintRoot`へ入る。current corpus facts、finding、obligation、last-evaluated time、repayment / blocking stateはConstraintRecordへ入れない。
|
|
71
|
+
|
|
72
|
+
corpus-wide ID uniquenessは明示Constraintがなくても常時評価するimplicit structural invariantである。ADR-032の`duplicate-node-id` extraction diagnosticをwinnerなしで受け取り、後述`WCR-005` violationへ投影する。duplicate candidateを偽の別IDへ書き換えてNodePinにしない。
|
|
73
|
+
|
|
74
|
+
### 3. 機械ruleを5種類の構造判定に限定する
|
|
75
|
+
|
|
76
|
+
v1の機械判定categoryは次だけとする。
|
|
77
|
+
|
|
78
|
+
1. **existence** — endpointが一意に存在するか、baselineから削除されたか、明示alias targetが存在するか。
|
|
79
|
+
2. **ID uniqueness** — canonical IDが一つのcandidateだけへ解決するか。
|
|
80
|
+
3. **explicit reference** — 宣言されたstable ID reference / relationが解決するか。
|
|
81
|
+
4. **declared dependency** — 明示された`depends-on` relationとendpointが解決するか。
|
|
82
|
+
5. **digest equality** — 各current endpoint digestがrecorded pinと一致するか。明示`content-equals`では両current digestも一致するか。
|
|
83
|
+
|
|
84
|
+
prose similarity、heading similarity、naming convention、co-change、timestamp、LLM classification、暗黙のdomain knowledgeから新しいfactやviolationを生成しない。意味的妥当性、因果、改善度を機械ruleに含めない。
|
|
85
|
+
|
|
86
|
+
malformed declarationのschema / type admissionは、これらのruleを安全に適用する前段の構造検査である。malformed inputを部分的なConstraintRecordとして評価へ流さない。
|
|
87
|
+
|
|
88
|
+
### 4. World constraint rule IDを`WCR-NNN`で固定する
|
|
89
|
+
|
|
90
|
+
v1 rulesetのstable IDを次のとおり定義する。
|
|
91
|
+
|
|
92
|
+
| rule ID | name | category / decision |
|
|
93
|
+
|---|---|---|
|
|
94
|
+
| `WCR-001` | `declaration-well-formed` | required field、ID、digest、fact type、rule IDがmalformed / unsupported |
|
|
95
|
+
| `WCR-002` | `endpoint-exists` | current snapshotにendpointがなく、baselineにも同一IDの存在証拠がない |
|
|
96
|
+
| `WCR-003` | `endpoint-not-deleted` | baselineにはexact endpointが存在し、currentではmissing、かつvalid explicit aliasがない |
|
|
97
|
+
| `WCR-004` | `explicit-rename-resolves` | rename continuityを主張するexplicit aliasがsingle-hop / target / role / uniqueness条件を満たさない |
|
|
98
|
+
| `WCR-005` | `node-id-unique` | 一つのcanonical node IDが複数locator / candidateへ解決する |
|
|
99
|
+
| `WCR-006` | `explicit-reference-resolves` | explicit reference / `refines` targetまたは宣言relationが解決しない |
|
|
100
|
+
| `WCR-007` | `declared-dependency-resolves` | explicit `depends-on` endpointまたは依存relationが解決しない |
|
|
101
|
+
| `WCR-008` | `endpoint-digest-equals` | claimant / premise current digestがpinと不一致、またはexplicit `content-equals`の両current digestが不一致 |
|
|
102
|
+
|
|
103
|
+
`WCR-001`はdeclaration admission、`WCR-002`〜`WCR-004`はexistence / explicit resolution familyであり、§3の5 category外の意味推論を追加しない。
|
|
104
|
+
|
|
105
|
+
rule ID namespaceは次を混同しない。
|
|
106
|
+
|
|
107
|
+
- ADR-032 extraction diagnostics: `duplicate-node-id`, `invalid-node-id`, `missing-reflection-target`等のlowercase code
|
|
108
|
+
- World constraint evaluation rules: `WCR-NNN`
|
|
109
|
+
- validator-system validator IDs: registryに登録された`Lx-NNN`
|
|
110
|
+
|
|
111
|
+
extraction diagnosticはcorpus / declarationをlosslessly説明し、WCR violationはconstraint evaluation結果を説明する。同一のduplicate事象が両方へ現れても、互換aliasにはせず、evaluation evidenceでsource diagnosticを参照する。
|
|
112
|
+
|
|
113
|
+
### 5. Missing、deletion、renameを推論せず区別する
|
|
114
|
+
|
|
115
|
+
一つのendpointのresolutionは次のprecedenceを持つ。
|
|
116
|
+
|
|
117
|
+
1. declarationがmalformedなら`WCR-001`。ConstraintRecordを作らない。
|
|
118
|
+
2. exact IDまたはalias targetがduplicateなら`WCR-005`。winnerを選ばない。
|
|
119
|
+
3. exact IDがcurrent snapshotに一意に存在すればresolved。
|
|
120
|
+
4. exact IDがなくexplicit aliasがあれば`WCR-004`で検証する。validならcanonical targetへsingle-hop解決し、`resolved-via-alias` evidenceを残す。
|
|
121
|
+
5. exact IDがbaseline snapshotに存在したなら`WCR-003` deletion。
|
|
122
|
+
6. それ以外は`WCR-002` missing endpoint。
|
|
123
|
+
|
|
124
|
+
同じendpointへ`WCR-002`と`WCR-003`を同時に出さない。unresolved endpointへdigest mismatchを追加しない。
|
|
125
|
+
|
|
126
|
+
path-based Artifact / SourceFile renameはADR-032どおりold missing + new addedであり、digest一致してもrenameとは呼ばない。explicit aliasがvalidな場合だけrename continuityを認める。explicit Fragmentは同一corpus role / DeclaredKeyを維持するfile moveやheading renameでidentityが変わらないため、rename ruleではなく同一nodeのlocator / digest changeとして扱う。
|
|
127
|
+
|
|
128
|
+
### 6. `refines`は明示stable ID declarationだけを事実化する
|
|
129
|
+
|
|
130
|
+
`refines` factはdeclarationがclaimant / premise両方のstable World node IDを明示し、両endpointが一意に解決した場合だけ生成する。
|
|
131
|
+
|
|
132
|
+
- same DeclaredKey、heading text / level / order、path、WorkItem、content digest、prose similarityから推論しない。
|
|
133
|
+
- ADR-032の`@world-reflects`が作る`proposal --reflected-as--> canonical`を自動的に`refines`へ変換しない。
|
|
134
|
+
- target不在 / relation不在は`WCR-006`、構文 / node type不正は`WCR-001`。
|
|
135
|
+
- 「より詳細になった」「置換した」「意味を保った」という判定は行わない。
|
|
136
|
+
|
|
137
|
+
product canonicalとinception proposalはADR-031どおり別artifact / corpus roleのままであり、`refines`やdigest equalityによってdeduplicateしない。
|
|
138
|
+
|
|
139
|
+
### 7. Change provenanceをsnapshot差とchanged candidatesで表す
|
|
140
|
+
|
|
141
|
+
evaluation evidenceは次の非因果的`ChangeProvenance`を持てる。
|
|
142
|
+
|
|
143
|
+
```text
|
|
144
|
+
ChangeProvenance {
|
|
145
|
+
baselineSnapshotId: pgw:v1:snapshot:... | null
|
|
146
|
+
baselineCorpusRoot: sha256:... | null
|
|
147
|
+
currentSnapshotId: pgw:v1:snapshot:...
|
|
148
|
+
currentCorpusRoot: sha256:...
|
|
149
|
+
changedCandidates: [{
|
|
150
|
+
nodeId
|
|
151
|
+
changeKind: added | removed | modified | candidate-cardinality-changed
|
|
152
|
+
baselineDigest?
|
|
153
|
+
currentDigest?
|
|
154
|
+
baselineLocators[]
|
|
155
|
+
currentLocators[]
|
|
156
|
+
}]
|
|
157
|
+
}
|
|
158
|
+
```
|
|
159
|
+
|
|
160
|
+
- baseline / currentはADR-033のSnapshot ID / `corpusRoot`を参照する。
|
|
161
|
+
- initial evaluationはbaselineを`null`にできる。
|
|
162
|
+
- changed candidatesはNode ID、change kind、locatorのcanonical tupleでsortする。
|
|
163
|
+
- candidateは再評価対象を説明するevidenceであり、「candidate Aがfinding Bを引き起こした」という因果ではない。
|
|
164
|
+
- path-based renameはold `removed` + new `added`。valid explicit aliasがある場合だけrename continuityを別evidenceとして表示する。
|
|
165
|
+
- digest一致、類似heading、近接commit / timestampからsuccessorやcauseを推論しない。
|
|
166
|
+
|
|
167
|
+
baseline snapshotは比較対象のWorld snapshotであり、ADR-035が定義するadoption baselineとは別物である。前者はchange evidence、後者は既知violation fingerprintのpolicy inputである。
|
|
168
|
+
|
|
169
|
+
### 8. Evaluation outputはpolicyを持たない
|
|
170
|
+
|
|
171
|
+
world-modelのevaluation DTOは最低限、`evaluationId`、`constraintId`、`ruleId`、claimant / premiseのdeclared pinとcurrent resolution evidence、source diagnostic、ChangeProvenanceを返す。
|
|
172
|
+
|
|
173
|
+
severity、blocking、exit code、waived / adopted classificationをconstraint evaluatorへ入れない。validator-system adapterがWorld evaluation DTOをvalidation resultへ変換し、ADR-031のownershipどおりpolicyを適用する。obligation / fingerprint / adoption / waiverはADR-035で決める。
|
|
174
|
+
|
|
175
|
+
### 9. §10のvalidator ID未決事項はADR-037へ委譲する
|
|
176
|
+
|
|
177
|
+
`docs/inception/_cross/WI-280/delivery_plan.md` §10の「world-modelのconfig keyとvalidator ID」はADR-037で決定する。config discovery、CLI、validator registry、layer、default enablement、output / exit codeを一緒に決める必要があるためである。
|
|
178
|
+
|
|
179
|
+
本ADRが決定するのはWorld内部rulesetの`WCR-NNN`だけであり、`L2-NNN` / `L3-NNN`を先取りしない。validator-systemの現行`ValidatorId`はregistryに列挙されたIDだけを受理するため、実装時の新validator ID追加はADR-037の決定と対応する正式WIで行う。
|
|
180
|
+
|
|
181
|
+
## Consequences
|
|
182
|
+
|
|
183
|
+
### Positive
|
|
184
|
+
|
|
185
|
+
- fact directionを失わず、claimant / premiseどちらのdriftも検出できる。
|
|
186
|
+
- 両endpoint pinにより、前提側だけの編集も同じconstraintで再現可能に評価できる。
|
|
187
|
+
- missing、deletion、explicit rename failure、duplicate、digest driftをstable rule IDで区別できる。
|
|
188
|
+
- `refines`やrenameを意味推論せず、明示宣言の範囲だけを機械保証できる。
|
|
189
|
+
- snapshot comparisonとadoption baselineを別概念に保てる。
|
|
190
|
+
- World rule、extraction diagnostic、layer validatorのID衝突を避けられる。
|
|
191
|
+
|
|
192
|
+
### Negative / Trade-off
|
|
193
|
+
|
|
194
|
+
- declaration採用時に両endpointのID / digestを明示pinする作業が必要になる。
|
|
195
|
+
- endpointの正当な変更でもpin更新reviewが必要になる。
|
|
196
|
+
- aliasなしのfile renameは意図したrenameでもold removed + new addedとして見える。
|
|
197
|
+
- prose上明白なrefinementやcausal relationを自動認定しないため、人による明示宣言が必要になる。
|
|
198
|
+
- baselineなしのinitial evaluationではmissingとdeletionを区別できず、missingとして扱う。
|
|
199
|
+
|
|
200
|
+
## Alternatives
|
|
201
|
+
|
|
202
|
+
- **fact edge自体を双方向化する** — dependency / referenceの意味方向を失い、reverse relationを誤って主張するため不採用。
|
|
203
|
+
- **claimantだけをpinする** — premise側変更を見落とし、endpoint-symmetric evaluationにならないため不採用。
|
|
204
|
+
- **content digestをnode identityにする** —編集ごとにendpoint identityが変わり、ADR-032と矛盾するため不採用。
|
|
205
|
+
- **digest / heading similarityからrenameやrefinesを推論する** —意味的continuityを機械が過剰主張し、曖昧candidateのwinner選択を生むため不採用。
|
|
206
|
+
- **既存`Lx-NNN`をWorld rule IDに流用する** —validator単位と個別constraint ruleを混同し、validator-system ownershipを侵すため不採用。
|
|
207
|
+
- **ci-governanceのSHA-1 path baselineをWorld adoption baselineに流用する** —artifact lifecycle、identity、hash algorithm、policy purposeが異なるため不採用。
|
|
208
|
+
|
|
209
|
+
## 関連要件・文書
|
|
210
|
+
|
|
211
|
+
- `docs/inception/_cross/WI-280/delivery_plan.md` §1, §3 WM-04, §7 ADR-034, §10
|
|
212
|
+
- `docs/inception/_cross/WI-284/description.md`
|
|
213
|
+
- `docs/inception/_cross/WI-284/logical_design.md`
|
|
214
|
+
- ADR-031(World ownership / corpus lifecycle)
|
|
215
|
+
- ADR-032(World node identity / alias / reflection)
|
|
216
|
+
- ADR-033(canonical snapshot / constraintRoot / evaluationId)
|
|
217
|
+
- ADR-005(ヘキサゴナルアーキテクチャ)
|
|
218
|
+
- ADR-027(成果物駆動状態導出)
|