@openwop/openwop-conformance 2.0.0-rc.9 → 2.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (65) hide show
  1. package/CHANGELOG.md +46 -0
  2. package/README.md +8 -3
  3. package/dist/cli.js +24 -34
  4. package/dist/lib/requirement-registry.js +69 -0
  5. package/dist/lib/scenario-disposition.js +84 -11
  6. package/dist/lib/seams.js +72 -0
  7. package/dist/lib/soft-skip.js +39 -8
  8. package/dist/spec-artifacts.lock.json +2 -2
  9. package/package.json +2 -2
  10. package/requirement-aliases.json +4 -1
  11. package/requirements.json +1028 -55
  12. package/scenario-majors.json +57 -3
  13. package/schemas/CORPUS-STAMP.json +40 -37
  14. package/src/cli.ts +23 -30
  15. package/src/global-setup.ts +11 -0
  16. package/src/lib/corpus-stamp.ts +24 -2
  17. package/src/lib/era2-seed.ts +12 -1
  18. package/src/lib/fixtures.ts +31 -0
  19. package/src/lib/requirement-registry.ts +68 -0
  20. package/src/lib/scenario-disposition.ts +88 -9
  21. package/src/lib/seams.ts +31 -1
  22. package/src/lib/soft-skip.ts +42 -7
  23. package/src/lib/sse.ts +8 -0
  24. package/src/scenarios/era-key-stamped-v1.test.ts +156 -0
  25. package/src/scenarios/pause-resume.test.ts +159 -75
  26. package/src/scenarios/v2-advertised-fixtures-exist.test.ts +25 -43
  27. package/src/scenarios/v2-advertised-path-space-served.test.ts +165 -0
  28. package/src/scenarios/v2-assurance-downgrade-audited.test.ts +1 -1
  29. package/src/scenarios/v2-chain-pin-exact.test.ts +1 -1
  30. package/src/scenarios/v2-coherence-not-in-bundle.test.ts +11 -2
  31. package/src/scenarios/v2-created-run-readable.test.ts +98 -0
  32. package/src/scenarios/v2-dual-stack-negotiation.test.ts +29 -1
  33. package/src/scenarios/v2-effect-identity-business-key.test.ts +1 -1
  34. package/src/scenarios/v2-effect-seam-manifest.test.ts +21 -55
  35. package/src/scenarios/v2-effect-seam-no-refire.test.ts +104 -0
  36. package/src/scenarios/v2-era-2-append-vocabulary.test.ts +16 -2
  37. package/src/scenarios/v2-interrupt-token-scheme.test.ts +1 -1
  38. package/src/scenarios/v2-malformed-body-envelope.test.ts +79 -0
  39. package/src/scenarios/v2-manifest-ceiling-refused.test.ts +1 -1
  40. package/src/scenarios/v2-manifest-hatch-carried.test.ts +1 -1
  41. package/src/scenarios/v2-minimum-version-refused.test.ts +1 -1
  42. package/src/scenarios/v2-mrtr-rounds-ceiling.test.ts +1 -1
  43. package/src/scenarios/v2-negotiation-authenticated.test.ts +1 -1
  44. package/src/scenarios/v2-negotiation-decided-emitted.test.ts +1 -1
  45. package/src/scenarios/v2-pack-isolation.test.ts +1 -1
  46. package/src/scenarios/v2-peer-dependency-declared.test.ts +1 -1
  47. package/src/scenarios/v2-poll-cursor-v2.test.ts +18 -0
  48. package/src/scenarios/v2-revocation-honored.test.ts +1 -1
  49. package/src/scenarios/v2-run-annotation-not-event.test.ts +71 -0
  50. package/src/scenarios/v2-run-bulk-cancel.test.ts +91 -0
  51. package/src/scenarios/v2-run-cancel.test.ts +97 -0
  52. package/src/scenarios/v2-run-completed-outputs.test.ts +93 -0
  53. package/src/scenarios/v2-run-diff-identical.test.ts +75 -0
  54. package/src/scenarios/v2-run-fork-prefix.test.ts +160 -0
  55. package/src/scenarios/v2-run-fork-refusals.test.ts +70 -0
  56. package/src/scenarios/v2-run-options-limits.test.ts +69 -0
  57. package/src/scenarios/v2-run-pause-resume.test.ts +117 -0
  58. package/src/scenarios/v2-run-snapshot-etag.test.ts +57 -0
  59. package/src/scenarios/v2-sse-last-event-id.test.ts +93 -0
  60. package/src/scenarios/v2-stream-mode-refusal.test.ts +118 -0
  61. package/src/scenarios/v2-stream-sse-projection.test.ts +79 -0
  62. package/src/scenarios/v2-subject-link-record.test.ts +1 -1
  63. package/src/scenarios/v2-v1-signed-webhook-accepted.test.ts +1 -1
  64. package/src/scenarios/version-negotiation.test.ts +25 -3
  65. package/src/setup.ts +104 -50
package/requirements.json CHANGED
@@ -2,11 +2,11 @@
2
2
  "$comment": "GENERATED by conformance/scripts/generate-requirement-registry.mjs — do not edit. One record per it()/test() in src/scenarios. Ids: openwop.it.<file-stem>.<title-slug>[~n] (src/lib/requirement-ids.ts). A record with id null has an interpolated title; its run-time row is keyed by the rendered title and maps here by file+line only. Renamed ids need a row in requirement-aliases.json.",
3
3
  "generatedFrom": "src/scenarios/*.test.ts",
4
4
  "counts": {
5
- "files": 544,
6
- "tests": 2118,
7
- "withStableId": 2118,
8
- "interpolatedTitles": 0,
9
- "explicitIds": 2057
5
+ "files": 565,
6
+ "tests": 2150,
7
+ "withStableId": 2149,
8
+ "interpolatedTitles": 1,
9
+ "explicitIds": 2058
10
10
  },
11
11
  "records": [
12
12
  {
@@ -12262,6 +12262,58 @@
12262
12262
  }
12263
12263
  ]
12264
12264
  },
12265
+ {
12266
+ "id": "openwop.it.era-key-stamped-v1.a-run-the-host-just-created-carries-eventlogschemaversion",
12267
+ "file": "era-key-stamped-v1.test.ts",
12268
+ "line": 75,
12269
+ "title": "a run the host just created carries eventLogSchemaVersion",
12270
+ "explicitId": null,
12271
+ "citations": [
12272
+ {
12273
+ "section": null,
12274
+ "requirement": "every persisted run document MUST carry an eventLogSchemaVersion — the field is prose-only (run-snapshot.schema.json requires just runId, workflowId and status), so a snapshot without it validates cleanly and only this check can see its absence",
12275
+ "interpolated": true
12276
+ },
12277
+ {
12278
+ "section": null,
12279
+ "requirement": null,
12280
+ "interpolated": true
12281
+ }
12282
+ ]
12283
+ },
12284
+ {
12285
+ "id": "openwop.it.era-key-stamped-v1.a-freshly-created-run-is-not-classified-legacy-by-the-host-s-own-rule",
12286
+ "file": "era-key-stamped-v1.test.ts",
12287
+ "line": 98,
12288
+ "title": "a freshly created run is not classified legacy by the host's own rule",
12289
+ "explicitId": null,
12290
+ "citations": [
12291
+ {
12292
+ "section": "spec/v1/version-negotiation.md §Legacy detection",
12293
+ "requirement": null,
12294
+ "interpolated": true
12295
+ }
12296
+ ]
12297
+ },
12298
+ {
12299
+ "id": "openwop.it.era-key-stamped-v1.a-run-the-host-just-created-carries-engineversion-the-legacy-escape-cannot-reach",
12300
+ "file": "era-key-stamped-v1.test.ts",
12301
+ "line": 124,
12302
+ "title": "a run the host just created carries engineVersion — the legacy escape cannot reach it",
12303
+ "explicitId": null,
12304
+ "citations": [
12305
+ {
12306
+ "section": null,
12307
+ "requirement": "every persisted run document MUST carry engineVersion; the \"MAY omit\" escape applies only to legacy runs that predate the contract, and this run was created moments ago",
12308
+ "interpolated": true
12309
+ },
12310
+ {
12311
+ "section": null,
12312
+ "requirement": null,
12313
+ "interpolated": true
12314
+ }
12315
+ ]
12316
+ },
12265
12317
  {
12266
12318
  "id": "openwop.it.errors.get-v1-runs-nonexistentid-returns-canonical-envelope",
12267
12319
  "file": "errors.test.ts",
@@ -18675,80 +18727,131 @@
18675
18727
  {
18676
18728
  "id": "openwop.it.pause-resume.pause-transitions-to-paused-resume-returns-the-run-to-running",
18677
18729
  "file": "pause-resume.test.ts",
18678
- "line": 36,
18730
+ "line": 62,
18679
18731
  "title": "pause transitions to paused; resume returns the run to running",
18680
18732
  "explicitId": "openwop.it.pause-resume.pause-transitions-to-paused-resume-returns-the-run-to-running",
18681
18733
  "citations": [
18682
18734
  {
18683
- "section": "rest-endpoints.md POST /v1/runs/{runId}:pause",
18684
- "requirement": ":pause MUST return 202 on a pausable run"
18735
+ "section": null,
18736
+ "requirement": ":pause MUST return 202 on a pausable run",
18737
+ "interpolated": true
18685
18738
  },
18686
18739
  {
18687
- "section": "rest-endpoints.md POST /v1/runs/{runId}:resume",
18688
- "requirement": ":resume MUST return 202 on a paused run"
18740
+ "section": null,
18741
+ "requirement": ":resume MUST return 202 on a paused run",
18742
+ "interpolated": true
18689
18743
  }
18690
18744
  ]
18691
18745
  },
18692
18746
  {
18693
18747
  "id": "openwop.it.pause-resume.resuming-a-running-not-paused-run-returns-409-with-details-runstatus",
18694
18748
  "file": "pause-resume.test.ts",
18695
- "line": 82,
18749
+ "line": 110,
18696
18750
  "title": "resuming a running (not paused) run returns 409 with details.runStatus",
18697
18751
  "explicitId": "openwop.it.pause-resume.resuming-a-running-not-paused-run-returns-409-with-details-runstatus",
18698
18752
  "citations": [
18699
18753
  {
18700
- "section": "rest-endpoints.md POST /v1/runs/{runId}:resume",
18701
- "requirement": ":resume on a non-paused run MUST return 409"
18754
+ "section": null,
18755
+ "requirement": ":resume on a non-paused run MUST return 409",
18756
+ "interpolated": true
18757
+ },
18758
+ {
18759
+ "section": null,
18760
+ "requirement": "the 409 MUST carry details.runStatus with the actual state",
18761
+ "interpolated": true
18702
18762
  }
18703
18763
  ]
18704
18764
  },
18705
18765
  {
18706
- "id": "openwop.it.pause-resume.pause-on-an-already-paused-run-is-a-no-op-200-202-idempotent",
18766
+ "id": "openwop.it.pause-resume.pause-on-an-already-paused-run-returns-409-with-details-runstatus-paused-unless",
18707
18767
  "file": "pause-resume.test.ts",
18708
- "line": 115,
18709
- "title": ":pause on an already-paused run is a no-op (200/202) idempotent",
18710
- "explicitId": "openwop.it.pause-resume.pause-on-an-already-paused-run-is-a-no-op-200-202-idempotent",
18768
+ "line": 144,
18769
+ "title": ":pause on an already-paused run returns 409 with details.runStatus paused, unless the request carries the original Idempotency-Key",
18770
+ "explicitId": "openwop.it.pause-resume.pause-on-an-already-paused-run-returns-409-with-details-runstatus-paused-unless",
18711
18771
  "citations": [
18712
18772
  {
18713
- "section": "rest-endpoints.md POST /v1/runs/{runId}:pause",
18714
- "requirement": ":pause on an already-paused run MUST be idempotent (200/202), not 409"
18773
+ "section": null,
18774
+ "requirement": ":pause MUST return 202 on a pausable run",
18775
+ "interpolated": true
18776
+ },
18777
+ {
18778
+ "section": null,
18779
+ "requirement": ":pause on an already-paused run without a matching Idempotency-Key MUST return 409",
18780
+ "interpolated": true
18781
+ },
18782
+ {
18783
+ "section": null,
18784
+ "requirement": "the 409 MUST carry details.runStatus: paused",
18785
+ "interpolated": true
18786
+ },
18787
+ {
18788
+ "section": null,
18789
+ "requirement": ":pause with an Idempotency-Key MUST return 202 on a pausable run",
18790
+ "interpolated": true
18791
+ },
18792
+ {
18793
+ "section": null,
18794
+ "requirement": "a :pause carrying the original Idempotency-Key MUST return 202 with the cached response, not 409",
18795
+ "interpolated": true
18715
18796
  }
18716
18797
  ]
18717
18798
  },
18718
18799
  {
18719
18800
  "id": "openwop.it.pause-resume.pause-on-a-completed-cancelled-failed-run-must-return-409",
18720
18801
  "file": "pause-resume.test.ts",
18721
- "line": 153,
18802
+ "line": 205,
18722
18803
  "title": ":pause on a completed/cancelled/failed run MUST return 409",
18723
18804
  "explicitId": "openwop.it.pause-resume.pause-on-a-completed-cancelled-failed-run-must-return-409",
18724
18805
  "citations": [
18725
18806
  {
18726
- "section": "rest-endpoints.md POST /v1/runs/{runId}:pause",
18727
- "requirement": ":pause on a terminal run MUST return 409"
18807
+ "section": null,
18808
+ "requirement": ":pause on a terminal run MUST return 409",
18809
+ "interpolated": true
18810
+ }
18811
+ ]
18812
+ },
18813
+ {
18814
+ "id": "openwop.it.pause-resume.under-drain-current-node-node-completed-precedes-run-paused-in-the-log",
18815
+ "file": "pause-resume.test.ts",
18816
+ "line": 229,
18817
+ "title": "under drain-current-node node.completed precedes run.paused in the log",
18818
+ "explicitId": "openwop.it.pause-resume.under-drain-current-node-node-completed-precedes-run-paused-in-the-log",
18819
+ "citations": [
18820
+ {
18821
+ "section": null,
18822
+ "requirement": ":pause with drainPolicy drain-current-node MUST return 202 (pause requested)",
18823
+ "interpolated": true
18824
+ },
18825
+ {
18826
+ "section": null,
18827
+ "requirement": null,
18828
+ "interpolated": true
18728
18829
  }
18729
18830
  ]
18730
18831
  },
18731
18832
  {
18732
18833
  "id": "openwop.it.pause-resume.pause-must-not-silently-override-an-active-interrupt-suspend",
18733
18834
  "file": "pause-resume.test.ts",
18734
- "line": 177,
18835
+ "line": 268,
18735
18836
  "title": ":pause MUST NOT silently override an active interrupt suspend",
18736
18837
  "explicitId": "openwop.it.pause-resume.pause-must-not-silently-override-an-active-interrupt-suspend",
18737
18838
  "citations": [
18738
18839
  {
18739
- "section": "rest-endpoints.md POST /v1/runs/{runId}:pause",
18740
- "requirement": ":pause-during-suspend MUST surface the active waiting-* status in the conflict envelope"
18840
+ "section": null,
18841
+ "requirement": ":pause-during-suspend MUST surface the active waiting-* status in the conflict envelope",
18842
+ "interpolated": true
18741
18843
  },
18742
18844
  {
18743
- "section": "rest-endpoints.md POST /v1/runs/{runId}:pause",
18744
- "requirement": ":pause-during-suspend MUST NOT silently discard the active interrupt"
18845
+ "section": null,
18846
+ "requirement": ":pause-during-suspend MUST NOT silently discard the active interrupt",
18847
+ "interpolated": true
18745
18848
  }
18746
18849
  ]
18747
18850
  },
18748
18851
  {
18749
18852
  "id": "openwop.it.pause-resume.every-drainpolicy-advertised-by-the-host-is-accepted-on-pause",
18750
18853
  "file": "pause-resume.test.ts",
18751
- "line": 238,
18854
+ "line": 324,
18752
18855
  "title": "every drainPolicy advertised by the host is accepted on :pause",
18753
18856
  "explicitId": "openwop.it.pause-resume.every-drainpolicy-advertised-by-the-host-is-accepted-on-pause",
18754
18857
  "citations": [
@@ -25742,10 +25845,10 @@
25742
25845
  ]
25743
25846
  },
25744
25847
  {
25745
- "id": "openwop.it.v2-advertised-fixtures-exist.every-advertised-fixture-id-is-one-the-corpus-defines",
25848
+ "id": "openwop.it.v2-advertised-fixtures-exist.a-sampled-advertised-fixture-is-actually-creatable-not-just-listed",
25746
25849
  "file": "v2-advertised-fixtures-exist.test.ts",
25747
- "line": 60,
25748
- "title": "every advertised fixture id is one the corpus defines",
25850
+ "line": 62,
25851
+ "title": "a sampled advertised fixture is actually creatable, not just listed",
25749
25852
  "explicitId": null,
25750
25853
  "citations": [
25751
25854
  {
@@ -25756,16 +25859,21 @@
25756
25859
  ]
25757
25860
  },
25758
25861
  {
25759
- "id": "openwop.it.v2-advertised-fixtures-exist.a-sampled-advertised-fixture-is-actually-creatable-not-just-listed",
25760
- "file": "v2-advertised-fixtures-exist.test.ts",
25761
- "line": 80,
25762
- "title": "a sampled advertised fixture is actually creatable, not just listed",
25862
+ "id": "openwop.it.v2-advertised-path-space-served.a-host-advertising-major-2-reaches-the-surfaces-it-already-serves-under-v1",
25863
+ "file": "v2-advertised-path-space-served.test.ts",
25864
+ "line": 107,
25865
+ "title": "a host advertising major 2 reaches the surfaces it already serves under /v1",
25763
25866
  "explicitId": null,
25764
25867
  "citations": [
25765
25868
  {
25766
25869
  "section": null,
25767
25870
  "requirement": null,
25768
25871
  "interpolated": true
25872
+ },
25873
+ {
25874
+ "section": null,
25875
+ "requirement": "at least one non-well-known surface MUST be reachable under major 2, or the advertisement rests entirely on the one resource the header selects",
25876
+ "interpolated": true
25769
25877
  }
25770
25878
  ]
25771
25879
  },
@@ -26120,7 +26228,7 @@
26120
26228
  {
26121
26229
  "id": "openwop.it.v2-coherence-not-in-bundle.the-bundle-schema-rejects-a-v3-bundle-carrying-a-corpus-coherence-id-and-accepts",
26122
26230
  "file": "v2-coherence-not-in-bundle.test.ts",
26123
- "line": 89,
26231
+ "line": 98,
26124
26232
  "title": "the bundle schema rejects a v3 bundle carrying a corpus-coherence id and accepts one under openwop.requirement.",
26125
26233
  "explicitId": "openwop.requirement.0168.coherence-not-in-bundle.schema-forbids-coherence-ids",
26126
26234
  "citations": [
@@ -26254,6 +26362,40 @@
26254
26362
  }
26255
26363
  ]
26256
26364
  },
26365
+ {
26366
+ "id": "openwop.it.v2-created-run-readable.a-run-created-at-this-base-is-readable-and-pollable-at-this-base-by-the-id-it-re",
26367
+ "file": "v2-created-run-readable.test.ts",
26368
+ "line": 63,
26369
+ "title": "a run created at this base is readable and pollable at this base by the id it returned, and its links stay on this base",
26370
+ "explicitId": null,
26371
+ "citations": [
26372
+ {
26373
+ "section": "spec/v2/core/identity.md §5",
26374
+ "requirement": null,
26375
+ "interpolated": true
26376
+ },
26377
+ {
26378
+ "section": null,
26379
+ "requirement": null,
26380
+ "interpolated": true
26381
+ },
26382
+ {
26383
+ "section": "spec/v2/core/events.md §Poll",
26384
+ "requirement": null,
26385
+ "interpolated": true
26386
+ },
26387
+ {
26388
+ "section": null,
26389
+ "requirement": null,
26390
+ "interpolated": true
26391
+ },
26392
+ {
26393
+ "section": null,
26394
+ "requirement": null,
26395
+ "interpolated": true
26396
+ }
26397
+ ]
26398
+ },
26257
26399
  {
26258
26400
  "id": "openwop.it.v2-dual-stack-negotiation.a-run-created-through-v1-runs-with-no-header-is-readable-through-runs-under-open",
26259
26401
  "file": "v2-dual-stack-negotiation.test.ts",
@@ -26271,7 +26413,8 @@
26271
26413
  },
26272
26414
  {
26273
26415
  "section": "spec/v2/core/versioning.md §5",
26274
- "requirement": "the v2 read MUST name the same run"
26416
+ "requirement": null,
26417
+ "interpolated": true
26275
26418
  },
26276
26419
  {
26277
26420
  "section": "spec/v2/core/versioning.md §1.4",
@@ -26282,7 +26425,7 @@
26282
26425
  {
26283
26426
  "id": "openwop.it.v2-dual-stack-negotiation.an-unlisted-major-is-406-protocol-version-unsupported-with-details-protocolversi",
26284
26427
  "file": "v2-dual-stack-negotiation.test.ts",
26285
- "line": 83,
26428
+ "line": 111,
26286
26429
  "title": "an unlisted major is 406 protocol_version_unsupported with details.protocolVersions[]",
26287
26430
  "explicitId": "openwop.requirement.0172.dual-stack-negotiation.unlisted-major",
26288
26431
  "citations": [
@@ -26306,7 +26449,7 @@
26306
26449
  {
26307
26450
  "id": "openwop.it.v2-dual-stack-negotiation.openwop-version-2-0-on-a-v1-path-is-400-protocol-version-mismatch",
26308
26451
  "file": "v2-dual-stack-negotiation.test.ts",
26309
- "line": 94,
26452
+ "line": 122,
26310
26453
  "title": "OpenWOP-Version: 2.0 on a /v1/ path is 400 protocol_version_mismatch",
26311
26454
  "explicitId": "openwop.requirement.0172.dual-stack-negotiation.v1-path-mismatch",
26312
26455
  "citations": [
@@ -26325,7 +26468,7 @@
26325
26468
  {
26326
26469
  "id": "openwop.it.v2-dual-stack-negotiation.every-response-reports-the-contract-that-produced-it",
26327
26470
  "file": "v2-dual-stack-negotiation.test.ts",
26328
- "line": 103,
26471
+ "line": 131,
26329
26472
  "title": "every response reports the contract that produced it",
26330
26473
  "explicitId": "openwop.requirement.0172.dual-stack-negotiation.response-header",
26331
26474
  "citations": [
@@ -26410,7 +26553,7 @@
26410
26553
  {
26411
26554
  "id": "openwop.it.v2-effect-seam-manifest.get-host-effect-seams-validates-and-every-row-is-guarded",
26412
26555
  "file": "v2-effect-seam-manifest.test.ts",
26413
- "line": 51,
26556
+ "line": 53,
26414
26557
  "title": "GET /host/effect-seams validates and every row is guarded",
26415
26558
  "explicitId": "openwop.requirement.0173.effect-seam-manifest",
26416
26559
  "citations": [
@@ -26442,6 +26585,11 @@
26442
26585
  "requirement": null,
26443
26586
  "interpolated": true
26444
26587
  },
26588
+ {
26589
+ "section": "replay.md §The effect-seam manifest",
26590
+ "requirement": null,
26591
+ "interpolated": true
26592
+ },
26445
26593
  {
26446
26594
  "section": "RFC 0173 §C.1",
26447
26595
  "requirement": null,
@@ -26457,7 +26605,7 @@
26457
26605
  {
26458
26606
  "id": "openwop.it.v2-effect-seam-manifest.the-replay-facet-names-the-manifest-address-as-the-constant-host-effect-seams",
26459
26607
  "file": "v2-effect-seam-manifest.test.ts",
26460
- "line": 106,
26608
+ "line": 118,
26461
26609
  "title": "the replay facet names the manifest address as the constant /host/effect-seams",
26462
26610
  "explicitId": "openwop.requirement.0173.effect-seam-manifest.facet",
26463
26611
  "citations": [
@@ -26468,11 +26616,11 @@
26468
26616
  ]
26469
26617
  },
26470
26618
  {
26471
- "id": "openwop.it.v2-effect-seam-manifest.driving-one-seam-of-each-kind-observes-no-re-fire-on-replay",
26472
- "file": "v2-effect-seam-manifest.test.ts",
26473
- "line": 117,
26619
+ "id": "openwop.it.v2-effect-seam-no-refire.driving-one-seam-of-each-kind-observes-no-re-fire-on-replay",
26620
+ "file": "v2-effect-seam-no-refire.test.ts",
26621
+ "line": 42,
26474
26622
  "title": "driving one seam of each kind observes no re-fire on replay",
26475
- "explicitId": "openwop.requirement.0173.effect-seam-manifest.no-re-fire",
26623
+ "explicitId": "openwop.requirement.0173.effect-seam-no-refire",
26476
26624
  "citations": [
26477
26625
  {
26478
26626
  "section": "spec/v2/core/replay.md §The effect-seam manifest",
@@ -26561,7 +26709,7 @@
26561
26709
  {
26562
26710
  "id": "openwop.it.v2-era-2-append-vocabulary.the-run-keeps-the-era-it-was-created-with-an-append-does-not-promote-it-to-era-3",
26563
26711
  "file": "v2-era-2-append-vocabulary.test.ts",
26564
- "line": 119,
26712
+ "line": 133,
26565
26713
  "title": "the run keeps the era it was created with; an append does not promote it to era 3",
26566
26714
  "explicitId": null,
26567
26715
  "citations": [
@@ -27070,6 +27218,39 @@
27070
27218
  }
27071
27219
  ]
27072
27220
  },
27221
+ {
27222
+ "id": null,
27223
+ "file": "v2-malformed-body-envelope.test.ts",
27224
+ "line": 53,
27225
+ "title": null,
27226
+ "explicitId": null,
27227
+ "citations": [
27228
+ {
27229
+ "section": null,
27230
+ "requirement": null,
27231
+ "interpolated": true
27232
+ },
27233
+ {
27234
+ "section": "spec/v2/core/errors.md",
27235
+ "requirement": null,
27236
+ "interpolated": true
27237
+ },
27238
+ {
27239
+ "section": "spec/v2/core/errors.md",
27240
+ "requirement": null,
27241
+ "interpolated": true
27242
+ },
27243
+ {
27244
+ "section": "spec/v2/core/errors.md",
27245
+ "requirement": null,
27246
+ "interpolated": true
27247
+ },
27248
+ {
27249
+ "section": "spec/v2/core/errors.md",
27250
+ "requirement": "the envelope's `error` MUST be the registered code for a malformed request body, validation_error"
27251
+ }
27252
+ ]
27253
+ },
27073
27254
  {
27074
27255
  "id": "openwop.it.v2-manifest-ceiling-refused.an-engines-openwop-range-with-no-upper-bound-1-0-0-reads-2-0-0-and-is-refused-at",
27075
27256
  "file": "v2-manifest-ceiling-refused.test.ts",
@@ -27653,7 +27834,7 @@
27653
27834
  {
27654
27835
  "id": "openwop.it.v2-poll-cursor-v2.a-cursor-past-the-end-of-the-log-returns-200-with-an-empty-events-array",
27655
27836
  "file": "v2-poll-cursor-v2.test.ts",
27656
- "line": 103,
27837
+ "line": 121,
27657
27838
  "title": "a cursor past the end of the log returns 200 with an empty events array",
27658
27839
  "explicitId": "openwop.requirement.0171.poll-cursor-v2.past-end",
27659
27840
  "citations": [
@@ -27956,6 +28137,661 @@
27956
28137
  }
27957
28138
  ]
27958
28139
  },
28140
+ {
28141
+ "id": "openwop.it.v2-run-annotation-not-event.an-annotation-is-created-and-listed-and-never-enters-the-run-s-event-log",
28142
+ "file": "v2-run-annotation-not-event.test.ts",
28143
+ "line": 40,
28144
+ "title": "an annotation is created and listed, and never enters the run's event log",
28145
+ "explicitId": null,
28146
+ "citations": [
28147
+ {
28148
+ "section": null,
28149
+ "requirement": null,
28150
+ "interpolated": true
28151
+ },
28152
+ {
28153
+ "section": "schemas/v2/annotation.schema.json",
28154
+ "requirement": null,
28155
+ "interpolated": true
28156
+ },
28157
+ {
28158
+ "section": null,
28159
+ "requirement": null,
28160
+ "interpolated": true
28161
+ },
28162
+ {
28163
+ "section": null,
28164
+ "requirement": "listAnnotations MUST return the annotation just created (the control: a host that discards annotations must not pass the log assertion for free)",
28165
+ "interpolated": true
28166
+ },
28167
+ {
28168
+ "section": null,
28169
+ "requirement": "run.annotated is a live notification and MUST NOT enter the event log",
28170
+ "interpolated": true
28171
+ },
28172
+ {
28173
+ "section": null,
28174
+ "requirement": null,
28175
+ "interpolated": true
28176
+ }
28177
+ ]
28178
+ },
28179
+ {
28180
+ "id": "openwop.it.v2-run-bulk-cancel.101-ids-are-refused-400-validation-error-with-details-maxrunids",
28181
+ "file": "v2-run-bulk-cancel.test.ts",
28182
+ "line": 48,
28183
+ "title": "101 ids are refused 400 validation_error with details.maxRunIds",
28184
+ "explicitId": null,
28185
+ "citations": [
28186
+ {
28187
+ "section": null,
28188
+ "requirement": null,
28189
+ "interpolated": true
28190
+ },
28191
+ {
28192
+ "section": null,
28193
+ "requirement": "the refusal MUST be validation_error",
28194
+ "interpolated": true
28195
+ },
28196
+ {
28197
+ "section": null,
28198
+ "requirement": null,
28199
+ "interpolated": true
28200
+ }
28201
+ ]
28202
+ },
28203
+ {
28204
+ "id": "openwop.it.v2-run-bulk-cancel.results-come-back-in-request-order-each-id-processed-independently-a-foreign-id",
28205
+ "file": "v2-run-bulk-cancel.test.ts",
28206
+ "line": 63,
28207
+ "title": "results[] come back in request order, each id processed independently, a foreign id refused in its entry and never as a top-level 403",
28208
+ "explicitId": null,
28209
+ "citations": [
28210
+ {
28211
+ "section": null,
28212
+ "requirement": null,
28213
+ "interpolated": true
28214
+ },
28215
+ {
28216
+ "section": null,
28217
+ "requirement": null,
28218
+ "interpolated": true
28219
+ },
28220
+ {
28221
+ "section": null,
28222
+ "requirement": "results[] MUST be in request order",
28223
+ "interpolated": true
28224
+ },
28225
+ {
28226
+ "section": null,
28227
+ "requirement": "the foreign-tenant entry MUST be ok: false",
28228
+ "interpolated": true
28229
+ },
28230
+ {
28231
+ "section": "api/v2/openapi.yaml bulkCancelRuns results[].error",
28232
+ "requirement": null,
28233
+ "interpolated": true
28234
+ },
28235
+ {
28236
+ "section": "spec/v2/core/identity.md §5",
28237
+ "requirement": null,
28238
+ "interpolated": true
28239
+ },
28240
+ {
28241
+ "section": null,
28242
+ "requirement": null,
28243
+ "interpolated": true
28244
+ }
28245
+ ]
28246
+ },
28247
+ {
28248
+ "id": "openwop.it.v2-run-cancel.cancelling-a-terminal-run-is-refused-409-run-terminal",
28249
+ "file": "v2-run-cancel.test.ts",
28250
+ "line": 65,
28251
+ "title": "cancelling a terminal run is refused 409 run_terminal",
28252
+ "explicitId": null,
28253
+ "citations": [
28254
+ {
28255
+ "section": null,
28256
+ "requirement": null,
28257
+ "interpolated": true
28258
+ },
28259
+ {
28260
+ "section": null,
28261
+ "requirement": "the refusal MUST be run_terminal",
28262
+ "interpolated": true
28263
+ }
28264
+ ]
28265
+ },
28266
+ {
28267
+ "id": "openwop.it.v2-run-cancel.cancelling-a-running-run-answers-200-with-cancelling-cancelled-emits-run-cancell",
28268
+ "file": "v2-run-cancel.test.ts",
28269
+ "line": 79,
28270
+ "title": "cancelling a running run answers 200 with cancelling|cancelled, emits run.cancelled within 5 s, and the snapshot reads cancelled",
28271
+ "explicitId": null,
28272
+ "citations": [
28273
+ {
28274
+ "section": null,
28275
+ "requirement": null,
28276
+ "interpolated": true
28277
+ },
28278
+ {
28279
+ "section": null,
28280
+ "requirement": "the 200 body MUST carry the run's runId",
28281
+ "interpolated": true
28282
+ },
28283
+ {
28284
+ "section": null,
28285
+ "requirement": null,
28286
+ "interpolated": true
28287
+ },
28288
+ {
28289
+ "section": null,
28290
+ "requirement": null,
28291
+ "interpolated": true
28292
+ },
28293
+ {
28294
+ "section": "spec/v2/core/events.md §run.cancelled",
28295
+ "requirement": null,
28296
+ "interpolated": true
28297
+ }
28298
+ ]
28299
+ },
28300
+ {
28301
+ "id": "openwop.it.v2-run-completed-outputs.the-run-completed-event-of-a-run-that-completed-carries-an-outputs-object",
28302
+ "file": "v2-run-completed-outputs.test.ts",
28303
+ "line": 72,
28304
+ "title": "the run.completed event of a run that completed carries an outputs object",
28305
+ "explicitId": null,
28306
+ "citations": [
28307
+ {
28308
+ "section": null,
28309
+ "requirement": "run.completed MUST carry a payload object",
28310
+ "interpolated": true
28311
+ },
28312
+ {
28313
+ "section": null,
28314
+ "requirement": null,
28315
+ "interpolated": true
28316
+ },
28317
+ {
28318
+ "section": null,
28319
+ "requirement": null,
28320
+ "interpolated": true
28321
+ }
28322
+ ]
28323
+ },
28324
+ {
28325
+ "id": "openwop.it.v2-run-diff-identical.two-identical-logs-diff-to-divergedatseq-null-and-empty-eventdiffs-in-a-response",
28326
+ "file": "v2-run-diff-identical.test.ts",
28327
+ "line": 54,
28328
+ "title": "two identical logs diff to divergedAtSeq null and empty eventDiffs, in a response that validates and echoes both ids",
28329
+ "explicitId": null,
28330
+ "citations": [
28331
+ {
28332
+ "section": null,
28333
+ "requirement": null,
28334
+ "interpolated": true
28335
+ },
28336
+ {
28337
+ "section": "schemas/v2/run-diff-response.schema.json",
28338
+ "requirement": null,
28339
+ "interpolated": true
28340
+ },
28341
+ {
28342
+ "section": null,
28343
+ "requirement": "the response MUST name the two runs it compared",
28344
+ "interpolated": true
28345
+ },
28346
+ {
28347
+ "section": null,
28348
+ "requirement": null,
28349
+ "interpolated": true
28350
+ },
28351
+ {
28352
+ "section": null,
28353
+ "requirement": "identical logs MUST yield empty eventDiffs",
28354
+ "interpolated": true
28355
+ },
28356
+ {
28357
+ "section": null,
28358
+ "requirement": null,
28359
+ "interpolated": true
28360
+ }
28361
+ ]
28362
+ },
28363
+ {
28364
+ "id": "openwop.it.v2-run-fork-prefix.a-replay-fork-inherits-exactly-0-fromseq-the-event-at-fromseq-is-re-executed-nev",
28365
+ "file": "v2-run-fork-prefix.test.ts",
28366
+ "line": 106,
28367
+ "title": "a replay fork inherits exactly [0, fromSeq): the event at fromSeq is re-executed, never carried over",
28368
+ "explicitId": null,
28369
+ "citations": [
28370
+ {
28371
+ "section": "spec/v2/core/runs.md §Fork",
28372
+ "requirement": null,
28373
+ "interpolated": true
28374
+ },
28375
+ {
28376
+ "section": null,
28377
+ "requirement": null,
28378
+ "interpolated": true
28379
+ },
28380
+ {
28381
+ "section": null,
28382
+ "requirement": null,
28383
+ "interpolated": true
28384
+ }
28385
+ ]
28386
+ },
28387
+ {
28388
+ "id": "openwop.it.v2-run-fork-refusals.replay-overlay-400-a-fromseq-outside-the-log-422-fork-point-invalid-a-valid-repl",
28389
+ "file": "v2-run-fork-refusals.test.ts",
28390
+ "line": 38,
28391
+ "title": "replay+overlay → 400; a fromSeq outside the log → 422 fork_point_invalid; a valid replay fork → 201 with the parent's owner verbatim",
28392
+ "explicitId": null,
28393
+ "citations": [
28394
+ {
28395
+ "section": null,
28396
+ "requirement": null,
28397
+ "interpolated": true
28398
+ },
28399
+ {
28400
+ "section": null,
28401
+ "requirement": null,
28402
+ "interpolated": true
28403
+ },
28404
+ {
28405
+ "section": null,
28406
+ "requirement": "the refusal MUST be fork_point_invalid",
28407
+ "interpolated": true
28408
+ },
28409
+ {
28410
+ "section": null,
28411
+ "requirement": null,
28412
+ "interpolated": true
28413
+ },
28414
+ {
28415
+ "section": null,
28416
+ "requirement": "the 201 MUST name the parent as sourceRunId",
28417
+ "interpolated": true
28418
+ },
28419
+ {
28420
+ "section": null,
28421
+ "requirement": "the 201 MUST echo the mode",
28422
+ "interpolated": true
28423
+ },
28424
+ {
28425
+ "section": null,
28426
+ "requirement": "the 201 MUST carry runId and eventsUrl",
28427
+ "interpolated": true
28428
+ },
28429
+ {
28430
+ "section": "RFCS/0170 §A.4",
28431
+ "requirement": "the child's owner MUST be copied verbatim from the parent"
28432
+ }
28433
+ ]
28434
+ },
28435
+ {
28436
+ "id": "openwop.it.v2-run-options-limits.more-than-100-tags-a-tag-over-256-characters-and-an-unknown-root-key-are-each-re",
28437
+ "file": "v2-run-options-limits.test.ts",
28438
+ "line": 46,
28439
+ "title": "more than 100 tags, a tag over 256 characters, and an unknown root key are each refused 400 validation_error",
28440
+ "explicitId": null,
28441
+ "citations": []
28442
+ },
28443
+ {
28444
+ "id": "openwop.it.v2-run-options-limits.odd-format-tags-and-free-form-metadata-are-accepted-and-surface-unchanged-on-the",
28445
+ "file": "v2-run-options-limits.test.ts",
28446
+ "line": 56,
28447
+ "title": "odd-format tags and free-form metadata are accepted and surface unchanged on the snapshot",
28448
+ "explicitId": null,
28449
+ "citations": [
28450
+ {
28451
+ "section": null,
28452
+ "requirement": null,
28453
+ "interpolated": true
28454
+ },
28455
+ {
28456
+ "section": null,
28457
+ "requirement": "tags MUST surface unchanged on RunSnapshot",
28458
+ "interpolated": true
28459
+ },
28460
+ {
28461
+ "section": null,
28462
+ "requirement": "metadata MUST be persisted and surface unchanged on RunSnapshot",
28463
+ "interpolated": true
28464
+ }
28465
+ ]
28466
+ },
28467
+ {
28468
+ "id": "openwop.it.v2-run-pause-resume.pause-and-resume-on-a-terminal-run-answer-409-with-an-error-envelope",
28469
+ "file": "v2-run-pause-resume.test.ts",
28470
+ "line": 59,
28471
+ "title": "pause and resume on a terminal run answer 409 with an error envelope",
28472
+ "explicitId": null,
28473
+ "citations": [
28474
+ {
28475
+ "section": null,
28476
+ "requirement": null,
28477
+ "interpolated": true
28478
+ },
28479
+ {
28480
+ "section": null,
28481
+ "requirement": null,
28482
+ "interpolated": true
28483
+ },
28484
+ {
28485
+ "section": null,
28486
+ "requirement": null,
28487
+ "interpolated": true
28488
+ },
28489
+ {
28490
+ "section": null,
28491
+ "requirement": null,
28492
+ "interpolated": true
28493
+ }
28494
+ ]
28495
+ },
28496
+ {
28497
+ "id": "openwop.it.v2-run-pause-resume.a-running-run-pauses-202-paused-refuses-a-second-pause-409-resumes-202-running-a",
28498
+ "file": "v2-run-pause-resume.test.ts",
28499
+ "line": 77,
28500
+ "title": "a running run pauses (202 paused), refuses a second pause (409), resumes (202 running), and the log carries run.paused then run.resumed",
28501
+ "explicitId": null,
28502
+ "citations": [
28503
+ {
28504
+ "section": null,
28505
+ "requirement": null,
28506
+ "interpolated": true
28507
+ },
28508
+ {
28509
+ "section": null,
28510
+ "requirement": "the 202 MUST carry the runId",
28511
+ "interpolated": true
28512
+ },
28513
+ {
28514
+ "section": null,
28515
+ "requirement": null,
28516
+ "interpolated": true
28517
+ },
28518
+ {
28519
+ "section": null,
28520
+ "requirement": null,
28521
+ "interpolated": true
28522
+ },
28523
+ {
28524
+ "section": null,
28525
+ "requirement": null,
28526
+ "interpolated": true
28527
+ },
28528
+ {
28529
+ "section": null,
28530
+ "requirement": null,
28531
+ "interpolated": true
28532
+ },
28533
+ {
28534
+ "section": null,
28535
+ "requirement": null,
28536
+ "interpolated": true
28537
+ },
28538
+ {
28539
+ "section": null,
28540
+ "requirement": null,
28541
+ "interpolated": true
28542
+ },
28543
+ {
28544
+ "section": "spec/v2/core/events.md §run.paused",
28545
+ "requirement": null,
28546
+ "interpolated": true
28547
+ },
28548
+ {
28549
+ "section": null,
28550
+ "requirement": null,
28551
+ "interpolated": true
28552
+ },
28553
+ {
28554
+ "section": null,
28555
+ "requirement": null,
28556
+ "interpolated": true
28557
+ }
28558
+ ]
28559
+ },
28560
+ {
28561
+ "id": "openwop.it.v2-run-snapshot-etag.a-matching-if-none-match-receives-304-with-no-body-and-the-version-header-a-non",
28562
+ "file": "v2-run-snapshot-etag.test.ts",
28563
+ "line": 34,
28564
+ "title": "a matching If-None-Match receives 304 with no body and the version header; a non-matching one receives 200",
28565
+ "explicitId": null,
28566
+ "citations": [
28567
+ {
28568
+ "section": null,
28569
+ "requirement": null,
28570
+ "interpolated": true
28571
+ },
28572
+ {
28573
+ "section": null,
28574
+ "requirement": null,
28575
+ "interpolated": true
28576
+ },
28577
+ {
28578
+ "section": "spec/v2/core/versioning.md §1.4",
28579
+ "requirement": "every response carries OpenWOP-Version, the 304 included"
28580
+ },
28581
+ {
28582
+ "section": null,
28583
+ "requirement": null,
28584
+ "interpolated": true
28585
+ },
28586
+ {
28587
+ "section": null,
28588
+ "requirement": "the 200 body is the snapshot",
28589
+ "interpolated": true
28590
+ }
28591
+ ]
28592
+ },
28593
+ {
28594
+ "id": "openwop.it.v2-sse-last-event-id.last-event-id-resumes-at-the-next-sequence-never-re-emits-the-resumption-point-l",
28595
+ "file": "v2-sse-last-event-id.test.ts",
28596
+ "line": 59,
28597
+ "title": "Last-Event-ID resumes at the next sequence, never re-emits the resumption point, loses nothing, and at the last id yields nothing",
28598
+ "explicitId": null,
28599
+ "citations": [
28600
+ {
28601
+ "section": null,
28602
+ "requirement": null,
28603
+ "interpolated": true
28604
+ },
28605
+ {
28606
+ "section": null,
28607
+ "requirement": "the completed log MUST stream as at least one frame",
28608
+ "interpolated": true
28609
+ },
28610
+ {
28611
+ "section": null,
28612
+ "requirement": null,
28613
+ "interpolated": true
28614
+ },
28615
+ {
28616
+ "section": null,
28617
+ "requirement": null,
28618
+ "interpolated": true
28619
+ },
28620
+ {
28621
+ "section": null,
28622
+ "requirement": "frames MUST arrive in log order",
28623
+ "interpolated": true
28624
+ },
28625
+ {
28626
+ "section": null,
28627
+ "requirement": null,
28628
+ "interpolated": true
28629
+ },
28630
+ {
28631
+ "section": null,
28632
+ "requirement": null,
28633
+ "interpolated": true
28634
+ },
28635
+ {
28636
+ "section": null,
28637
+ "requirement": null,
28638
+ "interpolated": true
28639
+ },
28640
+ {
28641
+ "section": null,
28642
+ "requirement": null,
28643
+ "interpolated": true
28644
+ },
28645
+ {
28646
+ "section": null,
28647
+ "requirement": null,
28648
+ "interpolated": true
28649
+ },
28650
+ {
28651
+ "section": null,
28652
+ "requirement": "the host MUST close the empty resume itself",
28653
+ "interpolated": true
28654
+ },
28655
+ {
28656
+ "section": null,
28657
+ "requirement": null,
28658
+ "interpolated": true
28659
+ },
28660
+ {
28661
+ "section": null,
28662
+ "requirement": null,
28663
+ "interpolated": true
28664
+ }
28665
+ ]
28666
+ },
28667
+ {
28668
+ "id": "openwop.it.v2-stream-mode-refusal.a-value-outside-the-pattern-a-forbidden-combination-and-an-unimplemented-mode-ar",
28669
+ "file": "v2-stream-mode-refusal.test.ts",
28670
+ "line": 64,
28671
+ "title": "a value outside the pattern, a forbidden combination, and an unimplemented mode are refused 400 unsupported_stream_mode with details.supported — before content negotiation",
28672
+ "explicitId": null,
28673
+ "citations": [
28674
+ {
28675
+ "section": null,
28676
+ "requirement": null,
28677
+ "interpolated": true
28678
+ },
28679
+ {
28680
+ "section": null,
28681
+ "requirement": "the refusal MUST be unsupported_stream_mode",
28682
+ "interpolated": true
28683
+ },
28684
+ {
28685
+ "section": null,
28686
+ "requirement": null,
28687
+ "interpolated": true
28688
+ },
28689
+ {
28690
+ "section": null,
28691
+ "requirement": "a host MUST implement updates, so supported MUST list it",
28692
+ "interpolated": true
28693
+ },
28694
+ {
28695
+ "section": null,
28696
+ "requirement": null,
28697
+ "interpolated": true
28698
+ },
28699
+ {
28700
+ "section": null,
28701
+ "requirement": null,
28702
+ "interpolated": true
28703
+ },
28704
+ {
28705
+ "section": null,
28706
+ "requirement": "the refusal MUST be unsupported_stream_mode",
28707
+ "interpolated": true
28708
+ },
28709
+ {
28710
+ "section": null,
28711
+ "requirement": null,
28712
+ "interpolated": true
28713
+ },
28714
+ {
28715
+ "section": null,
28716
+ "requirement": "the refusal MUST be unsupported_stream_mode",
28717
+ "interpolated": true
28718
+ }
28719
+ ]
28720
+ },
28721
+ {
28722
+ "id": "openwop.it.v2-stream-mode-refusal.updates-streams-200-text-event-stream-with-frames-bufferms-yields-at-least-one-b",
28723
+ "file": "v2-stream-mode-refusal.test.ts",
28724
+ "line": 95,
28725
+ "title": "updates streams 200 text/event-stream with frames; bufferMs yields at least one batch frame whose data is an array and loses nothing; without bufferMs no frame is batch",
28726
+ "explicitId": null,
28727
+ "citations": [
28728
+ {
28729
+ "section": null,
28730
+ "requirement": null,
28731
+ "interpolated": true
28732
+ },
28733
+ {
28734
+ "section": "spec/v2/core/events.md §SSE frames",
28735
+ "requirement": "the completed run's log MUST stream as at least one frame before the server closes"
28736
+ },
28737
+ {
28738
+ "section": "spec/v2/core/events.md §SSE frames",
28739
+ "requirement": null,
28740
+ "interpolated": true
28741
+ },
28742
+ {
28743
+ "section": "spec/v2/core/events.md §SSE frames",
28744
+ "requirement": "without bufferMs no frame is a batch (the control for the batch leg)"
28745
+ },
28746
+ {
28747
+ "section": "spec/v2/core/events.md §SSE frames",
28748
+ "requirement": null,
28749
+ "interpolated": true
28750
+ },
28751
+ {
28752
+ "section": "spec/v2/core/events.md §SSE frames",
28753
+ "requirement": null,
28754
+ "interpolated": true
28755
+ },
28756
+ {
28757
+ "section": "spec/v2/core/events.md §SSE frames",
28758
+ "requirement": "a batch frame's data MUST be an array of RunEventDoc"
28759
+ },
28760
+ {
28761
+ "section": "spec/v2/core/events.md §SSE frames",
28762
+ "requirement": "batching MUST NOT lose or reorder events: the flattened buffered stream equals the unbuffered log (a one-element batch and an unbatched frame are both tolerated)"
28763
+ }
28764
+ ]
28765
+ },
28766
+ {
28767
+ "id": "openwop.it.v2-stream-sse-projection.every-data-frame-on-the-major-2-stream-carries-the-tenant-bound-runid-of-the-run",
28768
+ "file": "v2-stream-sse-projection.test.ts",
28769
+ "line": 52,
28770
+ "title": "every data: frame on the major-2 stream carries the tenant-bound runId of the run it belongs to",
28771
+ "explicitId": null,
28772
+ "citations": [
28773
+ {
28774
+ "section": "spec/v2/core/identity.md §5",
28775
+ "requirement": null,
28776
+ "interpolated": true
28777
+ },
28778
+ {
28779
+ "section": null,
28780
+ "requirement": null,
28781
+ "interpolated": true
28782
+ },
28783
+ {
28784
+ "section": null,
28785
+ "requirement": null,
28786
+ "interpolated": true
28787
+ },
28788
+ {
28789
+ "section": null,
28790
+ "requirement": null,
28791
+ "interpolated": true
28792
+ }
28793
+ ]
28794
+ },
27959
28795
  {
27960
28796
  "id": "openwop.it.v2-subject-link-record.the-link-formed-across-scim-and-saml-is-a-closed-subjectlink-record",
27961
28797
  "file": "v2-subject-link-record.test.ts",
@@ -28420,7 +29256,7 @@
28420
29256
  {
28421
29257
  "id": "openwop.it.version-negotiation.get-well-known-openwop-returns-capabilities-with-protocolversion-string",
28422
29258
  "file": "version-negotiation.test.ts",
28423
- "line": 46,
29259
+ "line": 68,
28424
29260
  "title": "GET /.well-known/openwop returns Capabilities with protocolVersion (string)",
28425
29261
  "explicitId": "openwop.it.version-negotiation.get-well-known-openwop-returns-capabilities-with-protocolversion-string",
28426
29262
  "citations": [
@@ -28433,7 +29269,7 @@
28433
29269
  {
28434
29270
  "id": "openwop.it.version-negotiation.every-event-has-the-6-required-runeventdoc-fields-per-run-event-schema-json",
28435
29271
  "file": "version-negotiation.test.ts",
28436
- "line": 60,
29272
+ "line": 82,
28437
29273
  "title": "every event has the 6 required RunEventDoc fields per run-event.schema.json",
28438
29274
  "explicitId": "openwop.it.version-negotiation.every-event-has-the-6-required-runeventdoc-fields-per-run-event-schema-json",
28439
29275
  "citations": [
@@ -28474,7 +29310,7 @@
28474
29310
  {
28475
29311
  "id": "openwop.it.version-negotiation.event-sequences-within-a-run-are-strictly-monotonic",
28476
29312
  "file": "version-negotiation.test.ts",
28477
- "line": 104,
29313
+ "line": 126,
28478
29314
  "title": "event sequences within a run are strictly monotonic",
28479
29315
  "explicitId": "openwop.it.version-negotiation.event-sequences-within-a-run-are-strictly-monotonic",
28480
29316
  "citations": [
@@ -28488,7 +29324,7 @@
28488
29324
  {
28489
29325
  "id": "openwop.it.version-negotiation.events-poll-with-lastsequence-past-current-end-returns-empty-events-iscomplete",
28490
29326
  "file": "version-negotiation.test.ts",
28491
- "line": 132,
29327
+ "line": 154,
28492
29328
  "title": "events/poll with lastSequence past current end returns empty events + isComplete",
28493
29329
  "explicitId": "openwop.it.version-negotiation.events-poll-with-lastsequence-past-current-end-returns-empty-events-iscomplete",
28494
29330
  "citations": [
@@ -34538,7 +35374,7 @@
34538
35374
  {
34539
35375
  "id": "openwop.it.v2-bundle-signature-attributable.the-v2-discovery-root-publishes-signingkeys-the-surface-the-rfc-named",
34540
35376
  "file": "v2-bundle-signature-attributable.test.ts",
34541
- "line": 85,
35377
+ "line": 103,
34542
35378
  "title": "the v2 discovery root publishes signingKeys[] — the surface the RFC named",
34543
35379
  "explicitId": null,
34544
35380
  "citations": [
@@ -34567,7 +35403,7 @@
34567
35403
  {
34568
35404
  "id": "openwop.it.v2-bundle-signature-attributable.the-front-door-gate-verifies-the-attestation-instead-of-inspecting-the-string",
34569
35405
  "file": "v2-bundle-signature-attributable.test.ts",
34570
- "line": 116,
35406
+ "line": 134,
34571
35407
  "title": "the Front-door gate verifies the attestation instead of inspecting the string",
34572
35408
  "explicitId": null,
34573
35409
  "citations": [
@@ -34586,7 +35422,7 @@
34586
35422
  {
34587
35423
  "id": "openwop.it.v2-bundle-signature-attributable.the-four-signature-outcomes-stay-distinct-collapsing-any-two-restores-the-defect",
34588
35424
  "file": "v2-bundle-signature-attributable.test.ts",
34589
- "line": 131,
35425
+ "line": 149,
34590
35426
  "title": "the four signature outcomes stay distinct — collapsing any two restores the defect",
34591
35427
  "explicitId": null,
34592
35428
  "citations": [
@@ -34597,6 +35433,20 @@
34597
35433
  }
34598
35434
  ]
34599
35435
  },
35436
+ {
35437
+ "id": "openwop.it.v2-bundle-signature-attributable.signingkeys-is-reachable-from-a-v1-root-too-a-bundle-is-v3-regardless-of-major",
35438
+ "file": "v2-bundle-signature-attributable.test.ts",
35439
+ "line": 170,
35440
+ "title": "signingKeys[] is reachable from a v1 root too — a bundle is v3 regardless of major",
35441
+ "explicitId": null,
35442
+ "citations": [
35443
+ {
35444
+ "section": null,
35445
+ "requirement": "the v1 discovery root MUST also carry signingKeys[]: a certification bundle is v3 regardless of major, and a v1-only host has only this document to resolve signature.keyId against — putting the key on the v2 root alone leaves every v1 host bundle unattributable",
35446
+ "interpolated": true
35447
+ }
35448
+ ]
35449
+ },
34600
35450
  {
34601
35451
  "id": "openwop.it.v2-corpus-tag-pinned.every-vendoring-consumer-in-the-cross-repo-inventory-records-a-published-corpus",
34602
35452
  "file": "v2-corpus-tag-pinned.test.ts",
@@ -34625,6 +35475,58 @@
34625
35475
  }
34626
35476
  ]
34627
35477
  },
35478
+ {
35479
+ "id": "openwop.it.v2-eos-clock.the-clock-file-is-current-with-the-matrix-and-the-public-history",
35480
+ "file": "v2-eos-clock.test.ts",
35481
+ "line": 43,
35482
+ "title": "the clock file is current with the matrix and the public history",
35483
+ "explicitId": null,
35484
+ "citations": [
35485
+ {
35486
+ "section": null,
35487
+ "requirement": null,
35488
+ "interpolated": true
35489
+ }
35490
+ ]
35491
+ },
35492
+ {
35493
+ "id": "openwop.it.v2-eos-clock.check-removal-dates-fails-the-v1-tree-sources-of-v1-end-of-support-rows-once-the",
35494
+ "file": "v2-eos-clock.test.ts",
35495
+ "line": 49,
35496
+ "title": "check-removal-dates FAILS the v1-tree sources of v1-end-of-support rows once the clock has passed",
35497
+ "explicitId": null,
35498
+ "citations": [
35499
+ {
35500
+ "section": null,
35501
+ "requirement": null,
35502
+ "interpolated": true
35503
+ },
35504
+ {
35505
+ "section": null,
35506
+ "requirement": "the failure MUST name the row and the source it found",
35507
+ "interpolated": true
35508
+ }
35509
+ ]
35510
+ },
35511
+ {
35512
+ "id": "openwop.it.v2-eos-clock.check-removal-dates-passes-under-the-same-clock-when-today-is-before-the-date-an",
35513
+ "file": "v2-eos-clock.test.ts",
35514
+ "line": 59,
35515
+ "title": "check-removal-dates PASSES under the same clock when today is before the date, and prints the clock state",
35516
+ "explicitId": null,
35517
+ "citations": [
35518
+ {
35519
+ "section": null,
35520
+ "requirement": null,
35521
+ "interpolated": true
35522
+ },
35523
+ {
35524
+ "section": null,
35525
+ "requirement": "the script MUST print the clock state on a green run — \"not anchored\" and \"far away\" must not print the same nothing",
35526
+ "interpolated": true
35527
+ }
35528
+ ]
35529
+ },
34628
35530
  {
34629
35531
  "id": "openwop.it.v2-error-registry-prose-parity.errors-md-states-the-registry-count-it-was-generated-from-and-renders-every-code",
34630
35532
  "file": "v2-error-registry-prose-parity.test.ts",
@@ -34728,6 +35630,20 @@
34728
35630
  }
34729
35631
  ]
34730
35632
  },
35633
+ {
35634
+ "id": "openwop.it.v2-id-kinds-bound.every-v2-id-field-refs-its-kind-and-every-id-property-is-triaged",
35635
+ "file": "v2-id-kinds-bound.test.ts",
35636
+ "line": 57,
35637
+ "title": "every v2 id field $refs its kind, and every *Id property is triaged",
35638
+ "explicitId": null,
35639
+ "citations": [
35640
+ {
35641
+ "section": "spec/v2/core/identity.md §5",
35642
+ "requirement": null,
35643
+ "interpolated": true
35644
+ }
35645
+ ]
35646
+ },
34731
35647
  {
34732
35648
  "id": "openwop.it.v2-one-signing-scheme.registry-version-manifest-signing-has-exactly-one-scheme-ed25519-canonical-json",
34733
35649
  "file": "v2-one-signing-scheme.test.ts",
@@ -34814,6 +35730,63 @@
34814
35730
  }
34815
35731
  ]
34816
35732
  },
35733
+ {
35734
+ "id": "openwop.it.v2-retention-floors.the-registry-validates-and-the-script-prints-the-floor-state-offline",
35735
+ "file": "v2-retention-floors.test.ts",
35736
+ "line": 53,
35737
+ "title": "the registry validates and the script prints the floor state offline",
35738
+ "explicitId": null,
35739
+ "citations": [
35740
+ {
35741
+ "section": null,
35742
+ "requirement": null,
35743
+ "interpolated": true
35744
+ },
35745
+ {
35746
+ "section": null,
35747
+ "requirement": "the floor state MUST be printed on every run — \"not started\" and \"every version present\" must not print the same nothing",
35748
+ "interpolated": true
35749
+ }
35750
+ ]
35751
+ },
35752
+ {
35753
+ "id": "openwop.it.v2-retention-floors.a-pinned-old-major-version-missing-from-its-registry-while-the-floor-is-open-fai",
35754
+ "file": "v2-retention-floors.test.ts",
35755
+ "line": 60,
35756
+ "title": "a pinned old-major version missing from its registry while the floor is open FAILS, naming the artifact",
35757
+ "explicitId": null,
35758
+ "citations": [
35759
+ {
35760
+ "section": null,
35761
+ "requirement": null,
35762
+ "interpolated": true
35763
+ },
35764
+ {
35765
+ "section": null,
35766
+ "requirement": "the failure MUST name the artifact and the version",
35767
+ "interpolated": true
35768
+ }
35769
+ ]
35770
+ },
35771
+ {
35772
+ "id": "openwop.it.v2-retention-floors.the-same-probe-with-every-pinned-version-present-passes-while-the-floor-is-open",
35773
+ "file": "v2-retention-floors.test.ts",
35774
+ "line": 67,
35775
+ "title": "the same probe with every pinned version present PASSES while the floor is open",
35776
+ "explicitId": null,
35777
+ "citations": [
35778
+ {
35779
+ "section": null,
35780
+ "requirement": null,
35781
+ "interpolated": true
35782
+ },
35783
+ {
35784
+ "section": null,
35785
+ "requirement": "the open floor MUST print its closing date",
35786
+ "interpolated": true
35787
+ }
35788
+ ]
35789
+ },
34817
35790
  {
34818
35791
  "id": "openwop.it.v2-seams-not-in-canonical.the-corpus-gate-script-exits-0",
34819
35792
  "file": "v2-seams-not-in-canonical.test.ts",