@openwop/openwop-conformance 2.0.0-rc.0 → 2.0.0-rc.10

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 (77) hide show
  1. package/README.md +2 -2
  2. package/dist/cli.js +257 -14
  3. package/dist/lib/certification-bundle-v3.js +142 -0
  4. package/dist/lib/requirement-ids.js +23 -0
  5. package/dist/lib/requirement-ledger.js +1 -0
  6. package/dist/lib/requirement-registry.js +20 -0
  7. package/dist/lib/scenario-disposition.js +5 -1
  8. package/dist/spec-artifacts.lock.json +2 -2
  9. package/package.json +2 -2
  10. package/requirements.json +2939 -4
  11. package/scenario-majors.json +164 -2
  12. package/schemas/CORPUS-STAMP.json +21 -21
  13. package/src/cli.ts +235 -19
  14. package/src/lib/certification-bundle-v3.ts +175 -0
  15. package/src/lib/driver.ts +9 -1
  16. package/src/lib/era2-seed.ts +197 -0
  17. package/src/lib/requirement-ids.ts +21 -0
  18. package/src/lib/requirement-ledger.ts +7 -1
  19. package/src/lib/requirement-registry.ts +21 -0
  20. package/src/lib/scenario-disposition.ts +5 -1
  21. package/src/lib/seams.ts +45 -0
  22. package/src/lib/v2.ts +62 -0
  23. package/src/scenarios/v2-advertised-fixtures-exist.test.ts +108 -0
  24. package/src/scenarios/v2-approver-enforced.test.ts +97 -0
  25. package/src/scenarios/v2-assurance-downgrade-audited.test.ts +75 -0
  26. package/src/scenarios/v2-bundle-v3-signed.test.ts +96 -0
  27. package/src/scenarios/v2-capabilities-root-closed.test.ts +63 -0
  28. package/src/scenarios/v2-capability-record-shape.test.ts +104 -0
  29. package/src/scenarios/v2-chain-pin-exact.test.ts +118 -0
  30. package/src/scenarios/v2-coherence-not-in-bundle.test.ts +98 -0
  31. package/src/scenarios/v2-compensation-read-projection.test.ts +85 -0
  32. package/src/scenarios/v2-configurable-closed.test.ts +67 -0
  33. package/src/scenarios/v2-dual-stack-negotiation.test.ts +118 -0
  34. package/src/scenarios/v2-effect-identity-business-key.test.ts +132 -0
  35. package/src/scenarios/v2-effect-seam-manifest.test.ts +163 -0
  36. package/src/scenarios/v2-enum-growth-rule.test.ts +69 -0
  37. package/src/scenarios/v2-era-2-append-vocabulary.test.ts +140 -0
  38. package/src/scenarios/v2-era-key.test.ts +86 -0
  39. package/src/scenarios/v2-era-stamp-universal.test.ts +103 -0
  40. package/src/scenarios/v2-error-registry.test.ts +89 -0
  41. package/src/scenarios/v2-event-type-closed.test.ts +97 -0
  42. package/src/scenarios/v2-fork-a-v1-run.test.ts +109 -0
  43. package/src/scenarios/v2-form-when-reuses-edge-conditions.test.ts +70 -0
  44. package/src/scenarios/v2-header-scheme.test.ts +67 -0
  45. package/src/scenarios/v2-id-grammar.test.ts +77 -0
  46. package/src/scenarios/v2-idempotency-key-grammar.test.ts +65 -0
  47. package/src/scenarios/v2-interrupt-token-scheme.test.ts +55 -0
  48. package/src/scenarios/v2-lane-issuer-advertised.test.ts +62 -0
  49. package/src/scenarios/v2-legacy-profiles-absent.test.ts +78 -0
  50. package/src/scenarios/v2-manifest-ceiling-refused.test.ts +130 -0
  51. package/src/scenarios/v2-manifest-hatch-carried.test.ts +120 -0
  52. package/src/scenarios/v2-min-client-version.test.ts +48 -0
  53. package/src/scenarios/v2-minimum-version-refused.test.ts +141 -0
  54. package/src/scenarios/v2-mrtr-rounds-ceiling.test.ts +95 -0
  55. package/src/scenarios/v2-negotiation-authenticated.test.ts +125 -0
  56. package/src/scenarios/v2-negotiation-decided-emitted.test.ts +149 -0
  57. package/src/scenarios/v2-no-transport-advertisement.test.ts +57 -0
  58. package/src/scenarios/v2-owner-subject-required.test.ts +72 -0
  59. package/src/scenarios/v2-pack-isolation.test.ts +147 -0
  60. package/src/scenarios/v2-payload-registry-closed.test.ts +110 -0
  61. package/src/scenarios/v2-peer-dependency-declared.test.ts +132 -0
  62. package/src/scenarios/v2-pinned-run-disposition.test.ts +124 -0
  63. package/src/scenarios/v2-poll-cursor-v2.test.ts +114 -0
  64. package/src/scenarios/v2-preferred-version-default.test.ts +83 -0
  65. package/src/scenarios/v2-profiles-derived-only.test.ts +70 -0
  66. package/src/scenarios/v2-provider-conflict.test.ts +115 -0
  67. package/src/scenarios/v2-refresh-sla.test.ts +78 -0
  68. package/src/scenarios/v2-relaxation-recorded.test.ts +134 -0
  69. package/src/scenarios/v2-revocation-honored.test.ts +66 -0
  70. package/src/scenarios/v2-subject-link-record.test.ts +102 -0
  71. package/src/scenarios/v2-unmapped-type-refused.test.ts +95 -0
  72. package/src/scenarios/v2-v1-events-translated.test.ts +105 -0
  73. package/src/scenarios/v2-v1-signed-webhook-accepted.test.ts +109 -0
  74. package/src/scenarios/v2-version-header-honored.test.ts +124 -0
  75. package/src/scenarios/v2-webhook-durable-delivery.test.ts +238 -0
  76. package/src/scenarios/v2-well-known-one-resource.test.ts +129 -0
  77. package/src/setup.ts +40 -4
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": 473,
6
- "tests": 1974,
7
- "withStableId": 1974,
5
+ "files": 544,
6
+ "tests": 2118,
7
+ "withStableId": 2118,
8
8
  "interpolatedTitles": 0,
9
- "explicitIds": 1939
9
+ "explicitIds": 2057
10
10
  },
11
11
  "records": [
12
12
  {
@@ -25741,6 +25741,2558 @@
25741
25741
  }
25742
25742
  ]
25743
25743
  },
25744
+ {
25745
+ "id": "openwop.it.v2-advertised-fixtures-exist.every-advertised-fixture-id-is-one-the-corpus-defines",
25746
+ "file": "v2-advertised-fixtures-exist.test.ts",
25747
+ "line": 60,
25748
+ "title": "every advertised fixture id is one the corpus defines",
25749
+ "explicitId": null,
25750
+ "citations": [
25751
+ {
25752
+ "section": null,
25753
+ "requirement": null,
25754
+ "interpolated": true
25755
+ }
25756
+ ]
25757
+ },
25758
+ {
25759
+ "id": "openwop.it.v2-advertised-fixtures-exist.a-sampled-advertised-fixture-is-actually-creatable-not-just-listed",
25760
+ "file": "v2-advertised-fixtures-exist.test.ts",
25761
+ "line": 80,
25762
+ "title": "a sampled advertised fixture is actually creatable, not just listed",
25763
+ "explicitId": null,
25764
+ "citations": [
25765
+ {
25766
+ "section": null,
25767
+ "requirement": null,
25768
+ "interpolated": true
25769
+ }
25770
+ ]
25771
+ },
25772
+ {
25773
+ "id": "openwop.it.v2-approver-enforced.a-resolver-outside-approverslist-is-refused-at-resolve-time",
25774
+ "file": "v2-approver-enforced.test.ts",
25775
+ "line": 52,
25776
+ "title": "a resolver outside approversList is refused at resolve time",
25777
+ "explicitId": "openwop.requirement.0173.approver-enforced",
25778
+ "citations": [
25779
+ {
25780
+ "section": "facets/interrupt.schema.json refKinds",
25781
+ "requirement": null,
25782
+ "interpolated": true
25783
+ },
25784
+ {
25785
+ "section": "runs.md §Create",
25786
+ "requirement": null,
25787
+ "interpolated": true
25788
+ },
25789
+ {
25790
+ "section": "interrupt.md §Approver enforcement",
25791
+ "requirement": "the fixture MUST suspend on its approval gate (status waiting-approval) before a resolve can be attempted"
25792
+ },
25793
+ {
25794
+ "section": "interrupt.md §Approver enforcement",
25795
+ "requirement": "a host advertising `interrupt` MUST refuse a resolver not in approversList with 403 (RFC 0173 §B — enforcement, not advice)"
25796
+ },
25797
+ {
25798
+ "section": "errors.json",
25799
+ "requirement": "the refusal MUST carry a registered 403 code (forbidden | run_forbidden) in the canonical envelope"
25800
+ },
25801
+ {
25802
+ "section": "interrupt.md §Approver enforcement",
25803
+ "requirement": "a refused resolve MUST NOT resume the run — the interrupt stays pending"
25804
+ }
25805
+ ]
25806
+ },
25807
+ {
25808
+ "id": "openwop.it.v2-assurance-downgrade-audited.an-identity-below-the-lane-floor-is-refused-with-sender-constraint-missing",
25809
+ "file": "v2-assurance-downgrade-audited.test.ts",
25810
+ "line": 53,
25811
+ "title": "an identity below the lane floor is refused with sender_constraint_missing",
25812
+ "explicitId": "openwop.requirement.0170.assurance-downgrade-audited.refused",
25813
+ "citations": [
25814
+ {
25815
+ "section": null,
25816
+ "requirement": null,
25817
+ "interpolated": true
25818
+ },
25819
+ {
25820
+ "section": null,
25821
+ "requirement": "the refusal code MUST be sender_constraint_missing",
25822
+ "interpolated": true
25823
+ }
25824
+ ]
25825
+ },
25826
+ {
25827
+ "id": "openwop.it.v2-assurance-downgrade-audited.a-resolved-identity-records-the-assurance-actually-used-never-a-downgraded-beare",
25828
+ "file": "v2-assurance-downgrade-audited.test.ts",
25829
+ "line": 63,
25830
+ "title": "a resolved identity records the assurance actually used, never a downgraded bearer under a sender-constrained label",
25831
+ "explicitId": "openwop.requirement.0170.assurance-downgrade-audited.audited",
25832
+ "citations": [
25833
+ {
25834
+ "section": null,
25835
+ "requirement": null,
25836
+ "interpolated": true
25837
+ },
25838
+ {
25839
+ "section": null,
25840
+ "requirement": null,
25841
+ "interpolated": true
25842
+ }
25843
+ ]
25844
+ },
25845
+ {
25846
+ "id": "openwop.it.v2-bundle-v3-signed.a-signed-v3-bundle-validates-against-the-closed-root-schema-an-extra-root-key-is",
25847
+ "file": "v2-bundle-v3-signed.test.ts",
25848
+ "line": 60,
25849
+ "title": "a signed v3 bundle validates against the closed-root schema; an extra root key is rejected",
25850
+ "explicitId": "openwop.requirement.0168.bundle-v3-signed.schema-closed-root",
25851
+ "citations": [
25852
+ {
25853
+ "section": null,
25854
+ "requirement": null,
25855
+ "interpolated": true
25856
+ },
25857
+ {
25858
+ "section": null,
25859
+ "requirement": "the v3 root is closed — an unknown root key MUST be rejected (RFC 0168 §E.1)",
25860
+ "interpolated": true
25861
+ }
25862
+ ]
25863
+ },
25864
+ {
25865
+ "id": "openwop.it.v2-bundle-v3-signed.the-attestation-verifies-under-the-host-key-and-a-flipped-witnesssha256-is-refus",
25866
+ "file": "v2-bundle-v3-signed.test.ts",
25867
+ "line": 69,
25868
+ "title": "the attestation verifies under the host key, and a flipped witnessSha256 is refused with witness-digest",
25869
+ "explicitId": "openwop.requirement.0168.bundle-v3-signed.witness-digest",
25870
+ "citations": [
25871
+ {
25872
+ "section": null,
25873
+ "requirement": null,
25874
+ "interpolated": true
25875
+ },
25876
+ {
25877
+ "section": null,
25878
+ "requirement": "the Ed25519 attestation MUST verify under the host key",
25879
+ "interpolated": true
25880
+ },
25881
+ {
25882
+ "section": null,
25883
+ "requirement": "a witnessSha256 that is not the digest of the rows MUST be refused with witness-digest (RFC 0148 §C)",
25884
+ "interpolated": true
25885
+ },
25886
+ {
25887
+ "section": null,
25888
+ "requirement": "the attestation covers witnessSha256, so a flipped digest MUST NOT verify under the host key",
25889
+ "interpolated": true
25890
+ }
25891
+ ]
25892
+ },
25893
+ {
25894
+ "id": "openwop.it.v2-bundle-v3-signed.an-independent-claim-self-signed-under-the-host-key-is-refused-a-distinct-verifi",
25895
+ "file": "v2-bundle-v3-signed.test.ts",
25896
+ "line": 82,
25897
+ "title": "an independent claim self-signed under the host key is refused; a distinct verifier key verifies",
25898
+ "explicitId": "openwop.requirement.0168.bundle-v3-signed.independent-self-signed",
25899
+ "citations": [
25900
+ {
25901
+ "section": null,
25902
+ "requirement": "an independent claim whose verifier key id equals the host key id MUST be refused with independent-self-signed (RFC 0148 R5)",
25903
+ "interpolated": true
25904
+ },
25905
+ {
25906
+ "section": null,
25907
+ "requirement": "a refused independent claim MUST NOT certify",
25908
+ "interpolated": true
25909
+ },
25910
+ {
25911
+ "section": null,
25912
+ "requirement": null,
25913
+ "interpolated": true
25914
+ },
25915
+ {
25916
+ "section": null,
25917
+ "requirement": "the verifier attestation MUST verify under the verifier key",
25918
+ "interpolated": true
25919
+ }
25920
+ ]
25921
+ },
25922
+ {
25923
+ "id": "openwop.it.v2-capabilities-root-closed.the-host-document-validates-against-capabilities-schema-json",
25924
+ "file": "v2-capabilities-root-closed.test.ts",
25925
+ "line": 32,
25926
+ "title": "the host document validates against capabilities.schema.json",
25927
+ "explicitId": "openwop.requirement.0169.capabilities-root-closed.valid",
25928
+ "citations": [
25929
+ {
25930
+ "section": null,
25931
+ "requirement": null,
25932
+ "interpolated": true
25933
+ }
25934
+ ]
25935
+ },
25936
+ {
25937
+ "id": "openwop.it.v2-capabilities-root-closed.an-unknown-root-key-fails-validation",
25938
+ "file": "v2-capabilities-root-closed.test.ts",
25939
+ "line": 40,
25940
+ "title": "an unknown root key fails validation",
25941
+ "explicitId": "openwop.requirement.0169.capabilities-root-closed.unknown-root-key",
25942
+ "citations": [
25943
+ {
25944
+ "section": null,
25945
+ "requirement": "any root key that is not a metadata key, a declared family, or `extensions` MUST fail validation",
25946
+ "interpolated": true
25947
+ }
25948
+ ]
25949
+ },
25950
+ {
25951
+ "id": "openwop.it.v2-capabilities-root-closed.a-dotted-mirror-key-fails-validation",
25952
+ "file": "v2-capabilities-root-closed.test.ts",
25953
+ "line": 46,
25954
+ "title": "a dotted mirror key fails validation",
25955
+ "explicitId": "openwop.requirement.0169.capabilities-root-closed.dotted-key",
25956
+ "citations": [
25957
+ {
25958
+ "section": null,
25959
+ "requirement": "a dotted key (the v1 `host.<family>` mirror) MUST fail validation at the closed root",
25960
+ "interpolated": true
25961
+ }
25962
+ ]
25963
+ },
25964
+ {
25965
+ "id": "openwop.it.v2-capabilities-root-closed.the-v1-capabilities-wrapper-fails-validation",
25966
+ "file": "v2-capabilities-root-closed.test.ts",
25967
+ "line": 52,
25968
+ "title": "the v1 `capabilities` wrapper fails validation",
25969
+ "explicitId": "openwop.requirement.0169.capabilities-root-closed.wrapper",
25970
+ "citations": [
25971
+ {
25972
+ "section": null,
25973
+ "requirement": "the v1 `capabilities` wrapper MUST fail validation at the closed root (migration row C2.1)",
25974
+ "interpolated": true
25975
+ }
25976
+ ]
25977
+ },
25978
+ {
25979
+ "id": "openwop.it.v2-capabilities-root-closed.a-root-profiles-fails-validation",
25980
+ "file": "v2-capabilities-root-closed.test.ts",
25981
+ "line": 58,
25982
+ "title": "a root `profiles[]` fails validation",
25983
+ "explicitId": "openwop.requirement.0169.capabilities-root-closed.profiles",
25984
+ "citations": [
25985
+ {
25986
+ "section": "spec/v2/core/capabilities.md §7",
25987
+ "requirement": "no `profiles[]` exists at the v2 root; a host that emits one MUST fail schema validation (row C2.10)"
25988
+ }
25989
+ ]
25990
+ },
25991
+ {
25992
+ "id": "openwop.it.v2-capability-record-shape.every-family-record-carries-status-since-and-witness-from-the-wire-legal-sets",
25993
+ "file": "v2-capability-record-shape.test.ts",
25994
+ "line": 66,
25995
+ "title": "every family record carries status, since and witness from the wire-legal sets",
25996
+ "explicitId": "openwop.requirement.0169.capability-record-shape.required-fields",
25997
+ "citations": [
25998
+ {
25999
+ "section": null,
26000
+ "requirement": null,
26001
+ "interpolated": true
26002
+ },
26003
+ {
26004
+ "section": null,
26005
+ "requirement": null,
26006
+ "interpolated": true
26007
+ },
26008
+ {
26009
+ "section": null,
26010
+ "requirement": null,
26011
+ "interpolated": true
26012
+ },
26013
+ {
26014
+ "section": null,
26015
+ "requirement": null,
26016
+ "interpolated": true
26017
+ }
26018
+ ]
26019
+ },
26020
+ {
26021
+ "id": "openwop.it.v2-capability-record-shape.until-is-present-iff-the-record-is-experimental-or-deprecated",
26022
+ "file": "v2-capability-record-shape.test.ts",
26023
+ "line": 79,
26024
+ "title": "`until` is present iff the record is experimental or deprecated",
26025
+ "explicitId": "openwop.requirement.0169.capability-record-shape.until-iff-not-stable",
26026
+ "citations": [
26027
+ {
26028
+ "section": null,
26029
+ "requirement": null,
26030
+ "interpolated": true
26031
+ },
26032
+ {
26033
+ "section": null,
26034
+ "requirement": null,
26035
+ "interpolated": true
26036
+ }
26037
+ ]
26038
+ },
26039
+ {
26040
+ "id": "openwop.it.v2-capability-record-shape.no-advertised-record-carries-an-until-already-in-the-past",
26041
+ "file": "v2-capability-record-shape.test.ts",
26042
+ "line": 94,
26043
+ "title": "no advertised record carries an `until` already in the past",
26044
+ "explicitId": "openwop.requirement.0169.capability-record-shape.until-not-past",
26045
+ "citations": [
26046
+ {
26047
+ "section": "spec/v2/core/capabilities.md §2 (`until` in the past)",
26048
+ "requirement": null,
26049
+ "interpolated": true
26050
+ }
26051
+ ]
26052
+ },
26053
+ {
26054
+ "id": "openwop.it.v2-chain-pin-exact.a-chain-reference-carrying-a-range-core-ai-callprompt-1-is-refused-at-register",
26055
+ "file": "v2-chain-pin-exact.test.ts",
26056
+ "line": 102,
26057
+ "title": "a chain reference carrying a range (core.ai.callPrompt@^1) is refused at register",
26058
+ "explicitId": "openwop.requirement.0177.chain-pin-exact.range-refused",
26059
+ "citations": [
26060
+ {
26061
+ "section": null,
26062
+ "requirement": null,
26063
+ "interpolated": true
26064
+ },
26065
+ {
26066
+ "section": null,
26067
+ "requirement": "the refusal MUST carry an error code in the canonical envelope",
26068
+ "interpolated": true
26069
+ }
26070
+ ]
26071
+ },
26072
+ {
26073
+ "id": "openwop.it.v2-chain-pin-exact.a-chain-reference-pinning-an-exact-version-core-ai-callprompt-1-0-0-registers",
26074
+ "file": "v2-chain-pin-exact.test.ts",
26075
+ "line": 111,
26076
+ "title": "a chain reference pinning an exact version (core.ai.callPrompt@1.0.0) registers",
26077
+ "explicitId": "openwop.requirement.0177.chain-pin-exact.exact-accepted",
26078
+ "citations": [
26079
+ {
26080
+ "section": null,
26081
+ "requirement": null,
26082
+ "interpolated": true
26083
+ }
26084
+ ]
26085
+ },
26086
+ {
26087
+ "id": "openwop.it.v2-coherence-not-in-bundle.every-corpus-ledger-id-has-a-scenario-in-src-coherence-and-none-in-src-scenarios",
26088
+ "file": "v2-coherence-not-in-bundle.test.ts",
26089
+ "line": 60,
26090
+ "title": "every corpus-ledger id has a scenario in src/coherence and none in src/scenarios — the two id sets are disjoint by construction",
26091
+ "explicitId": "openwop.requirement.0168.coherence-not-in-bundle.disjoint-by-construction",
26092
+ "citations": [
26093
+ {
26094
+ "section": null,
26095
+ "requirement": "the corpus ledger MUST carry at least one requirement id",
26096
+ "interpolated": true
26097
+ },
26098
+ {
26099
+ "section": null,
26100
+ "requirement": null,
26101
+ "interpolated": true
26102
+ },
26103
+ {
26104
+ "section": null,
26105
+ "requirement": null,
26106
+ "interpolated": true
26107
+ },
26108
+ {
26109
+ "section": null,
26110
+ "requirement": null,
26111
+ "interpolated": true
26112
+ },
26113
+ {
26114
+ "section": null,
26115
+ "requirement": null,
26116
+ "interpolated": true
26117
+ }
26118
+ ]
26119
+ },
26120
+ {
26121
+ "id": "openwop.it.v2-coherence-not-in-bundle.the-bundle-schema-rejects-a-v3-bundle-carrying-a-corpus-coherence-id-and-accepts",
26122
+ "file": "v2-coherence-not-in-bundle.test.ts",
26123
+ "line": 89,
26124
+ "title": "the bundle schema rejects a v3 bundle carrying a corpus-coherence id and accepts one under openwop.requirement.",
26125
+ "explicitId": "openwop.requirement.0168.coherence-not-in-bundle.schema-forbids-coherence-ids",
26126
+ "citations": [
26127
+ {
26128
+ "section": null,
26129
+ "requirement": null,
26130
+ "interpolated": true
26131
+ },
26132
+ {
26133
+ "section": null,
26134
+ "requirement": "a v3 bundle carrying an openwop.it.spec-corpus-validity. id MUST be rejected by the bundle schema",
26135
+ "interpolated": true
26136
+ }
26137
+ ]
26138
+ },
26139
+ {
26140
+ "id": "openwop.it.v2-compensation-read-projection.get-runs-runid-compensation-on-a-fresh-run-validates-with-status-none",
26141
+ "file": "v2-compensation-read-projection.test.ts",
26142
+ "line": 43,
26143
+ "title": "GET /runs/{runId}/compensation on a fresh run validates with status none",
26144
+ "explicitId": "openwop.requirement.0173.compensation-read-projection",
26145
+ "citations": [
26146
+ {
26147
+ "section": "runs.md §Create",
26148
+ "requirement": "POST /runs MUST answer 201 for the noop fixture"
26149
+ },
26150
+ {
26151
+ "section": "security-defaults.md §Compensation",
26152
+ "requirement": "a host advertising `compensation` MUST serve GET /runs/{runId}/compensation with 200 (RFC 0173 §B — the read projection is the obligation's witness)"
26153
+ },
26154
+ {
26155
+ "section": "compensation-projection.schema.json",
26156
+ "requirement": null,
26157
+ "interpolated": true
26158
+ },
26159
+ {
26160
+ "section": "compensation-projection.schema.json runId",
26161
+ "requirement": "runId MUST echo the run read"
26162
+ },
26163
+ {
26164
+ "section": "compensation-projection.schema.json status",
26165
+ "requirement": "a run with nothing to compensate MUST project status \"none\""
26166
+ },
26167
+ {
26168
+ "section": "compensation-projection.schema.json attempts",
26169
+ "requirement": "no attempt exists before an unwind"
26170
+ }
26171
+ ]
26172
+ },
26173
+ {
26174
+ "id": "openwop.it.v2-compensation-read-projection.an-unknown-run-projects-404-not-found-through-the-canonical-envelope",
26175
+ "file": "v2-compensation-read-projection.test.ts",
26176
+ "line": 74,
26177
+ "title": "an unknown run projects 404 not_found through the canonical envelope",
26178
+ "explicitId": "openwop.requirement.0173.compensation-read-projection.not-found",
26179
+ "citations": [
26180
+ {
26181
+ "section": "openapi.yaml getRunCompensation 404",
26182
+ "requirement": "an unknown runId MUST answer 404"
26183
+ },
26184
+ {
26185
+ "section": "errors.md §Envelope",
26186
+ "requirement": "the 404 MUST carry the registered not_found code in the flat envelope"
26187
+ }
26188
+ ]
26189
+ },
26190
+ {
26191
+ "id": "openwop.it.v2-configurable-closed.the-standalone-schema-rejects-a-dotted-key-and-an-unknown-root-key-and-accepts-t",
26192
+ "file": "v2-configurable-closed.test.ts",
26193
+ "line": 46,
26194
+ "title": "the standalone schema rejects a dotted key and an unknown root key and accepts the versioned control",
26195
+ "explicitId": "openwop.requirement.0171.configurable-closed.schema",
26196
+ "citations": [
26197
+ {
26198
+ "section": null,
26199
+ "requirement": "{ version: 1 } is the smallest valid configurable (version REQUIRED, const 1)",
26200
+ "interpolated": true
26201
+ },
26202
+ {
26203
+ "section": null,
26204
+ "requirement": "a dotted key (`ai.provider` as a string key) MUST fail the closed nested schema",
26205
+ "interpolated": true
26206
+ },
26207
+ {
26208
+ "section": null,
26209
+ "requirement": "an unknown root key MUST fail the closed schema (additionalProperties: false in the standalone artifact)",
26210
+ "interpolated": true
26211
+ },
26212
+ {
26213
+ "section": null,
26214
+ "requirement": "a configurable without `version` MUST fail",
26215
+ "interpolated": true
26216
+ }
26217
+ ]
26218
+ },
26219
+ {
26220
+ "id": "openwop.it.v2-configurable-closed.post-runs-rejects-a-dotted-key-with-400-validation-error",
26221
+ "file": "v2-configurable-closed.test.ts",
26222
+ "line": 54,
26223
+ "title": "POST /runs rejects a dotted key with 400 validation_error",
26224
+ "explicitId": "openwop.requirement.0171.configurable-closed.dotted-key",
26225
+ "citations": [
26226
+ {
26227
+ "section": null,
26228
+ "requirement": "a dotted key inside a section MUST be rejected with 400",
26229
+ "interpolated": true
26230
+ },
26231
+ {
26232
+ "section": null,
26233
+ "requirement": "the refusal code MUST be validation_error",
26234
+ "interpolated": true
26235
+ }
26236
+ ]
26237
+ },
26238
+ {
26239
+ "id": "openwop.it.v2-configurable-closed.post-runs-rejects-an-unknown-root-key-with-400-validation-error",
26240
+ "file": "v2-configurable-closed.test.ts",
26241
+ "line": 61,
26242
+ "title": "POST /runs rejects an unknown root key with 400 validation_error",
26243
+ "explicitId": "openwop.requirement.0171.configurable-closed.unknown-key",
26244
+ "citations": [
26245
+ {
26246
+ "section": null,
26247
+ "requirement": "an unknown root key MUST be rejected with 400",
26248
+ "interpolated": true
26249
+ },
26250
+ {
26251
+ "section": null,
26252
+ "requirement": "the refusal code MUST be validation_error",
26253
+ "interpolated": true
26254
+ }
26255
+ ]
26256
+ },
26257
+ {
26258
+ "id": "openwop.it.v2-dual-stack-negotiation.a-run-created-through-v1-runs-with-no-header-is-readable-through-runs-under-open",
26259
+ "file": "v2-dual-stack-negotiation.test.ts",
26260
+ "line": 68,
26261
+ "title": "a run created through /v1/runs with no header is readable through /runs under OpenWOP-Version: 2.0",
26262
+ "explicitId": "openwop.requirement.0172.dual-stack-negotiation.cross-major-read",
26263
+ "citations": [
26264
+ {
26265
+ "section": "spec/v2/core/versioning.md §1.4",
26266
+ "requirement": "a /v1/ response MUST report the 1.x contract that produced it"
26267
+ },
26268
+ {
26269
+ "section": "spec/v2/core/versioning.md §5",
26270
+ "requirement": "the overlap: a run created through /v1/runs MUST be readable through GET /runs/{runId} with OpenWOP-Version: 2.0"
26271
+ },
26272
+ {
26273
+ "section": "spec/v2/core/versioning.md §5",
26274
+ "requirement": "the v2 read MUST name the same run"
26275
+ },
26276
+ {
26277
+ "section": "spec/v2/core/versioning.md §1.4",
26278
+ "requirement": "the v2 read MUST report the 2.x contract that produced it"
26279
+ }
26280
+ ]
26281
+ },
26282
+ {
26283
+ "id": "openwop.it.v2-dual-stack-negotiation.an-unlisted-major-is-406-protocol-version-unsupported-with-details-protocolversi",
26284
+ "file": "v2-dual-stack-negotiation.test.ts",
26285
+ "line": 83,
26286
+ "title": "an unlisted major is 406 protocol_version_unsupported with details.protocolVersions[]",
26287
+ "explicitId": "openwop.requirement.0172.dual-stack-negotiation.unlisted-major",
26288
+ "citations": [
26289
+ {
26290
+ "section": null,
26291
+ "requirement": "a header naming a major not in protocolVersions[] MUST be answered 406",
26292
+ "interpolated": true
26293
+ },
26294
+ {
26295
+ "section": null,
26296
+ "requirement": "the refusal code MUST be protocol_version_unsupported",
26297
+ "interpolated": true
26298
+ },
26299
+ {
26300
+ "section": null,
26301
+ "requirement": "details.protocolVersions[] MUST echo the advertised list",
26302
+ "interpolated": true
26303
+ }
26304
+ ]
26305
+ },
26306
+ {
26307
+ "id": "openwop.it.v2-dual-stack-negotiation.openwop-version-2-0-on-a-v1-path-is-400-protocol-version-mismatch",
26308
+ "file": "v2-dual-stack-negotiation.test.ts",
26309
+ "line": 94,
26310
+ "title": "OpenWOP-Version: 2.0 on a /v1/ path is 400 protocol_version_mismatch",
26311
+ "explicitId": "openwop.requirement.0172.dual-stack-negotiation.v1-path-mismatch",
26312
+ "citations": [
26313
+ {
26314
+ "section": null,
26315
+ "requirement": "a /v1/… path with OpenWOP-Version other than 1 MUST be answered 400",
26316
+ "interpolated": true
26317
+ },
26318
+ {
26319
+ "section": null,
26320
+ "requirement": "the refusal code MUST be protocol_version_mismatch",
26321
+ "interpolated": true
26322
+ }
26323
+ ]
26324
+ },
26325
+ {
26326
+ "id": "openwop.it.v2-dual-stack-negotiation.every-response-reports-the-contract-that-produced-it",
26327
+ "file": "v2-dual-stack-negotiation.test.ts",
26328
+ "line": 103,
26329
+ "title": "every response reports the contract that produced it",
26330
+ "explicitId": "openwop.requirement.0172.dual-stack-negotiation.response-header",
26331
+ "citations": [
26332
+ {
26333
+ "section": "spec/v2/core/versioning.md §1.4",
26334
+ "requirement": "a header-less /v1/ response MUST carry OpenWOP-Version: 1.<minor> — the contract used, never another (silent downgrade)"
26335
+ },
26336
+ {
26337
+ "section": "spec/v2/core/versioning.md §1.4",
26338
+ "requirement": "a /v1/ response under OpenWOP-Version: 1.0 MUST carry OpenWOP-Version: 1.<minor>"
26339
+ },
26340
+ {
26341
+ "section": "spec/v2/core/versioning.md §1.4",
26342
+ "requirement": "a response under OpenWOP-Version: 2.0 MUST carry OpenWOP-Version: 2.<minor>"
26343
+ },
26344
+ {
26345
+ "section": "spec/v2/core/versioning.md §1.4",
26346
+ "requirement": null,
26347
+ "interpolated": true
26348
+ }
26349
+ ]
26350
+ },
26351
+ {
26352
+ "id": "openwop.it.v2-effect-identity-business-key.get-runs-runid-effects-validates-and-every-row-is-keyed-on-business-identity-or",
26353
+ "file": "v2-effect-identity-business-key.test.ts",
26354
+ "line": 49,
26355
+ "title": "GET /runs/{runId}/effects validates and every row is keyed on business identity or the activity recipe",
26356
+ "explicitId": "openwop.requirement.0173.effect-identity-business-key",
26357
+ "citations": [
26358
+ {
26359
+ "section": "runs.md §Create",
26360
+ "requirement": "POST /runs MUST answer 201 for the noop fixture"
26361
+ },
26362
+ {
26363
+ "section": "security-defaults.md §Layer-2 effect identity",
26364
+ "requirement": "a host advertising `idempotency` MUST serve GET /runs/{runId}/effects with 200 (RFC 0173 §B)"
26365
+ },
26366
+ {
26367
+ "section": "effect-ledger-projection.schema.json",
26368
+ "requirement": null,
26369
+ "interpolated": true
26370
+ },
26371
+ {
26372
+ "section": "effect-ledger-projection.schema.json runId",
26373
+ "requirement": "runId MUST echo the run read"
26374
+ },
26375
+ {
26376
+ "section": "security-defaults.md §Layer-2 effect identity",
26377
+ "requirement": null,
26378
+ "interpolated": true
26379
+ },
26380
+ {
26381
+ "section": "RFC 0150 §B",
26382
+ "requirement": null,
26383
+ "interpolated": true
26384
+ },
26385
+ {
26386
+ "section": "effect-ledger-projection.schema.json providerKey",
26387
+ "requirement": "providerKey is a redaction-safe identity, never credential material"
26388
+ }
26389
+ ]
26390
+ },
26391
+ {
26392
+ "id": "openwop.it.v2-effect-identity-business-key.the-same-provider-key-is-presented-across-two-transport-retries",
26393
+ "file": "v2-effect-identity-business-key.test.ts",
26394
+ "line": 96,
26395
+ "title": "the same provider key is presented across two transport retries",
26396
+ "explicitId": "openwop.requirement.0173.effect-identity-business-key.retry",
26397
+ "citations": [
26398
+ {
26399
+ "section": "spec/v2/core/replay.md §Effect identity",
26400
+ "requirement": null,
26401
+ "interpolated": true
26402
+ },
26403
+ {
26404
+ "section": "spec/v2/core/replay.md §Effect identity",
26405
+ "requirement": null,
26406
+ "interpolated": true
26407
+ }
26408
+ ]
26409
+ },
26410
+ {
26411
+ "id": "openwop.it.v2-effect-seam-manifest.get-host-effect-seams-validates-and-every-row-is-guarded",
26412
+ "file": "v2-effect-seam-manifest.test.ts",
26413
+ "line": 51,
26414
+ "title": "GET /host/effect-seams validates and every row is guarded",
26415
+ "explicitId": "openwop.requirement.0173.effect-seam-manifest",
26416
+ "citations": [
26417
+ {
26418
+ "section": "replay.md §The effect-seam manifest",
26419
+ "requirement": "a host advertising `replay` MUST serve GET /host/effect-seams with 200 (RFC 0173 §C.1)"
26420
+ },
26421
+ {
26422
+ "section": "effect-seam-manifest.schema.json",
26423
+ "requirement": null,
26424
+ "interpolated": true
26425
+ },
26426
+ {
26427
+ "section": "replay.md §The effect-seam manifest",
26428
+ "requirement": "the manifest MUST enumerate at least one outbound effect seam — a node runtime with no effect path does not need `replay`"
26429
+ },
26430
+ {
26431
+ "section": "RFC 0173 §C.1",
26432
+ "requirement": null,
26433
+ "interpolated": true
26434
+ },
26435
+ {
26436
+ "section": "RFC 0173 §C.1",
26437
+ "requirement": null,
26438
+ "interpolated": true
26439
+ },
26440
+ {
26441
+ "section": "effect-seam-manifest.schema.json seams[].kind",
26442
+ "requirement": null,
26443
+ "interpolated": true
26444
+ },
26445
+ {
26446
+ "section": "RFC 0173 §C.1",
26447
+ "requirement": null,
26448
+ "interpolated": true
26449
+ },
26450
+ {
26451
+ "section": "effect-seam-manifest.schema.json seams[].branchReFires",
26452
+ "requirement": null,
26453
+ "interpolated": true
26454
+ }
26455
+ ]
26456
+ },
26457
+ {
26458
+ "id": "openwop.it.v2-effect-seam-manifest.the-replay-facet-names-the-manifest-address-as-the-constant-host-effect-seams",
26459
+ "file": "v2-effect-seam-manifest.test.ts",
26460
+ "line": 106,
26461
+ "title": "the replay facet names the manifest address as the constant /host/effect-seams",
26462
+ "explicitId": "openwop.requirement.0173.effect-seam-manifest.facet",
26463
+ "citations": [
26464
+ {
26465
+ "section": "facets/replay.schema.json effectSeamsManifest",
26466
+ "requirement": "the facet MUST carry the constant \"/host/effect-seams\" (replay.md §The surface)"
26467
+ }
26468
+ ]
26469
+ },
26470
+ {
26471
+ "id": "openwop.it.v2-effect-seam-manifest.driving-one-seam-of-each-kind-observes-no-re-fire-on-replay",
26472
+ "file": "v2-effect-seam-manifest.test.ts",
26473
+ "line": 117,
26474
+ "title": "driving one seam of each kind observes no re-fire on replay",
26475
+ "explicitId": "openwop.requirement.0173.effect-seam-manifest.no-re-fire",
26476
+ "citations": [
26477
+ {
26478
+ "section": "spec/v2/core/replay.md §The effect-seam manifest",
26479
+ "requirement": null,
26480
+ "interpolated": true
26481
+ }
26482
+ ]
26483
+ },
26484
+ {
26485
+ "id": "openwop.it.v2-enum-growth-rule.the-envelope-accepts-a-registered-but-unknown-to-this-suite-vendor-member",
26486
+ "file": "v2-enum-growth-rule.test.ts",
26487
+ "line": 53,
26488
+ "title": "the envelope accepts a registered-but-unknown-to-this-suite vendor member",
26489
+ "explicitId": "openwop.requirement.0171.enum-growth-rule.unknown-member-accepted",
26490
+ "citations": [
26491
+ {
26492
+ "section": null,
26493
+ "requirement": null,
26494
+ "interpolated": true
26495
+ },
26496
+ {
26497
+ "section": null,
26498
+ "requirement": null,
26499
+ "interpolated": true
26500
+ },
26501
+ {
26502
+ "section": null,
26503
+ "requirement": "the vendor branch admits an optional third segment (<org>.<domain>.<name>)",
26504
+ "interpolated": true
26505
+ }
26506
+ ]
26507
+ },
26508
+ {
26509
+ "id": "openwop.it.v2-enum-growth-rule.the-reserved-prefix-and-a-malformed-member-are-rejected",
26510
+ "file": "v2-enum-growth-rule.test.ts",
26511
+ "line": 63,
26512
+ "title": "the reserved prefix and a malformed member are rejected",
26513
+ "explicitId": "openwop.requirement.0171.enum-growth-rule.reserved-rejected",
26514
+ "citations": [
26515
+ {
26516
+ "section": null,
26517
+ "requirement": "openwop. is the only reserved prefix; a type under it that is not in the enum MUST fail",
26518
+ "interpolated": true
26519
+ },
26520
+ {
26521
+ "section": null,
26522
+ "requirement": "a member outside the positive pattern (upper-case) MUST fail",
26523
+ "interpolated": true
26524
+ },
26525
+ {
26526
+ "section": null,
26527
+ "requirement": "a single-segment member MUST fail — every type is <domain>.<name> or <org>.<name>",
26528
+ "interpolated": true
26529
+ }
26530
+ ]
26531
+ },
26532
+ {
26533
+ "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",
26534
+ "file": "v2-era-2-append-vocabulary.test.ts",
26535
+ "line": 48,
26536
+ "title": "a host append to an open era-2 run keeps the log in v1 vocabulary, so the whole log still reads",
26537
+ "explicitId": null,
26538
+ "citations": [
26539
+ {
26540
+ "section": null,
26541
+ "requirement": null,
26542
+ "interpolated": true
26543
+ },
26544
+ {
26545
+ "section": null,
26546
+ "requirement": null,
26547
+ "interpolated": true
26548
+ },
26549
+ {
26550
+ "section": null,
26551
+ "requirement": null,
26552
+ "interpolated": true
26553
+ },
26554
+ {
26555
+ "section": null,
26556
+ "requirement": null,
26557
+ "interpolated": true
26558
+ }
26559
+ ]
26560
+ },
26561
+ {
26562
+ "id": "openwop.it.v2-era-2-append-vocabulary.the-run-keeps-the-era-it-was-created-with-an-append-does-not-promote-it-to-era-3",
26563
+ "file": "v2-era-2-append-vocabulary.test.ts",
26564
+ "line": 119,
26565
+ "title": "the run keeps the era it was created with; an append does not promote it to era 3",
26566
+ "explicitId": null,
26567
+ "citations": [
26568
+ {
26569
+ "section": null,
26570
+ "requirement": null,
26571
+ "interpolated": true
26572
+ }
26573
+ ]
26574
+ },
26575
+ {
26576
+ "id": "openwop.it.v2-era-key.a-run-created-now-carries-eventlogschemaversion-3-on-its-snapshot",
26577
+ "file": "v2-era-key.test.ts",
26578
+ "line": 52,
26579
+ "title": "a run created now carries eventLogSchemaVersion 3 on its snapshot",
26580
+ "explicitId": "openwop.requirement.0176.era-key",
26581
+ "citations": [
26582
+ {
26583
+ "section": null,
26584
+ "requirement": "eventLogSchemaVersion is REQUIRED on every run snapshot (run-snapshot.schema.json) — the era key is never absent on a run a v2 host created",
26585
+ "interpolated": true
26586
+ },
26587
+ {
26588
+ "section": null,
26589
+ "requirement": null,
26590
+ "interpolated": true
26591
+ }
26592
+ ]
26593
+ },
26594
+ {
26595
+ "id": "openwop.it.v2-era-key.discovery-advertises-the-value-the-host-writes-for-new-runs-and-nothing-else",
26596
+ "file": "v2-era-key.test.ts",
26597
+ "line": 67,
26598
+ "title": "discovery advertises the value the host writes for new runs and nothing else",
26599
+ "explicitId": "openwop.requirement.0176.era-key.discovery",
26600
+ "citations": [
26601
+ {
26602
+ "section": "spec/v2/core/versioning.md §2.2",
26603
+ "requirement": null,
26604
+ "interpolated": true
26605
+ },
26606
+ {
26607
+ "section": "spec/v2/core/versioning.md §2.2",
26608
+ "requirement": null,
26609
+ "interpolated": true
26610
+ },
26611
+ {
26612
+ "section": null,
26613
+ "requirement": "the value stamped on a run created now MUST equal the value discovery advertises",
26614
+ "interpolated": true
26615
+ }
26616
+ ]
26617
+ },
26618
+ {
26619
+ "id": "openwop.it.v2-era-stamp-universal.discovery-advertises-an-era-the-host-actually-writes-and-a-new-run-carries-it",
26620
+ "file": "v2-era-stamp-universal.test.ts",
26621
+ "line": 40,
26622
+ "title": "discovery advertises an era the host actually writes, and a new run carries it",
26623
+ "explicitId": null,
26624
+ "citations": [
26625
+ {
26626
+ "section": null,
26627
+ "requirement": null,
26628
+ "interpolated": true
26629
+ },
26630
+ {
26631
+ "section": null,
26632
+ "requirement": null,
26633
+ "interpolated": true
26634
+ },
26635
+ {
26636
+ "section": null,
26637
+ "requirement": null,
26638
+ "interpolated": true
26639
+ }
26640
+ ]
26641
+ },
26642
+ {
26643
+ "id": "openwop.it.v2-era-stamp-universal.a-v2-era-host-stamps-3-so-its-new-runs-are-never-read-as-the-v1-era",
26644
+ "file": "v2-era-stamp-universal.test.ts",
26645
+ "line": 80,
26646
+ "title": "a v2-era host stamps 3, so its new runs are never read as the v1 era",
26647
+ "explicitId": null,
26648
+ "citations": [
26649
+ {
26650
+ "section": null,
26651
+ "requirement": "a host advertising era 3 MUST stamp 3 on every run it creates — an unstamped run made after the cut is indistinguishable from a pre-cut run and every reader translates it as era 2, which is a silent wrong read rather than an error",
26652
+ "interpolated": true
26653
+ }
26654
+ ]
26655
+ },
26656
+ {
26657
+ "id": "openwop.it.v2-error-registry.an-error-response-is-the-closed-envelope-with-a-registered-code-at-its-registere",
26658
+ "file": "v2-error-registry.test.ts",
26659
+ "line": 52,
26660
+ "title": "an error response is the closed envelope with a registered code at its registered status",
26661
+ "explicitId": "openwop.requirement.0171.error-registry.envelope",
26662
+ "citations": [
26663
+ {
26664
+ "section": null,
26665
+ "requirement": null,
26666
+ "interpolated": true
26667
+ },
26668
+ {
26669
+ "section": null,
26670
+ "requirement": null,
26671
+ "interpolated": true
26672
+ }
26673
+ ]
26674
+ },
26675
+ {
26676
+ "id": "openwop.it.v2-error-registry.retry-timing-is-never-spelled-inside-details",
26677
+ "file": "v2-error-registry.test.ts",
26678
+ "line": 64,
26679
+ "title": "retry timing is never spelled inside details",
26680
+ "explicitId": "openwop.requirement.0171.error-registry.no-retry-details",
26681
+ "citations": [
26682
+ {
26683
+ "section": "spec/v2/core/errors.md §Retry timing",
26684
+ "requirement": "details.retryAfter / retryAfterMs / retryAfterSeconds are not part of v2 and a host MUST NOT emit them — Retry-After is the only retry timing"
26685
+ }
26686
+ ]
26687
+ },
26688
+ {
26689
+ "id": "openwop.it.v2-error-registry.a-429-rate-limited-response-carries-retry-after",
26690
+ "file": "v2-error-registry.test.ts",
26691
+ "line": 72,
26692
+ "title": "a 429 rate_limited response carries Retry-After",
26693
+ "explicitId": "openwop.requirement.0171.error-registry.retry-after",
26694
+ "citations": [
26695
+ {
26696
+ "section": "spec/v2/core/errors.md §Retry timing",
26697
+ "requirement": "a 429 MUST carry the registered code rate_limited"
26698
+ },
26699
+ {
26700
+ "section": "spec/v2/core/errors.md §Retry timing",
26701
+ "requirement": "a 429 rate_limited response MUST set Retry-After"
26702
+ }
26703
+ ]
26704
+ },
26705
+ {
26706
+ "id": "openwop.it.v2-event-type-closed.every-emitted-type-is-a-registered-protocol-type-or-a-vendor-type-under-an-adver",
26707
+ "file": "v2-event-type-closed.test.ts",
26708
+ "line": 71,
26709
+ "title": "every emitted type is a registered protocol type or a vendor type under an advertised org",
26710
+ "explicitId": "openwop.requirement.0171.event-type-closed.type",
26711
+ "citations": [
26712
+ {
26713
+ "section": null,
26714
+ "requirement": null,
26715
+ "interpolated": true
26716
+ }
26717
+ ]
26718
+ },
26719
+ {
26720
+ "id": "openwop.it.v2-event-type-closed.every-emitted-event-validates-as-a-runeventdoc",
26721
+ "file": "v2-event-type-closed.test.ts",
26722
+ "line": 84,
26723
+ "title": "every emitted event validates as a RunEventDoc",
26724
+ "explicitId": "openwop.requirement.0171.event-type-closed.envelope",
26725
+ "citations": [
26726
+ {
26727
+ "section": "spec/v2/core/events.md §The envelope",
26728
+ "requirement": null,
26729
+ "interpolated": true
26730
+ },
26731
+ {
26732
+ "section": "spec/v2/core/events.md §The envelope",
26733
+ "requirement": "sequence is the one ordering field: integer ≥ 0, strictly increasing per run"
26734
+ }
26735
+ ]
26736
+ },
26737
+ {
26738
+ "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",
26739
+ "file": "v2-fork-a-v1-run.test.ts",
26740
+ "line": 62,
26741
+ "title": "the fork of an era-2 run is accepted and its prefix is byte-equivalent to the translated parent",
26742
+ "explicitId": "openwop.requirement.0176.fork-a-v1-run.prefix",
26743
+ "citations": [
26744
+ {
26745
+ "section": null,
26746
+ "requirement": null,
26747
+ "interpolated": true
26748
+ },
26749
+ {
26750
+ "section": null,
26751
+ "requirement": null,
26752
+ "interpolated": true
26753
+ },
26754
+ {
26755
+ "section": null,
26756
+ "requirement": null,
26757
+ "interpolated": true
26758
+ },
26759
+ {
26760
+ "section": "spec/v2/core/replay.md §Byte-equivalence of the prefix",
26761
+ "requirement": null,
26762
+ "interpolated": true
26763
+ }
26764
+ ]
26765
+ },
26766
+ {
26767
+ "id": "openwop.it.v2-fork-a-v1-run.run-started-on-the-fork-carries-the-legacy-subject-where-the-parent-had-none",
26768
+ "file": "v2-fork-a-v1-run.test.ts",
26769
+ "line": 86,
26770
+ "title": "run.started on the fork carries the legacy Subject where the parent had none",
26771
+ "explicitId": "openwop.requirement.0176.fork-a-v1-run.legacy-subject",
26772
+ "citations": [
26773
+ {
26774
+ "section": null,
26775
+ "requirement": "the fork's log MUST carry run.started at its head",
26776
+ "interpolated": true
26777
+ },
26778
+ {
26779
+ "section": "spec/v2/core/identity.md §1.2",
26780
+ "requirement": "run.started on the fork MUST carry owner.subject — the seeded parent had none, so the host stamps the legacy Subject at first v2 read (RFC 0170 §A.3) and the fork copies it verbatim (replay.md §The surface)"
26781
+ },
26782
+ {
26783
+ "section": "spec/v2/core/identity.md §1.2",
26784
+ "requirement": null,
26785
+ "interpolated": true
26786
+ },
26787
+ {
26788
+ "section": "spec/v2/core/persistence.md §Everything else a v1 host persisted",
26789
+ "requirement": null,
26790
+ "interpolated": true
26791
+ }
26792
+ ]
26793
+ },
26794
+ {
26795
+ "id": "openwop.it.v2-form-when-reuses-edge-conditions.a-field-when-is-the-edge-condition-grammar-type-left-right-and-no-other-expressi",
26796
+ "file": "v2-form-when-reuses-edge-conditions.test.ts",
26797
+ "line": 51,
26798
+ "title": "a field `when` is the edge-condition grammar { type, left, right } and no other expression language",
26799
+ "explicitId": "openwop.requirement.0177.form-when-reuses-edge-conditions",
26800
+ "citations": [
26801
+ {
26802
+ "section": null,
26803
+ "requirement": null,
26804
+ "interpolated": true
26805
+ },
26806
+ {
26807
+ "section": null,
26808
+ "requirement": "a `when` outside the edge-condition grammar (a second expression language) MUST be rejected",
26809
+ "interpolated": true
26810
+ },
26811
+ {
26812
+ "section": null,
26813
+ "requirement": "an operator outside expression|equals|notEquals|contains|regex|truthy|falsy MUST be rejected",
26814
+ "interpolated": true
26815
+ }
26816
+ ]
26817
+ },
26818
+ {
26819
+ "id": "openwop.it.v2-header-scheme.no-removed-header-family-appears-on-any-response",
26820
+ "file": "v2-header-scheme.test.ts",
26821
+ "line": 49,
26822
+ "title": "no removed header family appears on any response",
26823
+ "explicitId": "openwop.requirement.0171.header-scheme.no-legacy-headers",
26824
+ "citations": [
26825
+ {
26826
+ "section": null,
26827
+ "requirement": null,
26828
+ "interpolated": true
26829
+ }
26830
+ ]
26831
+ },
26832
+ {
26833
+ "id": "openwop.it.v2-header-scheme.openwop-version-names-the-contract-on-every-response",
26834
+ "file": "v2-header-scheme.test.ts",
26835
+ "line": 58,
26836
+ "title": "OpenWOP-Version names the contract on every response",
26837
+ "explicitId": "openwop.requirement.0171.header-scheme.version-on-every-response",
26838
+ "citations": [
26839
+ {
26840
+ "section": "spec/v2/core/versioning.md §1.4",
26841
+ "requirement": null,
26842
+ "interpolated": true
26843
+ },
26844
+ {
26845
+ "section": "spec/v2/core/versioning.md §1.4",
26846
+ "requirement": null,
26847
+ "interpolated": true
26848
+ }
26849
+ ]
26850
+ },
26851
+ {
26852
+ "id": "openwop.it.v2-id-grammar.every-id-on-the-run-snapshot-matches-its-ids-schema-json-kind",
26853
+ "file": "v2-id-grammar.test.ts",
26854
+ "line": 43,
26855
+ "title": "every id on the run snapshot matches its ids.schema.json kind",
26856
+ "explicitId": "openwop.requirement.0170.id-grammar.snapshot",
26857
+ "citations": [
26858
+ {
26859
+ "section": null,
26860
+ "requirement": null,
26861
+ "interpolated": true
26862
+ },
26863
+ {
26864
+ "section": null,
26865
+ "requirement": null,
26866
+ "interpolated": true
26867
+ }
26868
+ ]
26869
+ },
26870
+ {
26871
+ "id": "openwop.it.v2-id-grammar.every-id-on-the-run-events-matches-its-ids-schema-json-kind",
26872
+ "file": "v2-id-grammar.test.ts",
26873
+ "line": 53,
26874
+ "title": "every id on the run events matches its ids.schema.json kind",
26875
+ "explicitId": "openwop.requirement.0170.id-grammar.events",
26876
+ "citations": [
26877
+ {
26878
+ "section": null,
26879
+ "requirement": null,
26880
+ "interpolated": true
26881
+ },
26882
+ {
26883
+ "section": null,
26884
+ "requirement": "every event MUST carry the run's own runId",
26885
+ "interpolated": true
26886
+ }
26887
+ ]
26888
+ },
26889
+ {
26890
+ "id": "openwop.it.v2-id-grammar.a-run-id-whose-tenant-segment-is-not-the-caller-s-is-refused",
26891
+ "file": "v2-id-grammar.test.ts",
26892
+ "line": 68,
26893
+ "title": "a run id whose tenant segment is not the caller's is refused",
26894
+ "explicitId": "openwop.requirement.0170.id-grammar.tenant-binding",
26895
+ "citations": [
26896
+ {
26897
+ "section": null,
26898
+ "requirement": null,
26899
+ "interpolated": true
26900
+ },
26901
+ {
26902
+ "section": null,
26903
+ "requirement": null,
26904
+ "interpolated": true
26905
+ },
26906
+ {
26907
+ "section": "spec/v2/core/errors.md",
26908
+ "requirement": "the code MUST be answered with its registered HTTP status (id_tenant_mismatch → 403, not_found → 404)"
26909
+ }
26910
+ ]
26911
+ },
26912
+ {
26913
+ "id": "openwop.it.v2-idempotency-key-grammar.a-22-character-key-inside-the-grammar-is-accepted",
26914
+ "file": "v2-idempotency-key-grammar.test.ts",
26915
+ "line": 38,
26916
+ "title": "a 22+ character key inside the grammar is accepted",
26917
+ "explicitId": "openwop.requirement.0170.idempotency-key-grammar.valid-accepted",
26918
+ "citations": [
26919
+ {
26920
+ "section": null,
26921
+ "requirement": "the suite's key MUST itself be inside ^[A-Za-z0-9._~-]{22,128}$",
26922
+ "interpolated": true
26923
+ },
26924
+ {
26925
+ "section": null,
26926
+ "requirement": "a UUIDv4-strength key in base64url form satisfies the grammar and MUST NOT be refused as idempotency_key_invalid",
26927
+ "interpolated": true
26928
+ }
26929
+ ]
26930
+ },
26931
+ {
26932
+ "id": "openwop.it.v2-idempotency-key-grammar.a-key-outside-the-grammar-is-refused-with-400-idempotency-key-invalid",
26933
+ "file": "v2-idempotency-key-grammar.test.ts",
26934
+ "line": 50,
26935
+ "title": "a key outside the grammar is refused with 400 idempotency_key_invalid",
26936
+ "explicitId": "openwop.requirement.0170.idempotency-key-grammar.invalid-refused",
26937
+ "citations": [
26938
+ {
26939
+ "section": null,
26940
+ "requirement": "a host MUST reject an Idempotency-Key outside ^[A-Za-z0-9._~-]{22,128}$ with 400",
26941
+ "interpolated": true
26942
+ },
26943
+ {
26944
+ "section": null,
26945
+ "requirement": "the refusal code MUST be idempotency_key_invalid",
26946
+ "interpolated": true
26947
+ }
26948
+ ]
26949
+ },
26950
+ {
26951
+ "id": "openwop.it.v2-interrupt-token-scheme.a-token-without-the-ow2-prefix-is-refused",
26952
+ "file": "v2-interrupt-token-scheme.test.ts",
26953
+ "line": 37,
26954
+ "title": "a token without the ow2. prefix is refused",
26955
+ "explicitId": "openwop.requirement.0170.interrupt-token-scheme.unprefixed-refused",
26956
+ "citations": [
26957
+ {
26958
+ "section": null,
26959
+ "requirement": null,
26960
+ "interpolated": true
26961
+ },
26962
+ {
26963
+ "section": "spec/v2/core/interrupt.md §Tokens",
26964
+ "requirement": null,
26965
+ "interpolated": true
26966
+ }
26967
+ ]
26968
+ },
26969
+ {
26970
+ "id": "openwop.it.v2-interrupt-token-scheme.a-well-formed-token-under-a-kid-the-host-does-not-hold-is-401-interrupt-token-in",
26971
+ "file": "v2-interrupt-token-scheme.test.ts",
26972
+ "line": 46,
26973
+ "title": "a well-formed token under a kid the host does not hold is 401 interrupt_token_invalid",
26974
+ "explicitId": "openwop.requirement.0170.interrupt-token-scheme.unheld-kid-refused",
26975
+ "citations": [
26976
+ {
26977
+ "section": null,
26978
+ "requirement": "a host MUST refuse a token whose kid it does not hold with 401",
26979
+ "interpolated": true
26980
+ },
26981
+ {
26982
+ "section": null,
26983
+ "requirement": "the refusal code MUST be interrupt_token_invalid (one code per state — never not_found for a token the host cannot verify)",
26984
+ "interpolated": true
26985
+ }
26986
+ ]
26987
+ },
26988
+ {
26989
+ "id": "openwop.it.v2-lane-issuer-advertised.every-auth-lanes-member-names-lane-issuers-revocation-and-minimumassurance",
26990
+ "file": "v2-lane-issuer-advertised.test.ts",
26991
+ "line": 36,
26992
+ "title": "every auth.lanes[] member names lane, issuers[], revocation and minimumAssurance",
26993
+ "explicitId": "openwop.requirement.0170.lane-issuer-advertised.members",
26994
+ "citations": [
26995
+ {
26996
+ "section": null,
26997
+ "requirement": null,
26998
+ "interpolated": true
26999
+ },
27000
+ {
27001
+ "section": "spec/v2/core/identity.md §2.2",
27002
+ "requirement": null,
27003
+ "interpolated": true
27004
+ },
27005
+ {
27006
+ "section": "spec/v2/core/identity.md §2.2",
27007
+ "requirement": null,
27008
+ "interpolated": true
27009
+ },
27010
+ {
27011
+ "section": "spec/v2/core/identity.md §2.3",
27012
+ "requirement": null,
27013
+ "interpolated": true
27014
+ },
27015
+ {
27016
+ "section": "spec/v2/core/identity.md §2.4",
27017
+ "requirement": null,
27018
+ "interpolated": true
27019
+ }
27020
+ ]
27021
+ },
27022
+ {
27023
+ "id": "openwop.it.v2-lane-issuer-advertised.a-windowed-revocation-rule-advertises-revocationwindowseconds",
27024
+ "file": "v2-lane-issuer-advertised.test.ts",
27025
+ "line": 52,
27026
+ "title": "a windowed revocation rule advertises revocationWindowSeconds",
27027
+ "explicitId": "openwop.requirement.0170.lane-issuer-advertised.window",
27028
+ "citations": [
27029
+ {
27030
+ "section": "spec/v2/core/identity.md §2.2",
27031
+ "requirement": null,
27032
+ "interpolated": true
27033
+ }
27034
+ ]
27035
+ },
27036
+ {
27037
+ "id": "openwop.it.v2-legacy-profiles-absent.no-legacy-id-appears-in-a2a-profiles-or-mcp-profiles-and-each-id-matches-its-fac",
27038
+ "file": "v2-legacy-profiles-absent.test.ts",
27039
+ "line": 41,
27040
+ "title": "no -legacy id appears in a2a.profiles or mcp.profiles and each id matches its facet pattern",
27041
+ "explicitId": "openwop.requirement.0175.legacy-profiles-absent",
27042
+ "citations": [
27043
+ {
27044
+ "section": "interop.md §Legacy profiles are absent",
27045
+ "requirement": null,
27046
+ "interpolated": true
27047
+ },
27048
+ {
27049
+ "section": null,
27050
+ "requirement": null,
27051
+ "interpolated": true
27052
+ },
27053
+ {
27054
+ "section": null,
27055
+ "requirement": null,
27056
+ "interpolated": true
27057
+ }
27058
+ ]
27059
+ },
27060
+ {
27061
+ "id": "openwop.it.v2-legacy-profiles-absent.no-root-profiles-exists-in-the-v2-representation",
27062
+ "file": "v2-legacy-profiles-absent.test.ts",
27063
+ "line": 70,
27064
+ "title": "no root profiles[] exists in the v2 representation",
27065
+ "explicitId": "openwop.requirement.0175.legacy-profiles-absent.no-root-profiles",
27066
+ "citations": [
27067
+ {
27068
+ "section": "capabilities.md §Profiles",
27069
+ "requirement": "no `profiles[]` exists at the v2 root — a profile is a predicate over the declaration file, not an advertisement (RFC 0169 §C.1)"
27070
+ }
27071
+ ]
27072
+ },
27073
+ {
27074
+ "id": "openwop.it.v2-manifest-ceiling-refused.an-engines-openwop-range-with-no-upper-bound-1-0-0-reads-2-0-0-and-is-refused-at",
27075
+ "file": "v2-manifest-ceiling-refused.test.ts",
27076
+ "line": 105,
27077
+ "title": "an engines.openwop range with no upper bound (>=1.0.0) reads <2.0.0 and is refused at install with pack_engine_unsupported",
27078
+ "explicitId": "openwop.requirement.0177.manifest-ceiling-refused.unbounded",
27079
+ "citations": [
27080
+ {
27081
+ "section": null,
27082
+ "requirement": "an unbounded range does not admit protocol major 2 and MUST be refused with 400 pack_engine_unsupported",
27083
+ "interpolated": true
27084
+ },
27085
+ {
27086
+ "section": null,
27087
+ "requirement": "the refusal code MUST be pack_engine_unsupported (not pack_runtime_requirement_unmet)",
27088
+ "interpolated": true
27089
+ }
27090
+ ]
27091
+ },
27092
+ {
27093
+ "id": "openwop.it.v2-manifest-ceiling-refused.a-v1-ceiling-1-0-0-2-0-0-is-refused-at-install-with-pack-engine-unsupported",
27094
+ "file": "v2-manifest-ceiling-refused.test.ts",
27095
+ "line": 114,
27096
+ "title": "a v1 ceiling (>=1.0.0 <2.0.0) is refused at install with pack_engine_unsupported",
27097
+ "explicitId": "openwop.requirement.0177.manifest-ceiling-refused.v1-ceiling",
27098
+ "citations": [
27099
+ {
27100
+ "section": null,
27101
+ "requirement": "a <2.0.0 ceiling does not admit protocol major 2 and MUST be refused with 400 pack_engine_unsupported",
27102
+ "interpolated": true
27103
+ },
27104
+ {
27105
+ "section": null,
27106
+ "requirement": "the refusal code MUST be pack_engine_unsupported",
27107
+ "interpolated": true
27108
+ }
27109
+ ]
27110
+ },
27111
+ {
27112
+ "id": "openwop.it.v2-manifest-ceiling-refused.a-range-admitting-the-host-major-2-0-0-3-0-0-installs",
27113
+ "file": "v2-manifest-ceiling-refused.test.ts",
27114
+ "line": 123,
27115
+ "title": "a range admitting the host major (>=2.0.0 <3.0.0) installs",
27116
+ "explicitId": "openwop.requirement.0177.manifest-ceiling-refused.v2-installs",
27117
+ "citations": [
27118
+ {
27119
+ "section": null,
27120
+ "requirement": null,
27121
+ "interpolated": true
27122
+ }
27123
+ ]
27124
+ },
27125
+ {
27126
+ "id": "openwop.it.v2-manifest-hatch-carried.an-x-field-inside-agents-0-of-a-node-pack-is-ignored-not-rejected-the-pack-insta",
27127
+ "file": "v2-manifest-hatch-carried.test.ts",
27128
+ "line": 85,
27129
+ "title": "an x- field inside agents[0] of a node pack is ignored, not rejected — the pack installs",
27130
+ "explicitId": "openwop.requirement.0177.manifest-hatch-carried.agents-x-field",
27131
+ "citations": [
27132
+ {
27133
+ "section": null,
27134
+ "requirement": null,
27135
+ "interpolated": true
27136
+ }
27137
+ ]
27138
+ },
27139
+ {
27140
+ "id": "openwop.it.v2-manifest-hatch-carried.an-x-field-inside-a-prompt-template-of-a-prompt-pack-is-ignored-not-rejected-the",
27141
+ "file": "v2-manifest-hatch-carried.test.ts",
27142
+ "line": 103,
27143
+ "title": "an x- field inside a prompt template of a prompt pack is ignored, not rejected — the pack installs",
27144
+ "explicitId": "openwop.requirement.0177.manifest-hatch-carried.prompt-template-x-field",
27145
+ "citations": [
27146
+ {
27147
+ "section": null,
27148
+ "requirement": null,
27149
+ "interpolated": true
27150
+ }
27151
+ ]
27152
+ },
27153
+ {
27154
+ "id": "openwop.it.v2-min-client-version.a-client-below-minclientversion-is-refused-with-426-client-version-unsupported",
27155
+ "file": "v2-min-client-version.test.ts",
27156
+ "line": 35,
27157
+ "title": "a client below minClientVersion is refused with 426 client_version_unsupported",
27158
+ "explicitId": "openwop.requirement.0172.min-client-version",
27159
+ "citations": [
27160
+ {
27161
+ "section": null,
27162
+ "requirement": "minClientVersion MUST use the <major>.<minor> grammar (axis 15, as axis 1)",
27163
+ "interpolated": true
27164
+ },
27165
+ {
27166
+ "section": null,
27167
+ "requirement": "a 426 refusal MUST carry client_version_unsupported",
27168
+ "interpolated": true
27169
+ },
27170
+ {
27171
+ "section": "spec/v2/core/errors.md §The envelope",
27172
+ "requirement": null,
27173
+ "interpolated": true
27174
+ }
27175
+ ]
27176
+ },
27177
+ {
27178
+ "id": "openwop.it.v2-minimum-version-refused.an-a2a-peer-offering-only-a-version-below-minimumversion-is-refused",
27179
+ "file": "v2-minimum-version-refused.test.ts",
27180
+ "line": 86,
27181
+ "title": "an A2A peer offering only a version below minimumVersion is refused",
27182
+ "explicitId": "openwop.requirement.0175.minimum-version-refused",
27183
+ "citations": [
27184
+ {
27185
+ "section": "interop.md §The floor",
27186
+ "requirement": null,
27187
+ "interpolated": true
27188
+ }
27189
+ ]
27190
+ },
27191
+ {
27192
+ "id": "openwop.it.v2-minimum-version-refused.an-mcp-server-offering-only-a-revision-below-minimumrevision-is-refused",
27193
+ "file": "v2-minimum-version-refused.test.ts",
27194
+ "line": 114,
27195
+ "title": "an MCP server offering only a revision below minimumRevision is refused",
27196
+ "explicitId": "openwop.requirement.0175.minimum-version-refused.mcp",
27197
+ "citations": [
27198
+ {
27199
+ "section": "interop.md §The floor",
27200
+ "requirement": null,
27201
+ "interpolated": true
27202
+ }
27203
+ ]
27204
+ },
27205
+ {
27206
+ "id": "openwop.it.v2-mrtr-rounds-ceiling.mcp-mrtr-maxrounds-is-an-integer-ceiling-in-1-16",
27207
+ "file": "v2-mrtr-rounds-ceiling.test.ts",
27208
+ "line": 46,
27209
+ "title": "mcp.mrtr.maxRounds is an integer ceiling in 1..16",
27210
+ "explicitId": "openwop.requirement.0175.mrtr-rounds-ceiling",
27211
+ "citations": [
27212
+ {
27213
+ "section": "facets/mcp.schema.json mrtr.maxRounds",
27214
+ "requirement": null,
27215
+ "interpolated": true
27216
+ }
27217
+ ]
27218
+ },
27219
+ {
27220
+ "id": "openwop.it.v2-mrtr-rounds-ceiling.round-maxrounds-1-is-refused-with-mcp-mrtr-rounds-exceeded",
27221
+ "file": "v2-mrtr-rounds-ceiling.test.ts",
27222
+ "line": 59,
27223
+ "title": "round maxRounds + 1 is refused with mcp_mrtr_rounds_exceeded",
27224
+ "explicitId": "openwop.requirement.0175.mrtr-rounds-ceiling.refused",
27225
+ "citations": [
27226
+ {
27227
+ "section": "interop.md §The MCP round ceiling",
27228
+ "requirement": null,
27229
+ "interpolated": true
27230
+ },
27231
+ {
27232
+ "section": "errors.json mcp_mrtr_rounds_exceeded",
27233
+ "requirement": null,
27234
+ "interpolated": true
27235
+ },
27236
+ {
27237
+ "section": "interop.md §The MCP round ceiling",
27238
+ "requirement": null,
27239
+ "interpolated": true
27240
+ }
27241
+ ]
27242
+ },
27243
+ {
27244
+ "id": "openwop.it.v2-negotiation-authenticated.an-unauthenticated-a2a-exchange-cannot-lower-the-version-below-preferredversion",
27245
+ "file": "v2-negotiation-authenticated.test.ts",
27246
+ "line": 86,
27247
+ "title": "an unauthenticated A2A exchange cannot lower the version below preferredVersion",
27248
+ "explicitId": null,
27249
+ "citations": []
27250
+ },
27251
+ {
27252
+ "id": "openwop.it.v2-negotiation-authenticated.an-unauthenticated-mcp-exchange-cannot-lower-the-revision-below-preferredversion",
27253
+ "file": "v2-negotiation-authenticated.test.ts",
27254
+ "line": 106,
27255
+ "title": "an unauthenticated MCP exchange cannot lower the revision below preferredVersion",
27256
+ "explicitId": null,
27257
+ "citations": []
27258
+ },
27259
+ {
27260
+ "id": "openwop.it.v2-negotiation-decided-emitted.an-a2a-exchange-leaves-negotiation-decided-on-the-host-log",
27261
+ "file": "v2-negotiation-decided-emitted.test.ts",
27262
+ "line": 143,
27263
+ "title": "an A2A exchange leaves negotiation.decided on the host log",
27264
+ "explicitId": null,
27265
+ "citations": []
27266
+ },
27267
+ {
27268
+ "id": "openwop.it.v2-negotiation-decided-emitted.an-mcp-exchange-leaves-negotiation-decided-on-the-host-log",
27269
+ "file": "v2-negotiation-decided-emitted.test.ts",
27270
+ "line": 146,
27271
+ "title": "an MCP exchange leaves negotiation.decided on the host log",
27272
+ "explicitId": null,
27273
+ "citations": []
27274
+ },
27275
+ {
27276
+ "id": "openwop.it.v2-no-transport-advertisement.the-v2-root-carries-no-supportedtransports-and-no-grpc-block",
27277
+ "file": "v2-no-transport-advertisement.test.ts",
27278
+ "line": 29,
27279
+ "title": "the v2 root carries no supportedTransports and no grpc block",
27280
+ "explicitId": "openwop.requirement.0175.no-transport-advertisement",
27281
+ "citations": [
27282
+ {
27283
+ "section": "interop.md §REST is the wire",
27284
+ "requirement": "a v2 host MUST NOT advertise a transport list — `supportedTransports` does not exist in v2 (RFC 0175 §B.1, row C8.2)"
27285
+ },
27286
+ {
27287
+ "section": "interop.md §gRPC",
27288
+ "requirement": "a v2 host MUST NOT advertise a `grpc` capability block — an unwitnessable family is not advertisable (RFC 0175 §A.1, row C8.3)"
27289
+ },
27290
+ {
27291
+ "section": "interop.md §The facets",
27292
+ "requirement": null,
27293
+ "interpolated": true
27294
+ },
27295
+ {
27296
+ "section": "capabilities.schema.json (closed root)",
27297
+ "requirement": null,
27298
+ "interpolated": true
27299
+ }
27300
+ ]
27301
+ },
27302
+ {
27303
+ "id": "openwop.it.v2-owner-subject-required.owner-subject-is-present-and-validates-against-subject-schema-json",
27304
+ "file": "v2-owner-subject-required.test.ts",
27305
+ "line": 54,
27306
+ "title": "owner.subject is present and validates against subject.schema.json",
27307
+ "explicitId": "openwop.requirement.0170.owner-subject-required.subject",
27308
+ "citations": [
27309
+ {
27310
+ "section": null,
27311
+ "requirement": "RunSnapshot.owner.subject is REQUIRED",
27312
+ "interpolated": true
27313
+ },
27314
+ {
27315
+ "section": null,
27316
+ "requirement": null,
27317
+ "interpolated": true
27318
+ },
27319
+ {
27320
+ "section": null,
27321
+ "requirement": "RunSnapshot.owner.tenant is REQUIRED",
27322
+ "interpolated": true
27323
+ }
27324
+ ]
27325
+ },
27326
+ {
27327
+ "id": "openwop.it.v2-owner-subject-required.owner-carries-no-principal-principalkind",
27328
+ "file": "v2-owner-subject-required.test.ts",
27329
+ "line": 64,
27330
+ "title": "owner carries no principal / principalKind",
27331
+ "explicitId": "openwop.requirement.0170.owner-subject-required.no-principal",
27332
+ "citations": [
27333
+ {
27334
+ "section": null,
27335
+ "requirement": "`principal` is removed from RunSnapshot.owner — subject.subjectId carries it",
27336
+ "interpolated": true
27337
+ },
27338
+ {
27339
+ "section": null,
27340
+ "requirement": "`principalKind` is removed from RunSnapshot.owner — subject.kind carries it",
27341
+ "interpolated": true
27342
+ },
27343
+ {
27344
+ "section": null,
27345
+ "requirement": "owner is the closed block { tenant, workspace?, subject }",
27346
+ "interpolated": true
27347
+ }
27348
+ ]
27349
+ },
27350
+ {
27351
+ "id": "openwop.it.v2-pack-isolation.sandbox-isolationmodel-names-a-real-mechanism-never-node-vm",
27352
+ "file": "v2-pack-isolation.test.ts",
27353
+ "line": 70,
27354
+ "title": "sandbox.isolationModel names a real mechanism, never node:vm",
27355
+ "explicitId": "openwop.requirement.0173.pack-isolation",
27356
+ "citations": [
27357
+ {
27358
+ "section": "facets/sandbox.schema.json isolationModel",
27359
+ "requirement": "isolationModel MUST NOT be node:vm — it is escapable by design (RFC 0035 §130) and is not a v2 value (RFC 0173 §D.1)"
27360
+ },
27361
+ {
27362
+ "section": "facets/sandbox.schema.json isolationModel",
27363
+ "requirement": null,
27364
+ "interpolated": true
27365
+ }
27366
+ ]
27367
+ },
27368
+ {
27369
+ "id": "openwop.it.v2-pack-isolation.node-pack-sandbox-fs-gated-a-host-filesystem-read-is-refused",
27370
+ "file": "v2-pack-isolation.test.ts",
27371
+ "line": 84,
27372
+ "title": "node-pack-sandbox-fs-gated: a host filesystem read is refused",
27373
+ "explicitId": null,
27374
+ "citations": []
27375
+ },
27376
+ {
27377
+ "id": "openwop.it.v2-pack-isolation.node-pack-sandbox-fs-gated-a-host-filesystem-write-is-refused",
27378
+ "file": "v2-pack-isolation.test.ts",
27379
+ "line": 91,
27380
+ "title": "node-pack-sandbox-fs-gated: a host filesystem write is refused",
27381
+ "explicitId": null,
27382
+ "citations": []
27383
+ },
27384
+ {
27385
+ "id": "openwop.it.v2-pack-isolation.node-pack-sandbox-no-env-the-host-environment-does-not-leak",
27386
+ "file": "v2-pack-isolation.test.ts",
27387
+ "line": 98,
27388
+ "title": "node-pack-sandbox-no-env: the host environment does not leak",
27389
+ "explicitId": null,
27390
+ "citations": []
27391
+ },
27392
+ {
27393
+ "id": "openwop.it.v2-pack-isolation.node-pack-sandbox-network-gated-ungated-network-egress-is-refused",
27394
+ "file": "v2-pack-isolation.test.ts",
27395
+ "line": 105,
27396
+ "title": "node-pack-sandbox-network-gated: ungated network egress is refused",
27397
+ "explicitId": null,
27398
+ "citations": []
27399
+ },
27400
+ {
27401
+ "id": "openwop.it.v2-pack-isolation.node-pack-sandbox-no-process-host-process-access-is-refused",
27402
+ "file": "v2-pack-isolation.test.ts",
27403
+ "line": 112,
27404
+ "title": "node-pack-sandbox-no-process: host process access is refused",
27405
+ "explicitId": null,
27406
+ "citations": []
27407
+ },
27408
+ {
27409
+ "id": "openwop.it.v2-pack-isolation.node-pack-sandbox-timeout-exceeding-wallclocklimitms-fails-with-sandbox-timeout",
27410
+ "file": "v2-pack-isolation.test.ts",
27411
+ "line": 119,
27412
+ "title": "node-pack-sandbox-timeout: exceeding wallClockLimitMs fails with sandbox_timeout",
27413
+ "explicitId": "openwop.requirement.0173.pack-isolation.timeout",
27414
+ "citations": [
27415
+ {
27416
+ "section": "security-defaults.md §Sandbox isolation",
27417
+ "requirement": "node-pack-sandbox-timeout: a wall-clock overrun MUST fail with sandbox_timeout"
27418
+ }
27419
+ ]
27420
+ },
27421
+ {
27422
+ "id": "openwop.it.v2-pack-isolation.node-pack-sandbox-memory-cap-exceeding-memorylimitbytes-fails-with-sandbox-memor",
27423
+ "file": "v2-pack-isolation.test.ts",
27424
+ "line": 126,
27425
+ "title": "node-pack-sandbox-memory-cap: exceeding memoryLimitBytes fails with sandbox_memory_exceeded",
27426
+ "explicitId": "openwop.requirement.0173.pack-isolation.memory-cap",
27427
+ "citations": [
27428
+ {
27429
+ "section": "security-defaults.md §Sandbox isolation",
27430
+ "requirement": "node-pack-sandbox-memory-cap: a memory overrun MUST fail with sandbox_memory_exceeded"
27431
+ }
27432
+ ]
27433
+ },
27434
+ {
27435
+ "id": "openwop.it.v2-pack-isolation.node-pack-sandbox-isolated-context-a-pack-cannot-mutate-state-another-invocation",
27436
+ "file": "v2-pack-isolation.test.ts",
27437
+ "line": 133,
27438
+ "title": "node-pack-sandbox-isolated-context: a pack cannot mutate state another invocation sees",
27439
+ "explicitId": "openwop.requirement.0173.pack-isolation.isolated-context",
27440
+ "citations": [
27441
+ {
27442
+ "section": "host-sample-test-seams.md §8",
27443
+ "requirement": "misbehave.cross-pack-mutate is not a failure mode — it MUST return a result"
27444
+ },
27445
+ {
27446
+ "section": "security-defaults.md §Sandbox isolation",
27447
+ "requirement": "node-pack-sandbox-isolated-context: result.shared MUST equal 1 on every invocation — a mutation MUST NOT leak into a fresh context"
27448
+ }
27449
+ ]
27450
+ },
27451
+ {
27452
+ "id": "openwop.it.v2-payload-registry-closed.every-registered-event-carries-a-payload-that-validates-against-its-typeindex-en",
27453
+ "file": "v2-payload-registry-closed.test.ts",
27454
+ "line": 94,
27455
+ "title": "every registered event carries a payload that validates against its _typeIndex entry",
27456
+ "explicitId": "openwop.requirement.0171.payload-registry-closed",
27457
+ "citations": [
27458
+ {
27459
+ "section": null,
27460
+ "requirement": null,
27461
+ "interpolated": true
27462
+ },
27463
+ {
27464
+ "section": null,
27465
+ "requirement": null,
27466
+ "interpolated": true
27467
+ }
27468
+ ]
27469
+ },
27470
+ {
27471
+ "id": "openwop.it.v2-peer-dependency-declared.a-peerdependencies-key-the-declaration-file-does-not-name-is-refused-with-pack-p",
27472
+ "file": "v2-peer-dependency-declared.test.ts",
27473
+ "line": 104,
27474
+ "title": "a peerDependencies key the declaration file does not name is refused with pack_peer_dependency_undefined",
27475
+ "explicitId": "openwop.requirement.0177.peer-dependency-declared.undefined-key",
27476
+ "citations": [
27477
+ {
27478
+ "section": null,
27479
+ "requirement": "a key absent from spec/v2/declaration.json MUST be refused with 400 pack_peer_dependency_undefined",
27480
+ "interpolated": true
27481
+ },
27482
+ {
27483
+ "section": null,
27484
+ "requirement": "the refusal code MUST be pack_peer_dependency_undefined",
27485
+ "interpolated": true
27486
+ }
27487
+ ]
27488
+ },
27489
+ {
27490
+ "id": "openwop.it.v2-peer-dependency-declared.an-alias-table-row-host-fs-fs-resolves-through-the-overlap-and-the-pack-installs",
27491
+ "file": "v2-peer-dependency-declared.test.ts",
27492
+ "line": 113,
27493
+ "title": "an alias-table row (host.fs → fs) resolves through the overlap and the pack installs",
27494
+ "explicitId": "openwop.requirement.0177.peer-dependency-declared.alias-overlap",
27495
+ "citations": [
27496
+ {
27497
+ "section": "packs.md §\"The alias table\" (RFC 0177 §B.2)",
27498
+ "requirement": null,
27499
+ "interpolated": true
27500
+ }
27501
+ ]
27502
+ },
27503
+ {
27504
+ "id": "openwop.it.v2-pinned-run-disposition.a-pin-naming-a-change-id-the-host-does-not-implement-is-cancelled-with-v1-pin-un",
27505
+ "file": "v2-pinned-run-disposition.test.ts",
27506
+ "line": 76,
27507
+ "title": "a pin naming a change id the host does not implement is cancelled with v1_pin_unsupported / v2-cutover",
27508
+ "explicitId": "openwop.requirement.0176.pinned-run-disposition.cancelled",
27509
+ "citations": [
27510
+ {
27511
+ "section": null,
27512
+ "requirement": null,
27513
+ "interpolated": true
27514
+ },
27515
+ {
27516
+ "section": null,
27517
+ "requirement": "the cancellation MUST be an event on the run's own log (run.cancelled), not a silent status flip",
27518
+ "interpolated": true
27519
+ },
27520
+ {
27521
+ "section": "run-event-payloads.schema.json runCancelled.reason",
27522
+ "requirement": null,
27523
+ "interpolated": true
27524
+ },
27525
+ {
27526
+ "section": "run-event-payloads.schema.json runCancelled.cancelledBy",
27527
+ "requirement": null,
27528
+ "interpolated": true
27529
+ },
27530
+ {
27531
+ "section": null,
27532
+ "requirement": "the version.pinned row MUST survive the cancellation — the log is preserved (adversarial review 4)",
27533
+ "interpolated": true
27534
+ },
27535
+ {
27536
+ "section": null,
27537
+ "requirement": "version.pinned is never rewritten: the pin still names the change id it was seeded with",
27538
+ "interpolated": true
27539
+ }
27540
+ ]
27541
+ },
27542
+ {
27543
+ "id": "openwop.it.v2-pinned-run-disposition.a-pin-naming-a-change-id-the-host-still-implements-continues-under-the-reader-ru",
27544
+ "file": "v2-pinned-run-disposition.test.ts",
27545
+ "line": 101,
27546
+ "title": "a pin naming a change id the host still implements continues under the reader rule with the pin verbatim",
27547
+ "explicitId": "openwop.requirement.0176.pinned-run-disposition.continued",
27548
+ "citations": [
27549
+ {
27550
+ "section": null,
27551
+ "requirement": null,
27552
+ "interpolated": true
27553
+ },
27554
+ {
27555
+ "section": null,
27556
+ "requirement": null,
27557
+ "interpolated": true
27558
+ },
27559
+ {
27560
+ "section": null,
27561
+ "requirement": "the pin is honoured verbatim — version.pinned reads back with the seeded changeId and version",
27562
+ "interpolated": true
27563
+ }
27564
+ ]
27565
+ },
27566
+ {
27567
+ "id": "openwop.it.v2-poll-cursor-v2.the-response-is-the-closed-runid-events-lastsequence-status-isterminal",
27568
+ "file": "v2-poll-cursor-v2.test.ts",
27569
+ "line": 60,
27570
+ "title": "the response is the closed { runId, events, lastSequence, status, isTerminal }",
27571
+ "explicitId": "openwop.requirement.0171.poll-cursor-v2.shape",
27572
+ "citations": [
27573
+ {
27574
+ "section": null,
27575
+ "requirement": "pollRunEvents MUST answer 200",
27576
+ "interpolated": true
27577
+ },
27578
+ {
27579
+ "section": null,
27580
+ "requirement": "the poll response MUST be exactly { runId, events, lastSequence, status, isTerminal } (closed)",
27581
+ "interpolated": true
27582
+ },
27583
+ {
27584
+ "section": null,
27585
+ "requirement": "runId MUST echo the polled run",
27586
+ "interpolated": true
27587
+ },
27588
+ {
27589
+ "section": null,
27590
+ "requirement": "events MUST be an array",
27591
+ "interpolated": true
27592
+ },
27593
+ {
27594
+ "section": null,
27595
+ "requirement": "lastSequence is the highest sequence in the log (−1 when empty)",
27596
+ "interpolated": true
27597
+ },
27598
+ {
27599
+ "section": null,
27600
+ "requirement": "status is the snapshot status",
27601
+ "interpolated": true
27602
+ },
27603
+ {
27604
+ "section": null,
27605
+ "requirement": "isTerminal is a boolean",
27606
+ "interpolated": true
27607
+ },
27608
+ {
27609
+ "section": null,
27610
+ "requirement": "lastSequence MUST equal the highest sequence returned when the response carries the whole log",
27611
+ "interpolated": true
27612
+ }
27613
+ ]
27614
+ },
27615
+ {
27616
+ "id": "openwop.it.v2-poll-cursor-v2.omitting-the-cursor-returns-from-the-first-event-sequence-0",
27617
+ "file": "v2-poll-cursor-v2.test.ts",
27618
+ "line": 77,
27619
+ "title": "omitting the cursor returns from the first event (sequence 0)",
27620
+ "explicitId": "openwop.requirement.0171.poll-cursor-v2.from-first",
27621
+ "citations": [
27622
+ {
27623
+ "section": null,
27624
+ "requirement": "omission of afterSequence means \"from the first event\": the first returned sequence MUST be 0",
27625
+ "interpolated": true
27626
+ }
27627
+ ]
27628
+ },
27629
+ {
27630
+ "id": "openwop.it.v2-poll-cursor-v2.aftersequence-n-returns-only-events-with-sequence-n",
27631
+ "file": "v2-poll-cursor-v2.test.ts",
27632
+ "line": 87,
27633
+ "title": "afterSequence=N returns only events with sequence > N",
27634
+ "explicitId": "openwop.requirement.0171.poll-cursor-v2.after-sequence",
27635
+ "citations": [
27636
+ {
27637
+ "section": null,
27638
+ "requirement": "afterSequence is an integer ≥ 0 and MUST be accepted",
27639
+ "interpolated": true
27640
+ },
27641
+ {
27642
+ "section": null,
27643
+ "requirement": null,
27644
+ "interpolated": true
27645
+ },
27646
+ {
27647
+ "section": null,
27648
+ "requirement": "the cursor is exclusive and the log is not renumbered: afterSequence=first yields exactly the rest of the log",
27649
+ "interpolated": true
27650
+ }
27651
+ ]
27652
+ },
27653
+ {
27654
+ "id": "openwop.it.v2-poll-cursor-v2.a-cursor-past-the-end-of-the-log-returns-200-with-an-empty-events-array",
27655
+ "file": "v2-poll-cursor-v2.test.ts",
27656
+ "line": 103,
27657
+ "title": "a cursor past the end of the log returns 200 with an empty events array",
27658
+ "explicitId": "openwop.requirement.0171.poll-cursor-v2.past-end",
27659
+ "citations": [
27660
+ {
27661
+ "section": null,
27662
+ "requirement": "a cursor past the end of the log MUST return 200",
27663
+ "interpolated": true
27664
+ },
27665
+ {
27666
+ "section": null,
27667
+ "requirement": "a cursor past the end of the log MUST return an empty events array",
27668
+ "interpolated": true
27669
+ }
27670
+ ]
27671
+ },
27672
+ {
27673
+ "id": "openwop.it.v2-preferred-version-default.preferredversion-is-a-member-of-protocolversions",
27674
+ "file": "v2-preferred-version-default.test.ts",
27675
+ "line": 40,
27676
+ "title": "preferredVersion is a member of protocolVersions[]",
27677
+ "explicitId": "openwop.requirement.0172.preferred-version-default.member",
27678
+ "citations": [
27679
+ {
27680
+ "section": null,
27681
+ "requirement": "preferredVersion is REQUIRED root metadata with the <major>.<minor> grammar",
27682
+ "interpolated": true
27683
+ },
27684
+ {
27685
+ "section": null,
27686
+ "requirement": null,
27687
+ "interpolated": true
27688
+ },
27689
+ {
27690
+ "section": null,
27691
+ "requirement": "on a host serving a single major, preferredVersion MUST equal protocolVersion (RFC 0179 §A.1)",
27692
+ "interpolated": true
27693
+ }
27694
+ ]
27695
+ },
27696
+ {
27697
+ "id": "openwop.it.v2-preferred-version-default.a-header-less-get-well-known-openwop-is-the-preferredversion-representation",
27698
+ "file": "v2-preferred-version-default.test.ts",
27699
+ "line": 52,
27700
+ "title": "a header-less GET /.well-known/openwop is the preferredVersion representation",
27701
+ "explicitId": "openwop.requirement.0172.preferred-version-default.headerless",
27702
+ "citations": [
27703
+ {
27704
+ "section": "spec/v2/core/versioning.md §1.3",
27705
+ "requirement": "the discovery resource MUST answer a header-less request"
27706
+ },
27707
+ {
27708
+ "section": "spec/v2/core/versioning.md §1.3",
27709
+ "requirement": null,
27710
+ "interpolated": true
27711
+ },
27712
+ {
27713
+ "section": "spec/v2/core/capabilities.md §1",
27714
+ "requirement": null,
27715
+ "interpolated": true
27716
+ },
27717
+ {
27718
+ "section": "spec/v2/core/capabilities.md §1",
27719
+ "requirement": "preferredVersion is 1.x, so the header-less representation MUST be the v1 document (protocolVersion present) through the overlap"
27720
+ },
27721
+ {
27722
+ "section": "spec/v2/core/capabilities.md §1",
27723
+ "requirement": "the v1 representation MUST carry protocolVersions[] and preferredVersion additively so a single fetch names the other major"
27724
+ }
27725
+ ]
27726
+ },
27727
+ {
27728
+ "id": "openwop.it.v2-preferred-version-default.through-the-overlap-preferredversion-names-a-1-x-member",
27729
+ "file": "v2-preferred-version-default.test.ts",
27730
+ "line": 70,
27731
+ "title": "through the overlap preferredVersion names a 1.x member",
27732
+ "explicitId": "openwop.requirement.0172.preferred-version-default.overlap",
27733
+ "citations": [
27734
+ {
27735
+ "section": "spec/v2/core/versioning.md §1.1",
27736
+ "requirement": null,
27737
+ "interpolated": true
27738
+ }
27739
+ ]
27740
+ },
27741
+ {
27742
+ "id": "openwop.it.v2-profiles-derived-only.the-v2-document-carries-no-root-profiles",
27743
+ "file": "v2-profiles-derived-only.test.ts",
27744
+ "line": 43,
27745
+ "title": "the v2 document carries no root `profiles[]`",
27746
+ "explicitId": "openwop.requirement.0169.profiles-derived-only.no-root-profiles",
27747
+ "citations": [
27748
+ {
27749
+ "section": null,
27750
+ "requirement": "no `profiles[]` exists at the v2 root; a profile is a derived predicate, never a wire field (row C2.10)",
27751
+ "interpolated": true
27752
+ }
27753
+ ]
27754
+ },
27755
+ {
27756
+ "id": "openwop.it.v2-profiles-derived-only.every-registry-profile-is-derivable-from-the-document-the-discovery-core-predica",
27757
+ "file": "v2-profiles-derived-only.test.ts",
27758
+ "line": 49,
27759
+ "title": "every registry profile is derivable from the document; the discovery-core predicate holds on a valid document",
27760
+ "explicitId": "openwop.requirement.0169.profiles-derived-only.derivable",
27761
+ "citations": [
27762
+ {
27763
+ "section": null,
27764
+ "requirement": "spec/v2/profiles.json MUST list at least one profile",
27765
+ "interpolated": true
27766
+ },
27767
+ {
27768
+ "section": null,
27769
+ "requirement": null,
27770
+ "interpolated": true
27771
+ },
27772
+ {
27773
+ "section": null,
27774
+ "requirement": null,
27775
+ "interpolated": true
27776
+ },
27777
+ {
27778
+ "section": null,
27779
+ "requirement": "openwop-discovery-core (metadata protocolVersions + preferredVersion, both REQUIRED at the root) MUST derive true from every valid v2 document",
27780
+ "interpolated": true
27781
+ }
27782
+ ]
27783
+ },
27784
+ {
27785
+ "id": "openwop.it.v2-provider-conflict.two-definitions-of-one-bare-provider-id-fail-closed-the-later-registration-is-re",
27786
+ "file": "v2-provider-conflict.test.ts",
27787
+ "line": 84,
27788
+ "title": "two definitions of one bare provider id fail closed: the later registration is refused with connection_provider_conflict",
27789
+ "explicitId": "openwop.requirement.0177.provider-conflict.fail-closed",
27790
+ "citations": [
27791
+ {
27792
+ "section": null,
27793
+ "requirement": null,
27794
+ "interpolated": true
27795
+ },
27796
+ {
27797
+ "section": null,
27798
+ "requirement": "the later registration of a bare provider id MUST NOT install (no version precedence)",
27799
+ "interpolated": true
27800
+ },
27801
+ {
27802
+ "section": null,
27803
+ "requirement": "the later registration MUST be refused with connection_provider_conflict",
27804
+ "interpolated": true
27805
+ }
27806
+ ]
27807
+ },
27808
+ {
27809
+ "id": "openwop.it.v2-provider-conflict.the-qualified-form-packname-github-resolves-to-the-named-pack-s-definition",
27810
+ "file": "v2-provider-conflict.test.ts",
27811
+ "line": 102,
27812
+ "title": "the qualified form <packName>#github resolves to the named pack's definition",
27813
+ "explicitId": "openwop.requirement.0177.provider-conflict.qualified-form",
27814
+ "citations": [
27815
+ {
27816
+ "section": "connection-packs.md §\"The qualified form\" (RFC 0177 §D.1)",
27817
+ "requirement": null,
27818
+ "interpolated": true
27819
+ },
27820
+ {
27821
+ "section": "connection-packs.md §\"The qualified form\" (RFC 0177 §D.1)",
27822
+ "requirement": "a qualified reference resolves only to the named pack's definition (source: pack)"
27823
+ }
27824
+ ]
27825
+ },
27826
+ {
27827
+ "id": "openwop.it.v2-refresh-sla.refreshedat-on-each-embedded-protocol-facet-is-within-90-days-of-now",
27828
+ "file": "v2-refresh-sla.test.ts",
27829
+ "line": 34,
27830
+ "title": "refreshedAt on each embedded-protocol facet is within 90 days of now",
27831
+ "explicitId": "openwop.requirement.0175.refresh-sla",
27832
+ "citations": [
27833
+ {
27834
+ "section": null,
27835
+ "requirement": null,
27836
+ "interpolated": true
27837
+ },
27838
+ {
27839
+ "section": "interop.md §The refresh SLA",
27840
+ "requirement": null,
27841
+ "interpolated": true
27842
+ },
27843
+ {
27844
+ "section": "interop.md §The refresh SLA",
27845
+ "requirement": null,
27846
+ "interpolated": true
27847
+ },
27848
+ {
27849
+ "section": null,
27850
+ "requirement": null,
27851
+ "interpolated": true
27852
+ },
27853
+ {
27854
+ "section": "interop.md §The facets",
27855
+ "requirement": null,
27856
+ "interpolated": true
27857
+ },
27858
+ {
27859
+ "section": "interop.md §The facets",
27860
+ "requirement": null,
27861
+ "interpolated": true
27862
+ }
27863
+ ]
27864
+ },
27865
+ {
27866
+ "id": "openwop.it.v2-relaxation-recorded.a-bundle-recording-a-relaxation-cannot-certify-the-relaxed-profile",
27867
+ "file": "v2-relaxation-recorded.test.ts",
27868
+ "line": 68,
27869
+ "title": "a bundle recording a relaxation cannot certify the relaxed profile",
27870
+ "explicitId": "openwop.requirement.0173.relaxation-recorded",
27871
+ "citations": [
27872
+ {
27873
+ "section": "security-defaults.md §Relaxations",
27874
+ "requirement": "control: a bundle with no relaxation and a fully witnessed profile MUST verify clean"
27875
+ },
27876
+ {
27877
+ "section": "security-defaults.md §Relaxations",
27878
+ "requirement": "control: the unrelaxed profile certifies"
27879
+ },
27880
+ {
27881
+ "section": "security-defaults.md §Relaxations",
27882
+ "requirement": "a bundle that records a relaxation MUST NOT certify the profile the relaxed obligation belongs to (`relaxed-profile-certified`, RFC 0173 §A.2)"
27883
+ },
27884
+ {
27885
+ "section": "security-defaults.md §Relaxations",
27886
+ "requirement": "the rejection names the relaxed profile"
27887
+ },
27888
+ {
27889
+ "section": "security-defaults.md §Relaxations",
27890
+ "requirement": "the relaxed profile is not in `certifiedProfiles`"
27891
+ },
27892
+ {
27893
+ "section": "security-defaults.md §Relaxations",
27894
+ "requirement": "an unrelated profile still certifies — the relaxation is scoped to the obligation it names"
27895
+ },
27896
+ {
27897
+ "section": "security-defaults.md §Relaxations",
27898
+ "requirement": "a relaxation recorded against an unclaimed profile is not a rejection — recording is the obligation, claiming is the defect"
27899
+ }
27900
+ ]
27901
+ },
27902
+ {
27903
+ "id": "openwop.it.v2-relaxation-recorded.durability-is-a-closed-set-session-deployment-persisted",
27904
+ "file": "v2-relaxation-recorded.test.ts",
27905
+ "line": 108,
27906
+ "title": "durability is a closed set: session | deployment | persisted",
27907
+ "explicitId": "openwop.requirement.0173.relaxation-recorded.durability-closed",
27908
+ "citations": [
27909
+ {
27910
+ "section": "certification-bundle.schema.json host.relaxations[].durability",
27911
+ "requirement": null,
27912
+ "interpolated": true
27913
+ },
27914
+ {
27915
+ "section": "certification-bundle.schema.json host.relaxations[].durability",
27916
+ "requirement": null,
27917
+ "interpolated": true
27918
+ },
27919
+ {
27920
+ "section": "certification-bundle.schema.json host.relaxations[].durability",
27921
+ "requirement": "the failure names the durability enum"
27922
+ }
27923
+ ]
27924
+ },
27925
+ {
27926
+ "id": "openwop.it.v2-revocation-honored.a-revoked-next-request-credential-is-refused-on-the-next-request-with-credential",
27927
+ "file": "v2-revocation-honored.test.ts",
27928
+ "line": 38,
27929
+ "title": "a revoked next-request credential is refused on the next request with credential_revoked",
27930
+ "explicitId": "openwop.requirement.0170.revocation-honored",
27931
+ "citations": [
27932
+ {
27933
+ "section": null,
27934
+ "requirement": null,
27935
+ "interpolated": true
27936
+ },
27937
+ {
27938
+ "section": null,
27939
+ "requirement": null,
27940
+ "interpolated": true
27941
+ },
27942
+ {
27943
+ "section": null,
27944
+ "requirement": null,
27945
+ "interpolated": true
27946
+ },
27947
+ {
27948
+ "section": null,
27949
+ "requirement": null,
27950
+ "interpolated": true
27951
+ },
27952
+ {
27953
+ "section": null,
27954
+ "requirement": null,
27955
+ "interpolated": true
27956
+ }
27957
+ ]
27958
+ },
27959
+ {
27960
+ "id": "openwop.it.v2-subject-link-record.the-link-formed-across-scim-and-saml-is-a-closed-subjectlink-record",
27961
+ "file": "v2-subject-link-record.test.ts",
27962
+ "line": 80,
27963
+ "title": "the link formed across SCIM and SAML is a closed SubjectLink record",
27964
+ "explicitId": "openwop.requirement.0170.subject-link-record.shape",
27965
+ "citations": [
27966
+ {
27967
+ "section": null,
27968
+ "requirement": null,
27969
+ "interpolated": true
27970
+ },
27971
+ {
27972
+ "section": null,
27973
+ "requirement": "a link MUST join exactly two distinct subjects",
27974
+ "interpolated": true
27975
+ },
27976
+ {
27977
+ "section": null,
27978
+ "requirement": "a freshly formed link carries no deniedAt",
27979
+ "interpolated": true
27980
+ }
27981
+ ]
27982
+ },
27983
+ {
27984
+ "id": "openwop.it.v2-subject-link-record.deactivation-sets-deniedat-and-the-saml-decision-path-consults-it",
27985
+ "file": "v2-subject-link-record.test.ts",
27986
+ "line": 91,
27987
+ "title": "deactivation sets deniedAt and the SAML decision path consults it",
27988
+ "explicitId": "openwop.requirement.0170.subject-link-record.denied-at",
27989
+ "citations": [
27990
+ {
27991
+ "section": null,
27992
+ "requirement": null,
27993
+ "interpolated": true
27994
+ },
27995
+ {
27996
+ "section": null,
27997
+ "requirement": "deactivation MUST set deniedAt (date-time) on the link record",
27998
+ "interpolated": true
27999
+ },
28000
+ {
28001
+ "section": null,
28002
+ "requirement": "after deniedAt is set the SAML decision path MUST deny the linked subject (the leaver contract)",
28003
+ "interpolated": true
28004
+ }
28005
+ ]
28006
+ },
28007
+ {
28008
+ "id": "openwop.it.v2-unmapped-type-refused.poll-over-a-log-with-an-unmapped-unprefixed-type-fails-with-500-event-type-unmap",
28009
+ "file": "v2-unmapped-type-refused.test.ts",
28010
+ "line": 48,
28011
+ "title": "poll over a log with an unmapped, unprefixed type fails with 500 event_type_unmapped",
28012
+ "explicitId": "openwop.requirement.0176.unmapped-type-refused",
28013
+ "citations": [
28014
+ {
28015
+ "section": null,
28016
+ "requirement": null,
28017
+ "interpolated": true
28018
+ },
28019
+ {
28020
+ "section": null,
28021
+ "requirement": null,
28022
+ "interpolated": true
28023
+ },
28024
+ {
28025
+ "section": "spec/v2/errors.json",
28026
+ "requirement": null,
28027
+ "interpolated": true
28028
+ }
28029
+ ]
28030
+ },
28031
+ {
28032
+ "id": "openwop.it.v2-unmapped-type-refused.a-fork-of-the-same-log-is-refused-for-the-same-reason-the-rule-binds-every-reade",
28033
+ "file": "v2-unmapped-type-refused.test.ts",
28034
+ "line": 71,
28035
+ "title": "a fork of the same log is refused for the same reason — the rule binds every reader",
28036
+ "explicitId": "openwop.requirement.0176.unmapped-type-refused.fork",
28037
+ "citations": [
28038
+ {
28039
+ "section": "spec/v2/core/replay.md §Replay-from-event-log internals",
28040
+ "requirement": null,
28041
+ "interpolated": true
28042
+ },
28043
+ {
28044
+ "section": null,
28045
+ "requirement": null,
28046
+ "interpolated": true
28047
+ }
28048
+ ]
28049
+ },
28050
+ {
28051
+ "id": "openwop.it.v2-v1-events-translated.poll-reads-an-era-2-log-with-v2-type-names-and-sequence-0-present",
28052
+ "file": "v2-v1-events-translated.test.ts",
28053
+ "line": 56,
28054
+ "title": "poll reads an era-2 log with v2 type names and sequence 0 present",
28055
+ "explicitId": "openwop.requirement.0176.v1-events-translated.poll",
28056
+ "citations": [
28057
+ {
28058
+ "section": null,
28059
+ "requirement": null,
28060
+ "interpolated": true
28061
+ }
28062
+ ]
28063
+ },
28064
+ {
28065
+ "id": "openwop.it.v2-v1-events-translated.sse-reads-the-same-era-2-log-with-v2-type-names",
28066
+ "file": "v2-v1-events-translated.test.ts",
28067
+ "line": 70,
28068
+ "title": "SSE reads the same era-2 log with v2 type names",
28069
+ "explicitId": "openwop.requirement.0176.v1-events-translated.sse",
28070
+ "citations": [
28071
+ {
28072
+ "section": null,
28073
+ "requirement": null,
28074
+ "interpolated": true
28075
+ }
28076
+ ]
28077
+ },
28078
+ {
28079
+ "id": "openwop.it.v2-v1-events-translated.a-fork-of-the-era-2-run-reads-its-inherited-prefix-with-v2-type-names",
28080
+ "file": "v2-v1-events-translated.test.ts",
28081
+ "line": 84,
28082
+ "title": "a fork of the era-2 run reads its inherited prefix with v2 type names",
28083
+ "explicitId": "openwop.requirement.0176.v1-events-translated.fork",
28084
+ "citations": [
28085
+ {
28086
+ "section": "spec/v2/core/replay.md §Forking a v1 run",
28087
+ "requirement": null,
28088
+ "interpolated": true
28089
+ }
28090
+ ]
28091
+ },
28092
+ {
28093
+ "id": "openwop.it.v2-v1-signed-webhook-accepted.the-webhooks-facet-lists-scheme-v1-the-scheme-a-v1-signed-delivery-is-verified-u",
28094
+ "file": "v2-v1-signed-webhook-accepted.test.ts",
28095
+ "line": 79,
28096
+ "title": "the webhooks facet lists scheme \"v1\" — the scheme a v1-signed delivery is verified under",
28097
+ "explicitId": "openwop.requirement.0176.v1-signed-webhook-accepted.facet",
28098
+ "citations": [
28099
+ {
28100
+ "section": "spec/v2/core/webhooks.md §Surfaces",
28101
+ "requirement": "the webhooks facet is { signatureAlgorithms[] }"
28102
+ },
28103
+ {
28104
+ "section": "spec/v2/core/webhooks.md §Surfaces",
28105
+ "requirement": "signatureAlgorithms MUST list \"v1\" — the cut adds no signature scheme (RFC 0176 §D.2)"
28106
+ }
28107
+ ]
28108
+ },
28109
+ {
28110
+ "id": "openwop.it.v2-v1-signed-webhook-accepted.the-host-s-v2-receiver-path-accepts-an-x-openwop-only-scheme-v1-delivery-and-ref",
28111
+ "file": "v2-v1-signed-webhook-accepted.test.ts",
28112
+ "line": 89,
28113
+ "title": "the host's v2 receiver path accepts an X-openwop-*-only scheme-v1 delivery and refuses a tampered one",
28114
+ "explicitId": "openwop.requirement.0176.v1-signed-webhook-accepted",
28115
+ "citations": [
28116
+ {
28117
+ "section": null,
28118
+ "requirement": null,
28119
+ "interpolated": true
28120
+ },
28121
+ {
28122
+ "section": "spec/v2/core/webhooks.md §Verification",
28123
+ "requirement": "a receiver MUST verify before acting: the same delivery with a wrong X-openwop-Signature MUST be refused (a receiver that accepts everything is not verifying the v1 bytes)"
28124
+ }
28125
+ ]
28126
+ },
28127
+ {
28128
+ "id": "openwop.it.v2-version-header-honored.openwop-version-is-honored-or-refused-never-ignored",
28129
+ "file": "v2-version-header-honored.test.ts",
28130
+ "line": 61,
28131
+ "title": "OpenWOP-Version is honored or refused — never ignored",
28132
+ "explicitId": null,
28133
+ "citations": [
28134
+ {
28135
+ "section": null,
28136
+ "requirement": "a host that does not serve major 2 MUST refuse with 406 protocol_version_unsupported, which it did",
28137
+ "interpolated": true
28138
+ },
28139
+ {
28140
+ "section": null,
28141
+ "requirement": "answering 200 to OpenWOP-Version: 2.0 with a body byte-identical to the header-less fetch means the header was IGNORED, not honored — the host served v1 and called it v2. Refusing with 406 is the correct answer for a host that does not implement major 2; silently returning v1 is the one answer that no presence-gated scenario can detect, because an absent v2 shape records `inapplicable` whether the host refused or ignored",
28142
+ "interpolated": true
28143
+ }
28144
+ ]
28145
+ },
28146
+ {
28147
+ "id": "openwop.it.v2-version-header-honored.a-host-advertising-two-majors-serves-two-different-representations",
28148
+ "file": "v2-version-header-honored.test.ts",
28149
+ "line": 92,
28150
+ "title": "a host advertising two majors serves two different representations",
28151
+ "explicitId": null,
28152
+ "citations": [
28153
+ {
28154
+ "section": null,
28155
+ "requirement": null,
28156
+ "interpolated": true
28157
+ },
28158
+ {
28159
+ "section": null,
28160
+ "requirement": "the v1 document and the closed v2 root differ by construction (capabilities.md §1), so a host advertising both majors returning identical bytes for both has advertised a major it does not actually serve",
28161
+ "interpolated": true
28162
+ },
28163
+ {
28164
+ "section": null,
28165
+ "requirement": null,
28166
+ "interpolated": true
28167
+ }
28168
+ ]
28169
+ },
28170
+ {
28171
+ "id": "openwop.it.v2-webhook-durable-delivery.a-failed-attempt-is-retried-and-the-event-is-delivered-at-least-once",
28172
+ "file": "v2-webhook-durable-delivery.test.ts",
28173
+ "line": 145,
28174
+ "title": "a failed attempt is retried and the event is delivered at least once",
28175
+ "explicitId": "openwop.requirement.0173.webhook-durable-delivery",
28176
+ "citations": [
28177
+ {
28178
+ "section": "runs.md §Create",
28179
+ "requirement": "POST /runs MUST answer 201 for the noop fixture"
28180
+ },
28181
+ {
28182
+ "section": "webhooks.md §Durability",
28183
+ "requirement": "the host MUST attempt delivery of run.completed for THIS run to the registered subscriber"
28184
+ },
28185
+ {
28186
+ "section": "webhooks.md §Durability",
28187
+ "requirement": null,
28188
+ "interpolated": true
28189
+ },
28190
+ {
28191
+ "section": "webhooks.md §Durability",
28192
+ "requirement": "at-least-once: after the failing attempts the retry MUST land (the receiver answered 204 to the third attempt for the key)"
28193
+ },
28194
+ {
28195
+ "section": "webhooks.md §Durability",
28196
+ "requirement": null,
28197
+ "interpolated": true
28198
+ },
28199
+ {
28200
+ "section": "webhooks.md §Surfaces",
28201
+ "requirement": "DELETE /webhooks/{webhookId} MUST answer 204"
28202
+ }
28203
+ ]
28204
+ },
28205
+ {
28206
+ "id": "openwop.it.v2-webhook-durable-delivery.an-exhausted-delivery-is-dead-lettered-never-dropped",
28207
+ "file": "v2-webhook-durable-delivery.test.ts",
28208
+ "line": 199,
28209
+ "title": "an exhausted delivery is dead-lettered, never dropped",
28210
+ "explicitId": "openwop.requirement.0173.webhook-durable-delivery.dead-letter",
28211
+ "citations": [
28212
+ {
28213
+ "section": "runs.md §Create",
28214
+ "requirement": "POST /runs MUST answer 201 for the noop fixture"
28215
+ },
28216
+ {
28217
+ "section": "webhooks.md §Durability",
28218
+ "requirement": "a delivery that keeps failing MUST be retried before it can be exhausted (one attempt is a drop)"
28219
+ },
28220
+ {
28221
+ "section": "webhooks.md §Durability",
28222
+ "requirement": null,
28223
+ "interpolated": true
28224
+ }
28225
+ ]
28226
+ },
28227
+ {
28228
+ "id": "openwop.it.v2-well-known-one-resource.a-header-less-get-and-an-openwop-version-2-0-get-are-two-representations-of-one",
28229
+ "file": "v2-well-known-one-resource.test.ts",
28230
+ "line": 65,
28231
+ "title": "a header-less GET and an OpenWOP-Version: 2.0 GET are two representations of one path with equal protocolVersions[]",
28232
+ "explicitId": "openwop.requirement.0176.well-known-one-resource",
28233
+ "citations": [
28234
+ {
28235
+ "section": null,
28236
+ "requirement": null,
28237
+ "interpolated": true
28238
+ },
28239
+ {
28240
+ "section": null,
28241
+ "requirement": null,
28242
+ "interpolated": true
28243
+ },
28244
+ {
28245
+ "section": null,
28246
+ "requirement": "both representations MUST be JSON objects",
28247
+ "interpolated": true
28248
+ },
28249
+ {
28250
+ "section": null,
28251
+ "requirement": "the v1 representation MUST carry protocolVersions[] (RFC 0165 §A, additive) — a single fetch names the other major",
28252
+ "interpolated": true
28253
+ },
28254
+ {
28255
+ "section": null,
28256
+ "requirement": "the v2 representation MUST carry protocolVersions[]",
28257
+ "interpolated": true
28258
+ },
28259
+ {
28260
+ "section": null,
28261
+ "requirement": null,
28262
+ "interpolated": true
28263
+ },
28264
+ {
28265
+ "section": null,
28266
+ "requirement": "the header MUST select a representation — a host that serves one document for both majors is the charter's \"per-major sub-objects\" the RFC does not adopt (adversarial review 3)",
28267
+ "interpolated": true
28268
+ }
28269
+ ]
28270
+ },
28271
+ {
28272
+ "id": "openwop.it.v2-well-known-one-resource.the-v2-representation-carries-no-capabilities-wrapper-no-dotted-host-key-no-prof",
28273
+ "file": "v2-well-known-one-resource.test.ts",
28274
+ "line": 104,
28275
+ "title": "the v2 representation carries no `capabilities` wrapper, no dotted `host.*` key, no `profiles[]`, no Capabilities-Etag",
28276
+ "explicitId": "openwop.requirement.0176.well-known-one-resource.v2-representation",
28277
+ "citations": [
28278
+ {
28279
+ "section": "RFC 0176 §C.2",
28280
+ "requirement": "the `capabilities` wrapper (deprecation capabilities-wrapper, removalTrigger v2.0-cut) MUST be absent from the v2 representation"
28281
+ },
28282
+ {
28283
+ "section": "RFC 0176 §C.2",
28284
+ "requirement": "the dotted `host.*` mirror (deprecation host-dotted-mirror) MUST be absent from the v2 representation"
28285
+ },
28286
+ {
28287
+ "section": "spec/v2/core/capabilities.md §7",
28288
+ "requirement": "no `profiles[]` exists at the v2 root (RFC 0169 §C.1, row C2.10)"
28289
+ },
28290
+ {
28291
+ "section": "RFC 0176 §C.2",
28292
+ "requirement": "Capabilities-Etag (deprecation capabilities-etag-header) MUST be absent from the v2 representation — the standard ETag is the probe handle"
28293
+ }
28294
+ ]
28295
+ },
25744
28296
  {
25745
28297
  "id": "openwop.it.vector-knn-roundtrip.capabilities-vectorstore-is-either-absent-or-a-well-formed-object",
25746
28298
  "file": "vector-knn-roundtrip.test.ts",
@@ -31969,6 +34521,389 @@
31969
34521
  }
31970
34522
  ]
31971
34523
  },
34524
+ {
34525
+ "id": "openwop.it.v2-alias-covers-reword.the-corpus-gate-script-exits-0",
34526
+ "file": "v2-alias-covers-reword.test.ts",
34527
+ "line": 32,
34528
+ "title": "the corpus gate script exits 0",
34529
+ "explicitId": "openwop.requirement.0168.alias-covers-reword",
34530
+ "citations": [
34531
+ {
34532
+ "section": "RFC 0168 §A.1",
34533
+ "requirement": null,
34534
+ "interpolated": true
34535
+ }
34536
+ ]
34537
+ },
34538
+ {
34539
+ "id": "openwop.it.v2-bundle-signature-attributable.the-v2-discovery-root-publishes-signingkeys-the-surface-the-rfc-named",
34540
+ "file": "v2-bundle-signature-attributable.test.ts",
34541
+ "line": 85,
34542
+ "title": "the v2 discovery root publishes signingKeys[] — the surface the RFC named",
34543
+ "explicitId": null,
34544
+ "citations": [
34545
+ {
34546
+ "section": null,
34547
+ "requirement": "the v2 discovery root MUST carry signingKeys[] — RFC 0168 disposed of \"an Ed25519 attestation without a key registry is a signature nobody can check\" by naming this surface, so if it is absent the disposition names a place that does not exist and every bundle signature is unattributable",
34548
+ "interpolated": true
34549
+ },
34550
+ {
34551
+ "section": null,
34552
+ "requirement": null,
34553
+ "interpolated": true
34554
+ },
34555
+ {
34556
+ "section": null,
34557
+ "requirement": "a signingKeys[] entry MUST be closed; an open key record lets a host attach meaning the verifier does not read",
34558
+ "interpolated": true
34559
+ },
34560
+ {
34561
+ "section": null,
34562
+ "requirement": "a signingKeys[] entry MUST be able to record retirement, because a retired key has to stay listed — dropping it silently invalidates every bundle it already signed, which is the opposite of what an evidence trail is for",
34563
+ "interpolated": true
34564
+ }
34565
+ ]
34566
+ },
34567
+ {
34568
+ "id": "openwop.it.v2-bundle-signature-attributable.the-front-door-gate-verifies-the-attestation-instead-of-inspecting-the-string",
34569
+ "file": "v2-bundle-signature-attributable.test.ts",
34570
+ "line": 116,
34571
+ "title": "the Front-door gate verifies the attestation instead of inspecting the string",
34572
+ "explicitId": null,
34573
+ "citations": [
34574
+ {
34575
+ "section": null,
34576
+ "requirement": "the gate MUST NOT accept a bundle signature by presence: `typeof signature.sig === 'string'` is satisfied by any string, so it cannot distinguish a host key from a keypair minted seconds earlier by whoever wrote the bundle",
34577
+ "interpolated": true
34578
+ },
34579
+ {
34580
+ "section": null,
34581
+ "requirement": "the gate MUST resolve signature.keyId against the host's published signingKeys[] and verify the Ed25519 attestation under it — resolving without verifying, or verifying against a key the bundle supplied itself, both leave the signature unaccountable",
34582
+ "interpolated": true
34583
+ }
34584
+ ]
34585
+ },
34586
+ {
34587
+ "id": "openwop.it.v2-bundle-signature-attributable.the-four-signature-outcomes-stay-distinct-collapsing-any-two-restores-the-defect",
34588
+ "file": "v2-bundle-signature-attributable.test.ts",
34589
+ "line": 131,
34590
+ "title": "the four signature outcomes stay distinct — collapsing any two restores the defect",
34591
+ "explicitId": null,
34592
+ "citations": [
34593
+ {
34594
+ "section": null,
34595
+ "requirement": null,
34596
+ "interpolated": true
34597
+ }
34598
+ ]
34599
+ },
34600
+ {
34601
+ "id": "openwop.it.v2-corpus-tag-pinned.every-vendoring-consumer-in-the-cross-repo-inventory-records-a-published-corpus",
34602
+ "file": "v2-corpus-tag-pinned.test.ts",
34603
+ "line": 33,
34604
+ "title": "every vendoring consumer in the cross-repo inventory records a published corpus tag",
34605
+ "explicitId": null,
34606
+ "citations": [
34607
+ {
34608
+ "section": null,
34609
+ "requirement": null,
34610
+ "interpolated": true
34611
+ }
34612
+ ]
34613
+ },
34614
+ {
34615
+ "id": "openwop.it.v2-declaration-parity.the-corpus-gate-script-exits-0",
34616
+ "file": "v2-declaration-parity.test.ts",
34617
+ "line": 31,
34618
+ "title": "the corpus gate script exits 0",
34619
+ "explicitId": "openwop.requirement.0169.declaration-parity",
34620
+ "citations": [
34621
+ {
34622
+ "section": "RFC 0169 §B.2",
34623
+ "requirement": null,
34624
+ "interpolated": true
34625
+ }
34626
+ ]
34627
+ },
34628
+ {
34629
+ "id": "openwop.it.v2-error-registry-prose-parity.errors-md-states-the-registry-count-it-was-generated-from-and-renders-every-code",
34630
+ "file": "v2-error-registry-prose-parity.test.ts",
34631
+ "line": 26,
34632
+ "title": "errors.md states the registry count it was generated from and renders every code",
34633
+ "explicitId": null,
34634
+ "citations": [
34635
+ {
34636
+ "section": null,
34637
+ "requirement": null,
34638
+ "interpolated": true
34639
+ },
34640
+ {
34641
+ "section": null,
34642
+ "requirement": "errors.md states the registry size at least once, so the claim is checkable",
34643
+ "interpolated": true
34644
+ },
34645
+ {
34646
+ "section": null,
34647
+ "requirement": null,
34648
+ "interpolated": true
34649
+ }
34650
+ ]
34651
+ },
34652
+ {
34653
+ "id": "openwop.it.v2-event-naming-rule.every-closed-enum-v2-event-type-is-two-kebab-segments-and-every-recorded-artifac",
34654
+ "file": "v2-event-naming-rule.test.ts",
34655
+ "line": 36,
34656
+ "title": "every closed-enum v2 event type is two kebab segments, and every recorded artifact exception is an enum member",
34657
+ "explicitId": null,
34658
+ "citations": [
34659
+ {
34660
+ "section": null,
34661
+ "requirement": "run-event.schema.json properties.type.oneOf[0] MUST be the closed enum of v2 event types",
34662
+ "interpolated": true
34663
+ },
34664
+ {
34665
+ "section": null,
34666
+ "requirement": null,
34667
+ "interpolated": true
34668
+ },
34669
+ {
34670
+ "section": null,
34671
+ "requirement": null,
34672
+ "interpolated": true
34673
+ }
34674
+ ]
34675
+ },
34676
+ {
34677
+ "id": "openwop.it.v2-event-naming-rule.the-closed-enum-and-the-vendor-branch-are-disjoint-every-registered-type-validat",
34678
+ "file": "v2-event-naming-rule.test.ts",
34679
+ "line": 51,
34680
+ "title": "the closed enum and the vendor branch are disjoint: every registered type validates, and a typo of a registered domain does not",
34681
+ "explicitId": null,
34682
+ "citations": [
34683
+ {
34684
+ "section": "RFC 0171 §A.1",
34685
+ "requirement": null,
34686
+ "interpolated": true
34687
+ },
34688
+ {
34689
+ "section": "RFC 0171 §A.1",
34690
+ "requirement": null,
34691
+ "interpolated": true
34692
+ },
34693
+ {
34694
+ "section": "RFC 0171 §A.1",
34695
+ "requirement": "a genuine vendor type under an unregistered org MUST still validate"
34696
+ },
34697
+ {
34698
+ "section": "RFC 0171 §A.1",
34699
+ "requirement": "`openwop.` is reserved and MUST NOT match the vendor branch"
34700
+ }
34701
+ ]
34702
+ },
34703
+ {
34704
+ "id": "openwop.it.v2-events-channel-parity.the-corpus-gate-script-exits-0",
34705
+ "file": "v2-events-channel-parity.test.ts",
34706
+ "line": 31,
34707
+ "title": "the corpus gate script exits 0",
34708
+ "explicitId": "openwop.requirement.0171.events-channel-parity",
34709
+ "citations": [
34710
+ {
34711
+ "section": "RFC 0171 §E.1",
34712
+ "requirement": null,
34713
+ "interpolated": true
34714
+ }
34715
+ ]
34716
+ },
34717
+ {
34718
+ "id": "openwop.it.v2-externally-gated-never-stable.the-corpus-gate-script-exits-0",
34719
+ "file": "v2-externally-gated-never-stable.test.ts",
34720
+ "line": 31,
34721
+ "title": "the corpus gate script exits 0",
34722
+ "explicitId": "openwop.requirement.0169.externally-gated-never-stable",
34723
+ "citations": [
34724
+ {
34725
+ "section": "RFC 0169 §C.4",
34726
+ "requirement": null,
34727
+ "interpolated": true
34728
+ }
34729
+ ]
34730
+ },
34731
+ {
34732
+ "id": "openwop.it.v2-one-signing-scheme.registry-version-manifest-signing-has-exactly-one-scheme-ed25519-canonical-json",
34733
+ "file": "v2-one-signing-scheme.test.ts",
34734
+ "line": 37,
34735
+ "title": "registry-version-manifest signing has exactly one scheme, ed25519-canonical-json, and no method / publicKeyRef",
34736
+ "explicitId": null,
34737
+ "citations": [
34738
+ {
34739
+ "section": null,
34740
+ "requirement": "registry-version-manifest.schema.json MUST define a `signing` object",
34741
+ "interpolated": true
34742
+ },
34743
+ {
34744
+ "section": null,
34745
+ "requirement": "signing.scheme MUST be the single const `ed25519-canonical-json` — one scheme, not a menu",
34746
+ "interpolated": true
34747
+ },
34748
+ {
34749
+ "section": null,
34750
+ "requirement": "signing MUST require `keyId` and `scheme`",
34751
+ "interpolated": true
34752
+ },
34753
+ {
34754
+ "section": null,
34755
+ "requirement": "signing MUST be closed (additionalProperties: false) so a second scheme cannot be smuggled in",
34756
+ "interpolated": true
34757
+ },
34758
+ {
34759
+ "section": null,
34760
+ "requirement": "signing.method is gone in v2 — it MUST NOT appear in the signing object",
34761
+ "interpolated": true
34762
+ },
34763
+ {
34764
+ "section": null,
34765
+ "requirement": "signing.publicKeyRef is gone in v2 — the key is addressed by keyId alone",
34766
+ "interpolated": true
34767
+ }
34768
+ ]
34769
+ },
34770
+ {
34771
+ "id": "openwop.it.v2-path-parity.the-corpus-gate-script-exits-0",
34772
+ "file": "v2-path-parity.test.ts",
34773
+ "line": 31,
34774
+ "title": "the corpus gate script exits 0",
34775
+ "explicitId": "openwop.requirement.0172.path-parity",
34776
+ "citations": [
34777
+ {
34778
+ "section": "RFC 0172 §C.2",
34779
+ "requirement": null,
34780
+ "interpolated": true
34781
+ }
34782
+ ]
34783
+ },
34784
+ {
34785
+ "id": "openwop.it.v2-release-identity.the-corpus-gate-script-exits-0",
34786
+ "file": "v2-release-identity.test.ts",
34787
+ "line": 32,
34788
+ "title": "the corpus gate script exits 0",
34789
+ "explicitId": "openwop.requirement.0172.release-identity",
34790
+ "citations": [
34791
+ {
34792
+ "section": "RFC 0172 §D.1",
34793
+ "requirement": null,
34794
+ "interpolated": true
34795
+ },
34796
+ {
34797
+ "section": "RFC 0172 §D.1",
34798
+ "requirement": null,
34799
+ "interpolated": true
34800
+ }
34801
+ ]
34802
+ },
34803
+ {
34804
+ "id": "openwop.it.v2-req-only-assertions.the-corpus-gate-script-exits-0",
34805
+ "file": "v2-req-only-assertions.test.ts",
34806
+ "line": 31,
34807
+ "title": "the corpus gate script exits 0",
34808
+ "explicitId": "openwop.requirement.0168.req-only-assertions",
34809
+ "citations": [
34810
+ {
34811
+ "section": "RFC 0168 §A.1",
34812
+ "requirement": null,
34813
+ "interpolated": true
34814
+ }
34815
+ ]
34816
+ },
34817
+ {
34818
+ "id": "openwop.it.v2-seams-not-in-canonical.the-corpus-gate-script-exits-0",
34819
+ "file": "v2-seams-not-in-canonical.test.ts",
34820
+ "line": 31,
34821
+ "title": "the corpus gate script exits 0",
34822
+ "explicitId": "openwop.requirement.0168.seams-not-in-canonical",
34823
+ "citations": [
34824
+ {
34825
+ "section": "RFC 0168 §C.2",
34826
+ "requirement": null,
34827
+ "interpolated": true
34828
+ }
34829
+ ]
34830
+ },
34831
+ {
34832
+ "id": "openwop.it.v2-security-defaults-table.the-obligation-table-has-a-witness-column-and-no-row-is-unwitnessable",
34833
+ "file": "v2-security-defaults-table.test.ts",
34834
+ "line": 33,
34835
+ "title": "the obligation table has a Witness column and no row is unwitnessable",
34836
+ "explicitId": null,
34837
+ "citations": [
34838
+ {
34839
+ "section": null,
34840
+ "requirement": "spec/v2/core/security-defaults.md MUST exist — it is the obligation table RFC 0173 §A.1 names",
34841
+ "interpolated": true
34842
+ },
34843
+ {
34844
+ "section": null,
34845
+ "requirement": "the obligation table MUST have a `Witness` column (surface · obligation · witness · invariant)",
34846
+ "interpolated": true
34847
+ },
34848
+ {
34849
+ "section": null,
34850
+ "requirement": "the obligation table MUST list at least one obligation row",
34851
+ "interpolated": true
34852
+ },
34853
+ {
34854
+ "section": null,
34855
+ "requirement": null,
34856
+ "interpolated": true
34857
+ },
34858
+ {
34859
+ "section": null,
34860
+ "requirement": null,
34861
+ "interpolated": true
34862
+ }
34863
+ ]
34864
+ },
34865
+ {
34866
+ "id": "openwop.it.v2-spec-artifacts-digest.the-corpus-gate-script-exits-0",
34867
+ "file": "v2-spec-artifacts-digest.test.ts",
34868
+ "line": 31,
34869
+ "title": "the corpus gate script exits 0",
34870
+ "explicitId": "openwop.requirement.0168.spec-artifacts-digest",
34871
+ "citations": [
34872
+ {
34873
+ "section": "RFC 0168 §D.2",
34874
+ "requirement": null,
34875
+ "interpolated": true
34876
+ }
34877
+ ]
34878
+ },
34879
+ {
34880
+ "id": "openwop.it.v2-threat-model-template.the-corpus-gate-script-exits-0",
34881
+ "file": "v2-threat-model-template.test.ts",
34882
+ "line": 32,
34883
+ "title": "the corpus gate script exits 0",
34884
+ "explicitId": "openwop.requirement.0173.threat-model-template",
34885
+ "citations": [
34886
+ {
34887
+ "section": "RFC 0173 §E.2 / RFC 0175 §F.1",
34888
+ "requirement": null,
34889
+ "interpolated": true
34890
+ }
34891
+ ]
34892
+ },
34893
+ {
34894
+ "id": "openwop.it.v2-witness-required.the-corpus-gate-script-exits-0",
34895
+ "file": "v2-witness-required.test.ts",
34896
+ "line": 31,
34897
+ "title": "the corpus gate script exits 0",
34898
+ "explicitId": "openwop.requirement.0168.witness-required",
34899
+ "citations": [
34900
+ {
34901
+ "section": "RFC 0168 §B.1",
34902
+ "requirement": null,
34903
+ "interpolated": true
34904
+ }
34905
+ ]
34906
+ },
31972
34907
  {
31973
34908
  "id": "openwop.it.versioned-composition-profiles.a-versioned-advertisement-validates",
31974
34909
  "file": "versioned-composition-profiles.test.ts",