@openwop/openwop-conformance 2.4.1 → 2.4.2

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 CHANGED
@@ -1,5 +1,23 @@
1
1
  # `@openwop/openwop-conformance` Changelog
2
2
 
3
+ ## [2.4.2] — 2026-09-18 — an id no host could ever witness
4
+
5
+ **Why a patch.** One assertion moves into its own `it`; no scenario file is
6
+ added or removed and no host obligation changes.
7
+
8
+ ### Fixed
9
+
10
+ - **`openwop.requirement.0173.pack-isolation.seam`** was minted inside
11
+ `v2-pack-isolation`'s shared `invoke()` helper.
12
+ `generate-requirement-registry.mjs` harvests `req(…)` only within an `it`, so
13
+ the id never reached `requirements.json` and no bundle could carry a row for
14
+ it — while `check-cut-gates.mjs` scans every `req(` in the source and went on
15
+ demanding one, failing RFC 0167 §G.2 on a row no host could supply. The seam
16
+ contract now has its own `it`, which is the copy the registry can see. The
17
+ helper keeps its `req(…)` call — RFC 0168 §A.1 makes `req(…)` the only
18
+ assertion-message form in `src/scenarios`, so the fix is the extra `it`, not
19
+ a quieter assertion.
20
+
3
21
  ## [2.4.1] — 2026-09-18 — the leg that reads the host, not the schema
4
22
 
5
23
  **Why a patch.** A leg is added to an existing scenario file; no file is added or removed.
@@ -1,5 +1,5 @@
1
1
  {
2
2
  "package": "@openwop/spec-artifacts",
3
- "version": "2.4.1",
4
- "stampSha256": "576f2a6451072e6ae17a6398428f6fba4c8a505d80e8899431d4bcf69a2c0fec"
3
+ "version": "2.4.2",
4
+ "stampSha256": "cb840f92cef6dbff3beed39b860bde984adf1080e830dab5088487f2bf17d767"
5
5
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@openwop/openwop-conformance",
3
- "version": "2.4.1",
3
+ "version": "2.4.2",
4
4
  "description": "Production-ready black-box conformance suite for OpenWOP v1.0 compliant servers.",
5
5
  "repository": {
6
6
  "type": "git",
@@ -56,6 +56,6 @@
56
56
  "@openwop/spec-artifacts": "file:../spec-artifacts"
57
57
  },
58
58
  "peerDependencies": {
59
- "@openwop/spec-artifacts": "2.4.1"
59
+ "@openwop/spec-artifacts": "2.4.2"
60
60
  }
61
61
  }
package/requirements.json CHANGED
@@ -3,10 +3,10 @@
3
3
  "generatedFrom": "src/scenarios/*.test.ts",
4
4
  "counts": {
5
5
  "files": 571,
6
- "tests": 2173,
7
- "withStableId": 2173,
6
+ "tests": 2174,
7
+ "withStableId": 2174,
8
8
  "interpolatedTitles": 0,
9
- "explicitIds": 2126
9
+ "explicitIds": 2127
10
10
  },
11
11
  "records": [
12
12
  {
@@ -27681,7 +27681,7 @@
27681
27681
  {
27682
27682
  "id": "openwop.it.v2-pack-isolation.sandbox-isolationmodel-names-a-real-mechanism-never-node-vm",
27683
27683
  "file": "v2-pack-isolation.test.ts",
27684
- "line": 70,
27684
+ "line": 78,
27685
27685
  "title": "sandbox.isolationModel names a real mechanism, never node:vm",
27686
27686
  "explicitId": "openwop.requirement.0173.pack-isolation",
27687
27687
  "citations": [
@@ -27696,10 +27696,24 @@
27696
27696
  }
27697
27697
  ]
27698
27698
  },
27699
+ {
27700
+ "id": "openwop.it.v2-pack-isolation.the-sandbox-invoke-seam-answers-the-seam-contract",
27701
+ "file": "v2-pack-isolation.test.ts",
27702
+ "line": 92,
27703
+ "title": "the sandbox-invoke seam answers the seam contract",
27704
+ "explicitId": "openwop.requirement.0173.pack-isolation.seam",
27705
+ "citations": [
27706
+ {
27707
+ "section": "host-sample-test-seams.md §8",
27708
+ "requirement": null,
27709
+ "interpolated": true
27710
+ }
27711
+ ]
27712
+ },
27699
27713
  {
27700
27714
  "id": "openwop.it.v2-pack-isolation.node-pack-sandbox-fs-gated-a-host-filesystem-read-is-refused",
27701
27715
  "file": "v2-pack-isolation.test.ts",
27702
- "line": 84,
27716
+ "line": 104,
27703
27717
  "title": "node-pack-sandbox-fs-gated: a host filesystem read is refused",
27704
27718
  "explicitId": null,
27705
27719
  "citations": []
@@ -27707,7 +27721,7 @@
27707
27721
  {
27708
27722
  "id": "openwop.it.v2-pack-isolation.node-pack-sandbox-fs-gated-a-host-filesystem-write-is-refused",
27709
27723
  "file": "v2-pack-isolation.test.ts",
27710
- "line": 91,
27724
+ "line": 111,
27711
27725
  "title": "node-pack-sandbox-fs-gated: a host filesystem write is refused",
27712
27726
  "explicitId": null,
27713
27727
  "citations": []
@@ -27715,7 +27729,7 @@
27715
27729
  {
27716
27730
  "id": "openwop.it.v2-pack-isolation.node-pack-sandbox-no-env-the-host-environment-does-not-leak",
27717
27731
  "file": "v2-pack-isolation.test.ts",
27718
- "line": 98,
27732
+ "line": 118,
27719
27733
  "title": "node-pack-sandbox-no-env: the host environment does not leak",
27720
27734
  "explicitId": null,
27721
27735
  "citations": []
@@ -27723,7 +27737,7 @@
27723
27737
  {
27724
27738
  "id": "openwop.it.v2-pack-isolation.node-pack-sandbox-network-gated-ungated-network-egress-is-refused",
27725
27739
  "file": "v2-pack-isolation.test.ts",
27726
- "line": 105,
27740
+ "line": 125,
27727
27741
  "title": "node-pack-sandbox-network-gated: ungated network egress is refused",
27728
27742
  "explicitId": null,
27729
27743
  "citations": []
@@ -27731,7 +27745,7 @@
27731
27745
  {
27732
27746
  "id": "openwop.it.v2-pack-isolation.node-pack-sandbox-no-process-host-process-access-is-refused",
27733
27747
  "file": "v2-pack-isolation.test.ts",
27734
- "line": 112,
27748
+ "line": 132,
27735
27749
  "title": "node-pack-sandbox-no-process: host process access is refused",
27736
27750
  "explicitId": null,
27737
27751
  "citations": []
@@ -27739,7 +27753,7 @@
27739
27753
  {
27740
27754
  "id": "openwop.it.v2-pack-isolation.node-pack-sandbox-timeout-exceeding-wallclocklimitms-fails-with-sandbox-timeout",
27741
27755
  "file": "v2-pack-isolation.test.ts",
27742
- "line": 119,
27756
+ "line": 139,
27743
27757
  "title": "node-pack-sandbox-timeout: exceeding wallClockLimitMs fails with sandbox_timeout",
27744
27758
  "explicitId": "openwop.requirement.0173.pack-isolation.timeout",
27745
27759
  "citations": [
@@ -27752,7 +27766,7 @@
27752
27766
  {
27753
27767
  "id": "openwop.it.v2-pack-isolation.node-pack-sandbox-memory-cap-exceeding-memorylimitbytes-fails-with-sandbox-memor",
27754
27768
  "file": "v2-pack-isolation.test.ts",
27755
- "line": 126,
27769
+ "line": 146,
27756
27770
  "title": "node-pack-sandbox-memory-cap: exceeding memoryLimitBytes fails with sandbox_memory_exceeded",
27757
27771
  "explicitId": "openwop.requirement.0173.pack-isolation.memory-cap",
27758
27772
  "citations": [
@@ -27765,7 +27779,7 @@
27765
27779
  {
27766
27780
  "id": "openwop.it.v2-pack-isolation.node-pack-sandbox-isolated-context-a-pack-cannot-mutate-state-another-invocation",
27767
27781
  "file": "v2-pack-isolation.test.ts",
27768
- "line": 133,
27782
+ "line": 153,
27769
27783
  "title": "node-pack-sandbox-isolated-context: a pack cannot mutate state another invocation sees",
27770
27784
  "explicitId": "openwop.requirement.0173.pack-isolation.isolated-context",
27771
27785
  "citations": [
@@ -1,17 +1,17 @@
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.4.1",
5
- "corpusTag": "v2.4.1",
4
+ "version": "2.4.2",
5
+ "corpusTag": "v2.4.2",
6
6
  "files": {
7
7
  "api/.redocly.lint-ignore.yaml": "bf5a8350b88a72fa43f59605ed8d903ed24b6cfccda5e45509c9f6ed9ee4e712",
8
8
  "api/asyncapi.yaml": "d5ecb9ee6114582be3b1f662c84bfac9ae96dae7bacb853e461168f70a8e1c7d",
9
9
  "api/grpc/openwop.proto": "c3e72bb17cba514ee98feb6434e6c9b6ea6795bfd086489ec69fd882dd1ad977",
10
10
  "api/openapi.yaml": "39081c59fb696159806b0f2f9a42e7e9ff830d622fcf2ad4159b21357580a955",
11
11
  "api/redocly.yaml": "b0604c89b2ca6d5076ec25725c539dad44a741a811fe524439ee6daef8baa09f",
12
- "api/seams-v2.yaml": "f6385deac1f8292cce87c896725bcf709308b65dfb8050f9f8113a99492596c2",
13
- "api/v2/asyncapi.yaml": "edc8d91a418cc29fea8d4cbe20ad1a69af8a26c0addf9b55e29d2fbea50716b0",
14
- "api/v2/openapi.yaml": "ff765953f64a79f6d7e28e3d1e4adff7d912feb03e5ee804af2bffacbd8da2b3",
12
+ "api/seams-v2.yaml": "2a94a4195377913107f884aacd48605e71804f151333de8a8a0abc7b2799c5e2",
13
+ "api/v2/asyncapi.yaml": "930bd4ea705b35ec37605f139a0be7b08b39d8d9c7628c9756c4fdbe47f4655f",
14
+ "api/v2/openapi.yaml": "33298f7981473111ce767695367e44fa3eaa3cbdda9a52badc2b198efcd8259d",
15
15
  "api/v2/redocly.yaml": "1e66b60e6118ad11a823bb620678be464d99dfe50a40e3e6f93ec9429b88b34c",
16
16
  "schemas/README.md": "0c0b737ffcf8f30e7d2809cec8a498232de710f41443212922ad8337cdde0b51",
17
17
  "schemas/a2a-task-state.schema.json": "c9365918f993f943b4b619d42551eb066a1ed33a08d895d51b395432a5b1f1bc",
@@ -200,7 +200,7 @@
200
200
  "schemas/workspace-file.schema.json": "464de85c2a068243084ee9c1d969bc7cd5d8f7948574e58450d6493c38a0e1e4",
201
201
  "spec/v1/alias-detectors.json": "e90916db12d2297e2e560b2d54d2c4702d6cb3bef7179a575844687a7ec17262",
202
202
  "spec/v1/capability-declaration-classes.json": "e7729aed5c4b4e1dd02abab0530f14cc95f5d4070fe51fb139e7f5cccefa00c6",
203
- "spec/v1/core-standard-manifest.json": "195b0a6fa7944758b773e3814659ed7eb4791597ce08b3d5cf5e1588ab7c5702",
203
+ "spec/v1/core-standard-manifest.json": "1575d6d8b801b3d84c65c63d55a4f0563a3350a754e403ee06ffb853b996b639",
204
204
  "spec/v1/deprecations.json": "c81c8f71460936c8d489d8270477c7661cf4a5d7b7bad86c98899750b5656027",
205
205
  "spec/v1/deprecations.schema.json": "18c87e78bedc210431f795ae44c5b5d202f2f3317850d5cf86867d4f1fa1cdfb",
206
206
  "spec/v1/event-codemap.json": "3da60d884157793a360da532a9fcbbfb5285636db325a74cec94b34622186d97",
@@ -219,7 +219,7 @@
219
219
  "spec/v2/core/errors.md": "ad85fc830139e587f20deabf88297b91b1fb6ce31e80d5442624a650246ab16e",
220
220
  "spec/v2/core/events.md": "f1bac16419740f3b722febb6f5caaabed8838e092cba3d080fe9184024049dcf",
221
221
  "spec/v2/core/form-content-packs.md": "6ffaae85d4550be48dd53fb6e2959af8aceb35bd87c5343b722885084f197713",
222
- "spec/v2/core/headers.md": "91167479e63afd8fcfa1f5ee8f5da965eef8fd1cde87135911792dd2effa1b05",
222
+ "spec/v2/core/headers.md": "d34646a59632a79e9907439d0521c90e613ed968578af02129bad7002063de99",
223
223
  "spec/v2/core/idempotency.md": "b86c352d964aebad532727f314e26ed2177d49de382076fa64d3162e2f56118d",
224
224
  "spec/v2/core/identity.md": "9d2b823eb899463807452fe5721dcf09881837c161be024175957db27870b243",
225
225
  "spec/v2/core/interop.md": "d4c404e469e1d9d9be88bc2c939d777e7d7c1d0419b1251c18770f039838a401",
@@ -271,8 +271,8 @@
271
271
  "spec/v2/path-manifest.json": "a6f4e652e866889e8bde815874062f62929aee95dc8e58e7152c56adee262163",
272
272
  "spec/v2/peer-dependency-aliases.json": "d10299280abee08258502925bc327293ee413e0108cd6e6ec75ff6110653308d",
273
273
  "spec/v2/profiles.json": "0636f19fceae625390003a347e70ef4797d84766b5c24ce8a02cea52aadebca4",
274
- "spec/v2/release.json": "4d9ec16c653702e80967db2a08da55dd09326b5dce60e301623826a801702f78",
274
+ "spec/v2/release.json": "4fdf29fe944e63528cdf5dc108e22e5006b2d7fcb1349c33caee85a1cacdd81e",
275
275
  "spec/v2/retention-floors.json": "eaf3722d95c79947af1d4269ef85117e126518c588cfcf1a2b21b97269f51624"
276
276
  },
277
- "corpusCommit": "7e0c22fdb50aac7803ca4d9bf46c0406ae944b78"
277
+ "corpusCommit": "164711f69c396daffb6a300a94e89242640b4087"
278
278
  }
@@ -57,6 +57,14 @@ async function invoke(typeId: string, extra: Record<string, unknown> = {}): Prom
57
57
  if (!doc || !seamsProfileAdvertised(doc)) { softSkip('inapplicable', `the ${typeId} leg is seam-driven — seams profile (conformance.seamsProfile = openwop-conformance-seams-v2) not advertised`); return null; }
58
58
  const res = await driver.post(INVOKE, { typeId, ...extra });
59
59
  if (res.status === 404 || res.status === 403 || res.status === 405) { seamAbsent(`host advertises packs + sandbox but ${INVOKE} answered ${res.status} — the ${typeId} leg is unobservable (host-sample-test-seams.md §8)`); return null; }
60
+ // The same id is ALSO asserted by its own `it` above, and that is the copy the
61
+ // registry can see: `generate-requirement-registry.mjs` harvests `req(…)` only
62
+ // within an `it`, so this helper-level call alone left the id out of
63
+ // requirements.json — and no bundle could carry a row for it — while
64
+ // `check-cut-gates.mjs`, which scans every `req(` in the source, went on
65
+ // demanding one. §G.2 failed on a row no host could supply. RFC 0168 §A.1
66
+ // requires `req(…)` here rather than a bare describe, so the fix is the extra
67
+ // `it`, not a quieter assertion.
60
68
  expect(res.status, req('openwop.requirement.0173.pack-isolation.seam', 'host-sample-test-seams.md §8', `${INVOKE} MUST answer 200 { result } | 200 { error } for ${typeId}`)).toBe(200);
61
69
  return (res.json ?? {}) as InvokeResult;
62
70
  }
@@ -81,6 +89,18 @@ describe('RFC 0173 §B — pack-isolation (gated on packs + sandbox)', () => {
81
89
  ).toContain(model);
82
90
  });
83
91
 
92
+ it('the sandbox-invoke seam answers the seam contract', async () => {
93
+ if (!(await gated())) return softSkip('inapplicable', 'gate not met (reason recorded above)');
94
+ const doc = await discovery();
95
+ if (!doc || !seamsProfileAdvertised(doc)) return softSkip('inapplicable', 'seam-driven — seams profile (conformance.seamsProfile = openwop-conformance-seams-v2) not advertised');
96
+ const res = await driver.post(INVOKE, { typeId: 'misbehave.fs-escape-read' });
97
+ if (res.status === 404 || res.status === 403 || res.status === 405) return seamAbsent(`host advertises packs + sandbox but ${INVOKE} answered ${res.status}`);
98
+ expect(
99
+ res.status,
100
+ req('openwop.requirement.0173.pack-isolation.seam', 'host-sample-test-seams.md §8', `${INVOKE} MUST answer 200 { result } | 200 { error } — the eight behavioural legs are unobservable otherwise`),
101
+ ).toBe(200);
102
+ });
103
+
84
104
  it('node-pack-sandbox-fs-gated: a host filesystem read is refused', async () => {
85
105
  if (!(await gated())) return softSkip('inapplicable', 'gate not met (reason recorded above)');
86
106
  const r = await invoke('misbehave.fs-escape-read');