@openwop/openwop-conformance 2.42.6 → 2.42.8

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 (129) hide show
  1. package/CHANGELOG.md +34 -0
  2. package/README.md +3 -3
  3. package/coverage.md +1 -1
  4. package/dist/lib/soft-skip.js +13 -0
  5. package/dist/spec-artifacts.lock.json +2 -2
  6. package/fixtures/conformance-envelope-retry-attempted.json +2 -1
  7. package/package.json +2 -2
  8. package/requirements.json +581 -175
  9. package/scenario-majors.json +22 -3
  10. package/schemas/CORPUS-STAMP.json +70 -67
  11. package/src/lib/audit-checkpoint.ts +72 -0
  12. package/src/lib/ext-claims.ts +96 -0
  13. package/src/lib/mock-ai-budgets.ts +40 -0
  14. package/src/lib/soft-skip.ts +14 -0
  15. package/src/scenarios/a2a-peer-authority.test.ts +6 -13
  16. package/src/scenarios/a2a-task-roundtrip.test.ts +6 -34
  17. package/src/scenarios/a2a-version-negotiation.test.ts +6 -12
  18. package/src/scenarios/a2ui-surface-delta-transport.test.ts +23 -12
  19. package/src/scenarios/agent-channel-dispatch.test.ts +13 -4
  20. package/src/scenarios/agent-live-invocation-bracket.test.ts +1 -1
  21. package/src/scenarios/agent-manifest-runtime.test.ts +3 -0
  22. package/src/scenarios/aiEnvelope.capBreached.test.ts +2 -2
  23. package/src/scenarios/aiEnvelope.contractRefusal.test.ts +2 -2
  24. package/src/scenarios/aiEnvelope.schemaDrift.test.ts +2 -2
  25. package/src/scenarios/aiEnvelope.universalKinds.test.ts +2 -2
  26. package/src/scenarios/aiproviders-selfhosted-honesty.test.ts +2 -2
  27. package/src/scenarios/append-ordering.test.ts +26 -21
  28. package/src/scenarios/artifact-auth.test.ts +3 -1
  29. package/src/scenarios/artifact-type-registration-source.test.ts +2 -2
  30. package/src/scenarios/audit-checkpoint-signature.test.ts +63 -0
  31. package/src/scenarios/audit-checkpoint-vectors.test.ts +93 -0
  32. package/src/scenarios/audit-log-integrity.test.ts +7 -16
  33. package/src/scenarios/auth-mtls.test.ts +7 -6
  34. package/src/scenarios/auth-subject-link-key-class.test.ts +3 -3
  35. package/src/scenarios/auth-subject-link.test.ts +19 -18
  36. package/src/scenarios/blob-presign-expiry.test.ts +2 -2
  37. package/src/scenarios/byok-roundtrip.test.ts +4 -1
  38. package/src/scenarios/compensation-behavior.test.ts +10 -5
  39. package/src/scenarios/conformance-advertised-seam-required.test.ts +6 -0
  40. package/src/scenarios/connection-pack-apihosts.test.ts +2 -2
  41. package/src/scenarios/connection-provider-resolution.test.ts +2 -2
  42. package/src/scenarios/context-budget-transcript-bound.test.ts +7 -3
  43. package/src/scenarios/context-summarization-replay.test.ts +2 -0
  44. package/src/scenarios/cost-attribution.test.ts +3 -1
  45. package/src/scenarios/debugBundle.test.ts +12 -4
  46. package/src/scenarios/discovery.test.ts +6 -2
  47. package/src/scenarios/dispatch-cross-worker-handoff.test.ts +2 -2
  48. package/src/scenarios/dispatch-input-mapping.test.ts +2 -2
  49. package/src/scenarios/dispatch-output-mapping.test.ts +15 -2
  50. package/src/scenarios/distillation-token-budget.test.ts +2 -2
  51. package/src/scenarios/durability-poison-exhaustion.test.ts +2 -2
  52. package/src/scenarios/envelope-completion-distinguishes-truncation.test.ts +51 -15
  53. package/src/scenarios/envelope-nl-to-format-engaged.test.ts +2 -2
  54. package/src/scenarios/envelope-recovery-applied.test.ts +2 -2
  55. package/src/scenarios/envelope-refusal-shape.test.ts +2 -2
  56. package/src/scenarios/envelope-retry-attempted.test.ts +2 -2
  57. package/src/scenarios/envelope-retry-exhausted.test.ts +2 -2
  58. package/src/scenarios/envelope-tier-one-subset-static.test.ts +1 -1
  59. package/src/scenarios/envelope-truncation-cap-exhaustion.test.ts +2 -2
  60. package/src/scenarios/eventOrdering.test.ts +17 -10
  61. package/src/scenarios/form-content-instantiation.test.ts +2 -2
  62. package/src/scenarios/heartbeat-idempotent-no-spam.test.ts +2 -2
  63. package/src/scenarios/highConcurrency.test.ts +9 -9
  64. package/src/scenarios/idempotency-concurrent-claim.test.ts +5 -5
  65. package/src/scenarios/idempotency-key-determinism.test.ts +8 -8
  66. package/src/scenarios/idempotency.test.ts +6 -6
  67. package/src/scenarios/idempotencyRetry.test.ts +16 -11
  68. package/src/scenarios/interrupt-token-matrix.test.ts +24 -11
  69. package/src/scenarios/mcp-cache-tenant-scope.test.ts +3 -3
  70. package/src/scenarios/mcp-current-auth-boundary.test.ts +9 -6
  71. package/src/scenarios/mcp-extension-opacity.test.ts +6 -5
  72. package/src/scenarios/mcp-mrtr-roundtrip.test.ts +9 -8
  73. package/src/scenarios/mcp-version-negotiation.test.ts +5 -10
  74. package/src/scenarios/media-url-inline-cap.test.ts +3 -2
  75. package/src/scenarios/memory-compaction-provenance-tag.test.ts +2 -0
  76. package/src/scenarios/memory-compaction-sr1-carry-forward.test.ts +2 -2
  77. package/src/scenarios/memory-consolidation-idempotent.test.ts +2 -2
  78. package/src/scenarios/memory-injection-budget.test.ts +2 -2
  79. package/src/scenarios/multi-party-conversation-behavioral.test.ts +2 -2
  80. package/src/scenarios/multi-region-idempotency-behavior.test.ts +9 -9
  81. package/src/scenarios/multi-region-idempotency.test.ts +2 -2
  82. package/src/scenarios/pack-registry-isolation.test.ts +13 -12
  83. package/src/scenarios/pack-registry.test.ts +3 -2
  84. package/src/scenarios/pause-resume.test.ts +30 -11
  85. package/src/scenarios/prompt-read-workspace-membership-enforced.test.ts +43 -34
  86. package/src/scenarios/provider-usage.test.ts +2 -2
  87. package/src/scenarios/redaction.test.ts +7 -5
  88. package/src/scenarios/redactionAdversarial.test.ts +5 -4
  89. package/src/scenarios/registry-public.test.ts +5 -1
  90. package/src/scenarios/replay-divergence-at-refusal.test.ts +10 -7
  91. package/src/scenarios/replay-fanout-suppression.test.ts +7 -4
  92. package/src/scenarios/replay-fork-arbitrary.test.ts +2 -2
  93. package/src/scenarios/replay-side-effect-suppression.test.ts +2 -2
  94. package/src/scenarios/replayDeterminism.test.ts +9 -4
  95. package/src/scenarios/runner-ledger.test.ts +4 -0
  96. package/src/scenarios/runtime-capabilities.test.ts +2 -0
  97. package/src/scenarios/speech-synthesis-roundtrip.test.ts +1 -1
  98. package/src/scenarios/streamReconnect.test.ts +2 -2
  99. package/src/scenarios/subrun-approval-gate.test.ts +2 -2
  100. package/src/scenarios/subworkflow-input-mapping.test.ts +2 -2
  101. package/src/scenarios/tool-catalog-projection.test.ts +10 -7
  102. package/src/scenarios/tool-session-lifecycle.test.ts +1 -1
  103. package/src/scenarios/trigger-ingestion.test.ts +2 -2
  104. package/src/scenarios/v2-a2ui-v09-surface.test.ts +15 -0
  105. package/src/scenarios/v2-client-version-header.test.ts +124 -0
  106. package/src/scenarios/v2-effect-identity-business-key.test.ts +12 -0
  107. package/src/scenarios/v2-ext-family-claims.test.ts +62 -0
  108. package/src/scenarios/v2-ext-rest-transport.test.ts +151 -0
  109. package/src/scenarios/v2-id-grammar.test.ts +17 -5
  110. package/src/scenarios/v2-idempotency-in-flight.test.ts +3 -0
  111. package/src/scenarios/v2-legacy-profiles-absent.test.ts +4 -6
  112. package/src/scenarios/v2-mcp-tasks.test.ts +1 -1
  113. package/src/scenarios/v2-min-client-version.test.ts +20 -14
  114. package/src/scenarios/v2-preferred-version-default.test.ts +19 -1
  115. package/src/scenarios/v2-refresh-sla.test.ts +6 -5
  116. package/src/scenarios/v2-sse-last-event-id-cursor.test.ts +3 -3
  117. package/src/scenarios/v2-sse-last-event-id.test.ts +2 -0
  118. package/src/scenarios/v2-version-header-honored.test.ts +3 -0
  119. package/src/scenarios/v2-webhook-durable-delivery.test.ts +2 -0
  120. package/src/scenarios/v2-webhook-generated-secret.test.ts +76 -0
  121. package/src/scenarios/v2-webhook-secret-rotation.test.ts +8 -1
  122. package/src/scenarios/verifier-gating.test.ts +2 -2
  123. package/src/scenarios/version-fold.test.ts +2 -2
  124. package/src/scenarios/wasm-pack-invoke-suspended.test.ts +7 -6
  125. package/src/scenarios/webhook-signed-delivery.test.ts +2 -0
  126. package/src/scenarios/workflow-chain-host-expansion.test.ts +10 -1
  127. package/src/scenarios/workflow-variable-format.test.ts +2 -2
  128. package/src/scenarios/workload-identity-chain-bounds.test.ts +6 -3
  129. package/vectors/audit-checkpoint-v1.json +260 -0
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": 636,
6
- "tests": 2439,
7
- "withStableId": 2439,
5
+ "files": 642,
6
+ "tests": 2466,
7
+ "withStableId": 2466,
8
8
  "interpolatedTitles": 0,
9
- "explicitIds": 2331
9
+ "explicitIds": 2356
10
10
  },
11
11
  "records": [
12
12
  {
@@ -331,11 +331,6 @@
331
331
  "section": "RFCS/0152 §E",
332
332
  "requirement": "the host MUST have created a task on the peer for this leg to mean anything"
333
333
  },
334
- {
335
- "section": "host-sample-test-seams.md §22",
336
- "requirement": null,
337
- "interpolated": true
338
- },
339
334
  {
340
335
  "section": "RFCS/0152 §E",
341
336
  "requirement": "peer content MUST NOT advance an approval gate (a2a-peer-no-authority-escalation)"
@@ -366,7 +361,7 @@
366
361
  {
367
362
  "id": "openwop.it.a2a-task-roundtrip.host-consuming-an-a2a-peer-that-returns-auth-required-projects-to-waiting-input",
368
363
  "file": "a2a-task-roundtrip.test.ts",
369
- "line": 223,
364
+ "line": 195,
370
365
  "title": "host consuming an A2A peer that returns AUTH_REQUIRED projects to waiting-input with metadata.subkind=auth",
371
366
  "explicitId": "openwop.it.a2a-task-roundtrip.host-consuming-an-a2a-peer-that-returns-auth-required-projects-to-waiting-input",
372
367
  "citations": [
@@ -379,7 +374,7 @@
379
374
  {
380
375
  "id": "openwop.it.a2a-task-roundtrip.host-consuming-an-a2a-peer-that-returns-rejected-projects-to-failed-with-rejecte",
381
376
  "file": "a2a-task-roundtrip.test.ts",
382
- "line": 263,
377
+ "line": 235,
383
378
  "title": "host consuming an A2A peer that returns REJECTED projects to failed with rejected_by_remote",
384
379
  "explicitId": "openwop.it.a2a-task-roundtrip.host-consuming-an-a2a-peer-that-returns-rejected-projects-to-failed-with-rejecte",
385
380
  "citations": [
@@ -396,7 +391,7 @@
396
391
  {
397
392
  "id": "openwop.it.a2a-task-roundtrip.a-conforming-a2ataskstate-validates-with-the-lowercase-hyphen-state-enum-and-tas",
398
393
  "file": "a2a-task-roundtrip.test.ts",
399
- "line": 315,
394
+ "line": 287,
400
395
  "title": "a conforming A2ATaskState validates with the lowercase-hyphen state enum and taskId == runId",
401
396
  "explicitId": "openwop.it.a2a-task-roundtrip.a-conforming-a2ataskstate-validates-with-the-lowercase-hyphen-state-enum-and-tas",
402
397
  "citations": [
@@ -410,7 +405,7 @@
410
405
  {
411
406
  "id": "openwop.it.a2a-task-roundtrip.an-uppercase-state-fails-the-persisted-wire-form-is-the-a2a-v0-3-lowercase-hyphe",
412
407
  "file": "a2a-task-roundtrip.test.ts",
413
- "line": 330,
408
+ "line": 302,
414
409
  "title": "an UPPERCASE state fails (the persisted/wire form is the A2A v0.3 lowercase-hyphen variant)",
415
410
  "explicitId": "openwop.it.a2a-task-roundtrip.an-uppercase-state-fails-the-persisted-wire-form-is-the-a2a-v0-3-lowercase-hyphe",
416
411
  "citations": [
@@ -423,7 +418,7 @@
423
418
  {
424
419
  "id": "openwop.it.a2a-task-roundtrip.an-a2ataskstate-carrying-run-inputs-artifacts-inline-fails-additionalproperties",
425
420
  "file": "a2a-task-roundtrip.test.ts",
426
- "line": 337,
421
+ "line": 309,
427
422
  "title": "an A2ATaskState carrying run inputs/artifacts inline fails (additionalProperties:false; SR-1)",
428
423
  "explicitId": "openwop.it.a2a-task-roundtrip.an-a2ataskstate-carrying-run-inputs-artifacts-inline-fails-additionalproperties",
429
424
  "citations": [
@@ -436,7 +431,7 @@
436
431
  {
437
432
  "id": "openwop.it.a2a-task-roundtrip.a-pushconfig-requires-url-and-structurally-rejects-a-raw-non-truncated-push-toke",
438
433
  "file": "a2a-task-roundtrip.test.ts",
439
- "line": 350,
434
+ "line": 322,
440
435
  "title": "a PushConfig requires `url` and structurally rejects a raw (non-truncated) push token",
441
436
  "explicitId": "openwop.it.a2a-task-roundtrip.a-pushconfig-requires-url-and-structurally-rejects-a-raw-non-truncated-push-toke",
442
437
  "citations": [
@@ -457,7 +452,7 @@
457
452
  {
458
453
  "id": "openwop.it.a2a-task-roundtrip.the-capabilities-a2a-block-shape-is-declared-supported-agentcardurl-required-thr",
459
454
  "file": "a2a-task-roundtrip.test.ts",
460
- "line": 366,
455
+ "line": 338,
461
456
  "title": "the capabilities.a2a block shape is declared (supported + agentCardUrl required; three optional booleans)",
462
457
  "explicitId": "openwop.it.a2a-task-roundtrip.the-capabilities-a2a-block-shape-is-declared-supported-agentcardurl-required-thr",
463
458
  "citations": [
@@ -479,7 +474,7 @@
479
474
  {
480
475
  "id": "openwop.it.a2a-task-roundtrip.a-paused-at-hitl-run-projects-a-live-input-required-task-on-a-later-tasks-get-re",
481
476
  "file": "a2a-task-roundtrip.test.ts",
482
- "line": 380,
477
+ "line": 352,
483
478
  "title": "a paused-at-HITL run projects a live input-required task on a later tasks/get read",
484
479
  "explicitId": "openwop.it.a2a-task-roundtrip.a-paused-at-hitl-run-projects-a-live-input-required-task-on-a-later-tasks-get-re",
485
480
  "citations": [
@@ -496,7 +491,7 @@
496
491
  {
497
492
  "id": "openwop.it.a2a-task-roundtrip.address-arm-an-https-pushconfig-url-at-a-private-address-is-refused",
498
493
  "file": "a2a-task-roundtrip.test.ts",
499
- "line": 451,
494
+ "line": 423,
500
495
  "title": "ADDRESS arm: an https pushConfig.url at a private address is refused",
501
496
  "explicitId": "openwop.it.a2a-task-roundtrip.address-arm-an-https-pushconfig-url-at-a-private-address-is-refused",
502
497
  "citations": [
@@ -509,7 +504,7 @@
509
504
  {
510
505
  "id": "openwop.it.a2a-task-roundtrip.scheme-arm-an-http-pushconfig-url-at-a-public-host-is-refused",
511
506
  "file": "a2a-task-roundtrip.test.ts",
512
- "line": 465,
507
+ "line": 437,
513
508
  "title": "SCHEME arm: an http pushConfig.url at a public host is refused",
514
509
  "explicitId": "openwop.it.a2a-task-roundtrip.scheme-arm-an-http-pushconfig-url-at-a-public-host-is-refused",
515
510
  "citations": [
@@ -541,11 +536,6 @@
541
536
  "title": "outbound calls carry an explicit A2A-Version header",
542
537
  "explicitId": "openwop.it.a2a-version-negotiation.outbound-calls-carry-an-explicit-a2a-version-header",
543
538
  "citations": [
544
- {
545
- "section": "RFCS/0152 §B",
546
- "requirement": null,
547
- "interpolated": true
548
- },
549
539
  {
550
540
  "section": "RFCS/0152 §B",
551
541
  "requirement": "the host MUST have called the peer"
@@ -560,7 +550,7 @@
560
550
  {
561
551
  "id": "openwop.it.a2a-version-negotiation.an-authenticated-request-is-not-silently-downgraded",
562
552
  "file": "a2a-version-negotiation.test.ts",
563
- "line": 109,
553
+ "line": 103,
564
554
  "title": "an authenticated request is not silently downgraded",
565
555
  "explicitId": "openwop.it.a2a-version-negotiation.an-authenticated-request-is-not-silently-downgraded",
566
556
  "citations": [
@@ -578,7 +568,7 @@
578
568
  {
579
569
  "id": "openwop.it.a2a-version-negotiation.an-unsupported-version-fails-through-the-canonical-interop-error-envelope",
580
570
  "file": "a2a-version-negotiation.test.ts",
581
- "line": 149,
571
+ "line": 143,
582
572
  "title": "an unsupported version fails through the canonical interop error envelope",
583
573
  "explicitId": "openwop.it.a2a-version-negotiation.an-unsupported-version-fails-through-the-canonical-interop-error-envelope",
584
574
  "citations": [
@@ -784,14 +774,6 @@
784
774
  "title": "drives the emit-surface seam: a ?a2uiDelta=1 subscriber reconstruction equals the non-negotiating full",
785
775
  "explicitId": "openwop.it.a2ui-surface-delta-transport.drives-the-emit-surface-seam-a-a2uidelta-1-subscriber-reconstruction-equals-the",
786
776
  "citations": [
787
- {
788
- "section": "RFC 0114 §15",
789
- "requirement": "the emit-surface seam MUST record the baseline full surface"
790
- },
791
- {
792
- "section": "RFC 0114 §15",
793
- "requirement": "the second emit MUST succeed"
794
- },
795
777
  {
796
778
  "section": "RFC 0114",
797
779
  "requirement": "a delta frame catalogVersion MUST equal the referenced full surface"
@@ -809,7 +791,7 @@
809
791
  {
810
792
  "id": "openwop.it.a2ui-surface-delta-transport.the-emit-surface-seam-rejects-an-out-of-catalog-surface-fail-closed-real-catalog",
811
793
  "file": "a2ui-surface-delta-transport.test.ts",
812
- "line": 575,
794
+ "line": 584,
813
795
  "title": "the emit-surface seam rejects an out-of-catalog surface fail-closed (real catalog gate)",
814
796
  "explicitId": "openwop.it.a2ui-surface-delta-transport.the-emit-surface-seam-rejects-an-out-of-catalog-surface-fail-closed-real-catalog",
815
797
  "citations": [
@@ -5443,10 +5425,116 @@
5443
5425
  }
5444
5426
  ]
5445
5427
  },
5428
+ {
5429
+ "id": "openwop.it.audit-checkpoint-signature.every-checkpoint-get-v1-audit-verify-returns-verifies-under-the-advertised-key",
5430
+ "file": "audit-checkpoint-signature.test.ts",
5431
+ "line": 30,
5432
+ "title": "every checkpoint GET /v1/audit/verify returns verifies under the advertised key",
5433
+ "explicitId": "openwop.requirement.0218.checkpoint-signature-over-root",
5434
+ "citations": [
5435
+ {
5436
+ "section": "RFC 0218 · spec/v1/auth-profiles.md §\"Audit-log integrity\" 3",
5437
+ "requirement": null,
5438
+ "interpolated": true
5439
+ }
5440
+ ]
5441
+ },
5442
+ {
5443
+ "id": "openwop.it.audit-checkpoint-vectors.the-vector-set-is-present-and-non-trivial",
5444
+ "file": "audit-checkpoint-vectors.test.ts",
5445
+ "line": 50,
5446
+ "title": "the vector set is present and non-trivial",
5447
+ "explicitId": "openwop.requirement.0218.checkpoint-preimage-vectors",
5448
+ "citations": [
5449
+ {
5450
+ "section": "RFC 0218 · spec/v1/auth-profiles.md §\"Audit-log integrity\" 3",
5451
+ "requirement": "the vector file carries entries"
5452
+ },
5453
+ {
5454
+ "section": "RFC 0218 · spec/v1/auth-profiles.md §\"Audit-log integrity\" 3",
5455
+ "requirement": "the checkpoints cover 1, 2, 4 and 5 leaves (odd promotion at 5)"
5456
+ }
5457
+ ]
5458
+ },
5459
+ {
5460
+ "id": "openwop.it.audit-checkpoint-vectors.every-entry-hash-is-the-sha-256-of-the-entry-s-jcs-bytes-and-chains-as-prevhash",
5461
+ "file": "audit-checkpoint-vectors.test.ts",
5462
+ "line": 56,
5463
+ "title": "every entry hash is the SHA-256 of the entry's JCS bytes, and chains as prevHash",
5464
+ "explicitId": "openwop.requirement.0218.checkpoint-preimage-vectors",
5465
+ "citations": [
5466
+ {
5467
+ "section": "RFC 0218 · spec/v1/auth-profiles.md §\"Audit-log integrity\" 3",
5468
+ "requirement": null,
5469
+ "interpolated": true
5470
+ },
5471
+ {
5472
+ "section": "RFC 0218 · spec/v1/auth-profiles.md §\"Audit-log integrity\" 3",
5473
+ "requirement": null,
5474
+ "interpolated": true
5475
+ }
5476
+ ]
5477
+ },
5478
+ {
5479
+ "id": "openwop.it.audit-checkpoint-vectors.every-root-is-recomputed-over-p-atsequence-pairwise-odd-node-promoted",
5480
+ "file": "audit-checkpoint-vectors.test.ts",
5481
+ "line": 65,
5482
+ "title": "every root is recomputed over (P, atSequence], pairwise, odd node promoted",
5483
+ "explicitId": "openwop.requirement.0218.checkpoint-preimage-vectors",
5484
+ "citations": [
5485
+ {
5486
+ "section": "RFC 0218 · spec/v1/auth-profiles.md §\"Audit-log integrity\" 3",
5487
+ "requirement": null,
5488
+ "interpolated": true
5489
+ }
5490
+ ]
5491
+ },
5492
+ {
5493
+ "id": "openwop.it.audit-checkpoint-vectors.every-signature-verifies-as-ed25519-over-the-32-root-bytes",
5494
+ "file": "audit-checkpoint-vectors.test.ts",
5495
+ "line": 72,
5496
+ "title": "every signature verifies as Ed25519 over the 32 root bytes",
5497
+ "explicitId": "openwop.requirement.0218.checkpoint-preimage-vectors",
5498
+ "citations": [
5499
+ {
5500
+ "section": "RFC 0218 · spec/v1/auth-profiles.md §\"Audit-log integrity\" 3",
5501
+ "requirement": null,
5502
+ "interpolated": true
5503
+ }
5504
+ ]
5505
+ },
5506
+ {
5507
+ "id": "openwop.it.audit-checkpoint-vectors.refuses-a-leaf-list-whose-count-is-not-atsequence-p-an-uppercase-leaf-and-an-emp",
5508
+ "file": "audit-checkpoint-vectors.test.ts",
5509
+ "line": 79,
5510
+ "title": "refuses a leaf list whose count is not atSequence − P, an uppercase leaf, and an empty range",
5511
+ "explicitId": "openwop.requirement.0218.checkpoint-preimage-vectors",
5512
+ "citations": [
5513
+ {
5514
+ "section": "RFC 0218 · spec/v1/auth-profiles.md §\"Audit-log integrity\" 3",
5515
+ "requirement": null,
5516
+ "interpolated": true
5517
+ }
5518
+ ]
5519
+ },
5520
+ {
5521
+ "id": "openwop.it.audit-checkpoint-vectors.a-signature-over-any-other-preimage-does-not-verify",
5522
+ "file": "audit-checkpoint-vectors.test.ts",
5523
+ "line": 87,
5524
+ "title": "a signature over any other preimage does not verify",
5525
+ "explicitId": "openwop.requirement.0218.checkpoint-preimage-vectors",
5526
+ "citations": [
5527
+ {
5528
+ "section": "RFC 0218 · spec/v1/auth-profiles.md §\"Audit-log integrity\" 3",
5529
+ "requirement": null,
5530
+ "interpolated": true
5531
+ }
5532
+ ]
5533
+ },
5446
5534
  {
5447
5535
  "id": "openwop.it.audit-log-integrity.host-that-claims-the-profile-advertises-required-capability-fields",
5448
5536
  "file": "audit-log-integrity.test.ts",
5449
- "line": 69,
5537
+ "line": 60,
5450
5538
  "title": "host that claims the profile advertises required capability fields",
5451
5539
  "explicitId": "openwop.it.audit-log-integrity.host-that-claims-the-profile-advertises-required-capability-fields",
5452
5540
  "citations": [
@@ -5463,7 +5551,7 @@
5463
5551
  {
5464
5552
  "id": "openwop.it.audit-log-integrity.get-v1-audit-verify-on-a-recent-range-reports-chainvalid-true",
5465
5553
  "file": "audit-log-integrity.test.ts",
5466
- "line": 92,
5554
+ "line": 83,
5467
5555
  "title": "GET /v1/audit/verify on a recent range reports chainValid: true",
5468
5556
  "explicitId": "openwop.it.audit-log-integrity.get-v1-audit-verify-on-a-recent-range-reports-chainvalid-true",
5469
5557
  "citations": [
@@ -6068,7 +6156,7 @@
6068
6156
  {
6069
6157
  "id": "openwop.it.auth-subject-link.a-scim-deactivation-does-not-deny-a-saml-login-whose-run-subject-is-legacy-issue",
6070
6158
  "file": "auth-subject-link.test.ts",
6071
- "line": 219,
6159
+ "line": 220,
6072
6160
  "title": "a SCIM deactivation does not deny a SAML login whose run subject is legacy-issued",
6073
6161
  "explicitId": null,
6074
6162
  "citations": []
@@ -6668,7 +6756,7 @@
6668
6756
  {
6669
6757
  "id": "openwop.it.byok-roundtrip.byok-fixture-run-must-emit-a-node-completed-event-for-the-resolve-step",
6670
6758
  "file": "byok-roundtrip.test.ts",
6671
- "line": 101,
6759
+ "line": 104,
6672
6760
  "title": "BYOK fixture run MUST emit a node.completed event for the resolve step",
6673
6761
  "explicitId": "openwop.it.byok-roundtrip.byok-fixture-run-must-emit-a-node-completed-event-for-the-resolve-step",
6674
6762
  "citations": [
@@ -6681,7 +6769,7 @@
6681
6769
  {
6682
6770
  "id": "openwop.it.byok-roundtrip.byok-fixture-run-event-log-must-not-echo-the-resolved-secret-value-redaction",
6683
6771
  "file": "byok-roundtrip.test.ts",
6684
- "line": 127,
6772
+ "line": 130,
6685
6773
  "title": "BYOK fixture run event log MUST NOT echo the resolved secret value (redaction)",
6686
6774
  "explicitId": "openwop.it.byok-roundtrip.byok-fixture-run-event-log-must-not-echo-the-resolved-secret-value-redaction",
6687
6775
  "citations": [
@@ -8319,7 +8407,7 @@
8319
8407
  {
8320
8408
  "id": "openwop.it.compensation-behavior.compensation-events-carry-no-provider-bodies-or-credentials",
8321
8409
  "file": "compensation-behavior.test.ts",
8322
- "line": 208,
8410
+ "line": 211,
8323
8411
  "title": "compensation events carry no provider bodies or credentials",
8324
8412
  "explicitId": "openwop.it.compensation-behavior.compensation-events-carry-no-provider-bodies-or-credentials",
8325
8413
  "citations": [
@@ -8333,7 +8421,7 @@
8333
8421
  {
8334
8422
  "id": "openwop.it.compensation-behavior.a-healthy-run-that-declares-a-compensator-reports-compensationstatus-none-sp-11a",
8335
8423
  "file": "compensation-behavior.test.ts",
8336
- "line": 230,
8424
+ "line": 233,
8337
8425
  "title": "a healthy run that DECLARES a compensator reports compensationStatus `none` (SP-11a)",
8338
8426
  "explicitId": "openwop.it.compensation-behavior.a-healthy-run-that-declares-a-compensator-reports-compensationstatus-none-sp-11a",
8339
8427
  "citations": [
@@ -8564,7 +8652,7 @@
8564
8652
  {
8565
8653
  "id": "openwop.it.conformance-advertised-seam-required.the-sanctioned-escape-is-an-explicit-opt-out-which-records-skipped-with-the-reas",
8566
8654
  "file": "conformance-advertised-seam-required.test.ts",
8567
- "line": 110,
8655
+ "line": 116,
8568
8656
  "title": "the sanctioned escape is an explicit opt-out, which records skipped with the reason — still never a pass",
8569
8657
  "explicitId": "openwop.it.conformance-advertised-seam-required.the-sanctioned-escape-is-an-explicit-opt-out-which-records-skipped-with-the-reas",
8570
8658
  "citations": [
@@ -9692,7 +9780,7 @@
9692
9780
  {
9693
9781
  "id": "openwop.it.cost-attribution.metrics-openwopcost-must-carry-the-canary-cost-shape-after-the-fixture-node-runs",
9694
9782
  "file": "cost-attribution.test.ts",
9695
- "line": 134,
9783
+ "line": 136,
9696
9784
  "title": "metrics.openwopCost MUST carry the canary cost shape after the fixture node runs",
9697
9785
  "explicitId": "openwop.it.cost-attribution.metrics-openwopcost-must-carry-the-canary-cost-shape-after-the-fixture-node-runs",
9698
9786
  "citations": [
@@ -9733,7 +9821,7 @@
9733
9821
  {
9734
9822
  "id": "openwop.it.cost-attribution.cost-emit-fixture-run-must-emit-a-node-completed-event-for-the-cost-emitting-nod",
9735
9823
  "file": "cost-attribution.test.ts",
9736
- "line": 221,
9824
+ "line": 223,
9737
9825
  "title": "cost-emit fixture run MUST emit a node.completed event for the cost-emitting node",
9738
9826
  "explicitId": "openwop.it.cost-attribution.cost-emit-fixture-run-must-emit-a-node-completed-event-for-the-cost-emitting-nod",
9739
9827
  "citations": [
@@ -9746,7 +9834,7 @@
9746
9834
  {
9747
9835
  "id": "openwop.it.cost-attribution.only-allowlisted-openwop-cost-attributes-reach-the-otel-span-g6-close-criteria-a",
9748
9836
  "file": "cost-attribution.test.ts",
9749
- "line": 260,
9837
+ "line": 262,
9750
9838
  "title": "only allowlisted openwop.cost.* attributes reach the OTel span (G6 close criteria — allowlist enforcement)",
9751
9839
  "explicitId": "openwop.it.cost-attribution.only-allowlisted-openwop-cost-attributes-reach-the-otel-span-g6-close-criteria-a",
9752
9840
  "citations": [
@@ -9763,7 +9851,7 @@
9763
9851
  {
9764
9852
  "id": "openwop.it.cost-attribution.credential-shaped-canaries-do-not-leak-to-any-otel-attribute-g6-close-criteria-r",
9765
9853
  "file": "cost-attribution.test.ts",
9766
- "line": 299,
9854
+ "line": 301,
9767
9855
  "title": "credential-shaped canaries do NOT leak to any OTel attribute (G6 close criteria — redaction)",
9768
9856
  "explicitId": "openwop.it.cost-attribution.credential-shaped-canaries-do-not-leak-to-any-otel-attribute-g6-close-criteria-r",
9769
9857
  "citations": [
@@ -10349,7 +10437,7 @@
10349
10437
  {
10350
10438
  "id": "openwop.it.debugBundle.canary-in-workflow-inputs-must-not-appear-verbatim-in-the-bundle-response",
10351
10439
  "file": "debugBundle.test.ts",
10352
- "line": 204,
10440
+ "line": 206,
10353
10441
  "title": "canary in workflow inputs MUST NOT appear verbatim in the bundle response",
10354
10442
  "explicitId": "openwop.it.debugBundle.canary-in-workflow-inputs-must-not-appear-verbatim-in-the-bundle-response",
10355
10443
  "citations": [
@@ -10366,7 +10454,7 @@
10366
10454
  {
10367
10455
  "id": "openwop.it.debugBundle.span-traceid-kind-status-have-the-rfc-0207-shape-and-the-run-span-joins-the-call",
10368
10456
  "file": "debugBundle.test.ts",
10369
- "line": 238,
10457
+ "line": 240,
10370
10458
  "title": "span traceId / kind / status have the RFC 0207 shape and the run span joins the caller trace",
10371
10459
  "explicitId": null,
10372
10460
  "citations": [
@@ -10519,7 +10607,7 @@
10519
10607
  {
10520
10608
  "id": "openwop.it.discovery.declares-non-zero-limits-per-capabilities-md-3-capabilitylimiter-shape",
10521
10609
  "file": "discovery.test.ts",
10522
- "line": 84,
10610
+ "line": 86,
10523
10611
  "title": "declares non-zero limits per capabilities.md §3 (CapabilityLimiter shape)",
10524
10612
  "explicitId": "openwop.it.discovery.declares-non-zero-limits-per-capabilities-md-3-capabilitylimiter-shape",
10525
10613
  "citations": [
@@ -10542,7 +10630,7 @@
10542
10630
  {
10543
10631
  "id": "openwop.it.discovery.if-fixtures-is-present-it-must-be-a-string-of-unique-non-empty-entries",
10544
10632
  "file": "discovery.test.ts",
10545
- "line": 108,
10633
+ "line": 110,
10546
10634
  "title": "IF fixtures is present, it MUST be a string[] of unique non-empty entries",
10547
10635
  "explicitId": "openwop.it.discovery.if-fixtures-is-present-it-must-be-a-string-of-unique-non-empty-entries",
10548
10636
  "citations": [
@@ -10567,7 +10655,7 @@
10567
10655
  {
10568
10656
  "id": "openwop.it.discovery.returns-200-with-a-parseable-openapi-3-1-document",
10569
10657
  "file": "discovery.test.ts",
10570
- "line": 148,
10658
+ "line": 152,
10571
10659
  "title": "returns 200 with a parseable OpenAPI 3.1 document",
10572
10660
  "explicitId": "openwop.it.discovery.returns-200-with-a-parseable-openapi-3-1-document",
10573
10661
  "citations": [
@@ -10584,7 +10672,7 @@
10584
10672
  {
10585
10673
  "id": "openwop.it.discovery.host-claiming-auth-scoped-discovery-advertises-required-fields",
10586
10674
  "file": "discovery.test.ts",
10587
- "line": 207,
10675
+ "line": 211,
10588
10676
  "title": "host claiming auth-scoped discovery advertises required fields",
10589
10677
  "explicitId": "openwop.it.discovery.host-claiming-auth-scoped-discovery-advertises-required-fields",
10590
10678
  "citations": [
@@ -10605,7 +10693,7 @@
10605
10693
  {
10606
10694
  "id": "openwop.it.discovery.authenticated-discovery-preserves-required-capabilities-fields",
10607
10695
  "file": "discovery.test.ts",
10608
- "line": 243,
10696
+ "line": 247,
10609
10697
  "title": "authenticated discovery preserves required Capabilities fields",
10610
10698
  "explicitId": "openwop.it.discovery.authenticated-discovery-preserves-required-capabilities-fields",
10611
10699
  "citations": [
@@ -10627,7 +10715,7 @@
10627
10715
  {
10628
10716
  "id": "openwop.it.discovery.unauthorized-key-must-not-reveal-capabilities-outside-its-authorization",
10629
10717
  "file": "discovery.test.ts",
10630
- "line": 284,
10718
+ "line": 288,
10631
10719
  "title": "unauthorized key MUST NOT reveal capabilities outside its authorization",
10632
10720
  "explicitId": "openwop.it.discovery.unauthorized-key-must-not-reveal-capabilities-outside-its-authorization",
10633
10721
  "citations": [
@@ -11453,7 +11541,7 @@
11453
11541
  {
11454
11542
  "id": "openwop.it.envelope-completion-distinguishes-truncation.capabilities-envelopes-reliability-completion-when-present-conforms-to-rfc-0033",
11455
11543
  "file": "envelope-completion-distinguishes-truncation.test.ts",
11456
- "line": 103,
11544
+ "line": 104,
11457
11545
  "title": "capabilities.envelopes.reliability.completion (when present) conforms to RFC 0033 §E",
11458
11546
  "explicitId": "openwop.it.envelope-completion-distinguishes-truncation.capabilities-envelopes-reliability-completion-when-present-conforms-to-rfc-0033",
11459
11547
  "citations": [
@@ -11470,7 +11558,7 @@
11470
11558
  {
11471
11559
  "id": "openwop.it.envelope-completion-distinguishes-truncation.truncation-emits-envelope-truncated-envelope-retry-attempted-with-reason-truncat",
11472
11560
  "file": "envelope-completion-distinguishes-truncation.test.ts",
11473
- "line": 126,
11561
+ "line": 127,
11474
11562
  "title": "truncation: emits envelope.truncated + envelope.retry.attempted with reason: \"truncation\"",
11475
11563
  "explicitId": "openwop.it.envelope-completion-distinguishes-truncation.truncation-emits-envelope-truncated-envelope-retry-attempted-with-reason-truncat",
11476
11564
  "citations": [
@@ -11491,7 +11579,7 @@
11491
11579
  {
11492
11580
  "id": "openwop.it.envelope-completion-distinguishes-truncation.truncation-retry-budget-strictly-greater-than-initial-rfc-0033-b-truncationbudge",
11493
11581
  "file": "envelope-completion-distinguishes-truncation.test.ts",
11494
- "line": 151,
11582
+ "line": 152,
11495
11583
  "title": "truncation: retry budget strictly greater than initial (RFC 0033 §B truncationBudgetMultiplier)",
11496
11584
  "explicitId": "openwop.it.envelope-completion-distinguishes-truncation.truncation-retry-budget-strictly-greater-than-initial-rfc-0033-b-truncationbudge",
11497
11585
  "citations": [
@@ -11504,7 +11592,7 @@
11504
11592
  {
11505
11593
  "id": "openwop.it.envelope-completion-distinguishes-truncation.schema-violation-no-envelope-truncated-envelope-retry-attempted-reason-schema-vi",
11506
11594
  "file": "envelope-completion-distinguishes-truncation.test.ts",
11507
- "line": 175,
11595
+ "line": 176,
11508
11596
  "title": "schema-violation: NO envelope.truncated; envelope.retry.attempted reason ∈ {schema-violation, parse-error}",
11509
11597
  "explicitId": "openwop.it.envelope-completion-distinguishes-truncation.schema-violation-no-envelope-truncated-envelope-retry-attempted-reason-schema-vi",
11510
11598
  "citations": [
@@ -11521,13 +11609,18 @@
11521
11609
  {
11522
11610
  "id": "openwop.it.envelope-completion-distinguishes-truncation.schema-violation-retry-budget-unchanged-from-initial-no-budget-multiplication-on",
11523
11611
  "file": "envelope-completion-distinguishes-truncation.test.ts",
11524
- "line": 205,
11612
+ "line": 206,
11525
11613
  "title": "schema-violation: retry budget UNCHANGED from initial (no budget multiplication on this path)",
11526
11614
  "explicitId": "openwop.it.envelope-completion-distinguishes-truncation.schema-violation-retry-budget-unchanged-from-initial-no-budget-multiplication-on",
11527
11615
  "citations": [
11528
11616
  {
11529
11617
  "section": "RFCS/0033-envelope-completion-contract.md §C",
11530
11618
  "requirement": "schema-violation retry MUST NOT multiply maxTokens — budget stays at the original value (host default)"
11619
+ },
11620
+ {
11621
+ "section": "RFCS/0033-envelope-completion-contract.md §C",
11622
+ "requirement": null,
11623
+ "interpolated": true
11531
11624
  }
11532
11625
  ]
11533
11626
  },
@@ -12581,7 +12674,7 @@
12581
12674
  {
12582
12675
  "id": "openwop.it.eventOrdering.events-from-a-single-poll-have-non-decreasing-sequence-numbers",
12583
12676
  "file": "eventOrdering.test.ts",
12584
- "line": 46,
12677
+ "line": 53,
12585
12678
  "title": "events from a single poll have non-decreasing sequence numbers",
12586
12679
  "explicitId": "openwop.it.eventOrdering.events-from-a-single-poll-have-non-decreasing-sequence-numbers",
12587
12680
  "citations": [
@@ -12595,7 +12688,7 @@
12595
12688
  {
12596
12689
  "id": "openwop.it.eventOrdering.repeated-polls-of-a-terminal-run-yield-identical-event-sequences",
12597
12690
  "file": "eventOrdering.test.ts",
12598
- "line": 71,
12691
+ "line": 78,
12599
12692
  "title": "repeated polls of a terminal run yield identical event sequences",
12600
12693
  "explicitId": "openwop.it.eventOrdering.repeated-polls-of-a-terminal-run-yield-identical-event-sequences",
12601
12694
  "citations": [
@@ -12613,7 +12706,7 @@
12613
12706
  {
12614
12707
  "id": "openwop.it.eventOrdering.event-stream-contains-exactly-one-of-run-completed-run-failed-run-cancelled",
12615
12708
  "file": "eventOrdering.test.ts",
12616
- "line": 103,
12709
+ "line": 110,
12617
12710
  "title": "event stream contains exactly one of run.completed / run.failed / run.cancelled",
12618
12711
  "explicitId": "openwop.it.eventOrdering.event-stream-contains-exactly-one-of-run-completed-run-failed-run-cancelled",
12619
12712
  "citations": [
@@ -12626,7 +12719,7 @@
12626
12719
  {
12627
12720
  "id": "openwop.it.eventOrdering.the-terminal-event-is-the-last-event-in-the-stream",
12628
12721
  "file": "eventOrdering.test.ts",
12629
- "line": 124,
12722
+ "line": 131,
12630
12723
  "title": "the terminal event is the LAST event in the stream",
12631
12724
  "explicitId": "openwop.it.eventOrdering.the-terminal-event-is-the-last-event-in-the-stream",
12632
12725
  "citations": [
@@ -14226,19 +14319,19 @@
14226
14319
  "explicitId": "openwop.it.highConcurrency.10-parallel-requests-with-same-key-yield-one-runid-and-9-replays",
14227
14320
  "citations": [
14228
14321
  {
14229
- "section": "idempotency.md §Concurrent duplicates",
14322
+ "section": "spec/v1/idempotency.md §Concurrent duplicates",
14230
14323
  "requirement": "every concurrent request MUST resolve to either the cached response or a deterministic 409"
14231
14324
  },
14232
14325
  {
14233
- "section": "idempotency.md §Layer 1",
14326
+ "section": "spec/v1/idempotency.md §Layer 1",
14234
14327
  "requirement": "same idempotency key MUST yield exactly ONE runId across all successful responses"
14235
14328
  },
14236
14329
  {
14237
- "section": "idempotency.md",
14330
+ "section": "spec/v1/idempotency.md",
14238
14331
  "requirement": "409 on parallel idempotency-keyed retry MUST carry error=\"idempotency_in_flight\""
14239
14332
  },
14240
14333
  {
14241
- "section": "idempotency.md",
14334
+ "section": "spec/v1/idempotency.md",
14242
14335
  "requirement": "409 idempotency_in_flight MUST include a numeric retryAfter"
14243
14336
  }
14244
14337
  ]
@@ -14255,7 +14348,7 @@
14255
14348
  "requirement": "concurrent POST /v1/runs requests MUST resolve to either success or rate-limited"
14256
14349
  },
14257
14350
  {
14258
- "section": "idempotency.md §Layer 1",
14351
+ "section": "spec/v1/idempotency.md §Layer 1",
14259
14352
  "requirement": "distinct idempotency keys MUST yield distinct runIds (Layer 1 dedup is keyed)"
14260
14353
  },
14261
14354
  {
@@ -14276,15 +14369,15 @@
14276
14369
  "requirement": "host MUST handle ≥5 retries with same key 100ms apart without losing the cached response"
14277
14370
  },
14278
14371
  {
14279
- "section": "idempotency.md §Layer 1",
14372
+ "section": "spec/v1/idempotency.md §Layer 1",
14280
14373
  "requirement": "all 5 retries with same key MUST resolve to the same runId"
14281
14374
  },
14282
14375
  {
14283
- "section": "idempotency.md §Server responsibilities",
14376
+ "section": "spec/v1/idempotency.md §Server responsibilities",
14284
14377
  "requirement": "first request with new key MUST NOT be marked as replay"
14285
14378
  },
14286
14379
  {
14287
- "section": "idempotency.md §Server responsibilities #2",
14380
+ "section": "spec/v1/idempotency.md §Server responsibilities #2",
14288
14381
  "requirement": "replay responses SHOULD set openwop-Idempotent-Replay: true"
14289
14382
  }
14290
14383
  ]
@@ -14301,7 +14394,7 @@
14301
14394
  "requirement": "limits MUST be advertised in discovery"
14302
14395
  },
14303
14396
  {
14304
- "section": "idempotency.md",
14397
+ "section": "spec/v1/idempotency.md",
14305
14398
  "requirement": "limits.idempotencyAckTimeoutSec MUST be integer ≥5 when advertised"
14306
14399
  }
14307
14400
  ]
@@ -14491,7 +14584,7 @@
14491
14584
  "requirement": "fewer than two executors is not a race and cannot witness the rule"
14492
14585
  },
14493
14586
  {
14494
- "section": "idempotency.md §\"Idempotency key composition\" (Across a recovery boundary)",
14587
+ "section": "spec/v1/idempotency.md §\"Idempotency key composition\" (Across a recovery boundary)",
14495
14588
  "requirement": "all executors MUST mint one identity — differing ids mean they never collided, so a single delivery is a vacuous pass rather than a working claim"
14496
14589
  }
14497
14590
  ]
@@ -14508,7 +14601,7 @@
14508
14601
  "requirement": "the seam MUST report how many executors attempted the effect"
14509
14602
  },
14510
14603
  {
14511
- "section": "idempotency.md §\"Concurrent duplicates (Layer 2)\"",
14604
+ "section": "spec/v1/idempotency.md §\"Concurrent duplicates (Layer 2)\"",
14512
14605
  "requirement": "the engine MUST ensure at most one concurrent executor performs the external effect — the guarding persist MUST be an atomic claim, not a read-then-write"
14513
14606
  }
14514
14607
  ]
@@ -14529,7 +14622,7 @@
14529
14622
  "requirement": "the seam MUST report mintedIds, one per executor"
14530
14623
  },
14531
14624
  {
14532
- "section": "idempotency.md §\"Concurrent duplicates (Layer 2)\"",
14625
+ "section": "spec/v1/idempotency.md §\"Concurrent duplicates (Layer 2)\"",
14533
14626
  "requirement": "exactly one effect regardless of how many executors race — at most one wins the compare-and-set, the rest observe the hit"
14534
14627
  },
14535
14628
  {
@@ -14537,7 +14630,7 @@
14537
14630
  "requirement": "mintedIds length MUST equal attempted"
14538
14631
  },
14539
14632
  {
14540
- "section": "idempotency.md §\"Idempotency key composition\"",
14633
+ "section": "spec/v1/idempotency.md §\"Idempotency key composition\"",
14541
14634
  "requirement": "one identity across all executors at any concurrency"
14542
14635
  }
14543
14636
  ]
@@ -14558,8 +14651,8 @@
14558
14651
  "explicitId": "openwop.it.idempotency-key-determinism.default-mode-composite-identical-runid-nodeid-payload-produces-identical-keys",
14559
14652
  "citations": [
14560
14653
  {
14561
- "section": "idempotency.md §\"Idempotency-Key",
14562
- "requirement": "idempotency.md §Idempotency-Key: same logical request MUST produce same key"
14654
+ "section": "spec/v1/idempotency.md §\"Idempotency-Key",
14655
+ "requirement": "spec/v1/idempotency.md §Idempotency-Key: same logical request MUST produce same key"
14563
14656
  }
14564
14657
  ]
14565
14658
  },
@@ -14571,7 +14664,7 @@
14571
14664
  "explicitId": "openwop.it.idempotency-key-determinism.payload-sensitivity-different-payload-produces-different-key",
14572
14665
  "citations": [
14573
14666
  {
14574
- "section": "idempotency.md §\"Idempotency-Key",
14667
+ "section": "spec/v1/idempotency.md §\"Idempotency-Key",
14575
14668
  "requirement": "payload sensitivity — different payload produces different key"
14576
14669
  }
14577
14670
  ]
@@ -14584,7 +14677,7 @@
14584
14677
  "explicitId": "openwop.it.idempotency-key-determinism.run-isolation-different-runid-produces-different-key",
14585
14678
  "citations": [
14586
14679
  {
14587
- "section": "idempotency.md §\"Idempotency-Key",
14680
+ "section": "spec/v1/idempotency.md §\"Idempotency-Key",
14588
14681
  "requirement": "run isolation — different runId produces different key"
14589
14682
  }
14590
14683
  ]
@@ -14597,7 +14690,7 @@
14597
14690
  "explicitId": "openwop.it.idempotency-key-determinism.node-isolation-different-nodeid-produces-different-key",
14598
14691
  "citations": [
14599
14692
  {
14600
- "section": "idempotency.md §\"Idempotency-Key",
14693
+ "section": "spec/v1/idempotency.md §\"Idempotency-Key",
14601
14694
  "requirement": "node isolation — different nodeId produces different key"
14602
14695
  }
14603
14696
  ]
@@ -14610,7 +14703,7 @@
14610
14703
  "explicitId": "openwop.it.idempotency-key-determinism.hash-mode-is-deterministic-in-the-payload-alone-run-node-ignored",
14611
14704
  "citations": [
14612
14705
  {
14613
- "section": "idempotency.md §\"Idempotency-Key",
14706
+ "section": "spec/v1/idempotency.md §\"Idempotency-Key",
14614
14707
  "requirement": "hash mode MUST ignore run/node — useful for global remote-dedup caches"
14615
14708
  }
14616
14709
  ]
@@ -14623,7 +14716,7 @@
14623
14716
  "explicitId": "openwop.it.idempotency-key-determinism.output-shape-every-emitted-key-matches-openwop-sha256-prefix-16",
14624
14717
  "citations": [
14625
14718
  {
14626
- "section": "idempotency.md §\"Idempotency-Key",
14719
+ "section": "spec/v1/idempotency.md §\"Idempotency-Key",
14627
14720
  "requirement": null,
14628
14721
  "interpolated": true
14629
14722
  }
@@ -14637,7 +14730,7 @@
14637
14730
  "explicitId": "openwop.it.idempotency-key-determinism.uuid-mode-rejects-with-config-invalid-safety-fix-per-1-1-2",
14638
14731
  "citations": [
14639
14732
  {
14640
- "section": "idempotency.md §\"Idempotency-Key",
14733
+ "section": "spec/v1/idempotency.md §\"Idempotency-Key",
14641
14734
  "requirement": "mode: uuid MUST be rejected — the 1.1.0/1.1.1 non-deterministic default was removed"
14642
14735
  }
14643
14736
  ]
@@ -14650,7 +14743,7 @@
14650
14743
  "explicitId": "openwop.it.idempotency-key-determinism.cross-impl-invariant-pack-output-equals-canonical-sha-256-formula",
14651
14744
  "citations": [
14652
14745
  {
14653
- "section": "idempotency.md §\"Idempotency-Key",
14746
+ "section": "spec/v1/idempotency.md §\"Idempotency-Key",
14654
14747
  "requirement": null,
14655
14748
  "interpolated": true
14656
14749
  }
@@ -14668,11 +14761,11 @@
14668
14761
  "requirement": "first POST /v1/runs MUST return 201"
14669
14762
  },
14670
14763
  {
14671
- "section": "idempotency.md §Layer 1",
14764
+ "section": "spec/v1/idempotency.md §Layer 1",
14672
14765
  "requirement": "replay request with same key + same body MUST return success status (200/201)"
14673
14766
  },
14674
14767
  {
14675
- "section": "idempotency.md §Layer 1",
14768
+ "section": "spec/v1/idempotency.md §Layer 1",
14676
14769
  "requirement": "replay MUST return the SAME runId (no new run created)"
14677
14770
  },
14678
14771
  {
@@ -14689,16 +14782,16 @@
14689
14782
  "explicitId": "openwop.it.idempotency.returns-409-when-the-body-changes-under-the-same-key",
14690
14783
  "citations": [
14691
14784
  {
14692
- "section": "idempotency.md §Layer 1",
14785
+ "section": "spec/v1/idempotency.md §Layer 1",
14693
14786
  "requirement": "same Idempotency-Key with a different body MUST return 409"
14694
14787
  },
14695
14788
  {
14696
- "section": "idempotency.md §\"Record shape, digest, and lease\"",
14789
+ "section": "spec/v1/idempotency.md §\"Record shape, digest, and lease\"",
14697
14790
  "requirement": null,
14698
14791
  "interpolated": true
14699
14792
  },
14700
14793
  {
14701
- "section": "idempotency.md §\"Record shape, digest, and lease\"",
14794
+ "section": "spec/v1/idempotency.md §\"Record shape, digest, and lease\"",
14702
14795
  "requirement": "a digest mismatch MUST NOT return the cached body (no runId on the 409)"
14703
14796
  }
14704
14797
  ]
@@ -14715,19 +14808,19 @@
14715
14808
  "requirement": "first POST /v1/runs returns 201"
14716
14809
  },
14717
14810
  {
14718
- "section": "idempotency.md §Server responsibilities",
14811
+ "section": "spec/v1/idempotency.md §Server responsibilities",
14719
14812
  "requirement": "openwop-Idempotent-Replay value MUST be \"true\" or \"false\""
14720
14813
  },
14721
14814
  {
14722
- "section": "idempotency.md §Layer 1",
14815
+ "section": "spec/v1/idempotency.md §Layer 1",
14723
14816
  "requirement": "replay returns 200 or 201"
14724
14817
  },
14725
14818
  {
14726
- "section": "idempotency.md §Server responsibilities #2",
14819
+ "section": "spec/v1/idempotency.md §Server responsibilities #2",
14727
14820
  "requirement": "openwop-Idempotent-Replay SHOULD be set on idempotent replay responses"
14728
14821
  },
14729
14822
  {
14730
- "section": "idempotency.md §Server responsibilities #2",
14823
+ "section": "spec/v1/idempotency.md §Server responsibilities #2",
14731
14824
  "requirement": "openwop-Idempotent-Replay on replay MUST be \"true\""
14732
14825
  }
14733
14826
  ]
@@ -14744,7 +14837,7 @@
14744
14837
  "requirement": "host MUST handle ≥5 retries 100ms apart without losing the cached response"
14745
14838
  },
14746
14839
  {
14747
- "section": "idempotency.md §Layer 1",
14840
+ "section": "spec/v1/idempotency.md §Layer 1",
14748
14841
  "requirement": "5 retries with same key MUST collapse to exactly one runId"
14749
14842
  }
14750
14843
  ]
@@ -14757,11 +14850,11 @@
14757
14850
  "explicitId": "openwop.it.idempotencyRetry.host-advertising-idempotencyacktimeoutsec-sets-integer-5",
14758
14851
  "citations": [
14759
14852
  {
14760
- "section": "idempotency.md",
14853
+ "section": "spec/v1/idempotency.md",
14761
14854
  "requirement": "limits.idempotencyAckTimeoutSec MUST be an integer when advertised"
14762
14855
  },
14763
14856
  {
14764
- "section": "idempotency.md",
14857
+ "section": "spec/v1/idempotency.md",
14765
14858
  "requirement": "limits.idempotencyAckTimeoutSec MUST be ≥ 5"
14766
14859
  }
14767
14860
  ]
@@ -15308,7 +15401,7 @@
15308
15401
  {
15309
15402
  "id": "openwop.it.interrupt-token-matrix.unknown-token-returns-404-on-post",
15310
15403
  "file": "interrupt-token-matrix.test.ts",
15311
- "line": 118,
15404
+ "line": 131,
15312
15405
  "title": "unknown token returns 404 on POST",
15313
15406
  "explicitId": "openwop.it.interrupt-token-matrix.unknown-token-returns-404-on-post",
15314
15407
  "citations": [
@@ -16196,7 +16289,7 @@
16196
16289
  {
16197
16290
  "id": "openwop.it.mcp-current-auth-boundary.a-mount-that-requires-oauth-lane-authentication-offers-resource-metadata-or-a-pa",
16198
16291
  "file": "mcp-current-auth-boundary.test.ts",
16199
- "line": 97,
16292
+ "line": 100,
16200
16293
  "title": "a mount that requires OAuth-lane authentication offers resource_metadata or a path-inserted PRM",
16201
16294
  "explicitId": "openwop.it.mcp-current-auth-boundary.a-mount-that-requires-oauth-lane-authentication-offers-resource-metadata-or-a-path-inserted-prm",
16202
16295
  "citations": [
@@ -16260,10 +16353,6 @@
16260
16353
  "section": "host-sample-test-seams.md §23",
16261
16354
  "requirement": "the host MUST have called the tool"
16262
16355
  },
16263
- {
16264
- "section": "host-sample-test-seams.md §23",
16265
- "requirement": "the seam SHOULD report `extensionAuthority: { scopesWidened, approvalAdvanced }` for scenario \"extension-asserts-authority\"; until it does the requirement is `blocked`, not passed"
16266
- },
16267
16356
  {
16268
16357
  "section": "mcp-integration.md §D",
16269
16358
  "requirement": "an extension MUST NOT gain tool authority or scope by appearing in _meta (mcp-extension-no-authority)"
@@ -16277,7 +16366,7 @@
16277
16366
  {
16278
16367
  "id": "openwop.it.mcp-extension-opacity.server-half-unknown-meta-extension-keys-on-a-request-are-ignored-not-refused-and",
16279
16368
  "file": "mcp-extension-opacity.test.ts",
16280
- "line": 67,
16369
+ "line": 68,
16281
16370
  "title": "server half: unknown _meta extension keys on a request are ignored, not refused and not honoured",
16282
16371
  "explicitId": "openwop.it.mcp-extension-opacity.server-half-unknown-meta-extension-keys-on-a-request-are-ignored-not-refused-and",
16283
16372
  "citations": [
@@ -16298,10 +16387,6 @@
16298
16387
  "section": "RFCS/0153 §C",
16299
16388
  "requirement": "the host MUST have called the tool at least once for this leg to mean anything"
16300
16389
  },
16301
- {
16302
- "section": "host-sample-test-seams.md §23",
16303
- "requirement": "the invoke seam SHOULD report `mrtr: { inputRequiredSeen, retried, requestStateEchoed, result }` for tool \"needs_input\"; until it does this requirement is unobservable and resolves to `blocked`"
16304
- },
16305
16390
  {
16306
16391
  "section": "mcp-integration.md §C.1",
16307
16392
  "requirement": "the host MUST recognise resultType input_required"
@@ -16335,7 +16420,7 @@
16335
16420
  {
16336
16421
  "id": "openwop.it.mcp-mrtr-roundtrip.a-suspending-tool-answers-input-required-with-elicitation-requeststate-the-retry",
16337
16422
  "file": "mcp-mrtr-roundtrip.test.ts",
16338
- "line": 95,
16423
+ "line": 96,
16339
16424
  "title": "a suspending tool answers input_required with elicitation + requestState; the retry resolves it; a forged requestState is refused",
16340
16425
  "explicitId": "openwop.it.mcp-mrtr-roundtrip.a-suspending-tool-answers-input-required-with-elicitation-requeststate-the-retry",
16341
16426
  "citations": [
@@ -16744,11 +16829,6 @@
16744
16829
  "title": "outbound calls carry MCP-Protocol-Version in date form",
16745
16830
  "explicitId": "openwop.it.mcp-version-negotiation.outbound-calls-carry-mcp-protocol-version-in-date-form",
16746
16831
  "citations": [
16747
- {
16748
- "section": "RFCS/0153 §B",
16749
- "requirement": null,
16750
- "interpolated": true
16751
- },
16752
16832
  {
16753
16833
  "section": "RFCS/0153 §B",
16754
16834
  "requirement": "the host MUST have called the server"
@@ -16767,7 +16847,7 @@
16767
16847
  {
16768
16848
  "id": "openwop.it.mcp-version-negotiation.the-negotiated-revision-is-one-the-host-advertises",
16769
16849
  "file": "mcp-version-negotiation.test.ts",
16770
- "line": 122,
16850
+ "line": 117,
16771
16851
  "title": "the negotiated revision is one the host advertises",
16772
16852
  "explicitId": "openwop.it.mcp-version-negotiation.the-negotiated-revision-is-one-the-host-advertises",
16773
16853
  "citations": [
@@ -16781,7 +16861,7 @@
16781
16861
  {
16782
16862
  "id": "openwop.it.mcp-version-negotiation.an-unsupported-revision-fails-through-the-canonical-interop-envelope",
16783
16863
  "file": "mcp-version-negotiation.test.ts",
16784
- "line": 146,
16864
+ "line": 141,
16785
16865
  "title": "an unsupported revision fails through the canonical interop envelope",
16786
16866
  "explicitId": "openwop.it.mcp-version-negotiation.an-unsupported-revision-fails-through-the-canonical-interop-envelope",
16787
16867
  "citations": [
@@ -18034,11 +18114,11 @@
18034
18114
  "explicitId": "openwop.it.multi-region-idempotency-behavior.two-region-conflict-resolves-to-the-lex-min-runid-per-annex-convergence-rule",
18035
18115
  "citations": [
18036
18116
  {
18037
- "section": "idempotency.md §\"Multi-region idempotency annex\"",
18117
+ "section": "spec/v1/idempotency.md §\"Multi-region idempotency annex\"",
18038
18118
  "requirement": "simulate-partition seam MUST return 200 when ≥2 conflicting claims are submitted"
18039
18119
  },
18040
18120
  {
18041
- "section": "idempotency.md §\"Convergence rule\"",
18121
+ "section": "spec/v1/idempotency.md §\"Convergence rule\"",
18042
18122
  "requirement": "winner MUST be the lex-min runId (run-a-west < run-b-east)"
18043
18123
  }
18044
18124
  ]
@@ -18051,11 +18131,11 @@
18051
18131
  "explicitId": "openwop.it.multi-region-idempotency-behavior.three-region-partition-resolves-to-a-single-winner",
18052
18132
  "citations": [
18053
18133
  {
18054
- "section": "idempotency.md §\"Convergence rule\"",
18134
+ "section": "spec/v1/idempotency.md §\"Convergence rule\"",
18055
18135
  "requirement": "winner MUST be the lex-min runId across all conflicting claims"
18056
18136
  },
18057
18137
  {
18058
- "section": "idempotency.md §\"Convergence rule\"",
18138
+ "section": "spec/v1/idempotency.md §\"Convergence rule\"",
18059
18139
  "requirement": "losers array MUST contain N-1 entries when N claims conflict"
18060
18140
  }
18061
18141
  ]
@@ -18068,11 +18148,11 @@
18068
18148
  "explicitId": "openwop.it.multi-region-idempotency-behavior.every-region-gets-a-cache-redirect-entry-pointing-at-the-winner",
18069
18149
  "citations": [
18070
18150
  {
18071
- "section": "idempotency.md §\"Convergence rule\"",
18151
+ "section": "spec/v1/idempotency.md §\"Convergence rule\"",
18072
18152
  "requirement": "cacheRedirects MUST contain one entry per claim (including the winner)"
18073
18153
  },
18074
18154
  {
18075
- "section": "idempotency.md §\"Convergence rule\"",
18155
+ "section": "spec/v1/idempotency.md §\"Convergence rule\"",
18076
18156
  "requirement": "every cache redirect MUST point at the winner runId"
18077
18157
  }
18078
18158
  ]
@@ -18085,7 +18165,7 @@
18085
18165
  "explicitId": "openwop.it.multi-region-idempotency-behavior.loser-cancel-reason-must-be-the-canonical-cross-region-dedup-loss-string",
18086
18166
  "citations": [
18087
18167
  {
18088
- "section": "idempotency.md §\"Convergence rule\"",
18168
+ "section": "spec/v1/idempotency.md §\"Convergence rule\"",
18089
18169
  "requirement": "loserCancelReason MUST be the canonical `cross_region_dedup_loss` string"
18090
18170
  }
18091
18171
  ]
@@ -18098,7 +18178,7 @@
18098
18178
  "explicitId": "openwop.it.multi-region-idempotency-behavior.resolver-is-order-invariant-shuffled-inputs-produce-the-same-winner",
18099
18179
  "citations": [
18100
18180
  {
18101
- "section": "idempotency.md §\"Convergence rule\" — determinism",
18181
+ "section": "spec/v1/idempotency.md §\"Convergence rule\" — determinism",
18102
18182
  "requirement": "resolver MUST be order-invariant; all permutations MUST produce the same lex-min winner"
18103
18183
  }
18104
18184
  ]
@@ -18111,7 +18191,7 @@
18111
18191
  "explicitId": "openwop.it.multi-region-idempotency-behavior.mismatched-tuple-rejects-with-400-validation-error",
18112
18192
  "citations": [
18113
18193
  {
18114
- "section": "idempotency.md §\"Convergence rule\"",
18194
+ "section": "spec/v1/idempotency.md §\"Convergence rule\"",
18115
18195
  "requirement": "claims with non-matching (tenantId, endpoint, key) MUST be rejected — it would be a programming error in the caller"
18116
18196
  }
18117
18197
  ]
@@ -18124,7 +18204,7 @@
18124
18204
  "explicitId": "openwop.it.multi-region-idempotency.idempotency-crossregion-when-advertised-must-be-one-of-the-closed-enum",
18125
18205
  "citations": [
18126
18206
  {
18127
- "section": "idempotency.md §\"Multi-region idempotency\" §\"Capability advertisement\"",
18207
+ "section": "spec/v1/idempotency.md §\"Multi-region idempotency\" §\"Capability advertisement\"",
18128
18208
  "requirement": "crossRegion MUST be one of {\"single-region\",\"reconciled-records\",\"fenced-effects\"}"
18129
18209
  }
18130
18210
  ]
@@ -18137,7 +18217,7 @@
18137
18217
  "explicitId": "openwop.it.multi-region-idempotency.multi-region-hosts-should-expose-the-cross-region-conflict-counter-per-operator",
18138
18218
  "citations": [
18139
18219
  {
18140
- "section": "idempotency.md §\"Operator surface\"",
18220
+ "section": "spec/v1/idempotency.md §\"Operator surface\"",
18141
18221
  "requirement": null,
18142
18222
  "interpolated": true
18143
18223
  }
@@ -19345,7 +19425,7 @@
19345
19425
  {
19346
19426
  "id": "openwop.it.pause-resume.pause-transitions-to-paused-resume-returns-the-run-to-running",
19347
19427
  "file": "pause-resume.test.ts",
19348
- "line": 62,
19428
+ "line": 81,
19349
19429
  "title": "pause transitions to paused; resume returns the run to running",
19350
19430
  "explicitId": "openwop.it.pause-resume.pause-transitions-to-paused-resume-returns-the-run-to-running",
19351
19431
  "citations": [
@@ -19362,7 +19442,7 @@
19362
19442
  {
19363
19443
  "id": "openwop.it.pause-resume.resuming-a-running-not-paused-run-returns-409-with-details-runstatus",
19364
19444
  "file": "pause-resume.test.ts",
19365
- "line": 110,
19445
+ "line": 129,
19366
19446
  "title": "resuming a running (not paused) run returns 409 with details.runStatus",
19367
19447
  "explicitId": "openwop.it.pause-resume.resuming-a-running-not-paused-run-returns-409-with-details-runstatus",
19368
19448
  "citations": [
@@ -19379,7 +19459,7 @@
19379
19459
  {
19380
19460
  "id": "openwop.it.pause-resume.pause-on-an-already-paused-run-returns-409-with-details-runstatus-paused-unless",
19381
19461
  "file": "pause-resume.test.ts",
19382
- "line": 144,
19462
+ "line": 163,
19383
19463
  "title": ":pause on an already-paused run returns 409 with details.runStatus paused, unless the request carries the original Idempotency-Key",
19384
19464
  "explicitId": "openwop.it.pause-resume.pause-on-an-already-paused-run-returns-409-with-details-runstatus-paused-unless",
19385
19465
  "citations": [
@@ -19408,7 +19488,7 @@
19408
19488
  {
19409
19489
  "id": "openwop.it.pause-resume.pause-on-a-completed-cancelled-failed-run-must-return-409",
19410
19490
  "file": "pause-resume.test.ts",
19411
- "line": 205,
19491
+ "line": 224,
19412
19492
  "title": ":pause on a completed/cancelled/failed run MUST return 409",
19413
19493
  "explicitId": "openwop.it.pause-resume.pause-on-a-completed-cancelled-failed-run-must-return-409",
19414
19494
  "citations": [
@@ -19421,7 +19501,7 @@
19421
19501
  {
19422
19502
  "id": "openwop.it.pause-resume.under-drain-current-node-node-completed-precedes-run-paused-in-the-log",
19423
19503
  "file": "pause-resume.test.ts",
19424
- "line": 229,
19504
+ "line": 248,
19425
19505
  "title": "under drain-current-node node.completed precedes run.paused in the log",
19426
19506
  "explicitId": "openwop.it.pause-resume.under-drain-current-node-node-completed-precedes-run-paused-in-the-log",
19427
19507
  "citations": [
@@ -19439,7 +19519,7 @@
19439
19519
  {
19440
19520
  "id": "openwop.it.pause-resume.pause-must-not-silently-override-an-active-interrupt-suspend",
19441
19521
  "file": "pause-resume.test.ts",
19442
- "line": 268,
19522
+ "line": 287,
19443
19523
  "title": ":pause MUST NOT silently override an active interrupt suspend",
19444
19524
  "explicitId": "openwop.it.pause-resume.pause-must-not-silently-override-an-active-interrupt-suspend",
19445
19525
  "citations": [
@@ -19456,7 +19536,7 @@
19456
19536
  {
19457
19537
  "id": "openwop.it.pause-resume.every-drainpolicy-advertised-by-the-host-is-accepted-on-pause",
19458
19538
  "file": "pause-resume.test.ts",
19459
- "line": 324,
19539
+ "line": 343,
19460
19540
  "title": "every drainPolicy advertised by the host is accepted on :pause",
19461
19541
  "explicitId": "openwop.it.pause-resume.every-drainpolicy-advertised-by-the-host-is-accepted-on-pause",
19462
19542
  "citations": [
@@ -20771,17 +20851,21 @@
20771
20851
  {
20772
20852
  "id": "openwop.it.prompt-read-workspace-membership-enforced.get-v1-prompts-workspaceid-non-member-must-refuse-or-return-empty-templates-neve",
20773
20853
  "file": "prompt-read-workspace-membership-enforced.test.ts",
20774
- "line": 101,
20854
+ "line": 102,
20775
20855
  "title": "GET /v1/prompts?workspaceId=<non-member> MUST refuse OR return empty templates[] — never another workspace's content",
20776
20856
  "explicitId": "openwop.it.prompt-read-workspace-membership-enforced.get-v1-prompts-workspaceid-non-member-must-refuse-or-return-empty-templates-neve",
20777
20857
  "citations": [
20778
20858
  {
20779
- "section": "spec/v1/rest-endpoints.md §Common error codes — workspace_membership_required",
20859
+ "section": "spec/v1/prompts.md §Workspace membership on workspace-scoped reads and writes",
20780
20860
  "requirement": null,
20781
20861
  "interpolated": true
20782
20862
  },
20783
20863
  {
20784
20864
  "section": "spec/v1/prompts.md §Workspace membership on workspace-scoped reads and writes",
20865
+ "requirement": "a workspace-scoped read for a non-member workspace MUST be refused (4xx) or return no templates"
20866
+ },
20867
+ {
20868
+ "section": "spec/v1/rest-endpoints.md §Common error codes — workspace_membership_required",
20785
20869
  "requirement": null,
20786
20870
  "interpolated": true
20787
20871
  }
@@ -21987,7 +22071,7 @@
21987
22071
  {
21988
22072
  "id": "openwop.it.redaction.aiproviders-is-well-formed-when-present-byok-supported",
21989
22073
  "file": "redaction.test.ts",
21990
- "line": 117,
22074
+ "line": 119,
21991
22075
  "title": "aiProviders is well-formed when present (byok ⊆ supported)",
21992
22076
  "explicitId": "openwop.it.redaction.aiproviders-is-well-formed-when-present-byok-supported",
21993
22077
  "citations": [
@@ -22001,7 +22085,7 @@
22001
22085
  {
22002
22086
  "id": "openwop.it.redaction.canary-s-planted-in-authorization-header-is-not-echoed-in-401-body",
22003
22087
  "file": "redaction.test.ts",
22004
- "line": 148,
22088
+ "line": 150,
22005
22089
  "title": "canary \"%s\" planted in Authorization header is not echoed in 401 body",
22006
22090
  "explicitId": null,
22007
22091
  "citations": []
@@ -22009,7 +22093,7 @@
22009
22093
  {
22010
22094
  "id": "openwop.it.redaction.the-marker-substring-alone-never-appears-in-a-401-body-universal",
22011
22095
  "file": "redaction.test.ts",
22012
- "line": 172,
22096
+ "line": 174,
22013
22097
  "title": "the marker substring alone never appears in a 401 body (universal)",
22014
22098
  "explicitId": "openwop.it.redaction.the-marker-substring-alone-never-appears-in-a-401-body-universal",
22015
22099
  "citations": [
@@ -22022,7 +22106,7 @@
22022
22106
  {
22023
22107
  "id": "openwop.it.redaction.skips-when-host-does-not-advertise-secrets-supported",
22024
22108
  "file": "redaction.test.ts",
22025
- "line": 189,
22109
+ "line": 191,
22026
22110
  "title": "skips when host does NOT advertise secrets.supported",
22027
22111
  "explicitId": "openwop.it.redaction.skips-when-host-does-not-advertise-secrets-supported",
22028
22112
  "citations": [
@@ -22056,7 +22140,7 @@
22056
22140
  {
22057
22141
  "id": "openwop.it.redactionAdversarial.jwt-shaped-canary-in-workflowid-of-a-404-failing-request-must-not-echo-verbatim",
22058
22142
  "file": "redactionAdversarial.test.ts",
22059
- "line": 97,
22143
+ "line": 98,
22060
22144
  "title": "JWT-shaped canary in workflowId of a 404-failing request MUST NOT echo verbatim in error response",
22061
22145
  "explicitId": "openwop.it.redactionAdversarial.jwt-shaped-canary-in-workflowid-of-a-404-failing-request-must-not-echo-verbatim",
22062
22146
  "citations": [
@@ -22073,7 +22157,7 @@
22073
22157
  {
22074
22158
  "id": "openwop.it.redactionAdversarial.anthropic-shaped-canary-embedded-in-non-credential-input-must-not-appear-verbati",
22075
22159
  "file": "redactionAdversarial.test.ts",
22076
- "line": 123,
22160
+ "line": 124,
22077
22161
  "title": "Anthropic-shaped canary embedded in non-credential input MUST NOT appear verbatim in events",
22078
22162
  "explicitId": "openwop.it.redactionAdversarial.anthropic-shaped-canary-embedded-in-non-credential-input-must-not-appear-verbati",
22079
22163
  "citations": [
@@ -22086,7 +22170,7 @@
22086
22170
  {
22087
22171
  "id": "openwop.it.redactionAdversarial.every-canary-in-canaries-has-the-marker-substring",
22088
22172
  "file": "redactionAdversarial.test.ts",
22089
- "line": 152,
22173
+ "line": 153,
22090
22174
  "title": "every canary in CANARIES has the marker substring",
22091
22175
  "explicitId": "openwop.it.redactionAdversarial.every-canary-in-canaries-has-the-marker-substring",
22092
22176
  "citations": [
@@ -22239,7 +22323,7 @@
22239
22323
  {
22240
22324
  "id": "openwop.it.replay-divergence-at-refusal.phase-4-host-must-emit-replay-divergedatrefusal-fail-with-replay-diverged-at-ref~2",
22241
22325
  "file": "replay-divergence-at-refusal.test.ts",
22242
- "line": 320,
22326
+ "line": 323,
22243
22327
  "title": "Phase 4 host MUST emit replay.divergedAtRefusal + fail with replay_diverged_at_refusal when original=refusal + replay=valid (symmetric case)",
22244
22328
  "explicitId": "openwop.it.replay-divergence-at-refusal.phase-4-host-must-emit-replay-divergedatrefusal-fail-with-replay-diverged-at-ref~2",
22245
22329
  "citations": [
@@ -22867,7 +22951,7 @@
22867
22951
  {
22868
22952
  "id": "openwop.it.replayDeterminism.branch-mode-does-not-need-to-produce-identical-event-sequences-negative-control",
22869
22953
  "file": "replayDeterminism.test.ts",
22870
- "line": 156,
22954
+ "line": 161,
22871
22955
  "title": "branch mode does NOT need to produce identical event sequences (negative-control)",
22872
22956
  "explicitId": "openwop.it.replayDeterminism.branch-mode-does-not-need-to-produce-identical-event-sequences-negative-control",
22873
22957
  "citations": [
@@ -23521,7 +23605,7 @@
23521
23605
  {
23522
23606
  "id": "openwop.it.runner-ledger.files-that-finished-before-this-one-appear-in-the-ledger-file-with-an-assertion",
23523
23607
  "file": "runner-ledger.test.ts",
23524
- "line": 270,
23608
+ "line": 274,
23525
23609
  "title": "files that finished before this one appear in the ledger file with an assertion count",
23526
23610
  "explicitId": "openwop.it.runner-ledger.files-that-finished-before-this-one-appear-in-the-ledger-file-with-an-assertion",
23527
23611
  "citations": [
@@ -23614,7 +23698,7 @@
23614
23698
  {
23615
23699
  "id": "openwop.it.runtime-capabilities.terminates-the-run-with-error-code-capability-not-provided",
23616
23700
  "file": "runtime-capabilities.test.ts",
23617
- "line": 92,
23701
+ "line": 94,
23618
23702
  "title": "terminates the run with error.code = capability_not_provided",
23619
23703
  "explicitId": "openwop.it.runtime-capabilities.terminates-the-run-with-error-code-capability-not-provided",
23620
23704
  "citations": [
@@ -25729,7 +25813,7 @@
25729
25813
  {
25730
25814
  "id": "openwop.it.tool-catalog-projection.advisory-should-an-unchanged-catalog-reads-identically-sorted-by-toolid",
25731
25815
  "file": "tool-catalog-projection.test.ts",
25732
- "line": 164,
25816
+ "line": 167,
25733
25817
  "title": "advisory (SHOULD): an unchanged catalog reads identically, sorted by toolId",
25734
25818
  "explicitId": "openwop.it.tool-catalog-projection.advisory-should-an-unchanged-catalog-reads-identically-sorted-by-toolid",
25735
25819
  "citations": [
@@ -27581,6 +27665,20 @@
27581
27665
  }
27582
27666
  ]
27583
27667
  },
27668
+ {
27669
+ "id": "openwop.it.v2-a2ui-v09-surface.a-version-2-surface-is-admitted-and-a-version-1-body-under-schema-version-2-is-r",
27670
+ "file": "v2-a2ui-v09-surface.test.ts",
27671
+ "line": 311,
27672
+ "title": "a version-2 surface is admitted and a version-1 body under schema version 2 is refused, in the same run",
27673
+ "explicitId": "openwop.family.a2uiSurface",
27674
+ "citations": [
27675
+ {
27676
+ "section": "spec/v2/ext/a2uiSurface/README.md §Conformance",
27677
+ "requirement": null,
27678
+ "interpolated": true
27679
+ }
27680
+ ]
27681
+ },
27584
27682
  {
27585
27683
  "id": "openwop.it.v2-advertised-fixtures-exist.a-sampled-advertised-fixture-is-actually-creatable-not-just-listed",
27586
27684
  "file": "v2-advertised-fixtures-exist.test.ts",
@@ -28256,6 +28354,86 @@
28256
28354
  }
28257
28355
  ]
28258
28356
  },
28357
+ {
28358
+ "id": "openwop.it.v2-client-version-header.a-client-at-the-floor-is-not-below-it-equal-on-major-minor-the-patch-never-decid",
28359
+ "file": "v2-client-version-header.test.ts",
28360
+ "line": 79,
28361
+ "title": "a client at the floor is not below it: equal on major.minor, the patch never decides",
28362
+ "explicitId": "openwop.requirement.0219.floor-comparison",
28363
+ "citations": [
28364
+ {
28365
+ "section": "spec/v2/core/versioning.md §1.5",
28366
+ "requirement": null,
28367
+ "interpolated": true
28368
+ },
28369
+ {
28370
+ "section": "spec/v2/core/versioning.md §1.5",
28371
+ "requirement": null,
28372
+ "interpolated": true
28373
+ }
28374
+ ]
28375
+ },
28376
+ {
28377
+ "id": "openwop.it.v2-client-version-header.a-malformed-openwop-client-version-is-treated-as-absent-never-426-never-400",
28378
+ "file": "v2-client-version-header.test.ts",
28379
+ "line": 90,
28380
+ "title": "a malformed OpenWOP-Client-Version is treated as absent: never 426, never 400",
28381
+ "explicitId": "openwop.requirement.0219.malformed-not-refused",
28382
+ "citations": [
28383
+ {
28384
+ "section": "spec/v2/core/versioning.md §1.5",
28385
+ "requirement": null,
28386
+ "interpolated": true
28387
+ },
28388
+ {
28389
+ "section": "spec/v2/core/versioning.md §1.5",
28390
+ "requirement": null,
28391
+ "interpolated": true
28392
+ },
28393
+ {
28394
+ "section": "spec/v2/core/versioning.md §1.5",
28395
+ "requirement": null,
28396
+ "interpolated": true
28397
+ }
28398
+ ]
28399
+ },
28400
+ {
28401
+ "id": "openwop.it.v2-client-version-header.a-request-without-openwop-client-version-is-served-where-a-below-floor-one-is-re",
28402
+ "file": "v2-client-version-header.test.ts",
28403
+ "line": 102,
28404
+ "title": "a request without OpenWOP-Client-Version is served where a below-floor one is refused",
28405
+ "explicitId": "openwop.requirement.0219.absent-not-refused",
28406
+ "citations": [
28407
+ {
28408
+ "section": "spec/v2/core/versioning.md §1.5",
28409
+ "requirement": "a host MUST NOT answer 426 client_version_unsupported to a request that carries no OpenWOP-Client-Version"
28410
+ },
28411
+ {
28412
+ "section": "spec/v2/core/versioning.md §1.5",
28413
+ "requirement": null,
28414
+ "interpolated": true
28415
+ }
28416
+ ]
28417
+ },
28418
+ {
28419
+ "id": "openwop.it.v2-client-version-header.a-host-that-advertises-no-minclientversion-refuses-no-client-on-version-grounds",
28420
+ "file": "v2-client-version-header.test.ts",
28421
+ "line": 115,
28422
+ "title": "a host that advertises no minClientVersion refuses no client on version grounds",
28423
+ "explicitId": "openwop.requirement.0219.no-floor-no-refusal",
28424
+ "citations": [
28425
+ {
28426
+ "section": "spec/v2/core/versioning.md §1.5",
28427
+ "requirement": null,
28428
+ "interpolated": true
28429
+ },
28430
+ {
28431
+ "section": "spec/v2/core/versioning.md §1.5",
28432
+ "requirement": null,
28433
+ "interpolated": true
28434
+ }
28435
+ ]
28436
+ },
28259
28437
  {
28260
28438
  "id": "openwop.it.v2-coherence-not-in-bundle.every-corpus-ledger-id-has-a-scenario-in-src-coherence-and-none-in-src-scenarios",
28261
28439
  "file": "v2-coherence-not-in-bundle.test.ts",
@@ -28908,7 +29086,7 @@
28908
29086
  {
28909
29087
  "id": "openwop.it.v2-effect-identity-business-key.get-runs-runid-effects-validates-and-every-row-is-keyed-on-business-identity-or",
28910
29088
  "file": "v2-effect-identity-business-key.test.ts",
28911
- "line": 50,
29089
+ "line": 59,
28912
29090
  "title": "GET /runs/{runId}/effects validates and every row is keyed on business identity or the activity recipe",
28913
29091
  "explicitId": "openwop.requirement.0173.effect-identity-business-key",
28914
29092
  "citations": [
@@ -28948,7 +29126,7 @@
28948
29126
  {
28949
29127
  "id": "openwop.it.v2-effect-identity-business-key.the-same-provider-key-is-presented-across-two-transport-retries",
28950
29128
  "file": "v2-effect-identity-business-key.test.ts",
28951
- "line": 108,
29129
+ "line": 120,
28952
29130
  "title": "the same provider key is presented across two transport retries",
28953
29131
  "explicitId": "openwop.requirement.0173.effect-identity-business-key.retry",
28954
29132
  "citations": [
@@ -29313,6 +29491,176 @@
29313
29491
  }
29314
29492
  ]
29315
29493
  },
29494
+ {
29495
+ "id": "openwop.it.v2-ext-family-claims.brand",
29496
+ "file": "v2-ext-family-claims.test.ts",
29497
+ "line": 51,
29498
+ "title": "brand",
29499
+ "explicitId": "openwop.family.brand",
29500
+ "citations": [
29501
+ {
29502
+ "section": null,
29503
+ "requirement": null,
29504
+ "interpolated": true
29505
+ }
29506
+ ]
29507
+ },
29508
+ {
29509
+ "id": "openwop.it.v2-ext-family-claims.canvas",
29510
+ "file": "v2-ext-family-claims.test.ts",
29511
+ "line": 52,
29512
+ "title": "canvas",
29513
+ "explicitId": "openwop.family.canvas",
29514
+ "citations": [
29515
+ {
29516
+ "section": null,
29517
+ "requirement": null,
29518
+ "interpolated": true
29519
+ }
29520
+ ]
29521
+ },
29522
+ {
29523
+ "id": "openwop.it.v2-ext-family-claims.chat",
29524
+ "file": "v2-ext-family-claims.test.ts",
29525
+ "line": 53,
29526
+ "title": "chat",
29527
+ "explicitId": "openwop.family.chat",
29528
+ "citations": [
29529
+ {
29530
+ "section": null,
29531
+ "requirement": null,
29532
+ "interpolated": true
29533
+ }
29534
+ ]
29535
+ },
29536
+ {
29537
+ "id": "openwop.it.v2-ext-family-claims.coordination",
29538
+ "file": "v2-ext-family-claims.test.ts",
29539
+ "line": 54,
29540
+ "title": "coordination",
29541
+ "explicitId": "openwop.family.coordination",
29542
+ "citations": [
29543
+ {
29544
+ "section": null,
29545
+ "requirement": null,
29546
+ "interpolated": true
29547
+ }
29548
+ ]
29549
+ },
29550
+ {
29551
+ "id": "openwop.it.v2-ext-family-claims.dataintegration",
29552
+ "file": "v2-ext-family-claims.test.ts",
29553
+ "line": 55,
29554
+ "title": "dataIntegration",
29555
+ "explicitId": "openwop.family.dataIntegration",
29556
+ "citations": [
29557
+ {
29558
+ "section": null,
29559
+ "requirement": null,
29560
+ "interpolated": true
29561
+ }
29562
+ ]
29563
+ },
29564
+ {
29565
+ "id": "openwop.it.v2-ext-family-claims.entities",
29566
+ "file": "v2-ext-family-claims.test.ts",
29567
+ "line": 56,
29568
+ "title": "entities",
29569
+ "explicitId": "openwop.family.entities",
29570
+ "citations": [
29571
+ {
29572
+ "section": null,
29573
+ "requirement": null,
29574
+ "interpolated": true
29575
+ }
29576
+ ]
29577
+ },
29578
+ {
29579
+ "id": "openwop.it.v2-ext-family-claims.kanban",
29580
+ "file": "v2-ext-family-claims.test.ts",
29581
+ "line": 57,
29582
+ "title": "kanban",
29583
+ "explicitId": "openwop.family.kanban",
29584
+ "citations": [
29585
+ {
29586
+ "section": null,
29587
+ "requirement": null,
29588
+ "interpolated": true
29589
+ }
29590
+ ]
29591
+ },
29592
+ {
29593
+ "id": "openwop.it.v2-ext-family-claims.knowledge",
29594
+ "file": "v2-ext-family-claims.test.ts",
29595
+ "line": 58,
29596
+ "title": "knowledge",
29597
+ "explicitId": "openwop.family.knowledge",
29598
+ "citations": [
29599
+ {
29600
+ "section": null,
29601
+ "requirement": null,
29602
+ "interpolated": true
29603
+ }
29604
+ ]
29605
+ },
29606
+ {
29607
+ "id": "openwop.it.v2-ext-family-claims.launchstudio",
29608
+ "file": "v2-ext-family-claims.test.ts",
29609
+ "line": 59,
29610
+ "title": "launchStudio",
29611
+ "explicitId": "openwop.family.launchStudio",
29612
+ "citations": [
29613
+ {
29614
+ "section": null,
29615
+ "requirement": null,
29616
+ "interpolated": true
29617
+ }
29618
+ ]
29619
+ },
29620
+ {
29621
+ "id": "openwop.it.v2-ext-family-claims.messaging",
29622
+ "file": "v2-ext-family-claims.test.ts",
29623
+ "line": 60,
29624
+ "title": "messaging",
29625
+ "explicitId": "openwop.family.messaging",
29626
+ "citations": [
29627
+ {
29628
+ "section": null,
29629
+ "requirement": null,
29630
+ "interpolated": true
29631
+ }
29632
+ ]
29633
+ },
29634
+ {
29635
+ "id": "openwop.it.v2-ext-family-claims.webresearch",
29636
+ "file": "v2-ext-family-claims.test.ts",
29637
+ "line": 61,
29638
+ "title": "webResearch",
29639
+ "explicitId": "openwop.family.webResearch",
29640
+ "citations": [
29641
+ {
29642
+ "section": null,
29643
+ "requirement": null,
29644
+ "interpolated": true
29645
+ }
29646
+ ]
29647
+ },
29648
+ {
29649
+ "id": "openwop.it.v2-ext-rest-transport.a-strong-etag-on-the-200-304-on-a-match-while-the-run-is-parked-and-a-new-etag-o",
29650
+ "file": "v2-ext-rest-transport.test.ts",
29651
+ "line": 75,
29652
+ "title": "a strong ETag on the 200, 304 on a match while the run is parked, and a new ETag once it completes",
29653
+ "explicitId": null,
29654
+ "citations": []
29655
+ },
29656
+ {
29657
+ "id": "openwop.it.v2-ext-rest-transport.each-coding-in-contentencodings-is-produced-when-asked-for-alone-and-decodes-to",
29658
+ "file": "v2-ext-rest-transport.test.ts",
29659
+ "line": 112,
29660
+ "title": "each coding in contentEncodings is produced when asked for alone and decodes to the identity body",
29661
+ "explicitId": null,
29662
+ "citations": []
29663
+ },
29316
29664
  {
29317
29665
  "id": "openwop.it.v2-fork-a-v1-run.the-fork-of-an-era-2-run-is-accepted-and-its-prefix-is-byte-equivalent-to-the-tr",
29318
29666
  "file": "v2-fork-a-v1-run.test.ts",
@@ -29427,7 +29775,7 @@
29427
29775
  {
29428
29776
  "id": "openwop.it.v2-id-grammar.every-id-on-the-run-snapshot-matches-its-ids-schema-json-kind",
29429
29777
  "file": "v2-id-grammar.test.ts",
29430
- "line": 53,
29778
+ "line": 55,
29431
29779
  "title": "every id on the run snapshot matches its ids.schema.json kind",
29432
29780
  "explicitId": "openwop.requirement.0170.id-grammar.snapshot",
29433
29781
  "citations": [
@@ -29446,7 +29794,7 @@
29446
29794
  {
29447
29795
  "id": "openwop.it.v2-id-grammar.every-id-on-the-run-events-matches-its-ids-schema-json-kind",
29448
29796
  "file": "v2-id-grammar.test.ts",
29449
- "line": 63,
29797
+ "line": 65,
29450
29798
  "title": "every id on the run events matches its ids.schema.json kind",
29451
29799
  "explicitId": "openwop.requirement.0170.id-grammar.events",
29452
29800
  "citations": [
@@ -29464,7 +29812,7 @@
29464
29812
  {
29465
29813
  "id": "openwop.it.v2-id-grammar.a-run-id-whose-tenant-segment-is-not-the-caller-s-is-refused",
29466
29814
  "file": "v2-id-grammar.test.ts",
29467
- "line": 78,
29815
+ "line": 90,
29468
29816
  "title": "a run id whose tenant segment is not the caller's is refused",
29469
29817
  "explicitId": "openwop.requirement.0170.id-grammar.tenant-binding",
29470
29818
  "citations": [
@@ -29487,7 +29835,7 @@
29487
29835
  {
29488
29836
  "id": "openwop.it.v2-id-grammar.a-bare-unbound-run-id-in-a-major-2-path-admitted-under-the-caller-s-tenant-throu",
29489
29837
  "file": "v2-id-grammar.test.ts",
29490
- "line": 88,
29838
+ "line": 100,
29491
29839
  "title": "a bare (unbound) run id in a major-2 path: admitted under the caller's tenant through the overlap, refused 400 validation_error after it",
29492
29840
  "explicitId": "openwop.requirement.0170.id-grammar.bare-id",
29493
29841
  "citations": [
@@ -29572,7 +29920,7 @@
29572
29920
  {
29573
29921
  "id": "openwop.it.v2-idempotency-in-flight.while-the-seam-holds-the-claim-a-same-key-create-is-refused-409-idempotency-in-f",
29574
29922
  "file": "v2-idempotency-in-flight.test.ts",
29575
- "line": 154,
29923
+ "line": 157,
29576
29924
  "title": "while the seam holds the claim, a same-key create is refused 409 idempotency_in_flight by the host and the held create still wins",
29577
29925
  "explicitId": "openwop.requirement.0213.in-flight-refused-under-hold",
29578
29926
  "citations": [
@@ -30019,7 +30367,7 @@
30019
30367
  {
30020
30368
  "id": "openwop.it.v2-legacy-profiles-absent.no-root-profiles-exists-in-the-v2-representation",
30021
30369
  "file": "v2-legacy-profiles-absent.test.ts",
30022
- "line": 70,
30370
+ "line": 68,
30023
30371
  "title": "no root profiles[] exists in the v2 representation",
30024
30372
  "explicitId": "openwop.requirement.0175.legacy-profiles-absent.no-root-profiles",
30025
30373
  "citations": [
@@ -31026,7 +31374,7 @@
31026
31374
  {
31027
31375
  "id": "openwop.it.v2-min-client-version.a-client-below-minclientversion-is-refused-with-426-client-version-unsupported",
31028
31376
  "file": "v2-min-client-version.test.ts",
31029
- "line": 35,
31377
+ "line": 38,
31030
31378
  "title": "a client below minClientVersion is refused with 426 client_version_unsupported",
31031
31379
  "explicitId": "openwop.requirement.0172.min-client-version",
31032
31380
  "citations": [
@@ -31034,6 +31382,11 @@
31034
31382
  "section": "spec/v2/core/versioning.md §1.5",
31035
31383
  "requirement": "minClientVersion MUST use the <major>.<minor> grammar (axis 15, as axis 1)"
31036
31384
  },
31385
+ {
31386
+ "section": "spec/v2/core/versioning.md §1.5",
31387
+ "requirement": null,
31388
+ "interpolated": true
31389
+ },
31037
31390
  {
31038
31391
  "section": "spec/v2/core/versioning.md §1.5",
31039
31392
  "requirement": "a 426 refusal MUST carry client_version_unsupported"
@@ -31042,6 +31395,11 @@
31042
31395
  "section": "spec/v2/core/errors.md §The envelope",
31043
31396
  "requirement": null,
31044
31397
  "interpolated": true
31398
+ },
31399
+ {
31400
+ "section": "spec/v2/core/versioning.md §1.5",
31401
+ "requirement": null,
31402
+ "interpolated": true
31045
31403
  }
31046
31404
  ]
31047
31405
  },
@@ -31975,7 +32333,7 @@
31975
32333
  {
31976
32334
  "id": "openwop.it.v2-preferred-version-default.preferredversion-is-a-member-of-protocolversions",
31977
32335
  "file": "v2-preferred-version-default.test.ts",
31978
- "line": 40,
32336
+ "line": 41,
31979
32337
  "title": "preferredVersion is a member of protocolVersions[]",
31980
32338
  "explicitId": "openwop.requirement.0172.preferred-version-default.member",
31981
32339
  "citations": [
@@ -31997,7 +32355,7 @@
31997
32355
  {
31998
32356
  "id": "openwop.it.v2-preferred-version-default.a-header-less-get-well-known-openwop-is-the-preferredversion-representation",
31999
32357
  "file": "v2-preferred-version-default.test.ts",
32000
- "line": 52,
32358
+ "line": 53,
32001
32359
  "title": "a header-less GET /.well-known/openwop is the preferredVersion representation",
32002
32360
  "explicitId": "openwop.requirement.0172.preferred-version-default.headerless",
32003
32361
  "citations": [
@@ -32025,10 +32383,24 @@
32025
32383
  }
32026
32384
  ]
32027
32385
  },
32386
+ {
32387
+ "id": "openwop.it.v2-preferred-version-default.a-header-less-request-on-any-other-unversioned-path-is-served-major-2",
32388
+ "file": "v2-preferred-version-default.test.ts",
32389
+ "line": 71,
32390
+ "title": "a header-less request on any other unversioned path is served major 2",
32391
+ "explicitId": "openwop.requirement.0172.preferred-version-default.unversioned-is-v2",
32392
+ "citations": [
32393
+ {
32394
+ "section": "spec/v2/core/versioning.md §1.2, §1.3",
32395
+ "requirement": null,
32396
+ "interpolated": true
32397
+ }
32398
+ ]
32399
+ },
32028
32400
  {
32029
32401
  "id": "openwop.it.v2-preferred-version-default.through-the-overlap-preferredversion-names-a-1-x-member",
32030
32402
  "file": "v2-preferred-version-default.test.ts",
32031
- "line": 70,
32403
+ "line": 88,
32032
32404
  "title": "through the overlap preferredVersion names a 1.x member",
32033
32405
  "explicitId": "openwop.requirement.0172.preferred-version-default.overlap",
32034
32406
  "citations": [
@@ -33407,7 +33779,7 @@
33407
33779
  {
33408
33780
  "id": "openwop.it.v2-version-header-honored.a-host-advertising-two-majors-serves-two-different-representations",
33409
33781
  "file": "v2-version-header-honored.test.ts",
33410
- "line": 185,
33782
+ "line": 188,
33411
33783
  "title": "a host advertising two majors serves two different representations",
33412
33784
  "explicitId": "openwop.requirement.0172.version-header-honored",
33413
33785
  "citations": [
@@ -33576,7 +33948,7 @@
33576
33948
  {
33577
33949
  "id": "openwop.it.v2-webhook-durable-delivery.an-exhausted-delivery-is-dead-lettered-never-dropped",
33578
33950
  "file": "v2-webhook-durable-delivery.test.ts",
33579
- "line": 376,
33951
+ "line": 378,
33580
33952
  "title": "an exhausted delivery is dead-lettered, never dropped",
33581
33953
  "explicitId": "openwop.requirement.0173.webhook-durable-delivery.dead-letter",
33582
33954
  "citations": [
@@ -33610,7 +33982,7 @@
33610
33982
  {
33611
33983
  "id": "openwop.it.v2-webhook-durable-delivery.the-dead-letter-read-is-served-and-its-records-carry-no-payload",
33612
33984
  "file": "v2-webhook-durable-delivery.test.ts",
33613
- "line": 478,
33985
+ "line": 480,
33614
33986
  "title": "the dead-letter read is served and its records carry no payload",
33615
33987
  "explicitId": "openwop.requirement.0188.dead-letter-read",
33616
33988
  "citations": [
@@ -33623,7 +33995,7 @@
33623
33995
  {
33624
33996
  "id": "openwop.it.v2-webhook-durable-delivery.after-unregister-the-dead-letter-read-answers-404-not-found-as-for-a-subscriptio",
33625
33997
  "file": "v2-webhook-durable-delivery.test.ts",
33626
- "line": 499,
33998
+ "line": 501,
33627
33999
  "title": "after unregister, the dead-letter read answers 404 not_found, as for a subscription that never existed",
33628
34000
  "explicitId": "openwop.requirement.0217.dead-letter-read-after-unregister",
33629
34001
  "citations": [
@@ -33650,7 +34022,7 @@
33650
34022
  {
33651
34023
  "id": "openwop.it.v2-webhook-durable-delivery.a-dead-letter-record-carries-no-delivered-payload",
33652
34024
  "file": "v2-webhook-durable-delivery.test.ts",
33653
- "line": 532,
34025
+ "line": 534,
33654
34026
  "title": "a dead-letter record carries no delivered payload",
33655
34027
  "explicitId": "openwop.requirement.0188.dead-letter-content-free",
33656
34028
  "citations": [
@@ -33757,6 +34129,40 @@
33757
34129
  }
33758
34130
  ]
33759
34131
  },
34132
+ {
34133
+ "id": "openwop.it.v2-webhook-generated-secret.a-secret-less-registration-returns-the-generated-secret-and-deliveries-verify-un",
34134
+ "file": "v2-webhook-generated-secret.test.ts",
34135
+ "line": 44,
34136
+ "title": "a secret-less registration returns the generated secret, and deliveries verify under it; a supplied secret is never echoed",
34137
+ "explicitId": "openwop.requirement.0221.generated-secret-returned",
34138
+ "citations": [
34139
+ {
34140
+ "section": "RFC 0221 · webhooks.md §Surfaces",
34141
+ "requirement": "a registration that omits secret MUST get the host-generated secret back in the 201 as a non-empty string"
34142
+ },
34143
+ {
34144
+ "section": "runs.md §Create",
34145
+ "requirement": "POST /runs MUST answer 201 for the noop fixture"
34146
+ },
34147
+ {
34148
+ "section": "webhooks.md §Durability",
34149
+ "requirement": "the subscription MUST receive the run.completed delivery"
34150
+ },
34151
+ {
34152
+ "section": "RFC 0221 · webhooks.md §Surfaces",
34153
+ "requirement": "the delivery MUST verify (OpenWOP-Signature, scheme v1) under the secret the 201 returned"
34154
+ },
34155
+ {
34156
+ "section": "RFC 0221 · webhooks.md §Surfaces",
34157
+ "requirement": null,
34158
+ "interpolated": true
34159
+ },
34160
+ {
34161
+ "section": "RFC 0221 · RFC 0201 §B.6",
34162
+ "requirement": "the 201 MUST NOT echo a supplied secret"
34163
+ }
34164
+ ]
34165
+ },
33760
34166
  {
33761
34167
  "id": "openwop.it.v2-webhook-message-id-stable.every-attempt-of-one-delivery-carries-one-webhook-id-and-distinct-deliveries-car",
33762
34168
  "file": "v2-webhook-message-id-stable.test.ts",
@@ -34875,7 +35281,7 @@
34875
35281
  {
34876
35282
  "id": "openwop.it.webhook-signed-delivery.control-with-a-tunnel-wired-the-host-still-refuses-the-loopback-receiver",
34877
35283
  "file": "webhook-signed-delivery.test.ts",
34878
- "line": 440,
35284
+ "line": 442,
34879
35285
  "title": "control: with a tunnel wired, the host still refuses the loopback receiver",
34880
35286
  "explicitId": "openwop.it.webhook-signed-delivery.control-with-a-tunnel-wired-the-host-still-refuses-the-loopback-receiver",
34881
35287
  "citations": [
@@ -35448,7 +35854,7 @@
35448
35854
  {
35449
35855
  "id": "openwop.it.workflow-chain-host-expansion.positive-2-node-chain-matches-the-reference-library-edge-rewrite-capability-prop",
35450
35856
  "file": "workflow-chain-host-expansion.test.ts",
35451
- "line": 205,
35857
+ "line": 208,
35452
35858
  "title": "positive — 2-node chain matches the reference library (edge rewrite + capability propagation)",
35453
35859
  "explicitId": "openwop.it.workflow-chain-host-expansion.positive-2-node-chain-matches-the-reference-library-edge-rewrite-capability-prop",
35454
35860
  "citations": [
@@ -35465,7 +35871,7 @@
35465
35871
  {
35466
35872
  "id": "openwop.it.workflow-chain-host-expansion.negative-unknown-pack-returns-404-pack-not-found",
35467
35873
  "file": "workflow-chain-host-expansion.test.ts",
35468
- "line": 237,
35874
+ "line": 240,
35469
35875
  "title": "negative — unknown pack returns 404 pack_not_found",
35470
35876
  "explicitId": "openwop.it.workflow-chain-host-expansion.negative-unknown-pack-returns-404-pack-not-found",
35471
35877
  "citations": [
@@ -35478,7 +35884,7 @@
35478
35884
  {
35479
35885
  "id": "openwop.it.workflow-chain-host-expansion.negative-known-pack-but-unknown-chainid-returns-404-chain-not-found",
35480
35886
  "file": "workflow-chain-host-expansion.test.ts",
35481
- "line": 249,
35887
+ "line": 252,
35482
35888
  "title": "negative — known pack but unknown chainId returns 404 chain_not_found",
35483
35889
  "explicitId": "openwop.it.workflow-chain-host-expansion.negative-known-pack-but-unknown-chainid-returns-404-chain-not-found",
35484
35890
  "citations": [
@@ -35491,7 +35897,7 @@
35491
35897
  {
35492
35898
  "id": "openwop.it.workflow-chain-host-expansion.negative-malformed-request-body-returns-422-invalid-request",
35493
35899
  "file": "workflow-chain-host-expansion.test.ts",
35494
- "line": 261,
35900
+ "line": 264,
35495
35901
  "title": "negative — malformed request body returns 422 invalid_request",
35496
35902
  "explicitId": "openwop.it.workflow-chain-host-expansion.negative-malformed-request-body-returns-422-invalid-request",
35497
35903
  "citations": [
@@ -35504,7 +35910,7 @@
35504
35910
  {
35505
35911
  "id": "openwop.it.workflow-chain-host-expansion.rfc-0157-a-compensating-chain-expands-through-the-live-path-with-compensation-an",
35506
35912
  "file": "workflow-chain-host-expansion.test.ts",
35507
- "line": 269,
35913
+ "line": 272,
35508
35914
  "title": "RFC 0157 — a compensating chain expands through the live path with `compensation` and `irreversibleEffect` carried verbatim onto the expanded nodes",
35509
35915
  "explicitId": "openwop.it.workflow-chain-host-expansion.rfc-0157-a-compensating-chain-expands-through-the-live-path-with-compensation-an",
35510
35916
  "citations": [
@@ -35532,7 +35938,7 @@
35532
35938
  {
35533
35939
  "id": "openwop.it.workflow-chain-host-expansion.rfc-0157-a-chain-carrying-an-unwind-policy-is-refused-with-capability-required-o",
35534
35940
  "file": "workflow-chain-host-expansion.test.ts",
35535
- "line": 308,
35941
+ "line": 311,
35536
35942
  "title": "RFC 0157 — a chain carrying an unwind POLICY is refused with capability_required on a host that does not advertise compensation, and expands on one that does",
35537
35943
  "explicitId": "openwop.it.workflow-chain-host-expansion.rfc-0157-a-chain-carrying-an-unwind-policy-is-refused-with-capability-required-o",
35538
35944
  "citations": [
@@ -36132,7 +36538,7 @@
36132
36538
  {
36133
36539
  "id": "openwop.it.workload-identity-chain-bounds.a-later-hop-claiming-a-scope-the-previous-hop-did-not-hold-is-refused",
36134
36540
  "file": "workload-identity-chain-bounds.test.ts",
36135
- "line": 121,
36541
+ "line": 124,
36136
36542
  "title": "a later hop claiming a scope the previous hop did not hold is refused",
36137
36543
  "explicitId": null,
36138
36544
  "citations": []
@@ -36140,7 +36546,7 @@
36140
36546
  {
36141
36547
  "id": "openwop.it.workload-identity-chain-bounds.a-well-formed-bounded-acyclic-non-amplifying-chain-still-resolves-the-negatives",
36142
36548
  "file": "workload-identity-chain-bounds.test.ts",
36143
- "line": 130,
36549
+ "line": 133,
36144
36550
  "title": "a well-formed bounded, acyclic, non-amplifying chain still resolves (the negatives are not a blanket refusal)",
36145
36551
  "explicitId": "openwop.it.workload-identity-chain-bounds.a-well-formed-bounded-acyclic-non-amplifying-chain-still-resolves-the-negatives",
36146
36552
  "citations": [