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

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