@openwop/openwop-conformance 2.42.5 → 2.42.7

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 (123) hide show
  1. package/CHANGELOG.md +26 -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/package.json +2 -2
  7. package/requirements.json +430 -162
  8. package/scenario-majors.json +16 -3
  9. package/schemas/CORPUS-STAMP.json +64 -63
  10. package/src/lib/audit-checkpoint.ts +72 -0
  11. package/src/lib/era2-seed.ts +30 -0
  12. package/src/lib/ext-claims.ts +96 -0
  13. package/src/lib/soft-skip.ts +14 -0
  14. package/src/scenarios/a2a-peer-authority.test.ts +6 -13
  15. package/src/scenarios/a2a-task-roundtrip.test.ts +6 -34
  16. package/src/scenarios/a2a-version-negotiation.test.ts +6 -12
  17. package/src/scenarios/a2ui-surface-delta-transport.test.ts +23 -12
  18. package/src/scenarios/agent-channel-dispatch.test.ts +13 -4
  19. package/src/scenarios/agent-live-invocation-bracket.test.ts +1 -1
  20. package/src/scenarios/agent-manifest-runtime.test.ts +3 -0
  21. package/src/scenarios/aiEnvelope.capBreached.test.ts +2 -2
  22. package/src/scenarios/aiEnvelope.contractRefusal.test.ts +2 -2
  23. package/src/scenarios/aiEnvelope.schemaDrift.test.ts +2 -2
  24. package/src/scenarios/aiEnvelope.universalKinds.test.ts +2 -2
  25. package/src/scenarios/aiproviders-selfhosted-honesty.test.ts +2 -2
  26. package/src/scenarios/append-ordering.test.ts +26 -21
  27. package/src/scenarios/artifact-auth.test.ts +3 -1
  28. package/src/scenarios/artifact-type-registration-source.test.ts +2 -2
  29. package/src/scenarios/audit-checkpoint-signature.test.ts +63 -0
  30. package/src/scenarios/audit-checkpoint-vectors.test.ts +93 -0
  31. package/src/scenarios/auth-mtls.test.ts +7 -6
  32. package/src/scenarios/auth-subject-link-key-class.test.ts +3 -3
  33. package/src/scenarios/auth-subject-link.test.ts +19 -18
  34. package/src/scenarios/blob-presign-expiry.test.ts +2 -2
  35. package/src/scenarios/byok-roundtrip.test.ts +4 -1
  36. package/src/scenarios/compensation-behavior.test.ts +10 -5
  37. package/src/scenarios/conformance-advertised-seam-required.test.ts +6 -0
  38. package/src/scenarios/connection-pack-apihosts.test.ts +2 -2
  39. package/src/scenarios/connection-provider-resolution.test.ts +2 -2
  40. package/src/scenarios/context-budget-transcript-bound.test.ts +7 -3
  41. package/src/scenarios/context-summarization-replay.test.ts +2 -0
  42. package/src/scenarios/cost-attribution.test.ts +3 -1
  43. package/src/scenarios/debugBundle.test.ts +12 -4
  44. package/src/scenarios/discovery.test.ts +6 -2
  45. package/src/scenarios/dispatch-cross-worker-handoff.test.ts +2 -2
  46. package/src/scenarios/dispatch-input-mapping.test.ts +2 -2
  47. package/src/scenarios/dispatch-output-mapping.test.ts +15 -2
  48. package/src/scenarios/distillation-token-budget.test.ts +2 -2
  49. package/src/scenarios/durability-poison-exhaustion.test.ts +2 -2
  50. package/src/scenarios/envelope-nl-to-format-engaged.test.ts +2 -2
  51. package/src/scenarios/envelope-recovery-applied.test.ts +2 -2
  52. package/src/scenarios/envelope-refusal-shape.test.ts +2 -2
  53. package/src/scenarios/envelope-retry-attempted.test.ts +2 -2
  54. package/src/scenarios/envelope-retry-exhausted.test.ts +2 -2
  55. package/src/scenarios/envelope-tier-one-subset-static.test.ts +1 -1
  56. package/src/scenarios/envelope-truncation-cap-exhaustion.test.ts +2 -2
  57. package/src/scenarios/eventOrdering.test.ts +17 -10
  58. package/src/scenarios/form-content-instantiation.test.ts +2 -2
  59. package/src/scenarios/heartbeat-idempotent-no-spam.test.ts +2 -2
  60. package/src/scenarios/highConcurrency.test.ts +9 -9
  61. package/src/scenarios/idempotency-concurrent-claim.test.ts +5 -5
  62. package/src/scenarios/idempotency-key-determinism.test.ts +8 -8
  63. package/src/scenarios/idempotency.test.ts +6 -6
  64. package/src/scenarios/idempotencyRetry.test.ts +16 -11
  65. package/src/scenarios/interrupt-token-matrix.test.ts +24 -11
  66. package/src/scenarios/mcp-cache-tenant-scope.test.ts +3 -3
  67. package/src/scenarios/mcp-current-auth-boundary.test.ts +9 -6
  68. package/src/scenarios/mcp-extension-opacity.test.ts +6 -5
  69. package/src/scenarios/mcp-mrtr-roundtrip.test.ts +9 -8
  70. package/src/scenarios/mcp-version-negotiation.test.ts +5 -10
  71. package/src/scenarios/media-url-inline-cap.test.ts +3 -2
  72. package/src/scenarios/memory-compaction-provenance-tag.test.ts +2 -0
  73. package/src/scenarios/memory-compaction-sr1-carry-forward.test.ts +2 -2
  74. package/src/scenarios/memory-consolidation-idempotent.test.ts +2 -2
  75. package/src/scenarios/memory-injection-budget.test.ts +2 -2
  76. package/src/scenarios/multi-party-conversation-behavioral.test.ts +2 -2
  77. package/src/scenarios/multi-region-idempotency-behavior.test.ts +9 -9
  78. package/src/scenarios/multi-region-idempotency.test.ts +2 -2
  79. package/src/scenarios/pack-registry-isolation.test.ts +13 -12
  80. package/src/scenarios/pack-registry.test.ts +3 -2
  81. package/src/scenarios/pause-resume.test.ts +30 -11
  82. package/src/scenarios/prompt-read-workspace-membership-enforced.test.ts +43 -34
  83. package/src/scenarios/provider-usage.test.ts +2 -2
  84. package/src/scenarios/redaction.test.ts +7 -5
  85. package/src/scenarios/redactionAdversarial.test.ts +5 -4
  86. package/src/scenarios/registry-public.test.ts +5 -1
  87. package/src/scenarios/replay-divergence-at-refusal.test.ts +10 -7
  88. package/src/scenarios/replay-fanout-suppression.test.ts +7 -4
  89. package/src/scenarios/replay-fork-arbitrary.test.ts +2 -2
  90. package/src/scenarios/replay-side-effect-suppression.test.ts +2 -2
  91. package/src/scenarios/replayDeterminism.test.ts +9 -4
  92. package/src/scenarios/runner-ledger.test.ts +4 -0
  93. package/src/scenarios/runtime-capabilities.test.ts +2 -0
  94. package/src/scenarios/speech-synthesis-roundtrip.test.ts +1 -1
  95. package/src/scenarios/streamReconnect.test.ts +2 -2
  96. package/src/scenarios/subrun-approval-gate.test.ts +2 -2
  97. package/src/scenarios/subworkflow-input-mapping.test.ts +2 -2
  98. package/src/scenarios/tool-catalog-projection.test.ts +10 -7
  99. package/src/scenarios/tool-session-lifecycle.test.ts +1 -1
  100. package/src/scenarios/trigger-ingestion.test.ts +2 -2
  101. package/src/scenarios/v2-a2ui-v09-surface.test.ts +15 -0
  102. package/src/scenarios/v2-effect-identity-business-key.test.ts +12 -0
  103. package/src/scenarios/v2-era-2-append-vocabulary.test.ts +39 -24
  104. package/src/scenarios/v2-ext-family-claims.test.ts +62 -0
  105. package/src/scenarios/v2-ext-rest-transport.test.ts +151 -0
  106. package/src/scenarios/v2-idempotency-in-flight.test.ts +3 -0
  107. package/src/scenarios/v2-legacy-profiles-absent.test.ts +4 -6
  108. package/src/scenarios/v2-mcp-tasks.test.ts +1 -1
  109. package/src/scenarios/v2-min-client-version.test.ts +2 -0
  110. package/src/scenarios/v2-refresh-sla.test.ts +6 -5
  111. package/src/scenarios/v2-sse-last-event-id-cursor.test.ts +3 -3
  112. package/src/scenarios/v2-sse-last-event-id.test.ts +2 -0
  113. package/src/scenarios/v2-version-header-honored.test.ts +3 -0
  114. package/src/scenarios/v2-webhook-durable-delivery.test.ts +2 -0
  115. package/src/scenarios/v2-webhook-secret-rotation.test.ts +8 -1
  116. package/src/scenarios/verifier-gating.test.ts +2 -2
  117. package/src/scenarios/version-fold.test.ts +2 -2
  118. package/src/scenarios/wasm-pack-invoke-suspended.test.ts +7 -6
  119. package/src/scenarios/webhook-signed-delivery.test.ts +2 -0
  120. package/src/scenarios/workflow-chain-host-expansion.test.ts +10 -1
  121. package/src/scenarios/workflow-variable-format.test.ts +2 -2
  122. package/src/scenarios/workload-identity-chain-bounds.test.ts +6 -3
  123. 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": 640,
6
+ "tests": 2460,
7
+ "withStableId": 2460,
8
8
  "interpolatedTitles": 0,
9
- "explicitIds": 2331
9
+ "explicitIds": 2350
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,6 +5425,112 @@
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",
@@ -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": [
@@ -12581,7 +12669,7 @@
12581
12669
  {
12582
12670
  "id": "openwop.it.eventOrdering.events-from-a-single-poll-have-non-decreasing-sequence-numbers",
12583
12671
  "file": "eventOrdering.test.ts",
12584
- "line": 46,
12672
+ "line": 53,
12585
12673
  "title": "events from a single poll have non-decreasing sequence numbers",
12586
12674
  "explicitId": "openwop.it.eventOrdering.events-from-a-single-poll-have-non-decreasing-sequence-numbers",
12587
12675
  "citations": [
@@ -12595,7 +12683,7 @@
12595
12683
  {
12596
12684
  "id": "openwop.it.eventOrdering.repeated-polls-of-a-terminal-run-yield-identical-event-sequences",
12597
12685
  "file": "eventOrdering.test.ts",
12598
- "line": 71,
12686
+ "line": 78,
12599
12687
  "title": "repeated polls of a terminal run yield identical event sequences",
12600
12688
  "explicitId": "openwop.it.eventOrdering.repeated-polls-of-a-terminal-run-yield-identical-event-sequences",
12601
12689
  "citations": [
@@ -12613,7 +12701,7 @@
12613
12701
  {
12614
12702
  "id": "openwop.it.eventOrdering.event-stream-contains-exactly-one-of-run-completed-run-failed-run-cancelled",
12615
12703
  "file": "eventOrdering.test.ts",
12616
- "line": 103,
12704
+ "line": 110,
12617
12705
  "title": "event stream contains exactly one of run.completed / run.failed / run.cancelled",
12618
12706
  "explicitId": "openwop.it.eventOrdering.event-stream-contains-exactly-one-of-run-completed-run-failed-run-cancelled",
12619
12707
  "citations": [
@@ -12626,7 +12714,7 @@
12626
12714
  {
12627
12715
  "id": "openwop.it.eventOrdering.the-terminal-event-is-the-last-event-in-the-stream",
12628
12716
  "file": "eventOrdering.test.ts",
12629
- "line": 124,
12717
+ "line": 131,
12630
12718
  "title": "the terminal event is the LAST event in the stream",
12631
12719
  "explicitId": "openwop.it.eventOrdering.the-terminal-event-is-the-last-event-in-the-stream",
12632
12720
  "citations": [
@@ -14226,19 +14314,19 @@
14226
14314
  "explicitId": "openwop.it.highConcurrency.10-parallel-requests-with-same-key-yield-one-runid-and-9-replays",
14227
14315
  "citations": [
14228
14316
  {
14229
- "section": "idempotency.md §Concurrent duplicates",
14317
+ "section": "spec/v1/idempotency.md §Concurrent duplicates",
14230
14318
  "requirement": "every concurrent request MUST resolve to either the cached response or a deterministic 409"
14231
14319
  },
14232
14320
  {
14233
- "section": "idempotency.md §Layer 1",
14321
+ "section": "spec/v1/idempotency.md §Layer 1",
14234
14322
  "requirement": "same idempotency key MUST yield exactly ONE runId across all successful responses"
14235
14323
  },
14236
14324
  {
14237
- "section": "idempotency.md",
14325
+ "section": "spec/v1/idempotency.md",
14238
14326
  "requirement": "409 on parallel idempotency-keyed retry MUST carry error=\"idempotency_in_flight\""
14239
14327
  },
14240
14328
  {
14241
- "section": "idempotency.md",
14329
+ "section": "spec/v1/idempotency.md",
14242
14330
  "requirement": "409 idempotency_in_flight MUST include a numeric retryAfter"
14243
14331
  }
14244
14332
  ]
@@ -14255,7 +14343,7 @@
14255
14343
  "requirement": "concurrent POST /v1/runs requests MUST resolve to either success or rate-limited"
14256
14344
  },
14257
14345
  {
14258
- "section": "idempotency.md §Layer 1",
14346
+ "section": "spec/v1/idempotency.md §Layer 1",
14259
14347
  "requirement": "distinct idempotency keys MUST yield distinct runIds (Layer 1 dedup is keyed)"
14260
14348
  },
14261
14349
  {
@@ -14276,15 +14364,15 @@
14276
14364
  "requirement": "host MUST handle ≥5 retries with same key 100ms apart without losing the cached response"
14277
14365
  },
14278
14366
  {
14279
- "section": "idempotency.md §Layer 1",
14367
+ "section": "spec/v1/idempotency.md §Layer 1",
14280
14368
  "requirement": "all 5 retries with same key MUST resolve to the same runId"
14281
14369
  },
14282
14370
  {
14283
- "section": "idempotency.md §Server responsibilities",
14371
+ "section": "spec/v1/idempotency.md §Server responsibilities",
14284
14372
  "requirement": "first request with new key MUST NOT be marked as replay"
14285
14373
  },
14286
14374
  {
14287
- "section": "idempotency.md §Server responsibilities #2",
14375
+ "section": "spec/v1/idempotency.md §Server responsibilities #2",
14288
14376
  "requirement": "replay responses SHOULD set openwop-Idempotent-Replay: true"
14289
14377
  }
14290
14378
  ]
@@ -14301,7 +14389,7 @@
14301
14389
  "requirement": "limits MUST be advertised in discovery"
14302
14390
  },
14303
14391
  {
14304
- "section": "idempotency.md",
14392
+ "section": "spec/v1/idempotency.md",
14305
14393
  "requirement": "limits.idempotencyAckTimeoutSec MUST be integer ≥5 when advertised"
14306
14394
  }
14307
14395
  ]
@@ -14491,7 +14579,7 @@
14491
14579
  "requirement": "fewer than two executors is not a race and cannot witness the rule"
14492
14580
  },
14493
14581
  {
14494
- "section": "idempotency.md §\"Idempotency key composition\" (Across a recovery boundary)",
14582
+ "section": "spec/v1/idempotency.md §\"Idempotency key composition\" (Across a recovery boundary)",
14495
14583
  "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
14584
  }
14497
14585
  ]
@@ -14508,7 +14596,7 @@
14508
14596
  "requirement": "the seam MUST report how many executors attempted the effect"
14509
14597
  },
14510
14598
  {
14511
- "section": "idempotency.md §\"Concurrent duplicates (Layer 2)\"",
14599
+ "section": "spec/v1/idempotency.md §\"Concurrent duplicates (Layer 2)\"",
14512
14600
  "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
14601
  }
14514
14602
  ]
@@ -14529,7 +14617,7 @@
14529
14617
  "requirement": "the seam MUST report mintedIds, one per executor"
14530
14618
  },
14531
14619
  {
14532
- "section": "idempotency.md §\"Concurrent duplicates (Layer 2)\"",
14620
+ "section": "spec/v1/idempotency.md §\"Concurrent duplicates (Layer 2)\"",
14533
14621
  "requirement": "exactly one effect regardless of how many executors race — at most one wins the compare-and-set, the rest observe the hit"
14534
14622
  },
14535
14623
  {
@@ -14537,7 +14625,7 @@
14537
14625
  "requirement": "mintedIds length MUST equal attempted"
14538
14626
  },
14539
14627
  {
14540
- "section": "idempotency.md §\"Idempotency key composition\"",
14628
+ "section": "spec/v1/idempotency.md §\"Idempotency key composition\"",
14541
14629
  "requirement": "one identity across all executors at any concurrency"
14542
14630
  }
14543
14631
  ]
@@ -14558,8 +14646,8 @@
14558
14646
  "explicitId": "openwop.it.idempotency-key-determinism.default-mode-composite-identical-runid-nodeid-payload-produces-identical-keys",
14559
14647
  "citations": [
14560
14648
  {
14561
- "section": "idempotency.md §\"Idempotency-Key",
14562
- "requirement": "idempotency.md §Idempotency-Key: same logical request MUST produce same key"
14649
+ "section": "spec/v1/idempotency.md §\"Idempotency-Key",
14650
+ "requirement": "spec/v1/idempotency.md §Idempotency-Key: same logical request MUST produce same key"
14563
14651
  }
14564
14652
  ]
14565
14653
  },
@@ -14571,7 +14659,7 @@
14571
14659
  "explicitId": "openwop.it.idempotency-key-determinism.payload-sensitivity-different-payload-produces-different-key",
14572
14660
  "citations": [
14573
14661
  {
14574
- "section": "idempotency.md §\"Idempotency-Key",
14662
+ "section": "spec/v1/idempotency.md §\"Idempotency-Key",
14575
14663
  "requirement": "payload sensitivity — different payload produces different key"
14576
14664
  }
14577
14665
  ]
@@ -14584,7 +14672,7 @@
14584
14672
  "explicitId": "openwop.it.idempotency-key-determinism.run-isolation-different-runid-produces-different-key",
14585
14673
  "citations": [
14586
14674
  {
14587
- "section": "idempotency.md §\"Idempotency-Key",
14675
+ "section": "spec/v1/idempotency.md §\"Idempotency-Key",
14588
14676
  "requirement": "run isolation — different runId produces different key"
14589
14677
  }
14590
14678
  ]
@@ -14597,7 +14685,7 @@
14597
14685
  "explicitId": "openwop.it.idempotency-key-determinism.node-isolation-different-nodeid-produces-different-key",
14598
14686
  "citations": [
14599
14687
  {
14600
- "section": "idempotency.md §\"Idempotency-Key",
14688
+ "section": "spec/v1/idempotency.md §\"Idempotency-Key",
14601
14689
  "requirement": "node isolation — different nodeId produces different key"
14602
14690
  }
14603
14691
  ]
@@ -14610,7 +14698,7 @@
14610
14698
  "explicitId": "openwop.it.idempotency-key-determinism.hash-mode-is-deterministic-in-the-payload-alone-run-node-ignored",
14611
14699
  "citations": [
14612
14700
  {
14613
- "section": "idempotency.md §\"Idempotency-Key",
14701
+ "section": "spec/v1/idempotency.md §\"Idempotency-Key",
14614
14702
  "requirement": "hash mode MUST ignore run/node — useful for global remote-dedup caches"
14615
14703
  }
14616
14704
  ]
@@ -14623,7 +14711,7 @@
14623
14711
  "explicitId": "openwop.it.idempotency-key-determinism.output-shape-every-emitted-key-matches-openwop-sha256-prefix-16",
14624
14712
  "citations": [
14625
14713
  {
14626
- "section": "idempotency.md §\"Idempotency-Key",
14714
+ "section": "spec/v1/idempotency.md §\"Idempotency-Key",
14627
14715
  "requirement": null,
14628
14716
  "interpolated": true
14629
14717
  }
@@ -14637,7 +14725,7 @@
14637
14725
  "explicitId": "openwop.it.idempotency-key-determinism.uuid-mode-rejects-with-config-invalid-safety-fix-per-1-1-2",
14638
14726
  "citations": [
14639
14727
  {
14640
- "section": "idempotency.md §\"Idempotency-Key",
14728
+ "section": "spec/v1/idempotency.md §\"Idempotency-Key",
14641
14729
  "requirement": "mode: uuid MUST be rejected — the 1.1.0/1.1.1 non-deterministic default was removed"
14642
14730
  }
14643
14731
  ]
@@ -14650,7 +14738,7 @@
14650
14738
  "explicitId": "openwop.it.idempotency-key-determinism.cross-impl-invariant-pack-output-equals-canonical-sha-256-formula",
14651
14739
  "citations": [
14652
14740
  {
14653
- "section": "idempotency.md §\"Idempotency-Key",
14741
+ "section": "spec/v1/idempotency.md §\"Idempotency-Key",
14654
14742
  "requirement": null,
14655
14743
  "interpolated": true
14656
14744
  }
@@ -14668,11 +14756,11 @@
14668
14756
  "requirement": "first POST /v1/runs MUST return 201"
14669
14757
  },
14670
14758
  {
14671
- "section": "idempotency.md §Layer 1",
14759
+ "section": "spec/v1/idempotency.md §Layer 1",
14672
14760
  "requirement": "replay request with same key + same body MUST return success status (200/201)"
14673
14761
  },
14674
14762
  {
14675
- "section": "idempotency.md §Layer 1",
14763
+ "section": "spec/v1/idempotency.md §Layer 1",
14676
14764
  "requirement": "replay MUST return the SAME runId (no new run created)"
14677
14765
  },
14678
14766
  {
@@ -14689,16 +14777,16 @@
14689
14777
  "explicitId": "openwop.it.idempotency.returns-409-when-the-body-changes-under-the-same-key",
14690
14778
  "citations": [
14691
14779
  {
14692
- "section": "idempotency.md §Layer 1",
14780
+ "section": "spec/v1/idempotency.md §Layer 1",
14693
14781
  "requirement": "same Idempotency-Key with a different body MUST return 409"
14694
14782
  },
14695
14783
  {
14696
- "section": "idempotency.md §\"Record shape, digest, and lease\"",
14784
+ "section": "spec/v1/idempotency.md §\"Record shape, digest, and lease\"",
14697
14785
  "requirement": null,
14698
14786
  "interpolated": true
14699
14787
  },
14700
14788
  {
14701
- "section": "idempotency.md §\"Record shape, digest, and lease\"",
14789
+ "section": "spec/v1/idempotency.md §\"Record shape, digest, and lease\"",
14702
14790
  "requirement": "a digest mismatch MUST NOT return the cached body (no runId on the 409)"
14703
14791
  }
14704
14792
  ]
@@ -14715,19 +14803,19 @@
14715
14803
  "requirement": "first POST /v1/runs returns 201"
14716
14804
  },
14717
14805
  {
14718
- "section": "idempotency.md §Server responsibilities",
14806
+ "section": "spec/v1/idempotency.md §Server responsibilities",
14719
14807
  "requirement": "openwop-Idempotent-Replay value MUST be \"true\" or \"false\""
14720
14808
  },
14721
14809
  {
14722
- "section": "idempotency.md §Layer 1",
14810
+ "section": "spec/v1/idempotency.md §Layer 1",
14723
14811
  "requirement": "replay returns 200 or 201"
14724
14812
  },
14725
14813
  {
14726
- "section": "idempotency.md §Server responsibilities #2",
14814
+ "section": "spec/v1/idempotency.md §Server responsibilities #2",
14727
14815
  "requirement": "openwop-Idempotent-Replay SHOULD be set on idempotent replay responses"
14728
14816
  },
14729
14817
  {
14730
- "section": "idempotency.md §Server responsibilities #2",
14818
+ "section": "spec/v1/idempotency.md §Server responsibilities #2",
14731
14819
  "requirement": "openwop-Idempotent-Replay on replay MUST be \"true\""
14732
14820
  }
14733
14821
  ]
@@ -14744,7 +14832,7 @@
14744
14832
  "requirement": "host MUST handle ≥5 retries 100ms apart without losing the cached response"
14745
14833
  },
14746
14834
  {
14747
- "section": "idempotency.md §Layer 1",
14835
+ "section": "spec/v1/idempotency.md §Layer 1",
14748
14836
  "requirement": "5 retries with same key MUST collapse to exactly one runId"
14749
14837
  }
14750
14838
  ]
@@ -14757,11 +14845,11 @@
14757
14845
  "explicitId": "openwop.it.idempotencyRetry.host-advertising-idempotencyacktimeoutsec-sets-integer-5",
14758
14846
  "citations": [
14759
14847
  {
14760
- "section": "idempotency.md",
14848
+ "section": "spec/v1/idempotency.md",
14761
14849
  "requirement": "limits.idempotencyAckTimeoutSec MUST be an integer when advertised"
14762
14850
  },
14763
14851
  {
14764
- "section": "idempotency.md",
14852
+ "section": "spec/v1/idempotency.md",
14765
14853
  "requirement": "limits.idempotencyAckTimeoutSec MUST be ≥ 5"
14766
14854
  }
14767
14855
  ]
@@ -15308,7 +15396,7 @@
15308
15396
  {
15309
15397
  "id": "openwop.it.interrupt-token-matrix.unknown-token-returns-404-on-post",
15310
15398
  "file": "interrupt-token-matrix.test.ts",
15311
- "line": 118,
15399
+ "line": 131,
15312
15400
  "title": "unknown token returns 404 on POST",
15313
15401
  "explicitId": "openwop.it.interrupt-token-matrix.unknown-token-returns-404-on-post",
15314
15402
  "citations": [
@@ -16196,7 +16284,7 @@
16196
16284
  {
16197
16285
  "id": "openwop.it.mcp-current-auth-boundary.a-mount-that-requires-oauth-lane-authentication-offers-resource-metadata-or-a-pa",
16198
16286
  "file": "mcp-current-auth-boundary.test.ts",
16199
- "line": 97,
16287
+ "line": 100,
16200
16288
  "title": "a mount that requires OAuth-lane authentication offers resource_metadata or a path-inserted PRM",
16201
16289
  "explicitId": "openwop.it.mcp-current-auth-boundary.a-mount-that-requires-oauth-lane-authentication-offers-resource-metadata-or-a-path-inserted-prm",
16202
16290
  "citations": [
@@ -16260,10 +16348,6 @@
16260
16348
  "section": "host-sample-test-seams.md §23",
16261
16349
  "requirement": "the host MUST have called the tool"
16262
16350
  },
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
16351
  {
16268
16352
  "section": "mcp-integration.md §D",
16269
16353
  "requirement": "an extension MUST NOT gain tool authority or scope by appearing in _meta (mcp-extension-no-authority)"
@@ -16277,7 +16361,7 @@
16277
16361
  {
16278
16362
  "id": "openwop.it.mcp-extension-opacity.server-half-unknown-meta-extension-keys-on-a-request-are-ignored-not-refused-and",
16279
16363
  "file": "mcp-extension-opacity.test.ts",
16280
- "line": 67,
16364
+ "line": 68,
16281
16365
  "title": "server half: unknown _meta extension keys on a request are ignored, not refused and not honoured",
16282
16366
  "explicitId": "openwop.it.mcp-extension-opacity.server-half-unknown-meta-extension-keys-on-a-request-are-ignored-not-refused-and",
16283
16367
  "citations": [
@@ -16298,10 +16382,6 @@
16298
16382
  "section": "RFCS/0153 §C",
16299
16383
  "requirement": "the host MUST have called the tool at least once for this leg to mean anything"
16300
16384
  },
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
16385
  {
16306
16386
  "section": "mcp-integration.md §C.1",
16307
16387
  "requirement": "the host MUST recognise resultType input_required"
@@ -16335,7 +16415,7 @@
16335
16415
  {
16336
16416
  "id": "openwop.it.mcp-mrtr-roundtrip.a-suspending-tool-answers-input-required-with-elicitation-requeststate-the-retry",
16337
16417
  "file": "mcp-mrtr-roundtrip.test.ts",
16338
- "line": 95,
16418
+ "line": 96,
16339
16419
  "title": "a suspending tool answers input_required with elicitation + requestState; the retry resolves it; a forged requestState is refused",
16340
16420
  "explicitId": "openwop.it.mcp-mrtr-roundtrip.a-suspending-tool-answers-input-required-with-elicitation-requeststate-the-retry",
16341
16421
  "citations": [
@@ -16744,11 +16824,6 @@
16744
16824
  "title": "outbound calls carry MCP-Protocol-Version in date form",
16745
16825
  "explicitId": "openwop.it.mcp-version-negotiation.outbound-calls-carry-mcp-protocol-version-in-date-form",
16746
16826
  "citations": [
16747
- {
16748
- "section": "RFCS/0153 §B",
16749
- "requirement": null,
16750
- "interpolated": true
16751
- },
16752
16827
  {
16753
16828
  "section": "RFCS/0153 §B",
16754
16829
  "requirement": "the host MUST have called the server"
@@ -16767,7 +16842,7 @@
16767
16842
  {
16768
16843
  "id": "openwop.it.mcp-version-negotiation.the-negotiated-revision-is-one-the-host-advertises",
16769
16844
  "file": "mcp-version-negotiation.test.ts",
16770
- "line": 122,
16845
+ "line": 117,
16771
16846
  "title": "the negotiated revision is one the host advertises",
16772
16847
  "explicitId": "openwop.it.mcp-version-negotiation.the-negotiated-revision-is-one-the-host-advertises",
16773
16848
  "citations": [
@@ -16781,7 +16856,7 @@
16781
16856
  {
16782
16857
  "id": "openwop.it.mcp-version-negotiation.an-unsupported-revision-fails-through-the-canonical-interop-envelope",
16783
16858
  "file": "mcp-version-negotiation.test.ts",
16784
- "line": 146,
16859
+ "line": 141,
16785
16860
  "title": "an unsupported revision fails through the canonical interop envelope",
16786
16861
  "explicitId": "openwop.it.mcp-version-negotiation.an-unsupported-revision-fails-through-the-canonical-interop-envelope",
16787
16862
  "citations": [
@@ -18034,11 +18109,11 @@
18034
18109
  "explicitId": "openwop.it.multi-region-idempotency-behavior.two-region-conflict-resolves-to-the-lex-min-runid-per-annex-convergence-rule",
18035
18110
  "citations": [
18036
18111
  {
18037
- "section": "idempotency.md §\"Multi-region idempotency annex\"",
18112
+ "section": "spec/v1/idempotency.md §\"Multi-region idempotency annex\"",
18038
18113
  "requirement": "simulate-partition seam MUST return 200 when ≥2 conflicting claims are submitted"
18039
18114
  },
18040
18115
  {
18041
- "section": "idempotency.md §\"Convergence rule\"",
18116
+ "section": "spec/v1/idempotency.md §\"Convergence rule\"",
18042
18117
  "requirement": "winner MUST be the lex-min runId (run-a-west < run-b-east)"
18043
18118
  }
18044
18119
  ]
@@ -18051,11 +18126,11 @@
18051
18126
  "explicitId": "openwop.it.multi-region-idempotency-behavior.three-region-partition-resolves-to-a-single-winner",
18052
18127
  "citations": [
18053
18128
  {
18054
- "section": "idempotency.md §\"Convergence rule\"",
18129
+ "section": "spec/v1/idempotency.md §\"Convergence rule\"",
18055
18130
  "requirement": "winner MUST be the lex-min runId across all conflicting claims"
18056
18131
  },
18057
18132
  {
18058
- "section": "idempotency.md §\"Convergence rule\"",
18133
+ "section": "spec/v1/idempotency.md §\"Convergence rule\"",
18059
18134
  "requirement": "losers array MUST contain N-1 entries when N claims conflict"
18060
18135
  }
18061
18136
  ]
@@ -18068,11 +18143,11 @@
18068
18143
  "explicitId": "openwop.it.multi-region-idempotency-behavior.every-region-gets-a-cache-redirect-entry-pointing-at-the-winner",
18069
18144
  "citations": [
18070
18145
  {
18071
- "section": "idempotency.md §\"Convergence rule\"",
18146
+ "section": "spec/v1/idempotency.md §\"Convergence rule\"",
18072
18147
  "requirement": "cacheRedirects MUST contain one entry per claim (including the winner)"
18073
18148
  },
18074
18149
  {
18075
- "section": "idempotency.md §\"Convergence rule\"",
18150
+ "section": "spec/v1/idempotency.md §\"Convergence rule\"",
18076
18151
  "requirement": "every cache redirect MUST point at the winner runId"
18077
18152
  }
18078
18153
  ]
@@ -18085,7 +18160,7 @@
18085
18160
  "explicitId": "openwop.it.multi-region-idempotency-behavior.loser-cancel-reason-must-be-the-canonical-cross-region-dedup-loss-string",
18086
18161
  "citations": [
18087
18162
  {
18088
- "section": "idempotency.md §\"Convergence rule\"",
18163
+ "section": "spec/v1/idempotency.md §\"Convergence rule\"",
18089
18164
  "requirement": "loserCancelReason MUST be the canonical `cross_region_dedup_loss` string"
18090
18165
  }
18091
18166
  ]
@@ -18098,7 +18173,7 @@
18098
18173
  "explicitId": "openwop.it.multi-region-idempotency-behavior.resolver-is-order-invariant-shuffled-inputs-produce-the-same-winner",
18099
18174
  "citations": [
18100
18175
  {
18101
- "section": "idempotency.md §\"Convergence rule\" — determinism",
18176
+ "section": "spec/v1/idempotency.md §\"Convergence rule\" — determinism",
18102
18177
  "requirement": "resolver MUST be order-invariant; all permutations MUST produce the same lex-min winner"
18103
18178
  }
18104
18179
  ]
@@ -18111,7 +18186,7 @@
18111
18186
  "explicitId": "openwop.it.multi-region-idempotency-behavior.mismatched-tuple-rejects-with-400-validation-error",
18112
18187
  "citations": [
18113
18188
  {
18114
- "section": "idempotency.md §\"Convergence rule\"",
18189
+ "section": "spec/v1/idempotency.md §\"Convergence rule\"",
18115
18190
  "requirement": "claims with non-matching (tenantId, endpoint, key) MUST be rejected — it would be a programming error in the caller"
18116
18191
  }
18117
18192
  ]
@@ -18124,7 +18199,7 @@
18124
18199
  "explicitId": "openwop.it.multi-region-idempotency.idempotency-crossregion-when-advertised-must-be-one-of-the-closed-enum",
18125
18200
  "citations": [
18126
18201
  {
18127
- "section": "idempotency.md §\"Multi-region idempotency\" §\"Capability advertisement\"",
18202
+ "section": "spec/v1/idempotency.md §\"Multi-region idempotency\" §\"Capability advertisement\"",
18128
18203
  "requirement": "crossRegion MUST be one of {\"single-region\",\"reconciled-records\",\"fenced-effects\"}"
18129
18204
  }
18130
18205
  ]
@@ -18137,7 +18212,7 @@
18137
18212
  "explicitId": "openwop.it.multi-region-idempotency.multi-region-hosts-should-expose-the-cross-region-conflict-counter-per-operator",
18138
18213
  "citations": [
18139
18214
  {
18140
- "section": "idempotency.md §\"Operator surface\"",
18215
+ "section": "spec/v1/idempotency.md §\"Operator surface\"",
18141
18216
  "requirement": null,
18142
18217
  "interpolated": true
18143
18218
  }
@@ -19345,7 +19420,7 @@
19345
19420
  {
19346
19421
  "id": "openwop.it.pause-resume.pause-transitions-to-paused-resume-returns-the-run-to-running",
19347
19422
  "file": "pause-resume.test.ts",
19348
- "line": 62,
19423
+ "line": 81,
19349
19424
  "title": "pause transitions to paused; resume returns the run to running",
19350
19425
  "explicitId": "openwop.it.pause-resume.pause-transitions-to-paused-resume-returns-the-run-to-running",
19351
19426
  "citations": [
@@ -19362,7 +19437,7 @@
19362
19437
  {
19363
19438
  "id": "openwop.it.pause-resume.resuming-a-running-not-paused-run-returns-409-with-details-runstatus",
19364
19439
  "file": "pause-resume.test.ts",
19365
- "line": 110,
19440
+ "line": 129,
19366
19441
  "title": "resuming a running (not paused) run returns 409 with details.runStatus",
19367
19442
  "explicitId": "openwop.it.pause-resume.resuming-a-running-not-paused-run-returns-409-with-details-runstatus",
19368
19443
  "citations": [
@@ -19379,7 +19454,7 @@
19379
19454
  {
19380
19455
  "id": "openwop.it.pause-resume.pause-on-an-already-paused-run-returns-409-with-details-runstatus-paused-unless",
19381
19456
  "file": "pause-resume.test.ts",
19382
- "line": 144,
19457
+ "line": 163,
19383
19458
  "title": ":pause on an already-paused run returns 409 with details.runStatus paused, unless the request carries the original Idempotency-Key",
19384
19459
  "explicitId": "openwop.it.pause-resume.pause-on-an-already-paused-run-returns-409-with-details-runstatus-paused-unless",
19385
19460
  "citations": [
@@ -19408,7 +19483,7 @@
19408
19483
  {
19409
19484
  "id": "openwop.it.pause-resume.pause-on-a-completed-cancelled-failed-run-must-return-409",
19410
19485
  "file": "pause-resume.test.ts",
19411
- "line": 205,
19486
+ "line": 224,
19412
19487
  "title": ":pause on a completed/cancelled/failed run MUST return 409",
19413
19488
  "explicitId": "openwop.it.pause-resume.pause-on-a-completed-cancelled-failed-run-must-return-409",
19414
19489
  "citations": [
@@ -19421,7 +19496,7 @@
19421
19496
  {
19422
19497
  "id": "openwop.it.pause-resume.under-drain-current-node-node-completed-precedes-run-paused-in-the-log",
19423
19498
  "file": "pause-resume.test.ts",
19424
- "line": 229,
19499
+ "line": 248,
19425
19500
  "title": "under drain-current-node node.completed precedes run.paused in the log",
19426
19501
  "explicitId": "openwop.it.pause-resume.under-drain-current-node-node-completed-precedes-run-paused-in-the-log",
19427
19502
  "citations": [
@@ -19439,7 +19514,7 @@
19439
19514
  {
19440
19515
  "id": "openwop.it.pause-resume.pause-must-not-silently-override-an-active-interrupt-suspend",
19441
19516
  "file": "pause-resume.test.ts",
19442
- "line": 268,
19517
+ "line": 287,
19443
19518
  "title": ":pause MUST NOT silently override an active interrupt suspend",
19444
19519
  "explicitId": "openwop.it.pause-resume.pause-must-not-silently-override-an-active-interrupt-suspend",
19445
19520
  "citations": [
@@ -19456,7 +19531,7 @@
19456
19531
  {
19457
19532
  "id": "openwop.it.pause-resume.every-drainpolicy-advertised-by-the-host-is-accepted-on-pause",
19458
19533
  "file": "pause-resume.test.ts",
19459
- "line": 324,
19534
+ "line": 343,
19460
19535
  "title": "every drainPolicy advertised by the host is accepted on :pause",
19461
19536
  "explicitId": "openwop.it.pause-resume.every-drainpolicy-advertised-by-the-host-is-accepted-on-pause",
19462
19537
  "citations": [
@@ -20771,17 +20846,21 @@
20771
20846
  {
20772
20847
  "id": "openwop.it.prompt-read-workspace-membership-enforced.get-v1-prompts-workspaceid-non-member-must-refuse-or-return-empty-templates-neve",
20773
20848
  "file": "prompt-read-workspace-membership-enforced.test.ts",
20774
- "line": 101,
20849
+ "line": 102,
20775
20850
  "title": "GET /v1/prompts?workspaceId=<non-member> MUST refuse OR return empty templates[] — never another workspace's content",
20776
20851
  "explicitId": "openwop.it.prompt-read-workspace-membership-enforced.get-v1-prompts-workspaceid-non-member-must-refuse-or-return-empty-templates-neve",
20777
20852
  "citations": [
20778
20853
  {
20779
- "section": "spec/v1/rest-endpoints.md §Common error codes — workspace_membership_required",
20854
+ "section": "spec/v1/prompts.md §Workspace membership on workspace-scoped reads and writes",
20780
20855
  "requirement": null,
20781
20856
  "interpolated": true
20782
20857
  },
20783
20858
  {
20784
20859
  "section": "spec/v1/prompts.md §Workspace membership on workspace-scoped reads and writes",
20860
+ "requirement": "a workspace-scoped read for a non-member workspace MUST be refused (4xx) or return no templates"
20861
+ },
20862
+ {
20863
+ "section": "spec/v1/rest-endpoints.md §Common error codes — workspace_membership_required",
20785
20864
  "requirement": null,
20786
20865
  "interpolated": true
20787
20866
  }
@@ -21987,7 +22066,7 @@
21987
22066
  {
21988
22067
  "id": "openwop.it.redaction.aiproviders-is-well-formed-when-present-byok-supported",
21989
22068
  "file": "redaction.test.ts",
21990
- "line": 117,
22069
+ "line": 119,
21991
22070
  "title": "aiProviders is well-formed when present (byok ⊆ supported)",
21992
22071
  "explicitId": "openwop.it.redaction.aiproviders-is-well-formed-when-present-byok-supported",
21993
22072
  "citations": [
@@ -22001,7 +22080,7 @@
22001
22080
  {
22002
22081
  "id": "openwop.it.redaction.canary-s-planted-in-authorization-header-is-not-echoed-in-401-body",
22003
22082
  "file": "redaction.test.ts",
22004
- "line": 148,
22083
+ "line": 150,
22005
22084
  "title": "canary \"%s\" planted in Authorization header is not echoed in 401 body",
22006
22085
  "explicitId": null,
22007
22086
  "citations": []
@@ -22009,7 +22088,7 @@
22009
22088
  {
22010
22089
  "id": "openwop.it.redaction.the-marker-substring-alone-never-appears-in-a-401-body-universal",
22011
22090
  "file": "redaction.test.ts",
22012
- "line": 172,
22091
+ "line": 174,
22013
22092
  "title": "the marker substring alone never appears in a 401 body (universal)",
22014
22093
  "explicitId": "openwop.it.redaction.the-marker-substring-alone-never-appears-in-a-401-body-universal",
22015
22094
  "citations": [
@@ -22022,7 +22101,7 @@
22022
22101
  {
22023
22102
  "id": "openwop.it.redaction.skips-when-host-does-not-advertise-secrets-supported",
22024
22103
  "file": "redaction.test.ts",
22025
- "line": 189,
22104
+ "line": 191,
22026
22105
  "title": "skips when host does NOT advertise secrets.supported",
22027
22106
  "explicitId": "openwop.it.redaction.skips-when-host-does-not-advertise-secrets-supported",
22028
22107
  "citations": [
@@ -22056,7 +22135,7 @@
22056
22135
  {
22057
22136
  "id": "openwop.it.redactionAdversarial.jwt-shaped-canary-in-workflowid-of-a-404-failing-request-must-not-echo-verbatim",
22058
22137
  "file": "redactionAdversarial.test.ts",
22059
- "line": 97,
22138
+ "line": 98,
22060
22139
  "title": "JWT-shaped canary in workflowId of a 404-failing request MUST NOT echo verbatim in error response",
22061
22140
  "explicitId": "openwop.it.redactionAdversarial.jwt-shaped-canary-in-workflowid-of-a-404-failing-request-must-not-echo-verbatim",
22062
22141
  "citations": [
@@ -22073,7 +22152,7 @@
22073
22152
  {
22074
22153
  "id": "openwop.it.redactionAdversarial.anthropic-shaped-canary-embedded-in-non-credential-input-must-not-appear-verbati",
22075
22154
  "file": "redactionAdversarial.test.ts",
22076
- "line": 123,
22155
+ "line": 124,
22077
22156
  "title": "Anthropic-shaped canary embedded in non-credential input MUST NOT appear verbatim in events",
22078
22157
  "explicitId": "openwop.it.redactionAdversarial.anthropic-shaped-canary-embedded-in-non-credential-input-must-not-appear-verbati",
22079
22158
  "citations": [
@@ -22086,7 +22165,7 @@
22086
22165
  {
22087
22166
  "id": "openwop.it.redactionAdversarial.every-canary-in-canaries-has-the-marker-substring",
22088
22167
  "file": "redactionAdversarial.test.ts",
22089
- "line": 152,
22168
+ "line": 153,
22090
22169
  "title": "every canary in CANARIES has the marker substring",
22091
22170
  "explicitId": "openwop.it.redactionAdversarial.every-canary-in-canaries-has-the-marker-substring",
22092
22171
  "citations": [
@@ -22239,7 +22318,7 @@
22239
22318
  {
22240
22319
  "id": "openwop.it.replay-divergence-at-refusal.phase-4-host-must-emit-replay-divergedatrefusal-fail-with-replay-diverged-at-ref~2",
22241
22320
  "file": "replay-divergence-at-refusal.test.ts",
22242
- "line": 320,
22321
+ "line": 323,
22243
22322
  "title": "Phase 4 host MUST emit replay.divergedAtRefusal + fail with replay_diverged_at_refusal when original=refusal + replay=valid (symmetric case)",
22244
22323
  "explicitId": "openwop.it.replay-divergence-at-refusal.phase-4-host-must-emit-replay-divergedatrefusal-fail-with-replay-diverged-at-ref~2",
22245
22324
  "citations": [
@@ -22867,7 +22946,7 @@
22867
22946
  {
22868
22947
  "id": "openwop.it.replayDeterminism.branch-mode-does-not-need-to-produce-identical-event-sequences-negative-control",
22869
22948
  "file": "replayDeterminism.test.ts",
22870
- "line": 156,
22949
+ "line": 161,
22871
22950
  "title": "branch mode does NOT need to produce identical event sequences (negative-control)",
22872
22951
  "explicitId": "openwop.it.replayDeterminism.branch-mode-does-not-need-to-produce-identical-event-sequences-negative-control",
22873
22952
  "citations": [
@@ -23521,7 +23600,7 @@
23521
23600
  {
23522
23601
  "id": "openwop.it.runner-ledger.files-that-finished-before-this-one-appear-in-the-ledger-file-with-an-assertion",
23523
23602
  "file": "runner-ledger.test.ts",
23524
- "line": 270,
23603
+ "line": 274,
23525
23604
  "title": "files that finished before this one appear in the ledger file with an assertion count",
23526
23605
  "explicitId": "openwop.it.runner-ledger.files-that-finished-before-this-one-appear-in-the-ledger-file-with-an-assertion",
23527
23606
  "citations": [
@@ -23614,7 +23693,7 @@
23614
23693
  {
23615
23694
  "id": "openwop.it.runtime-capabilities.terminates-the-run-with-error-code-capability-not-provided",
23616
23695
  "file": "runtime-capabilities.test.ts",
23617
- "line": 92,
23696
+ "line": 94,
23618
23697
  "title": "terminates the run with error.code = capability_not_provided",
23619
23698
  "explicitId": "openwop.it.runtime-capabilities.terminates-the-run-with-error-code-capability-not-provided",
23620
23699
  "citations": [
@@ -25729,7 +25808,7 @@
25729
25808
  {
25730
25809
  "id": "openwop.it.tool-catalog-projection.advisory-should-an-unchanged-catalog-reads-identically-sorted-by-toolid",
25731
25810
  "file": "tool-catalog-projection.test.ts",
25732
- "line": 164,
25811
+ "line": 167,
25733
25812
  "title": "advisory (SHOULD): an unchanged catalog reads identically, sorted by toolId",
25734
25813
  "explicitId": "openwop.it.tool-catalog-projection.advisory-should-an-unchanged-catalog-reads-identically-sorted-by-toolid",
25735
25814
  "citations": [
@@ -27581,6 +27660,20 @@
27581
27660
  }
27582
27661
  ]
27583
27662
  },
27663
+ {
27664
+ "id": "openwop.it.v2-a2ui-v09-surface.a-version-2-surface-is-admitted-and-a-version-1-body-under-schema-version-2-is-r",
27665
+ "file": "v2-a2ui-v09-surface.test.ts",
27666
+ "line": 311,
27667
+ "title": "a version-2 surface is admitted and a version-1 body under schema version 2 is refused, in the same run",
27668
+ "explicitId": "openwop.family.a2uiSurface",
27669
+ "citations": [
27670
+ {
27671
+ "section": "spec/v2/ext/a2uiSurface/README.md §Conformance",
27672
+ "requirement": null,
27673
+ "interpolated": true
27674
+ }
27675
+ ]
27676
+ },
27584
27677
  {
27585
27678
  "id": "openwop.it.v2-advertised-fixtures-exist.a-sampled-advertised-fixture-is-actually-creatable-not-just-listed",
27586
27679
  "file": "v2-advertised-fixtures-exist.test.ts",
@@ -28908,7 +29001,7 @@
28908
29001
  {
28909
29002
  "id": "openwop.it.v2-effect-identity-business-key.get-runs-runid-effects-validates-and-every-row-is-keyed-on-business-identity-or",
28910
29003
  "file": "v2-effect-identity-business-key.test.ts",
28911
- "line": 50,
29004
+ "line": 59,
28912
29005
  "title": "GET /runs/{runId}/effects validates and every row is keyed on business identity or the activity recipe",
28913
29006
  "explicitId": "openwop.requirement.0173.effect-identity-business-key",
28914
29007
  "citations": [
@@ -28948,7 +29041,7 @@
28948
29041
  {
28949
29042
  "id": "openwop.it.v2-effect-identity-business-key.the-same-provider-key-is-presented-across-two-transport-retries",
28950
29043
  "file": "v2-effect-identity-business-key.test.ts",
28951
- "line": 108,
29044
+ "line": 120,
28952
29045
  "title": "the same provider key is presented across two transport retries",
28953
29046
  "explicitId": "openwop.requirement.0173.effect-identity-business-key.retry",
28954
29047
  "citations": [
@@ -29109,7 +29202,7 @@
29109
29202
  {
29110
29203
  "id": "openwop.it.v2-era-2-append-vocabulary.a-host-append-to-an-open-era-2-run-keeps-the-log-in-v1-vocabulary-so-the-whole-l",
29111
29204
  "file": "v2-era-2-append-vocabulary.test.ts",
29112
- "line": 48,
29205
+ "line": 50,
29113
29206
  "title": "a host append to an open era-2 run keeps the log in v1 vocabulary, so the whole log still reads",
29114
29207
  "explicitId": "openwop.requirement.0176.era-2-append-vocabulary",
29115
29208
  "citations": [
@@ -29128,6 +29221,11 @@
29128
29221
  "requirement": null,
29129
29222
  "interpolated": true
29130
29223
  },
29224
+ {
29225
+ "section": "spec/v2/core/persistence.md §The writer rule",
29226
+ "requirement": null,
29227
+ "interpolated": true
29228
+ },
29131
29229
  {
29132
29230
  "section": "spec/v2/core/persistence.md §The writer rule",
29133
29231
  "requirement": null,
@@ -29138,7 +29236,7 @@
29138
29236
  {
29139
29237
  "id": "openwop.it.v2-era-2-append-vocabulary.the-run-keeps-the-era-it-was-created-with-an-append-does-not-promote-it-to-era-3",
29140
29238
  "file": "v2-era-2-append-vocabulary.test.ts",
29141
- "line": 174,
29239
+ "line": 189,
29142
29240
  "title": "the run keeps the era it was created with; an append does not promote it to era 3",
29143
29241
  "explicitId": "openwop.requirement.0176.era-2-append-vocabulary",
29144
29242
  "citations": [
@@ -29308,6 +29406,176 @@
29308
29406
  }
29309
29407
  ]
29310
29408
  },
29409
+ {
29410
+ "id": "openwop.it.v2-ext-family-claims.brand",
29411
+ "file": "v2-ext-family-claims.test.ts",
29412
+ "line": 51,
29413
+ "title": "brand",
29414
+ "explicitId": "openwop.family.brand",
29415
+ "citations": [
29416
+ {
29417
+ "section": null,
29418
+ "requirement": null,
29419
+ "interpolated": true
29420
+ }
29421
+ ]
29422
+ },
29423
+ {
29424
+ "id": "openwop.it.v2-ext-family-claims.canvas",
29425
+ "file": "v2-ext-family-claims.test.ts",
29426
+ "line": 52,
29427
+ "title": "canvas",
29428
+ "explicitId": "openwop.family.canvas",
29429
+ "citations": [
29430
+ {
29431
+ "section": null,
29432
+ "requirement": null,
29433
+ "interpolated": true
29434
+ }
29435
+ ]
29436
+ },
29437
+ {
29438
+ "id": "openwop.it.v2-ext-family-claims.chat",
29439
+ "file": "v2-ext-family-claims.test.ts",
29440
+ "line": 53,
29441
+ "title": "chat",
29442
+ "explicitId": "openwop.family.chat",
29443
+ "citations": [
29444
+ {
29445
+ "section": null,
29446
+ "requirement": null,
29447
+ "interpolated": true
29448
+ }
29449
+ ]
29450
+ },
29451
+ {
29452
+ "id": "openwop.it.v2-ext-family-claims.coordination",
29453
+ "file": "v2-ext-family-claims.test.ts",
29454
+ "line": 54,
29455
+ "title": "coordination",
29456
+ "explicitId": "openwop.family.coordination",
29457
+ "citations": [
29458
+ {
29459
+ "section": null,
29460
+ "requirement": null,
29461
+ "interpolated": true
29462
+ }
29463
+ ]
29464
+ },
29465
+ {
29466
+ "id": "openwop.it.v2-ext-family-claims.dataintegration",
29467
+ "file": "v2-ext-family-claims.test.ts",
29468
+ "line": 55,
29469
+ "title": "dataIntegration",
29470
+ "explicitId": "openwop.family.dataIntegration",
29471
+ "citations": [
29472
+ {
29473
+ "section": null,
29474
+ "requirement": null,
29475
+ "interpolated": true
29476
+ }
29477
+ ]
29478
+ },
29479
+ {
29480
+ "id": "openwop.it.v2-ext-family-claims.entities",
29481
+ "file": "v2-ext-family-claims.test.ts",
29482
+ "line": 56,
29483
+ "title": "entities",
29484
+ "explicitId": "openwop.family.entities",
29485
+ "citations": [
29486
+ {
29487
+ "section": null,
29488
+ "requirement": null,
29489
+ "interpolated": true
29490
+ }
29491
+ ]
29492
+ },
29493
+ {
29494
+ "id": "openwop.it.v2-ext-family-claims.kanban",
29495
+ "file": "v2-ext-family-claims.test.ts",
29496
+ "line": 57,
29497
+ "title": "kanban",
29498
+ "explicitId": "openwop.family.kanban",
29499
+ "citations": [
29500
+ {
29501
+ "section": null,
29502
+ "requirement": null,
29503
+ "interpolated": true
29504
+ }
29505
+ ]
29506
+ },
29507
+ {
29508
+ "id": "openwop.it.v2-ext-family-claims.knowledge",
29509
+ "file": "v2-ext-family-claims.test.ts",
29510
+ "line": 58,
29511
+ "title": "knowledge",
29512
+ "explicitId": "openwop.family.knowledge",
29513
+ "citations": [
29514
+ {
29515
+ "section": null,
29516
+ "requirement": null,
29517
+ "interpolated": true
29518
+ }
29519
+ ]
29520
+ },
29521
+ {
29522
+ "id": "openwop.it.v2-ext-family-claims.launchstudio",
29523
+ "file": "v2-ext-family-claims.test.ts",
29524
+ "line": 59,
29525
+ "title": "launchStudio",
29526
+ "explicitId": "openwop.family.launchStudio",
29527
+ "citations": [
29528
+ {
29529
+ "section": null,
29530
+ "requirement": null,
29531
+ "interpolated": true
29532
+ }
29533
+ ]
29534
+ },
29535
+ {
29536
+ "id": "openwop.it.v2-ext-family-claims.messaging",
29537
+ "file": "v2-ext-family-claims.test.ts",
29538
+ "line": 60,
29539
+ "title": "messaging",
29540
+ "explicitId": "openwop.family.messaging",
29541
+ "citations": [
29542
+ {
29543
+ "section": null,
29544
+ "requirement": null,
29545
+ "interpolated": true
29546
+ }
29547
+ ]
29548
+ },
29549
+ {
29550
+ "id": "openwop.it.v2-ext-family-claims.webresearch",
29551
+ "file": "v2-ext-family-claims.test.ts",
29552
+ "line": 61,
29553
+ "title": "webResearch",
29554
+ "explicitId": "openwop.family.webResearch",
29555
+ "citations": [
29556
+ {
29557
+ "section": null,
29558
+ "requirement": null,
29559
+ "interpolated": true
29560
+ }
29561
+ ]
29562
+ },
29563
+ {
29564
+ "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",
29565
+ "file": "v2-ext-rest-transport.test.ts",
29566
+ "line": 75,
29567
+ "title": "a strong ETag on the 200, 304 on a match while the run is parked, and a new ETag once it completes",
29568
+ "explicitId": null,
29569
+ "citations": []
29570
+ },
29571
+ {
29572
+ "id": "openwop.it.v2-ext-rest-transport.each-coding-in-contentencodings-is-produced-when-asked-for-alone-and-decodes-to",
29573
+ "file": "v2-ext-rest-transport.test.ts",
29574
+ "line": 112,
29575
+ "title": "each coding in contentEncodings is produced when asked for alone and decodes to the identity body",
29576
+ "explicitId": null,
29577
+ "citations": []
29578
+ },
29311
29579
  {
29312
29580
  "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",
29313
29581
  "file": "v2-fork-a-v1-run.test.ts",
@@ -29567,7 +29835,7 @@
29567
29835
  {
29568
29836
  "id": "openwop.it.v2-idempotency-in-flight.while-the-seam-holds-the-claim-a-same-key-create-is-refused-409-idempotency-in-f",
29569
29837
  "file": "v2-idempotency-in-flight.test.ts",
29570
- "line": 154,
29838
+ "line": 157,
29571
29839
  "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",
29572
29840
  "explicitId": "openwop.requirement.0213.in-flight-refused-under-hold",
29573
29841
  "citations": [
@@ -30014,7 +30282,7 @@
30014
30282
  {
30015
30283
  "id": "openwop.it.v2-legacy-profiles-absent.no-root-profiles-exists-in-the-v2-representation",
30016
30284
  "file": "v2-legacy-profiles-absent.test.ts",
30017
- "line": 70,
30285
+ "line": 68,
30018
30286
  "title": "no root profiles[] exists in the v2 representation",
30019
30287
  "explicitId": "openwop.requirement.0175.legacy-profiles-absent.no-root-profiles",
30020
30288
  "citations": [
@@ -33402,7 +33670,7 @@
33402
33670
  {
33403
33671
  "id": "openwop.it.v2-version-header-honored.a-host-advertising-two-majors-serves-two-different-representations",
33404
33672
  "file": "v2-version-header-honored.test.ts",
33405
- "line": 185,
33673
+ "line": 188,
33406
33674
  "title": "a host advertising two majors serves two different representations",
33407
33675
  "explicitId": "openwop.requirement.0172.version-header-honored",
33408
33676
  "citations": [
@@ -33571,7 +33839,7 @@
33571
33839
  {
33572
33840
  "id": "openwop.it.v2-webhook-durable-delivery.an-exhausted-delivery-is-dead-lettered-never-dropped",
33573
33841
  "file": "v2-webhook-durable-delivery.test.ts",
33574
- "line": 376,
33842
+ "line": 378,
33575
33843
  "title": "an exhausted delivery is dead-lettered, never dropped",
33576
33844
  "explicitId": "openwop.requirement.0173.webhook-durable-delivery.dead-letter",
33577
33845
  "citations": [
@@ -33605,7 +33873,7 @@
33605
33873
  {
33606
33874
  "id": "openwop.it.v2-webhook-durable-delivery.the-dead-letter-read-is-served-and-its-records-carry-no-payload",
33607
33875
  "file": "v2-webhook-durable-delivery.test.ts",
33608
- "line": 478,
33876
+ "line": 480,
33609
33877
  "title": "the dead-letter read is served and its records carry no payload",
33610
33878
  "explicitId": "openwop.requirement.0188.dead-letter-read",
33611
33879
  "citations": [
@@ -33618,7 +33886,7 @@
33618
33886
  {
33619
33887
  "id": "openwop.it.v2-webhook-durable-delivery.after-unregister-the-dead-letter-read-answers-404-not-found-as-for-a-subscriptio",
33620
33888
  "file": "v2-webhook-durable-delivery.test.ts",
33621
- "line": 499,
33889
+ "line": 501,
33622
33890
  "title": "after unregister, the dead-letter read answers 404 not_found, as for a subscription that never existed",
33623
33891
  "explicitId": "openwop.requirement.0217.dead-letter-read-after-unregister",
33624
33892
  "citations": [
@@ -33645,7 +33913,7 @@
33645
33913
  {
33646
33914
  "id": "openwop.it.v2-webhook-durable-delivery.a-dead-letter-record-carries-no-delivered-payload",
33647
33915
  "file": "v2-webhook-durable-delivery.test.ts",
33648
- "line": 532,
33916
+ "line": 534,
33649
33917
  "title": "a dead-letter record carries no delivered payload",
33650
33918
  "explicitId": "openwop.requirement.0188.dead-letter-content-free",
33651
33919
  "citations": [
@@ -34870,7 +35138,7 @@
34870
35138
  {
34871
35139
  "id": "openwop.it.webhook-signed-delivery.control-with-a-tunnel-wired-the-host-still-refuses-the-loopback-receiver",
34872
35140
  "file": "webhook-signed-delivery.test.ts",
34873
- "line": 440,
35141
+ "line": 442,
34874
35142
  "title": "control: with a tunnel wired, the host still refuses the loopback receiver",
34875
35143
  "explicitId": "openwop.it.webhook-signed-delivery.control-with-a-tunnel-wired-the-host-still-refuses-the-loopback-receiver",
34876
35144
  "citations": [
@@ -35443,7 +35711,7 @@
35443
35711
  {
35444
35712
  "id": "openwop.it.workflow-chain-host-expansion.positive-2-node-chain-matches-the-reference-library-edge-rewrite-capability-prop",
35445
35713
  "file": "workflow-chain-host-expansion.test.ts",
35446
- "line": 205,
35714
+ "line": 208,
35447
35715
  "title": "positive — 2-node chain matches the reference library (edge rewrite + capability propagation)",
35448
35716
  "explicitId": "openwop.it.workflow-chain-host-expansion.positive-2-node-chain-matches-the-reference-library-edge-rewrite-capability-prop",
35449
35717
  "citations": [
@@ -35460,7 +35728,7 @@
35460
35728
  {
35461
35729
  "id": "openwop.it.workflow-chain-host-expansion.negative-unknown-pack-returns-404-pack-not-found",
35462
35730
  "file": "workflow-chain-host-expansion.test.ts",
35463
- "line": 237,
35731
+ "line": 240,
35464
35732
  "title": "negative — unknown pack returns 404 pack_not_found",
35465
35733
  "explicitId": "openwop.it.workflow-chain-host-expansion.negative-unknown-pack-returns-404-pack-not-found",
35466
35734
  "citations": [
@@ -35473,7 +35741,7 @@
35473
35741
  {
35474
35742
  "id": "openwop.it.workflow-chain-host-expansion.negative-known-pack-but-unknown-chainid-returns-404-chain-not-found",
35475
35743
  "file": "workflow-chain-host-expansion.test.ts",
35476
- "line": 249,
35744
+ "line": 252,
35477
35745
  "title": "negative — known pack but unknown chainId returns 404 chain_not_found",
35478
35746
  "explicitId": "openwop.it.workflow-chain-host-expansion.negative-known-pack-but-unknown-chainid-returns-404-chain-not-found",
35479
35747
  "citations": [
@@ -35486,7 +35754,7 @@
35486
35754
  {
35487
35755
  "id": "openwop.it.workflow-chain-host-expansion.negative-malformed-request-body-returns-422-invalid-request",
35488
35756
  "file": "workflow-chain-host-expansion.test.ts",
35489
- "line": 261,
35757
+ "line": 264,
35490
35758
  "title": "negative — malformed request body returns 422 invalid_request",
35491
35759
  "explicitId": "openwop.it.workflow-chain-host-expansion.negative-malformed-request-body-returns-422-invalid-request",
35492
35760
  "citations": [
@@ -35499,7 +35767,7 @@
35499
35767
  {
35500
35768
  "id": "openwop.it.workflow-chain-host-expansion.rfc-0157-a-compensating-chain-expands-through-the-live-path-with-compensation-an",
35501
35769
  "file": "workflow-chain-host-expansion.test.ts",
35502
- "line": 269,
35770
+ "line": 272,
35503
35771
  "title": "RFC 0157 — a compensating chain expands through the live path with `compensation` and `irreversibleEffect` carried verbatim onto the expanded nodes",
35504
35772
  "explicitId": "openwop.it.workflow-chain-host-expansion.rfc-0157-a-compensating-chain-expands-through-the-live-path-with-compensation-an",
35505
35773
  "citations": [
@@ -35527,7 +35795,7 @@
35527
35795
  {
35528
35796
  "id": "openwop.it.workflow-chain-host-expansion.rfc-0157-a-chain-carrying-an-unwind-policy-is-refused-with-capability-required-o",
35529
35797
  "file": "workflow-chain-host-expansion.test.ts",
35530
- "line": 308,
35798
+ "line": 311,
35531
35799
  "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",
35532
35800
  "explicitId": "openwop.it.workflow-chain-host-expansion.rfc-0157-a-chain-carrying-an-unwind-policy-is-refused-with-capability-required-o",
35533
35801
  "citations": [
@@ -36127,7 +36395,7 @@
36127
36395
  {
36128
36396
  "id": "openwop.it.workload-identity-chain-bounds.a-later-hop-claiming-a-scope-the-previous-hop-did-not-hold-is-refused",
36129
36397
  "file": "workload-identity-chain-bounds.test.ts",
36130
- "line": 121,
36398
+ "line": 124,
36131
36399
  "title": "a later hop claiming a scope the previous hop did not hold is refused",
36132
36400
  "explicitId": null,
36133
36401
  "citations": []
@@ -36135,7 +36403,7 @@
36135
36403
  {
36136
36404
  "id": "openwop.it.workload-identity-chain-bounds.a-well-formed-bounded-acyclic-non-amplifying-chain-still-resolves-the-negatives",
36137
36405
  "file": "workload-identity-chain-bounds.test.ts",
36138
- "line": 130,
36406
+ "line": 133,
36139
36407
  "title": "a well-formed bounded, acyclic, non-amplifying chain still resolves (the negatives are not a blanket refusal)",
36140
36408
  "explicitId": "openwop.it.workload-identity-chain-bounds.a-well-formed-bounded-acyclic-non-amplifying-chain-still-resolves-the-negatives",
36141
36409
  "citations": [