@openwop/openwop-conformance 2.0.0-rc.37 → 2.0.0-rc.6
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/README.md +2 -2
- package/dist/spec-artifacts.lock.json +2 -2
- package/package.json +2 -2
- package/requirements.json +19 -234
- package/scenario-majors.json +3 -15
- package/schemas/CORPUS-STAMP.json +32 -34
- package/src/global-setup.ts +0 -11
- package/src/lib/corpus-stamp.ts +2 -24
- package/src/scenarios/v2-advertised-fixtures-exist.test.ts +43 -25
- package/src/scenarios/v2-dual-stack-negotiation.test.ts +1 -29
- package/src/scenarios/v2-era-2-append-vocabulary.test.ts +0 -9
- package/src/scenarios/v2-era-stamp-universal.test.ts +1 -1
- package/src/scenarios/v2-interrupt-token-scheme.test.ts +1 -1
- package/src/scenarios/version-negotiation.test.ts +3 -25
- package/src/setup.ts +0 -58
- package/src/scenarios/era-key-stamped-v1.test.ts +0 -156
- package/src/scenarios/v2-advertised-path-space-served.test.ts +0 -140
- package/src/scenarios/v2-run-completed-outputs.test.ts +0 -93
- package/src/scenarios/v2-version-header-honored.test.ts +0 -124
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"_comment": "Provenance of @openwop/spec-artifacts (RFC 0168 §D.2). files: SHA-256 per file; the conformance suite compares the installed peer against dist/spec-artifacts.lock.json at start.",
|
|
3
3
|
"package": "@openwop/spec-artifacts",
|
|
4
|
-
"version": "2.0.0-rc.
|
|
4
|
+
"version": "2.0.0-rc.6",
|
|
5
5
|
"corpusTag": null,
|
|
6
6
|
"files": {
|
|
7
7
|
"api/.redocly.lint-ignore.yaml": "bf5a8350b88a72fa43f59605ed8d903ed24b6cfccda5e45509c9f6ed9ee4e712",
|
|
@@ -9,9 +9,9 @@
|
|
|
9
9
|
"api/grpc/openwop.proto": "c3e72bb17cba514ee98feb6434e6c9b6ea6795bfd086489ec69fd882dd1ad977",
|
|
10
10
|
"api/openapi.yaml": "39081c59fb696159806b0f2f9a42e7e9ff830d622fcf2ad4159b21357580a955",
|
|
11
11
|
"api/redocly.yaml": "b0604c89b2ca6d5076ec25725c539dad44a741a811fe524439ee6daef8baa09f",
|
|
12
|
-
"api/seams-v2.yaml": "
|
|
13
|
-
"api/v2/asyncapi.yaml": "
|
|
14
|
-
"api/v2/openapi.yaml": "
|
|
12
|
+
"api/seams-v2.yaml": "ac5a9173b5d35869d6a5d2c0e7efd37b377414e5cded22fc261e088eb614a286",
|
|
13
|
+
"api/v2/asyncapi.yaml": "958537c1279125d6d14416889e9aa48a89dc1941f892348fa46496faedfd8a78",
|
|
14
|
+
"api/v2/openapi.yaml": "4bed5a9c899b77092a2da2a4337910c80c0fc39612b47b46a38d9a05a2868ade",
|
|
15
15
|
"api/v2/redocly.yaml": "1e66b60e6118ad11a823bb620678be464d99dfe50a40e3e6f93ec9429b88b34c",
|
|
16
16
|
"schemas/README.md": "0c0b737ffcf8f30e7d2809cec8a498232de710f41443212922ad8337cdde0b51",
|
|
17
17
|
"schemas/a2a-task-state.schema.json": "c9365918f993f943b4b619d42551eb066a1ed33a08d895d51b395432a5b1f1bc",
|
|
@@ -31,8 +31,8 @@
|
|
|
31
31
|
"schemas/artifact-type-pack-manifest.schema.json": "13932ea58e819e01b3a0cc7a65590b70683dd5fe9208fc06c64c339943d3c4ce",
|
|
32
32
|
"schemas/audit-verify-result.schema.json": "e8fd013fb610ba5db27ab0113ec2eb18e7da5f9310dd3de2dd3dc87a259c21fe",
|
|
33
33
|
"schemas/budget-policy.schema.json": "3d4fe30ae129fe136ab9ece395f2a2a42a76360786b1b9a1d5f1cbc753eb5b39",
|
|
34
|
-
"schemas/capabilities.schema.json": "
|
|
35
|
-
"schemas/certification-bundle-v2.schema.json": "
|
|
34
|
+
"schemas/capabilities.schema.json": "e672c35d503532d8039b5552115f5ec150d60317f537f13180d830b0fe315947",
|
|
35
|
+
"schemas/certification-bundle-v2.schema.json": "3540232676086869ae78d24f3b9c2154f9c4a8a5eeb976512d6a7409f8cf19bb",
|
|
36
36
|
"schemas/channel-presence-payload.schema.json": "f9d0ef4219814c2b765baf3e68cbe5eea2cb42379f516a93a0459dcd5f7db47e",
|
|
37
37
|
"schemas/channel-written-payload.schema.json": "54723a56bc5a35232f64544ca686ac1ac959a5fb05b32b2401facca6b3ef51a3",
|
|
38
38
|
"schemas/chat-card-pack-manifest.schema.json": "402f7e9081cc39857a52e772061f4e034a957dcbc17501fe6e8e0bcb3d337e42",
|
|
@@ -86,7 +86,7 @@
|
|
|
86
86
|
"schemas/run-event.schema.json": "c70c06932b9831295042836213e617c8e946f20ddd49cf4e889b74d89d2175a8",
|
|
87
87
|
"schemas/run-options.schema.json": "f8241ece6ddc6527de9160d811d42c231b4f77b935f2e107b3c05608545c59ab",
|
|
88
88
|
"schemas/run-orchestrator-decided-event.schema.json": "17a43a3c44680a24d411141357a867b3caed6107d56de88fe2e062eaf93fa2c1",
|
|
89
|
-
"schemas/run-snapshot.schema.json": "
|
|
89
|
+
"schemas/run-snapshot.schema.json": "8a45f997beec0a2fa596f4631129a869cfbc37c9ad38583530ed11655301d2ab",
|
|
90
90
|
"schemas/security-advisory.schema.json": "9c550f0bf10a3193dcca4a127081fb66fe5dc1b6f729c4c17bfaea3ba3ce05fc",
|
|
91
91
|
"schemas/self-hosted-runner-dispatch-frame.schema.json": "3f1d7edd572c6747657299525d8e85329b93b6fadf670e3a19c74d53e725adec",
|
|
92
92
|
"schemas/self-hosted-runner-registration.schema.json": "6c781adf1bb915a9e47796494f4a527353cbbf72b480e5a05be4aac65a6d0c6e",
|
|
@@ -100,9 +100,9 @@
|
|
|
100
100
|
"schemas/ui-plugin-message.schema.json": "346638babf1f8ea7b161cde75c0038b518cd2cc5bf0631772e20a9b74c96b5dd",
|
|
101
101
|
"schemas/v2/a2a-task-state.schema.json": "aa9bd0c15f653b7ecdb17427d61b1bccaf8156972c4b1a437dd3a8afb717b318",
|
|
102
102
|
"schemas/v2/a2ui-surface-delta-frame.schema.json": "43c10ebfd13c987520f0448df92fe74b52b846833763dfbbd5d35636bf75e8d9",
|
|
103
|
-
"schemas/v2/agent-deployment-transition.schema.json": "
|
|
104
|
-
"schemas/v2/agent-deployment.schema.json": "
|
|
105
|
-
"schemas/v2/agent-eval-suite.schema.json": "
|
|
103
|
+
"schemas/v2/agent-deployment-transition.schema.json": "5871ec764f531b2d34a6bb8b2e16efd35aad642664ca6d41411ba8d699fd759e",
|
|
104
|
+
"schemas/v2/agent-deployment.schema.json": "61979201c850c69360a0840f3e23373284b5445b6c11212012ea53d33be9a6e7",
|
|
105
|
+
"schemas/v2/agent-eval-suite.schema.json": "77c4bb06f5e21584994d4b4aaafc2304904008a51f0c6d8892794d7074e4f6b5",
|
|
106
106
|
"schemas/v2/agent-inventory-response.schema.json": "bbf19724986a867a59ef51c115a43ece1cc4a003836b2f7f45dfefb3078db8f9",
|
|
107
107
|
"schemas/v2/agent-manifest.schema.json": "006ca6163ca8f9dc9fb91ca1ce01bd4c523f118680f6cbad971a4ac09e975381",
|
|
108
108
|
"schemas/v2/agent-org-chart.schema.json": "e64f1bcc6c0e9d3fc39c363e8e5e73b2b1fc49275b92f89b0cb941a7a80d67f2",
|
|
@@ -112,14 +112,14 @@
|
|
|
112
112
|
"schemas/v2/ai-envelope.schema.json": "0dc7dfbf032a37239ffd81fc2d67f999a40782ff5074866a56e414164cdee809",
|
|
113
113
|
"schemas/v2/annotation-create.schema.json": "c2fc19d055be29bc499e53c4975a562eb76981e12c521a82f63f5827ac6ff6c7",
|
|
114
114
|
"schemas/v2/annotation.schema.json": "75c6785775d00e62bc1282626c2c27eafde0f93a01c7e80e4e5e985055907475",
|
|
115
|
-
"schemas/v2/artifact-type-pack-manifest.schema.json": "
|
|
115
|
+
"schemas/v2/artifact-type-pack-manifest.schema.json": "c911757562e521cb4f31a47c097f562573b64087efe60c8acb81fd352367d300",
|
|
116
116
|
"schemas/v2/audit-verify-result.schema.json": "cb54c4d89ba5dfb73f49aa8959a980be65c2dc2a87a12f71ba36d3e836fe85da",
|
|
117
117
|
"schemas/v2/budget-policy.schema.json": "c7449daeb6e1d95e7a047b8c2814d3d54748697c27046972834874867d9b5f4c",
|
|
118
|
-
"schemas/v2/capabilities.schema.json": "
|
|
119
|
-
"schemas/v2/certification-bundle.schema.json": "
|
|
118
|
+
"schemas/v2/capabilities.schema.json": "b6191deddf6bee19470eee9a45bb520de0d17385c195de6e3b8c5cb6d9520238",
|
|
119
|
+
"schemas/v2/certification-bundle.schema.json": "5afcce118ac567d4aee790aebe258bfbb60aa2708c4602b26f835943aa67b2c3",
|
|
120
120
|
"schemas/v2/channel-presence-payload.schema.json": "9475d46f358d21c19126e78204987a5633979917a2293653354ef5c5e044d54e",
|
|
121
121
|
"schemas/v2/channel-written-payload.schema.json": "ccecff3c71a3275ad8db035ac0e04db25e6f8d23cf091ddbcd5a60d1be1cbb6b",
|
|
122
|
-
"schemas/v2/chat-card-pack-manifest.schema.json": "
|
|
122
|
+
"schemas/v2/chat-card-pack-manifest.schema.json": "566982ce509a96d1619d58a72e383eff0773fe43fc65e4bfc85a4fe158f4eaff",
|
|
123
123
|
"schemas/v2/compact-tool-descriptor.schema.json": "fc03f20c254c0ddc2cba7e7d5a6c46080ebd2cf9fae36f3c2510cbf88aadebdc",
|
|
124
124
|
"schemas/v2/compensation-policy.schema.json": "b3c1142637f5bf980f2b0bb67adb47e8cb7abb99a0405a4b6816ccf5d9c089d6",
|
|
125
125
|
"schemas/v2/compensation-projection.schema.json": "f46977c7076347b5473faa8c4bbe73d8321c33b33c98fff2f26ee7cbada4ed98",
|
|
@@ -129,7 +129,7 @@
|
|
|
129
129
|
"schemas/v2/conversation-turn.schema.json": "4c24aa85dd83f6ad00945b4a13ee8ff0a071893e884011e9289a07e97d22989d",
|
|
130
130
|
"schemas/v2/credential-provenance.schema.json": "f86b09e94b1c524dec7d1c6353965665ae8891e9517faef6e742d639c5578c99",
|
|
131
131
|
"schemas/v2/credential-reference.schema.json": "ea699ce30f58fb2c32d4279158b3f730f70be7b2dc8c3037693a76e66eb3e001",
|
|
132
|
-
"schemas/v2/debug-bundle.schema.json": "
|
|
132
|
+
"schemas/v2/debug-bundle.schema.json": "e792a588131290bccce3042a279e8e57677018df94b0861bee2b2b98a9ea2124",
|
|
133
133
|
"schemas/v2/dispatch-config.schema.json": "4a7db312e6b4a14cf5b1ad2b71367878c77b6321cc456f5b3644dd6434e94cbd",
|
|
134
134
|
"schemas/v2/effect-ledger-projection.schema.json": "9e690f8e5dbf9aa7c82eef4bf7cf96c024f0f8626ad5bbaca3ff25ac63c7cab2",
|
|
135
135
|
"schemas/v2/effect-seam-manifest.schema.json": "3402a2956c810b2bfa9ec1ad0cb79d607ecea122cbe7d1e05184af006b06ef15",
|
|
@@ -142,21 +142,21 @@
|
|
|
142
142
|
"schemas/v2/envelopes/schema.response.schema.json": "d049a081267c06c28879c331b147f3ed821b14ccfd93005c67aff64db0a8c68e",
|
|
143
143
|
"schemas/v2/envelopes/ui.a2ui-surface.schema.json": "0a06fbbdc8ba797a6818c79336a98e211ac5ba5747945b4e4098072cd3974d79",
|
|
144
144
|
"schemas/v2/error-envelope.schema.json": "d550beeab958b528c8734fd32e74c438006b99172c5c586f9e0af20ef4b2bee7",
|
|
145
|
-
"schemas/v2/eval-summary.schema.json": "
|
|
145
|
+
"schemas/v2/eval-summary.schema.json": "dfc995c8481ed212e6f3d83de982547898a7938be8c891ddb0d3efe84352908d",
|
|
146
146
|
"schemas/v2/export-bundle.schema.json": "bd28905a7729437ab7f2ad8bb33e13a371b2bf5605a7eb2962a0d246de312d69",
|
|
147
147
|
"schemas/v2/form-content-pack-manifest.schema.json": "307884e57946703b6f86ec283034bf56beb68bea4a000743ebbc9eebeed31b07",
|
|
148
148
|
"schemas/v2/frontend-plugin-manifest.schema.json": "fed6b8ddb3056c53b1bfc91525410a4445a3c37a8bf9eb9f6f9964ffea26d993",
|
|
149
|
-
"schemas/v2/goal.schema.json": "
|
|
149
|
+
"schemas/v2/goal.schema.json": "d202ef21ed3dbff87c25fd4b553fa978862a3200999878d25c5918f6794b3060",
|
|
150
150
|
"schemas/v2/heartbeat-evaluated.schema.json": "4086b1ba1d0547c08b038dfb263ac89416a3e406430db1250156fb2f9b74f8d6",
|
|
151
151
|
"schemas/v2/heartbeat-state-changed.schema.json": "eb68d0082aa996650e3a6b8ccf32457f959cebc7e6728cc7c331b9d171a4bef6",
|
|
152
|
-
"schemas/v2/ids.schema.json": "
|
|
152
|
+
"schemas/v2/ids.schema.json": "0ccf5eb3ec0744296b3379f7ced3b46ec51d908705a4f03dc4404d42236ebe19",
|
|
153
153
|
"schemas/v2/localized-content-language-settings.schema.json": "92240f19a2b4b2f05ab41a797f703485a28813848035478e72f395edd04c1d35",
|
|
154
154
|
"schemas/v2/localized-content-page-response.schema.json": "476b5f2775b42e35e679814a4ce846a7be1d5311d3a748c10df4275a78b0fb27",
|
|
155
155
|
"schemas/v2/localized-content-page.schema.json": "717bb51fbc64d0b34eb0a4b35c8b463d08d505267bf251b4cbc67e0a016a567a",
|
|
156
156
|
"schemas/v2/localized-content-section.schema.json": "29c7bad0ad9ebc6c45211282e8afb3fdb35a4ca075ce0404b6e2c29f35fa5313",
|
|
157
157
|
"schemas/v2/memory-entry.schema.json": "290576ae84f4fef4cdf975932b87963283b11c50ea3d2654b32cd96aa6537c3d",
|
|
158
158
|
"schemas/v2/memory-list-options.schema.json": "f66703bccb68efb28391c273abb66aa117ee5b5ce475c477846ed700c336afcd",
|
|
159
|
-
"schemas/v2/node-pack-manifest.schema.json": "
|
|
159
|
+
"schemas/v2/node-pack-manifest.schema.json": "771328fa73691e7f08fca3c628c4e8ba68fa4e43529faaf1a6358aecf26b13f2",
|
|
160
160
|
"schemas/v2/orchestrator-decision.schema.json": "2da17538e84cfbe70151eb118f1ccf670cff58b8697148e394074d32ac4af6b4",
|
|
161
161
|
"schemas/v2/org-chart-responsibility-view.schema.json": "ebac7d2889bfd659bcf30311efb0d6eb0c7e940b972b6b62da69c7351b5bb586",
|
|
162
162
|
"schemas/v2/pack-lockfile.schema.json": "2685417702c105146b780cd99154296a46578fbb10d81c8c713348ee26fea898",
|
|
@@ -164,16 +164,16 @@
|
|
|
164
164
|
"schemas/v2/prompt-pack-manifest.schema.json": "a51667da3d601043d2c33fddaafa572e9dd7e47b8840393742b80eaf6238a1a5",
|
|
165
165
|
"schemas/v2/prompt-ref.schema.json": "11538fa36a7a652c93100cac4f1857eb4130137b546e3d94890618636d44b729",
|
|
166
166
|
"schemas/v2/prompt-template.schema.json": "494fc83028cb3af5dbb8a943d0e83b2348f7775e9fa02369162bcb58a6f81559",
|
|
167
|
-
"schemas/v2/proposal.schema.json": "
|
|
167
|
+
"schemas/v2/proposal.schema.json": "72623553611f00e87b4c7972d69ebeba73c2222b01ead75a44a0c2114b679fea",
|
|
168
168
|
"schemas/v2/registry-version-manifest.schema.json": "270704ebc6bae63be949efbf9503578938b103733db9da3cb8fcbee1cd7684dd",
|
|
169
169
|
"schemas/v2/residency.schema.json": "af2658a7104cbcacd0e20a91226271c4a77f91ef46ae97612768fe743e6091d8",
|
|
170
170
|
"schemas/v2/run-ancestry-response.schema.json": "907e36341ba83a2147a5d76963950b6dcd47506b663ecbccae9dfa553f3724d3",
|
|
171
171
|
"schemas/v2/run-diff-response.schema.json": "6ab6cd265dc7e0a2086c6659c46aa0e7b43e6302949f0adac5d7deb1c7c0ecd3",
|
|
172
|
-
"schemas/v2/run-event-payloads.schema.json": "
|
|
173
|
-
"schemas/v2/run-event.schema.json": "
|
|
172
|
+
"schemas/v2/run-event-payloads.schema.json": "8eb0e05e1bd3399b0e2654a1ec5a13198ac4ec8459a1fcbfd800ab2d0a0ae8c6",
|
|
173
|
+
"schemas/v2/run-event.schema.json": "4ec8eb048a79ca1343e00aa018acbf86814b5eda6768add6b17e8d7b83638fdf",
|
|
174
174
|
"schemas/v2/run-options.schema.json": "6d6052596ab0f17acfb00fdfc89907da7724f952e5ffbe1f81d94ba23d4c77cd",
|
|
175
175
|
"schemas/v2/run-orchestrator-decided-event.schema.json": "bb76e15ff72e669f12938684033b55dc567470e1a378e19ffc3fa0e4034ab5a7",
|
|
176
|
-
"schemas/v2/run-snapshot.schema.json": "
|
|
176
|
+
"schemas/v2/run-snapshot.schema.json": "e77bf491d11c1414e62ed84cbf0c1d7149279b133a2101dc8f5eec89d3e45204",
|
|
177
177
|
"schemas/v2/security-advisory.schema.json": "6a382f737730a738d634266315e9d335e5760020a0cdd9f30727c2f987a01770",
|
|
178
178
|
"schemas/v2/self-hosted-runner-dispatch-frame.schema.json": "d8129f11d4e731d17ea951e66faaea2086081d13958b62ceaaa359fd6637dd7d",
|
|
179
179
|
"schemas/v2/self-hosted-runner-registration.schema.json": "93d60003a668cacb0eeac37699ca2884c6b79332d9494cb9e0a1752ac8f8a16c",
|
|
@@ -186,9 +186,8 @@
|
|
|
186
186
|
"schemas/v2/trigger-subscription-registration.schema.json": "202f7ab9c29e78249e0ad04341ac53377b506d24a0cbfbb7bb54494e80165832",
|
|
187
187
|
"schemas/v2/trigger-subscription.schema.json": "074bec7f016aa9f4d60359c3a093296cc847045510f01e0a9dceaf4fa5084d12",
|
|
188
188
|
"schemas/v2/ui-plugin-message.schema.json": "879d65867c01656b3962d64283e66364dcb8f626ad26c5fcf2d2d55a79ae0ce9",
|
|
189
|
-
"schemas/v2/
|
|
190
|
-
"schemas/v2/workflow-
|
|
191
|
-
"schemas/v2/workflow-definition.schema.json": "da7e565cee6ecf3bcc9d46833bad224f579f8db8a378ae22ff3fbf58b1348f38",
|
|
189
|
+
"schemas/v2/workflow-chain-pack-manifest.schema.json": "d1e43617ebacc9b32d1faf98dc7a2074d3e25054f383a1c264b87a19047f674d",
|
|
190
|
+
"schemas/v2/workflow-definition.schema.json": "91e422faacb886c8a17fc86b6576d38b7bfd99a37aaff69c710dec598e361192",
|
|
192
191
|
"schemas/v2/workload-identity.schema.json": "1f589debfac6d70e0908da511550ec69a27b4bcc8314551cd843b6d923605efc",
|
|
193
192
|
"schemas/v2/workspace-file-create.schema.json": "b6b5260857318c3b67de0231ed15e3a746f525880a763e7b36a7854178dd10d0",
|
|
194
193
|
"schemas/v2/workspace-file.schema.json": "d2ed39e8c229dde33b56905c8df6f8b2ff056c97e1c5f615e3124baa54a6254f",
|
|
@@ -199,19 +198,19 @@
|
|
|
199
198
|
"schemas/workspace-file.schema.json": "464de85c2a068243084ee9c1d969bc7cd5d8f7948574e58450d6493c38a0e1e4",
|
|
200
199
|
"spec/v1/alias-detectors.json": "fee4594ef49953953ffcd0b3813300067d16b3e65ebff2aac722034ac9b3f545",
|
|
201
200
|
"spec/v1/capability-declaration-classes.json": "e7729aed5c4b4e1dd02abab0530f14cc95f5d4070fe51fb139e7f5cccefa00c6",
|
|
202
|
-
"spec/v1/core-standard-manifest.json": "
|
|
203
|
-
"spec/v1/deprecations.json": "
|
|
204
|
-
"spec/v1/deprecations.schema.json": "
|
|
201
|
+
"spec/v1/core-standard-manifest.json": "5f61d1d51233de923032cfb7fe1459ea0d8c60e4ff70fc9e610c001686da9864",
|
|
202
|
+
"spec/v1/deprecations.json": "520d79927a8ed43ccf62c207a7cf6cf7b19b16e00bbbbdf0410667e939c19d85",
|
|
203
|
+
"spec/v1/deprecations.schema.json": "4cdbbb8eb9c0092913a5704c943880f0c8581bcf0f640a7df5a84105d53c8aee",
|
|
205
204
|
"spec/v1/event-codemap.json": "3da60d884157793a360da532a9fcbbfb5285636db325a74cec94b34622186d97",
|
|
206
205
|
"spec/v1/event-codemap.schema.json": "d52caf29071e3784d4c20259cdbd5a7b533986548a440bb632a80b82cadd7ea5",
|
|
207
|
-
"spec/v1/extensions.json": "
|
|
206
|
+
"spec/v1/extensions.json": "4d7ba68bae7c7f50cc655b94646ad25945a5dd63b703d43c1d015470141cd668",
|
|
208
207
|
"spec/v1/gaps.json": "96ca051cb20f1a669b355d67a89421c56fef28aa5e6710c9519f592f26af33a3",
|
|
209
208
|
"spec/v1/gaps.schema.json": "8fd83259f556553c9df0f53e7a82ca8c2a4771d471197f69b4e2ae0ceeacfd66",
|
|
210
209
|
"spec/v1/migrations.json": "8839497d6a4830b53fa7867014a8336f0d725ef2346352e54fb580b7947897af",
|
|
211
210
|
"spec/v1/migrations.schema.json": "886779aa6c22e646db097f5df210adb018a4dd14a7b815465a18c8a7056c8f72",
|
|
212
211
|
"spec/v1/operation-path-manifest.json": "5f5f4e3842669371730ebbd1aace3fb794192615f0018dc144f484ba5db82ac3",
|
|
213
212
|
"spec/v1/spec-gaps.json": "6cc9962c6b969f632e07a78b52a4f61447ff579e2990cbae989866f584a86042",
|
|
214
|
-
"spec/v2/declaration.json": "
|
|
213
|
+
"spec/v2/declaration.json": "892b6fae1e87f279ff75451f67ffab2a63ef883203f8066886bd60f165469348",
|
|
215
214
|
"spec/v2/declaration.schema.json": "b0881a76228dfbd1b85a2ec7b7259a60197f768344535cdb475db6ff719b0e54",
|
|
216
215
|
"spec/v2/errors.json": "ad1725dc7c11002450e8abc682858eb5c11952a0718ea8ef6bdb2fb5ae6e7e21",
|
|
217
216
|
"spec/v2/event-codemap.json": "37869a03cdfd8758b57e6f350641a6ebbd383231cebda51f5473ad85f94ab74c",
|
|
@@ -226,11 +225,10 @@
|
|
|
226
225
|
"spec/v2/facets/replay.schema.json": "0a5aefb0108c708c6794fadd533cf256709704c4f16dbf44cd63fa8980c78018",
|
|
227
226
|
"spec/v2/facets/sandbox.schema.json": "e75f54486d387b2d089791aa93b5093cd1450f1920753a0f97fc23acdfe978ed",
|
|
228
227
|
"spec/v2/facets/webhooks.schema.json": "0b766033ef4b4c6c2ac6f9979a19843ba024d3a1d1576972dcb55aaba52f1b9a",
|
|
229
|
-
"spec/v2/id-field-bindings.json": "965814020c462ad13840b41b26f6830ac472734a1e2e5a67140fad92174c0370",
|
|
230
228
|
"spec/v2/path-manifest.json": "034152e09b1458c66810d4050e20a273b2b9b8fe2d92b66e8b819477de58a1be",
|
|
231
229
|
"spec/v2/peer-dependency-aliases.json": "d10299280abee08258502925bc327293ee413e0108cd6e6ec75ff6110653308d",
|
|
232
230
|
"spec/v2/profiles.json": "1f0ee40491131cf561ef19a0394c47ba476b4567514fe16befb6cada4a10a5a4",
|
|
233
|
-
"spec/v2/release.json": "
|
|
231
|
+
"spec/v2/release.json": "64dedadf70a0cd6928ee4bbe7012631cf0612c03e2e2df20d5e48f710998a2e9"
|
|
234
232
|
},
|
|
235
|
-
"corpusCommit": "
|
|
233
|
+
"corpusCommit": "12aac8ee261f99a5593551dd1c0f317195d5cb28"
|
|
236
234
|
}
|
package/src/global-setup.ts
CHANGED
|
@@ -75,17 +75,6 @@ export function setup(): void {
|
|
|
75
75
|
// Suite 2.0.0: in the published layout the contract is the spec-artifacts peer (RFC 0168 §D.2).
|
|
76
76
|
const stamp = LAYOUT === 'published' ? verifyPeerContract(PKG_ROOT_PATH) : verifyCorpusStamp(PKG_ROOT_PATH, LAYOUT);
|
|
77
77
|
process.stderr.write(`${describeVerdict(stamp)}\n`);
|
|
78
|
-
// A version skew and a digest mismatch both have to refuse, but they are
|
|
79
|
-
// different faults with different fixes, and reporting them in the same words
|
|
80
|
-
// sends the reader to debug a corrupt install when nothing is corrupt.
|
|
81
|
-
if (stamp.kind === 'peer-version') {
|
|
82
|
-
throw new Error(
|
|
83
|
-
`openwop-conformance: refusing to run — this suite was packed against @openwop/spec-artifacts@${stamp.lockVersion}, ` +
|
|
84
|
-
`but @openwop/spec-artifacts@${stamp.peerVersion} is installed. They are declared EXACT peers. ` +
|
|
85
|
-
`Install both at the same explicit version; do NOT install at a dist-tag such as \`next\`, which moves per package ` +
|
|
86
|
-
`and can name a pair that was never published together.`,
|
|
87
|
-
);
|
|
88
|
-
}
|
|
89
78
|
if (stamp.kind === 'mismatch') {
|
|
90
79
|
throw new Error('openwop-conformance: refusing to run — schemas/CORPUS-STAMP.json digests do not match the vendored api/ + schemas/ files. Reinstall the package; do not hand-patch vendored contract files.');
|
|
91
80
|
}
|
package/src/lib/corpus-stamp.ts
CHANGED
|
@@ -39,17 +39,7 @@ export interface CorpusStamp {
|
|
|
39
39
|
export type StampVerdict =
|
|
40
40
|
| { readonly kind: 'verified'; readonly files: number }
|
|
41
41
|
| { readonly kind: 'not-applicable'; readonly reason: string }
|
|
42
|
-
| { readonly kind: 'mismatch'; readonly missing: readonly string[]; readonly altered: readonly string[]; readonly extra: readonly string[] }
|
|
43
|
-
/**
|
|
44
|
-
* The peer is INSTALLED and INTACT but is a different version than the suite
|
|
45
|
-
* was packed against. Its own kind because the remedy is completely different
|
|
46
|
-
* from a digest mismatch — nothing is corrupt, two versions are simply out of
|
|
47
|
-
* step — and because the generic message sends readers to debug a broken
|
|
48
|
-
* install. Reported by a tier-2 host that hit it through the `next` dist-tag:
|
|
49
|
-
* the tag moves per package, so `@next` can name an exact-peer PAIR that was
|
|
50
|
-
* never published together.
|
|
51
|
-
*/
|
|
52
|
-
| { readonly kind: 'peer-version'; readonly peerVersion: string; readonly lockVersion: string };
|
|
42
|
+
| { readonly kind: 'mismatch'; readonly missing: readonly string[]; readonly altered: readonly string[]; readonly extra: readonly string[] };
|
|
53
43
|
|
|
54
44
|
export const STAMP_RELATIVE_PATH = join('schemas', 'CORPUS-STAMP.json');
|
|
55
45
|
|
|
@@ -104,11 +94,7 @@ export function verifyPeerContract(pkgRoot: string): StampVerdict {
|
|
|
104
94
|
if (!existsSync(stampPath)) return { kind: 'mismatch', missing: ['@openwop/spec-artifacts/CORPUS-STAMP.json'], altered: [], extra: [] };
|
|
105
95
|
const stamp = JSON.parse(readFileSync(stampPath, 'utf8')) as { package: string; version: string; files: Record<string, string> };
|
|
106
96
|
const digest = createHash('sha256').update(JSON.stringify({ package: stamp.package, version: stamp.version, files: stamp.files })).digest('hex');
|
|
107
|
-
|
|
108
|
-
// message names the two versions and the fix, instead of sending the reader
|
|
109
|
-
// to hunt a damaged install.
|
|
110
|
-
if (stamp.version !== lock.version) return { kind: 'peer-version', peerVersion: stamp.version, lockVersion: lock.version };
|
|
111
|
-
if (digest !== lock.stampSha256) return { kind: 'mismatch', missing: [], altered: [`@openwop/spec-artifacts ${stamp.version} stamp digest ${digest.slice(0, 12)} ≠ the suite's lock ${lock.stampSha256.slice(0, 12)} — same version, different contents`], extra: [] };
|
|
97
|
+
if (stamp.version !== lock.version || digest !== lock.stampSha256) return { kind: 'mismatch', missing: [], altered: [`@openwop/spec-artifacts ${stamp.version} (digest ${digest.slice(0, 12)}) ≠ the suite's lock ${lock.version} (${lock.stampSha256.slice(0, 12)})`], extra: [] };
|
|
112
98
|
const missing: string[] = []; const altered: string[] = [];
|
|
113
99
|
for (const [rel, d] of Object.entries(stamp.files)) { const p = join(peerRoot, ...rel.split('/')); if (!existsSync(p)) missing.push(rel); else if (sha256File(p) !== d) altered.push(rel); }
|
|
114
100
|
if (missing.length || altered.length) return { kind: 'mismatch', missing, altered, extra: [] };
|
|
@@ -157,14 +143,6 @@ export function describeVerdict(v: StampVerdict): string {
|
|
|
157
143
|
return `[openwop-conformance] corpus stamp VERIFIED — ${v.files} vendored api/ + schemas/ files match their SHA-256 digests`;
|
|
158
144
|
case 'not-applicable':
|
|
159
145
|
return `[openwop-conformance] corpus stamp not checked — ${v.reason}`;
|
|
160
|
-
case 'peer-version':
|
|
161
|
-
return (
|
|
162
|
-
`[openwop-conformance] peer version MISMATCH — this suite was packed against ` +
|
|
163
|
-
`@openwop/spec-artifacts@${v.lockVersion} but @openwop/spec-artifacts@${v.peerVersion} is installed. ` +
|
|
164
|
-
`Nothing is corrupt: the two are declared EXACT peers and are simply out of step. ` +
|
|
165
|
-
`Install both at the same explicit version — never at a dist-tag such as \`next\`, which moves per package ` +
|
|
166
|
-
`and can therefore name a pair that was never published together.`
|
|
167
|
-
);
|
|
168
146
|
case 'mismatch':
|
|
169
147
|
return (
|
|
170
148
|
`[openwop-conformance] corpus stamp MISMATCH — the vendored contract is not the one this suite shipped ` +
|
|
@@ -3,42 +3,40 @@
|
|
|
3
3
|
* the host must be able to honour (suite 2.0.0, target major 2; unaided).
|
|
4
4
|
*
|
|
5
5
|
* `fixtures[]` in discovery gates scenarios: `isFixtureAdvertised(id)` decides
|
|
6
|
-
* whether a scenario runs at all.
|
|
7
|
-
*
|
|
8
|
-
*
|
|
9
|
-
*
|
|
10
|
-
* that
|
|
6
|
+
* whether a scenario runs at all. Nothing checked that an advertised id names a
|
|
7
|
+
* fixture the corpus actually defines, or that the host can serve it. A host
|
|
8
|
+
* whose advertised list and seeded set drift apart therefore fails somewhere
|
|
9
|
+
* else entirely — the scenario gated on the missing fixture attempts, fails on
|
|
10
|
+
* a run that cannot be created, and the failure is attributed to that
|
|
11
|
+
* scenario's requirement rather than to the advertisement that was wrong.
|
|
11
12
|
*
|
|
12
|
-
*
|
|
13
|
-
*
|
|
14
|
-
*
|
|
15
|
-
*
|
|
16
|
-
*
|
|
17
|
-
*
|
|
18
|
-
*
|
|
19
|
-
*
|
|
20
|
-
* naming it precisely because "no such fixture ships in `conformance/fixtures/`".
|
|
13
|
+
* No host is currently known to exhibit this. A tier-2 host was thought to
|
|
14
|
+
* (46 seeded against 47 advertised) and then verified and retracted it — the
|
|
15
|
+
* count had been eyeballed from an array literal rather than measured, and the
|
|
16
|
+
* two sets are in fact identical. The scenario is kept because the failure mode
|
|
17
|
+
* is a property of the gating mechanism, not of that host: `fixtures[]` decides
|
|
18
|
+
* whether a scenario runs, so a wrong advertisement is charged to whatever runs
|
|
19
|
+
* next. Leg 1 is also the stronger check — an id the corpus catalog does not
|
|
20
|
+
* define is wrong however well a host's own two lists agree with each other.
|
|
21
21
|
*
|
|
22
|
-
*
|
|
23
|
-
*
|
|
24
|
-
*
|
|
25
|
-
*
|
|
26
|
-
*
|
|
27
|
-
*
|
|
28
|
-
*
|
|
29
|
-
* What survives is the leg that was always sound: an advertised fixture MUST be
|
|
30
|
-
* creatable. That holds whoever defines it, and it is the one that catches the
|
|
31
|
-
* drift the misattribution comes from.
|
|
22
|
+
* Two legs, both cheap:
|
|
23
|
+
* 1. the advertised ids are a subset of the corpus fixture catalog — the
|
|
24
|
+
* vocabulary is closed, so an id the corpus does not define is a typo or
|
|
25
|
+
* an invention, not a capability;
|
|
26
|
+
* 2. a bounded sample of advertised fixtures is actually creatable, so the
|
|
27
|
+
* list is a claim about reachable state rather than a wish.
|
|
32
28
|
*
|
|
33
29
|
* @see spec/v2/core/conformance.md
|
|
34
|
-
* @see conformance/
|
|
30
|
+
* @see conformance/fixtures.md
|
|
35
31
|
*/
|
|
36
32
|
|
|
37
33
|
import { describe, it, expect } from 'vitest';
|
|
34
|
+
import { existsSync, readdirSync } from 'node:fs';
|
|
38
35
|
import { driver, type OpenWOPResponse } from '../lib/driver.js';
|
|
39
36
|
import { v2Discovery } from '../lib/v2.js';
|
|
40
37
|
import { softSkip } from '../lib/soft-skip.js';
|
|
41
38
|
import { req } from '../lib/requirement-ids.js';
|
|
39
|
+
import { FIXTURES_DIR } from '../lib/paths.js';
|
|
42
40
|
|
|
43
41
|
const ID = 'openwop.requirement.0168.advertised-fixtures-exist';
|
|
44
42
|
const DOC = 'spec/v2/core/conformance.md §Fixtures';
|
|
@@ -59,6 +57,26 @@ function advertisedIds(doc: Record<string, unknown>): string[] {
|
|
|
59
57
|
}
|
|
60
58
|
|
|
61
59
|
describe('v2-advertised-fixtures-exist (conformance.md §Fixtures)', () => {
|
|
60
|
+
it('every advertised fixture id is one the corpus defines', async () => {
|
|
61
|
+
const doc = await v2Discovery().catch(() => null);
|
|
62
|
+
if (!doc) return softSkip('blocked', 'v2 discovery unreachable');
|
|
63
|
+
const ids = advertisedIds(doc);
|
|
64
|
+
if (ids.length === 0) return softSkip('inapplicable', 'the host advertises no fixtures[] — there is no claim to falsify');
|
|
65
|
+
if (FIXTURES_DIR === null || !existsSync(FIXTURES_DIR)) {
|
|
66
|
+
return softSkip('blocked', 'the fixture catalog is absent from this layout, so an advertised id cannot be checked against it');
|
|
67
|
+
}
|
|
68
|
+
const catalog = new Set(
|
|
69
|
+
readdirSync(FIXTURES_DIR)
|
|
70
|
+
.filter((f) => f.endsWith('.json'))
|
|
71
|
+
.map((f) => f.replace(/\.json$/, '')),
|
|
72
|
+
);
|
|
73
|
+
const unknown = ids.filter((id) => !catalog.has(id));
|
|
74
|
+
expect(
|
|
75
|
+
unknown,
|
|
76
|
+
req(ID, DOC, `every id in fixtures[] MUST name a fixture the corpus defines — the vocabulary is closed, so an id the catalog does not carry is a typo or an invention rather than a capability (${unknown.length} unknown of ${ids.length}: ${unknown.slice(0, 5).join(', ')})`),
|
|
77
|
+
).toEqual([]);
|
|
78
|
+
});
|
|
79
|
+
|
|
62
80
|
it('a sampled advertised fixture is actually creatable, not just listed', async () => {
|
|
63
81
|
const doc = await v2Discovery().catch(() => null);
|
|
64
82
|
if (!doc) return softSkip('blocked', 'v2 discovery unreachable');
|
|
@@ -76,35 +76,7 @@ describe('v2 dual-stack-negotiation (RFC 0172 §A.3–§A.4 — gated on two maj
|
|
|
76
76
|
const read = await http(() => driver.get(`/runs/${encodeURIComponent(runId)}`, { headers: { 'OpenWOP-Version': '2.0' } }));
|
|
77
77
|
if (read === null) return softSkip('blocked', 'GET /runs/{runId} unreachable (fetch failed)');
|
|
78
78
|
expect(read.status, req('openwop.requirement.0172.dual-stack-negotiation.cross-major-read', 'spec/v2/core/versioning.md §5', 'the overlap: a run created through /v1/runs MUST be readable through GET /runs/{runId} with OpenWOP-Version: 2.0')).toBe(200);
|
|
79
|
-
|
|
80
|
-
//
|
|
81
|
-
// This assertion has been wrong twice, in opposite directions, and the pair
|
|
82
|
-
// is the point:
|
|
83
|
-
//
|
|
84
|
-
// until 2026-09-04 `.toBe(runId)` — byte-equality with the v1 id, cited to
|
|
85
|
-
// versioning.md §5, which said nothing about identifiers.
|
|
86
|
-
// TIGHTER than its prose: it failed a host that had
|
|
87
|
-
// implemented identity.md §5 faithfully.
|
|
88
|
-
// rc.28 accepted the bare v1 id OR its projection. LOOSER than
|
|
89
|
-
// its prose: `run-snapshot.schema.json` binds `runId` to
|
|
90
|
-
// `ids.schema.json#/$defs/runId`, whose pattern REQUIRES
|
|
91
|
-
// the `/`. rc.28 passed a response the v2 contract
|
|
92
|
-
// rejects — the same defect it was written to fix,
|
|
93
|
-
// committed in the act of fixing it.
|
|
94
|
-
//
|
|
95
|
-
// §5 now states the rule outright, and the reason it is a MUST is not
|
|
96
|
-
// stylistic: `identity.md` §5 requires a host to refuse a tenant-bound id
|
|
97
|
-
// whose tenant segment is not the caller's (`403 id_tenant_mismatch`). A
|
|
98
|
-
// bare id HAS no tenant segment, so that mandatory check cannot run on it.
|
|
99
|
-
// A legacy unprefixed form would be a class of ids — precisely the ones
|
|
100
|
-
// carried over from v1 — exempt from major 2's tenant isolation.
|
|
101
|
-
//
|
|
102
|
-
// So: the projection, and only the projection. A bare id here is a finding.
|
|
103
|
-
const readId = (read.json as { runId?: unknown } | undefined)?.runId;
|
|
104
|
-
expect(
|
|
105
|
-
readId,
|
|
106
|
-
req('openwop.requirement.0172.dual-stack-negotiation.cross-major-read', 'spec/v2/core/versioning.md §5', `a run minted under major 1 MUST be named by its tenant-bound projection <tenantId>/${'${the v1 id}'} when read under major 2 — the bare id is not merely unconventional, it carries no tenant segment for the mandatory 403 id_tenant_mismatch check to read (identity.md §5), and ids.schema.json#/$defs/runId has no legacy branch. Got ${JSON.stringify(readId)} for a run created as ${JSON.stringify(runId)}`),
|
|
107
|
-
).toMatch(new RegExp(`^[A-Za-z0-9._~-]{1,128}/${runId.replace(/[.*+?^${}()|[\]\\]/g, '\\$&')}$`));
|
|
79
|
+
expect((read.json as { runId?: unknown } | undefined)?.runId, req('openwop.requirement.0172.dual-stack-negotiation.cross-major-read', 'spec/v2/core/versioning.md §5', 'the v2 read MUST name the same run')).toBe(runId);
|
|
108
80
|
expect(major(read), req('openwop.requirement.0172.dual-stack-negotiation.cross-major-read', 'spec/v2/core/versioning.md §1.4', 'the v2 read MUST report the 2.x contract that produced it')).toBe('2');
|
|
109
81
|
});
|
|
110
82
|
|
|
@@ -61,15 +61,6 @@ describe('v2-era-2-append-vocabulary (RFC 0176 §A — the writer rule)', () =>
|
|
|
61
61
|
return softSkip('blocked', `GET /runs/${runId}/events/poll answered ${before?.status ?? 'no response'} on the seeded era-2 run — the log cannot be read back`);
|
|
62
62
|
}
|
|
63
63
|
const seedCount = eventsOf(before).length;
|
|
64
|
-
// The seam returning ok is a WRAPPER claim; the readable log is the artifact.
|
|
65
|
-
// A seam that reports success and seeds nothing leaves no era-2 log to append
|
|
66
|
-
// to, so there is nothing here to witness the writer rule with — that is
|
|
67
|
-
// `blocked`, not a writer-rule failure. Asserting against an empty log would
|
|
68
|
-
// charge this requirement for a seam defect, which is the misattribution the
|
|
69
|
-
// suite exists to avoid.
|
|
70
|
-
if (seedCount === 0) {
|
|
71
|
-
return softSkip('blocked', `seedEra2Log reported success but the log reads back empty (0 events) — the seam's return value is not evidence that a log exists, and without a seeded era-2 log the writer rule is unwitnessed here`);
|
|
72
|
-
}
|
|
73
64
|
|
|
74
65
|
// One canonical mutation so the HOST's own writer appends. Cancel is the
|
|
75
66
|
// universally available terminal transition; a host that refuses it on a
|
|
@@ -83,7 +83,7 @@ describe('v2-era-stamp-universal (RFC 0176 §A.7)', () => {
|
|
|
83
83
|
const advertised = doc['eventLogSchemaVersion'];
|
|
84
84
|
if (advertised === undefined) return softSkip('inapplicable', 'the host advertises no eventLogSchemaVersion');
|
|
85
85
|
if (advertised !== 3) {
|
|
86
|
-
return softSkip('inapplicable', `the host advertises era ${JSON.stringify(advertised)}, not 3 —
|
|
86
|
+
return softSkip('inapplicable', `the host advertises era ${JSON.stringify(advertised)}, not 3 — it has not moved its writers to the v2 era, which is legitimate through the overlap`);
|
|
87
87
|
}
|
|
88
88
|
|
|
89
89
|
const created = await http(() => driver.post('/runs', { workflowId: 'conformance-noop', inputs: {} }));
|
|
@@ -40,7 +40,7 @@ describe('v2 interrupt-token-scheme (RFC 0170 §E.1)', () => {
|
|
|
40
40
|
if (res === null) return softSkip('blocked', 'GET /interrupts/{token} unreachable (fetch failed)');
|
|
41
41
|
expect([401, 404].includes(res.status), req('openwop.requirement.0170.interrupt-token-scheme.unprefixed-refused', DOC, `a token outside the ow2.<alg>.<kid>.<payload>.<mac> grammar MUST NOT resolve — 401 interrupt_token_invalid (or 404 not_found where the signed-token surface is not mounted); got ${res.status}`)).toBe(true);
|
|
42
42
|
const code = readErrorCode(res.json);
|
|
43
|
-
expect(res.status === 401 ? code === 'interrupt_token_invalid' :
|
|
43
|
+
expect(res.status === 401 ? code === 'interrupt_token_invalid' : code === 'not_found', req('openwop.requirement.0170.interrupt-token-scheme.unprefixed-refused', 'spec/v2/core/interrupt.md §Tokens', `the refusal MUST carry its registered code (401 → interrupt_token_invalid, 404 → not_found); got ${String(code)}`)).toBe(true);
|
|
44
44
|
});
|
|
45
45
|
|
|
46
46
|
it('a well-formed token under a kid the host does not hold is 401 interrupt_token_invalid', async () => {
|
|
@@ -7,31 +7,9 @@
|
|
|
7
7
|
*
|
|
8
8
|
* What we CAN test cheaply:
|
|
9
9
|
* 1. Server advertises a `protocolVersion` in `Capabilities`.
|
|
10
|
-
* 2.
|
|
11
|
-
*
|
|
12
|
-
*
|
|
13
|
-
* This file previously claimed to check "the four version axes
|
|
14
|
-
* (`engineVersion`, `eventLogSchemaVersion`, per-event `schemaVersion`,
|
|
15
|
-
* `pinnedVersions`)". IT DID NOT. `protocolVersion` was the only axis
|
|
16
|
-
* asserted, and across all 444 v1 scenario files the sole occurrence of the
|
|
17
|
-
* identifier `eventLogSchemaVersion` was that sentence — a docstring
|
|
18
|
-
* describing a check that did not exist. A comment claiming coverage is
|
|
19
|
-
* worse than no comment: it answers "is this tested?" for anyone who greps,
|
|
20
|
-
* and answers it wrongly.
|
|
21
|
-
*
|
|
22
|
-
* Current state of the four, stated so this comment can be checked rather
|
|
23
|
-
* than trusted: `eventLogSchemaVersion` and `engineVersion` are witnessed by
|
|
24
|
-
* `era-key-stamped-v1.test.ts` (both are run-document `MUST`s in
|
|
25
|
-
* `version-negotiation.md` §Stamping, and both were unasserted until
|
|
26
|
-
* 2026-09-04). Per-event `schemaVersion` and `pinnedVersions` are **not
|
|
27
|
-
* asserted here and carry no `MUST` in that document** — checked, rather
|
|
28
|
-
* than assumed to be a gap.
|
|
29
|
-
*
|
|
30
|
-
* This paragraph was itself wrong for one release candidate: it said
|
|
31
|
-
* `engineVersion` "remains UNASSERTED" after the leg asserting it had
|
|
32
|
-
* landed. A docstring that describes coverage goes stale the moment
|
|
33
|
-
* coverage changes, which is the argument for stating what can be
|
|
34
|
-
* re-derived rather than what was true once.
|
|
10
|
+
* 2. The four version axes (`engineVersion`,
|
|
11
|
+
* `eventLogSchemaVersion`, per-event `schemaVersion`,
|
|
12
|
+
* `pinnedVersions`) appear where the spec says they should.
|
|
35
13
|
* 3. Forward-compat read: events carrying an UNKNOWN
|
|
36
14
|
* `schemaVersion` SHOULD still be readable via the events/poll
|
|
37
15
|
* endpoint without 5xx (best-effort fold per
|
package/src/setup.ts
CHANGED
|
@@ -40,8 +40,6 @@ import { softSkipDisposition } from './lib/soft-skip.js';
|
|
|
40
40
|
import { ItIdAllocator, takeExplicitRequirementId } from './lib/requirement-ids.js';
|
|
41
41
|
import { SPEC_COHERENCE_SCENARIOS, SPEC_COHERENCE_DETAIL } from './lib/spec-coherence.js';
|
|
42
42
|
import type { DiscoveryPayload } from './lib/profiles.js';
|
|
43
|
-
import { targetMajor } from './lib/seams.js';
|
|
44
|
-
import { softSkip } from './lib/soft-skip.js';
|
|
45
43
|
|
|
46
44
|
const SUITE_INIT_TIMEOUT_MS = 5_000;
|
|
47
45
|
|
|
@@ -279,62 +277,6 @@ function _fileOf(task: { file?: { filepath?: string; name?: string } } | undefin
|
|
|
279
277
|
const f = task?.file?.filepath ?? task?.file?.name;
|
|
280
278
|
return typeof f === 'string' && f.length > 0 ? basename(f) : null;
|
|
281
279
|
}
|
|
282
|
-
// ---------------------------------------------------------------------------
|
|
283
|
-
// The applicability check and the assertion MUST run under the same contract.
|
|
284
|
-
//
|
|
285
|
-
// A scenario's registration in scenario-majors.json says which target majors it
|
|
286
|
-
// is written for. The driver reads OPENWOP_TARGET_MAJOR to decide which header
|
|
287
|
-
// and path space every probe uses. Nothing connected the two: a lane that ran
|
|
288
|
-
// vitest directly over all 501 files at the default (major 1) executed every
|
|
289
|
-
// major-2 scenario with major-1 requests. The scenarios' own gates call
|
|
290
|
-
// v2Discovery(), which sets the header EXPLICITLY, so the gate passed and the
|
|
291
|
-
// probe went out as v1 — a check that proved the host speaks v2 with one
|
|
292
|
-
// request, then tested a v2 requirement with a request that did not.
|
|
293
|
-
//
|
|
294
|
-
// Measured on a tier-1 host 2026-09-04: three "host defects" reported from that
|
|
295
|
-
// lane, all of which evaporated at major 2; the host was one edit from "fixing"
|
|
296
|
-
// correct behaviour. And in the other direction: 4 of 56 v2 files fail on every
|
|
297
|
-
// host forever under a major-1 driver, so a gate that runs them that way is red
|
|
298
|
-
// by construction and gets reasoned past. Both are the same defect: a scoped
|
|
299
|
-
// signal read as unscoped, with the scope nowhere in the output.
|
|
300
|
-
//
|
|
301
|
-
// So: a file whose registered majors do not include the driver's target major
|
|
302
|
-
// is INAPPLICABLE to this lane, recorded as such with the reason, and never
|
|
303
|
-
// probes. Files not in the registry (coherence checks, lib tests) are untouched.
|
|
304
|
-
// ---------------------------------------------------------------------------
|
|
305
|
-
const SCENARIO_MAJORS: Record<string, number[]> = (() => {
|
|
306
|
-
try {
|
|
307
|
-
const p = join(PKG_ROOT_PATH, 'scenario-majors.json');
|
|
308
|
-
if (!existsSync(p)) return {};
|
|
309
|
-
return (JSON.parse(readFileSync(p, 'utf8')) as { majors?: Record<string, number[]> }).majors ?? {};
|
|
310
|
-
} catch {
|
|
311
|
-
return {};
|
|
312
|
-
}
|
|
313
|
-
})();
|
|
314
|
-
|
|
315
|
-
beforeEach((ctx) => {
|
|
316
|
-
const p = (expect.getState() as { testPath?: string }).testPath;
|
|
317
|
-
if (!p) return;
|
|
318
|
-
const file = basename(p);
|
|
319
|
-
const majors = SCENARIO_MAJORS[file];
|
|
320
|
-
if (!majors) return;
|
|
321
|
-
const lane = targetMajor();
|
|
322
|
-
if (majors.includes(lane)) return;
|
|
323
|
-
const detail = `registered for target major ${majors.join('/')} and this lane runs at major ${lane} (OPENWOP_TARGET_MAJOR) — the probe would go out under a contract the scenario's gate does not use; select files with --target-major or set the variable`;
|
|
324
|
-
// Two records, one per resolver. The per-TEST disposition is read from the
|
|
325
|
-
// requirement journal (the same entry behaviorGate writes), so the row lands
|
|
326
|
-
// as `inapplicable` with this reason rather than `skipped`, which under RFC
|
|
327
|
-
// 0148 would claim the operator opted out. The per-FILE note covers the
|
|
328
|
-
// all-skipped fallback in resolveFileRecord.
|
|
329
|
-
try {
|
|
330
|
-
recordRequirement('openwop.family.lane-target-major', 'inapplicable', detail, { scenarioFile: file });
|
|
331
|
-
} catch {
|
|
332
|
-
/* never fail a test for bookkeeping */
|
|
333
|
-
}
|
|
334
|
-
softSkip('inapplicable', detail);
|
|
335
|
-
ctx.skip();
|
|
336
|
-
});
|
|
337
|
-
|
|
338
280
|
beforeAll(({}, suite) => {
|
|
339
281
|
// Mark the ledger journal BEFORE the file's tests run, so a behaviorGate
|
|
340
282
|
// decision made by the very first test is inside the file's window.
|