@whooshbang/contracts 1.0.0-rc.13

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 (229) hide show
  1. package/CHANGELOG.md +198 -0
  2. package/LICENSE +21 -0
  3. package/README.md +120 -0
  4. package/contract-manifest.json +390 -0
  5. package/dist/base64url.d.ts +2 -0
  6. package/dist/base64url.js +51 -0
  7. package/dist/base64url.js.map +1 -0
  8. package/dist/generated/artifact-index.d.ts +205 -0
  9. package/dist/generated/artifact-index.js +396 -0
  10. package/dist/generated/artifact-index.js.map +1 -0
  11. package/dist/generated/contract-manifest.d.ts +66 -0
  12. package/dist/generated/contract-manifest.js +6 -0
  13. package/dist/generated/contract-manifest.js.map +1 -0
  14. package/dist/generated/core-scenario.d.ts +18 -0
  15. package/dist/generated/core-scenario.js +6 -0
  16. package/dist/generated/core-scenario.js.map +1 -0
  17. package/dist/generated/fixture-index.d.ts +33 -0
  18. package/dist/generated/fixture-index.js +6 -0
  19. package/dist/generated/fixture-index.js.map +1 -0
  20. package/dist/generated/interaction-machine-scenario.d.ts +263 -0
  21. package/dist/generated/interaction-machine-scenario.js +6 -0
  22. package/dist/generated/interaction-machine-scenario.js.map +1 -0
  23. package/dist/generated/interaction-v1.d.ts +152 -0
  24. package/dist/generated/interaction-v1.js +6 -0
  25. package/dist/generated/interaction-v1.js.map +1 -0
  26. package/dist/generated/machine-v1.d.ts +169 -0
  27. package/dist/generated/machine-v1.js +6 -0
  28. package/dist/generated/machine-v1.js.map +1 -0
  29. package/dist/generated/provider-capabilities-v1.d.ts +78 -0
  30. package/dist/generated/provider-capabilities-v1.js +6 -0
  31. package/dist/generated/provider-capabilities-v1.js.map +1 -0
  32. package/dist/generated/validators-standalone.d.ts +659 -0
  33. package/dist/generated/validators-standalone.js +47800 -0
  34. package/dist/generated/validators-standalone.js.map +1 -0
  35. package/dist/generated/validators.d.ts +74 -0
  36. package/dist/generated/validators.js +493 -0
  37. package/dist/generated/validators.js.map +1 -0
  38. package/dist/generated/webhook-delivery-case-v1.d.ts +91 -0
  39. package/dist/generated/webhook-delivery-case-v1.js +6 -0
  40. package/dist/generated/webhook-delivery-case-v1.js.map +1 -0
  41. package/dist/generated/webhook-signing-vector-v1.d.ts +88 -0
  42. package/dist/generated/webhook-signing-vector-v1.js +6 -0
  43. package/dist/generated/webhook-signing-vector-v1.js.map +1 -0
  44. package/dist/generated/whooshbang-event-v1.d.ts +191 -0
  45. package/dist/generated/whooshbang-event-v1.js +6 -0
  46. package/dist/generated/whooshbang-event-v1.js.map +1 -0
  47. package/dist/generated/whooshbang-v1.d.ts +1162 -0
  48. package/dist/generated/whooshbang-v1.js +6 -0
  49. package/dist/generated/whooshbang-v1.js.map +1 -0
  50. package/dist/index.d.ts +20 -0
  51. package/dist/index.js +7 -0
  52. package/dist/index.js.map +1 -0
  53. package/dist/machine-credential.d.ts +31 -0
  54. package/dist/machine-credential.js +78 -0
  55. package/dist/machine-credential.js.map +1 -0
  56. package/dist/webhook-consumer.d.ts +50 -0
  57. package/dist/webhook-consumer.js +71 -0
  58. package/dist/webhook-consumer.js.map +1 -0
  59. package/dist/webhook-delivery.d.ts +46 -0
  60. package/dist/webhook-delivery.js +126 -0
  61. package/dist/webhook-delivery.js.map +1 -0
  62. package/dist/webhook-signature.d.ts +36 -0
  63. package/dist/webhook-signature.js +255 -0
  64. package/dist/webhook-signature.js.map +1 -0
  65. package/examples/python/verify_webhook.py +283 -0
  66. package/fixtures/.gitkeep +1 -0
  67. package/fixtures/core-v1/fixture-index.json +963 -0
  68. package/fixtures/core-v1/problems/auth-invalid.json +9 -0
  69. package/fixtures/core-v1/problems/authentication-required.json +9 -0
  70. package/fixtures/core-v1/problems/cancellation-too-late.json +9 -0
  71. package/fixtures/core-v1/problems/endpoint-rotation-conflict.json +10 -0
  72. package/fixtures/core-v1/problems/environment-mismatch.json +9 -0
  73. package/fixtures/core-v1/problems/idempotency-conflict.json +9 -0
  74. package/fixtures/core-v1/problems/idempotency-key-required.json +9 -0
  75. package/fixtures/core-v1/problems/project-slug-conflict.json +16 -0
  76. package/fixtures/core-v1/problems/provider-outcome-unknown.json +9 -0
  77. package/fixtures/core-v1/problems/provider-retryable.json +10 -0
  78. package/fixtures/core-v1/problems/provider-terminal.json +9 -0
  79. package/fixtures/core-v1/problems/rate-limited.json +10 -0
  80. package/fixtures/core-v1/problems/replay-unavailable-not-terminal.json +16 -0
  81. package/fixtures/core-v1/problems/replay-unavailable-payload.json +16 -0
  82. package/fixtures/core-v1/problems/replay-unavailable-rollout.json +16 -0
  83. package/fixtures/core-v1/problems/request-invalid.json +16 -0
  84. package/fixtures/core-v1/problems/resource-expired.json +9 -0
  85. package/fixtures/core-v1/problems/resource-not-found.json +9 -0
  86. package/fixtures/core-v1/problems/scope-forbidden.json +9 -0
  87. package/fixtures/core-v1/problems/subscriber-unbound.json +9 -0
  88. package/fixtures/core-v1/requests/create-api-credential.json +9 -0
  89. package/fixtures/core-v1/requests/create-customer-endpoint.json +5 -0
  90. package/fixtures/core-v1/requests/create-message.json +15 -0
  91. package/fixtures/core-v1/requests/create-project.json +4 -0
  92. package/fixtures/core-v1/requests/create-subscription-link.json +5 -0
  93. package/fixtures/core-v1/requests/rotate-api-credential.json +3 -0
  94. package/fixtures/core-v1/requests/rotate-customer-endpoint.json +3 -0
  95. package/fixtures/core-v1/scenarios/api-credential-invalid-indistinguishable.json +14 -0
  96. package/fixtures/core-v1/scenarios/api-credential-one-time-reveal.json +21 -0
  97. package/fixtures/core-v1/scenarios/api-credential-revocation-replay.json +17 -0
  98. package/fixtures/core-v1/scenarios/api-credential-rotation-overlap.json +18 -0
  99. package/fixtures/core-v1/scenarios/cancellation-too-late.json +15 -0
  100. package/fixtures/core-v1/scenarios/cross-account-project.json +14 -0
  101. package/fixtures/core-v1/scenarios/cross-project-resource.json +17 -0
  102. package/fixtures/core-v1/scenarios/environment-mismatch.json +17 -0
  103. package/fixtures/core-v1/scenarios/idempotency-conflict.json +35 -0
  104. package/fixtures/core-v1/scenarios/idempotency-equivalent-replay.json +27 -0
  105. package/fixtures/core-v1/scenarios/malformed-bearer.json +14 -0
  106. package/fixtures/core-v1/scenarios/metadata-overrun.json +14 -0
  107. package/fixtures/core-v1/scenarios/missing-scope.json +15 -0
  108. package/fixtures/core-v1/scenarios/project-create-equivalent-replay.json +26 -0
  109. package/fixtures/core-v1/scenarios/project-slug-conflict.json +21 -0
  110. package/fixtures/core-v1/scenarios/provider-outcome-unknown.json +15 -0
  111. package/fixtures/core-v1/scenarios/subscription-activation-replay.json +18 -0
  112. package/fixtures/core-v1/scenarios/subscription-expired-replay.json +16 -0
  113. package/fixtures/core-v1/success/account-projection.json +11 -0
  114. package/fixtures/core-v1/success/api-credential-collection.json +22 -0
  115. package/fixtures/core-v1/success/api-credential-created.json +20 -0
  116. package/fixtures/core-v1/success/api-credential-revoked.json +19 -0
  117. package/fixtures/core-v1/success/api-credential-rotated.json +41 -0
  118. package/fixtures/core-v1/success/customer-endpoint-attempts.json +15 -0
  119. package/fixtures/core-v1/success/customer-endpoint-collection.json +26 -0
  120. package/fixtures/core-v1/success/customer-endpoint-create-replayed.json +16 -0
  121. package/fixtures/core-v1/success/customer-endpoint-created.json +17 -0
  122. package/fixtures/core-v1/success/customer-endpoint-rotated.json +21 -0
  123. package/fixtures/core-v1/success/message-accepted.json +30 -0
  124. package/fixtures/core-v1/success/message-cancellation-too-late.json +27 -0
  125. package/fixtures/core-v1/success/message-cancelled.json +27 -0
  126. package/fixtures/core-v1/success/message-outcome-unknown.json +33 -0
  127. package/fixtures/core-v1/success/message-provider-accepted.json +30 -0
  128. package/fixtures/core-v1/success/project-collection.json +42 -0
  129. package/fixtures/core-v1/success/project-created.json +38 -0
  130. package/fixtures/core-v1/success/subscription-link-activated.json +22 -0
  131. package/fixtures/core-v1/success/subscription-link-cancelled.json +14 -0
  132. package/fixtures/core-v1/success/subscription-link-paused.json +22 -0
  133. package/fixtures/core-v1/success/subscription-link-pending.json +14 -0
  134. package/fixtures/core-v1/success/subscription-link-revoked.json +22 -0
  135. package/fixtures/interaction-machine-v1/capabilities/providers.json +57 -0
  136. package/fixtures/interaction-machine-v1/capabilities/telegram.json +52 -0
  137. package/fixtures/interaction-machine-v1/events/confirm-answered.json +22 -0
  138. package/fixtures/interaction-machine-v1/events/input-answered.json +22 -0
  139. package/fixtures/interaction-machine-v1/events/input-redacted.json +18 -0
  140. package/fixtures/interaction-machine-v1/events/select-answered.json +22 -0
  141. package/fixtures/interaction-machine-v1/requests/ack-processed.json +5 -0
  142. package/fixtures/interaction-machine-v1/requests/ack-quarantined.json +5 -0
  143. package/fixtures/interaction-machine-v1/requests/create-machine-client.json +6 -0
  144. package/fixtures/interaction-machine-v1/requests/create-message-confirm.json +18 -0
  145. package/fixtures/interaction-machine-v1/requests/create-message-input.json +16 -0
  146. package/fixtures/interaction-machine-v1/requests/create-message-select.json +26 -0
  147. package/fixtures/interaction-machine-v1/requests/register-machine-credential.json +4 -0
  148. package/fixtures/interaction-machine-v1/scenarios/ack-conflict.json +14 -0
  149. package/fixtures/interaction-machine-v1/scenarios/ack-cross-machine.json +15 -0
  150. package/fixtures/interaction-machine-v1/scenarios/ack-out-of-order.json +15 -0
  151. package/fixtures/interaction-machine-v1/scenarios/ack-replay.json +17 -0
  152. package/fixtures/interaction-machine-v1/scenarios/ambiguous-free-text.json +15 -0
  153. package/fixtures/interaction-machine-v1/scenarios/callback-token-opacity.json +16 -0
  154. package/fixtures/interaction-machine-v1/scenarios/credential-registration-conflict.json +16 -0
  155. package/fixtures/interaction-machine-v1/scenarios/credential-registration-replay.json +15 -0
  156. package/fixtures/interaction-machine-v1/scenarios/credential-revocation-replay.json +14 -0
  157. package/fixtures/interaction-machine-v1/scenarios/credential-rotation.json +16 -0
  158. package/fixtures/interaction-machine-v1/scenarios/first-credential-activates.json +15 -0
  159. package/fixtures/interaction-machine-v1/scenarios/interaction-duplicate.json +16 -0
  160. package/fixtures/interaction-machine-v1/scenarios/interaction-expired.json +17 -0
  161. package/fixtures/interaction-machine-v1/scenarios/interaction-mismatch.json +16 -0
  162. package/fixtures/interaction-machine-v1/scenarios/interaction-retired.json +16 -0
  163. package/fixtures/interaction-machine-v1/scenarios/interaction-stale.json +16 -0
  164. package/fixtures/interaction-machine-v1/scenarios/machine-admin-denied.json +14 -0
  165. package/fixtures/interaction-machine-v1/scenarios/machine-bound-message-create.json +22 -0
  166. package/fixtures/interaction-machine-v1/scenarios/machine-cancel-denied.json +14 -0
  167. package/fixtures/interaction-machine-v1/scenarios/machine-crash-before-ack.json +16 -0
  168. package/fixtures/interaction-machine-v1/scenarios/machine-notifier-mismatch.json +14 -0
  169. package/fixtures/interaction-machine-v1/scenarios/machine-other-message-read.json +14 -0
  170. package/fixtures/interaction-machine-v1/scenarios/machine-owned-message-read.json +22 -0
  171. package/fixtures/interaction-machine-v1/scenarios/machine-subscriber-mismatch.json +14 -0
  172. package/fixtures/interaction-machine-v1/scenarios/poll-uncommitted-cursor-rejected.json +17 -0
  173. package/fixtures/interaction-machine-v1/scenarios/project-credential-machine-endpoint-denied.json +14 -0
  174. package/fixtures/interaction-machine-v1/scenarios/quarantine-integrity-rejected.json +15 -0
  175. package/fixtures/interaction-machine-v1/scenarios/quarantine-signature-rejected.json +16 -0
  176. package/fixtures/interaction-machine-v1/scenarios/quarantine-valid.json +15 -0
  177. package/fixtures/interaction-machine-v1/scenarios/revoked-machine-credential.json +15 -0
  178. package/fixtures/interaction-machine-v1/success/ack-out-of-order.json +8 -0
  179. package/fixtures/interaction-machine-v1/success/ack-processed.json +8 -0
  180. package/fixtures/interaction-machine-v1/success/ack-quarantined.json +9 -0
  181. package/fixtures/interaction-machine-v1/success/interaction-answered-confirm.json +10 -0
  182. package/fixtures/interaction-machine-v1/success/interaction-answered-input.json +10 -0
  183. package/fixtures/interaction-machine-v1/success/interaction-answered-redacted.json +8 -0
  184. package/fixtures/interaction-machine-v1/success/interaction-answered-select.json +10 -0
  185. package/fixtures/interaction-machine-v1/success/interaction-open.json +7 -0
  186. package/fixtures/interaction-machine-v1/success/machine-client-active.json +20 -0
  187. package/fixtures/interaction-machine-v1/success/machine-client-provisioning.json +19 -0
  188. package/fixtures/interaction-machine-v1/success/machine-client-revoked.json +21 -0
  189. package/fixtures/interaction-machine-v1/success/machine-credential-active.json +13 -0
  190. package/fixtures/interaction-machine-v1/success/machine-credential-revoked.json +14 -0
  191. package/fixtures/interaction-machine-v1/success/message-interaction-open.json +33 -0
  192. package/fixtures/interaction-machine-v1/success/poll-empty.json +6 -0
  193. package/fixtures/interaction-machine-v1/success/poll-events.json +51 -0
  194. package/fixtures/interaction-machine-v1/tokens/callback-token.json +1 -0
  195. package/fixtures/whooshbang-events-v1/delivery/cases.json +418 -0
  196. package/fixtures/whooshbang-events-v1/events/agent-binding-degraded.json +17 -0
  197. package/fixtures/whooshbang-events-v1/events/interaction-expired.json +16 -0
  198. package/fixtures/whooshbang-events-v1/events/interaction-received.json +23 -0
  199. package/fixtures/whooshbang-events-v1/events/message-delivered.json +16 -0
  200. package/fixtures/whooshbang-events-v1/events/message-expired.json +15 -0
  201. package/fixtures/whooshbang-events-v1/events/message-failed.json +17 -0
  202. package/fixtures/whooshbang-events-v1/events/message-provider-accepted.json +15 -0
  203. package/fixtures/whooshbang-events-v1/events/subscription-activated.json +18 -0
  204. package/fixtures/whooshbang-events-v1/events/subscription-revoked.json +18 -0
  205. package/fixtures/whooshbang-events-v1/signing/vectors.json +852 -0
  206. package/openapi/.gitkeep +1 -0
  207. package/openapi/generated/whooshbang-v1.bundle.json +5913 -0
  208. package/openapi/whooshbang-v1.yaml +2334 -0
  209. package/package.json +63 -0
  210. package/schemas/contract-manifest.schema.json +140 -0
  211. package/schemas/core-scenario.schema.json +38 -0
  212. package/schemas/events/agent-binding-degraded-v1.schema.json +8 -0
  213. package/schemas/events/interaction-expired-v1.schema.json +8 -0
  214. package/schemas/events/interaction-received-v1.schema.json +8 -0
  215. package/schemas/events/message-delivered-v1.schema.json +8 -0
  216. package/schemas/events/message-expired-v1.schema.json +8 -0
  217. package/schemas/events/message-failed-v1.schema.json +8 -0
  218. package/schemas/events/message-provider-accepted-v1.schema.json +8 -0
  219. package/schemas/events/subscription-activated-v1.schema.json +8 -0
  220. package/schemas/events/subscription-revoked-v1.schema.json +8 -0
  221. package/schemas/events/whooshbang-event-v1.schema.json +689 -0
  222. package/schemas/fixture-index.schema.json +67 -0
  223. package/schemas/interaction-machine-scenario.schema.json +700 -0
  224. package/schemas/interaction-v1.schema.json +483 -0
  225. package/schemas/machine-v1.schema.json +430 -0
  226. package/schemas/provider-capabilities-v1.schema.json +263 -0
  227. package/schemas/webhooks/webhook-delivery-case-v1.schema.json +167 -0
  228. package/schemas/webhooks/webhook-signing-vector-v1.schema.json +197 -0
  229. package/schemas/whooshbang-v1.schema.json +2173 -0
@@ -0,0 +1,430 @@
1
+ {
2
+ "$schema": "https://json-schema.org/draft/2020-12/schema",
3
+ "$id": "https://whooshbang.flowxo.com/schemas/machine-v1.schema.json",
4
+ "x-contract-version": "1.0.0-rc.13",
5
+ "title": "MachineV1ContractDocument",
6
+ "description": "Machine-client administration, locally generated credential metadata, durable long-poll, and contiguous acknowledgement contracts.",
7
+ "oneOf": [
8
+ {
9
+ "$ref": "#/$defs/CreateMachineClientRequest"
10
+ },
11
+ {
12
+ "$ref": "#/$defs/MachineClient"
13
+ },
14
+ {
15
+ "$ref": "#/$defs/RegisterMachineCredentialRequest"
16
+ },
17
+ {
18
+ "$ref": "#/$defs/MachineCredential"
19
+ },
20
+ {
21
+ "$ref": "#/$defs/MachineEventPollResponse"
22
+ },
23
+ {
24
+ "$ref": "#/$defs/MachineEventAckRequest"
25
+ },
26
+ {
27
+ "$ref": "#/$defs/MachineEventAckResponse"
28
+ },
29
+ {
30
+ "$ref": "#/$defs/MachineCredentialBearer"
31
+ }
32
+ ],
33
+ "$defs": {
34
+ "OpaqueIdentifier": {
35
+ "type": "string",
36
+ "minLength": 1,
37
+ "maxLength": 128,
38
+ "pattern": "^[^\\u0000-\\u001F\\u007F]+$"
39
+ },
40
+ "Timestamp": {
41
+ "type": "string",
42
+ "format": "date-time",
43
+ "pattern": "^[0-9]{4}-(?:0[1-9]|1[0-2])-(?:0[1-9]|[12][0-9]|3[01])T(?:[01][0-9]|2[0-3]):[0-5][0-9]:[0-5][0-9](?:\\.[0-9]+)?(?:Z|[+-](?:[01][0-9]|2[0-3]):[0-5][0-9])$"
44
+ },
45
+ "Environment": {
46
+ "type": "string",
47
+ "enum": ["test", "live"]
48
+ },
49
+ "MachineCredentialId": {
50
+ "type": "string",
51
+ "pattern": "^mcred_[A-Za-z0-9_-]{21}[AQgw]$",
52
+ "description": "mcred_ followed by the canonical unpadded base64url encoding of exactly 16 random bytes."
53
+ },
54
+ "MachineSecretDigest": {
55
+ "type": "string",
56
+ "pattern": "^sha256:[a-f0-9]{64}$",
57
+ "description": "The only secret-derived value accepted by the administration API."
58
+ },
59
+ "MachineCredentialBearer": {
60
+ "type": "string",
61
+ "pattern": "^wb_mc1\\.mcred_[A-Za-z0-9_-]{21}[AQgw]\\.[A-Za-z0-9_-]{42}[AEIMQUYcgkosw048]$",
62
+ "description": "The exact runtime bearer syntax. The final segment is canonical unpadded base64url for exactly 32 locally generated random bytes."
63
+ },
64
+ "MachineScope": {
65
+ "type": "string",
66
+ "enum": [
67
+ "machine-messages:write",
68
+ "machine-messages:read",
69
+ "machine-events:read",
70
+ "machine-events:ack"
71
+ ]
72
+ },
73
+ "MachineScopeSummary": {
74
+ "type": "array",
75
+ "items": {
76
+ "$ref": "#/$defs/MachineScope"
77
+ },
78
+ "minItems": 4,
79
+ "maxItems": 4,
80
+ "uniqueItems": true,
81
+ "description": "Fixed least-privilege capabilities, each constrained to this client's bound destination or stream."
82
+ },
83
+ "CreateMachineClientRequest": {
84
+ "type": "object",
85
+ "required": ["machine_id", "notifier_id", "subscriber_id"],
86
+ "properties": {
87
+ "machine_id": {
88
+ "type": "string",
89
+ "minLength": 8,
90
+ "maxLength": 128,
91
+ "pattern": "^[^\\u0000-\\u001F\\u007F]+$"
92
+ },
93
+ "notifier_id": {
94
+ "$ref": "#/$defs/OpaqueIdentifier"
95
+ },
96
+ "subscriber_id": {
97
+ "$ref": "#/$defs/OpaqueIdentifier"
98
+ },
99
+ "display_name": {
100
+ "type": "string",
101
+ "minLength": 1,
102
+ "maxLength": 120
103
+ }
104
+ },
105
+ "additionalProperties": false
106
+ },
107
+ "MachineClient": {
108
+ "type": "object",
109
+ "required": [
110
+ "id",
111
+ "project_id",
112
+ "environment",
113
+ "machine_id",
114
+ "notifier_id",
115
+ "subscriber_id",
116
+ "binding_id",
117
+ "status",
118
+ "scope_summary",
119
+ "created_at",
120
+ "updated_at"
121
+ ],
122
+ "properties": {
123
+ "id": {
124
+ "$ref": "#/$defs/OpaqueIdentifier"
125
+ },
126
+ "project_id": {
127
+ "$ref": "#/$defs/OpaqueIdentifier"
128
+ },
129
+ "environment": {
130
+ "$ref": "#/$defs/Environment"
131
+ },
132
+ "machine_id": {
133
+ "$ref": "#/$defs/OpaqueIdentifier"
134
+ },
135
+ "notifier_id": {
136
+ "$ref": "#/$defs/OpaqueIdentifier"
137
+ },
138
+ "subscriber_id": {
139
+ "$ref": "#/$defs/OpaqueIdentifier"
140
+ },
141
+ "binding_id": {
142
+ "$ref": "#/$defs/OpaqueIdentifier"
143
+ },
144
+ "display_name": {
145
+ "type": "string",
146
+ "minLength": 1,
147
+ "maxLength": 120
148
+ },
149
+ "status": {
150
+ "type": "string",
151
+ "enum": ["provisioning", "active", "revoked"]
152
+ },
153
+ "scope_summary": {
154
+ "$ref": "#/$defs/MachineScopeSummary"
155
+ },
156
+ "created_at": {
157
+ "$ref": "#/$defs/Timestamp"
158
+ },
159
+ "updated_at": {
160
+ "$ref": "#/$defs/Timestamp"
161
+ },
162
+ "last_used_at": {
163
+ "$ref": "#/$defs/Timestamp"
164
+ },
165
+ "revoked_at": {
166
+ "$ref": "#/$defs/Timestamp"
167
+ }
168
+ },
169
+ "allOf": [
170
+ {
171
+ "if": {
172
+ "properties": {
173
+ "status": {
174
+ "const": "revoked"
175
+ }
176
+ },
177
+ "required": ["status"]
178
+ },
179
+ "then": {
180
+ "required": ["revoked_at"],
181
+ "properties": {
182
+ "revoked_at": {}
183
+ }
184
+ },
185
+ "else": {
186
+ "properties": {
187
+ "revoked_at": false
188
+ }
189
+ }
190
+ }
191
+ ],
192
+ "additionalProperties": false
193
+ },
194
+ "RegisterMachineCredentialRequest": {
195
+ "type": "object",
196
+ "required": ["credential_id", "secret_sha256"],
197
+ "properties": {
198
+ "credential_id": {
199
+ "$ref": "#/$defs/MachineCredentialId"
200
+ },
201
+ "secret_sha256": {
202
+ "$ref": "#/$defs/MachineSecretDigest"
203
+ }
204
+ },
205
+ "additionalProperties": false
206
+ },
207
+ "MachineCredential": {
208
+ "type": "object",
209
+ "required": [
210
+ "credential_id",
211
+ "machine_client_id",
212
+ "status",
213
+ "scope_summary",
214
+ "created_at"
215
+ ],
216
+ "properties": {
217
+ "credential_id": {
218
+ "$ref": "#/$defs/MachineCredentialId"
219
+ },
220
+ "machine_client_id": {
221
+ "$ref": "#/$defs/OpaqueIdentifier"
222
+ },
223
+ "status": {
224
+ "type": "string",
225
+ "enum": ["active", "revoked"]
226
+ },
227
+ "scope_summary": {
228
+ "$ref": "#/$defs/MachineScopeSummary"
229
+ },
230
+ "created_at": {
231
+ "$ref": "#/$defs/Timestamp"
232
+ },
233
+ "last_used_at": {
234
+ "$ref": "#/$defs/Timestamp"
235
+ },
236
+ "revoked_at": {
237
+ "$ref": "#/$defs/Timestamp"
238
+ }
239
+ },
240
+ "allOf": [
241
+ {
242
+ "if": {
243
+ "properties": {
244
+ "status": {
245
+ "const": "revoked"
246
+ }
247
+ },
248
+ "required": ["status"]
249
+ },
250
+ "then": {
251
+ "required": ["revoked_at"],
252
+ "properties": {
253
+ "revoked_at": {}
254
+ }
255
+ },
256
+ "else": {
257
+ "properties": {
258
+ "revoked_at": false
259
+ }
260
+ }
261
+ }
262
+ ],
263
+ "additionalProperties": false
264
+ },
265
+ "MachineCursor": {
266
+ "type": "string",
267
+ "minLength": 8,
268
+ "maxLength": 128,
269
+ "pattern": "^mcur_[A-Za-z0-9_-]+$",
270
+ "description": "An opaque position within only the authenticated machine stream."
271
+ },
272
+ "MachineEventPollResponse": {
273
+ "type": "object",
274
+ "required": ["schema", "events", "committed_cursor", "server_time"],
275
+ "properties": {
276
+ "schema": {
277
+ "const": "whooshbang.machine-events.v1"
278
+ },
279
+ "events": {
280
+ "type": "array",
281
+ "maxItems": 50,
282
+ "x-unique-property": "cursor",
283
+ "items": {
284
+ "$ref": "interaction-v1.schema.json#/$defs/InteractionEvent"
285
+ }
286
+ },
287
+ "committed_cursor": {
288
+ "oneOf": [
289
+ {
290
+ "$ref": "#/$defs/MachineCursor"
291
+ },
292
+ {
293
+ "type": "null"
294
+ }
295
+ ]
296
+ },
297
+ "server_time": {
298
+ "$ref": "#/$defs/Timestamp"
299
+ }
300
+ },
301
+ "additionalProperties": false
302
+ },
303
+ "MachineEventAckDisposition": {
304
+ "type": "string",
305
+ "enum": ["processed", "quarantined"]
306
+ },
307
+ "QuarantineReasonCode": {
308
+ "type": "string",
309
+ "minLength": 1,
310
+ "maxLength": 64,
311
+ "pattern": "^[a-z0-9][a-z0-9._-]*$"
312
+ },
313
+ "MachineEventAckRequest": {
314
+ "type": "object",
315
+ "required": ["cursor", "disposition"],
316
+ "properties": {
317
+ "cursor": {
318
+ "$ref": "#/$defs/MachineCursor"
319
+ },
320
+ "disposition": {
321
+ "$ref": "#/$defs/MachineEventAckDisposition"
322
+ },
323
+ "reason_code": {
324
+ "oneOf": [
325
+ {
326
+ "$ref": "#/$defs/QuarantineReasonCode"
327
+ },
328
+ {
329
+ "type": "null"
330
+ }
331
+ ]
332
+ }
333
+ },
334
+ "allOf": [
335
+ {
336
+ "if": {
337
+ "properties": {
338
+ "disposition": {
339
+ "const": "quarantined"
340
+ }
341
+ },
342
+ "required": ["disposition"]
343
+ },
344
+ "then": {
345
+ "required": ["reason_code"],
346
+ "properties": {
347
+ "reason_code": {
348
+ "$ref": "#/$defs/QuarantineReasonCode"
349
+ }
350
+ }
351
+ },
352
+ "else": {
353
+ "properties": {
354
+ "reason_code": {
355
+ "type": "null"
356
+ }
357
+ }
358
+ }
359
+ }
360
+ ],
361
+ "additionalProperties": false
362
+ },
363
+ "MachineEventAckResponse": {
364
+ "type": "object",
365
+ "required": [
366
+ "event_id",
367
+ "cursor",
368
+ "disposition",
369
+ "acknowledgement_status",
370
+ "committed_cursor",
371
+ "advanced"
372
+ ],
373
+ "properties": {
374
+ "event_id": {
375
+ "$ref": "#/$defs/OpaqueIdentifier"
376
+ },
377
+ "cursor": {
378
+ "$ref": "#/$defs/MachineCursor"
379
+ },
380
+ "disposition": {
381
+ "$ref": "#/$defs/MachineEventAckDisposition"
382
+ },
383
+ "reason_code": {
384
+ "$ref": "#/$defs/QuarantineReasonCode"
385
+ },
386
+ "acknowledgement_status": {
387
+ "type": "string",
388
+ "enum": ["recorded", "existing"]
389
+ },
390
+ "committed_cursor": {
391
+ "oneOf": [
392
+ {
393
+ "$ref": "#/$defs/MachineCursor"
394
+ },
395
+ {
396
+ "type": "null"
397
+ }
398
+ ]
399
+ },
400
+ "advanced": {
401
+ "type": "boolean"
402
+ }
403
+ },
404
+ "allOf": [
405
+ {
406
+ "if": {
407
+ "properties": {
408
+ "disposition": {
409
+ "const": "quarantined"
410
+ }
411
+ },
412
+ "required": ["disposition"]
413
+ },
414
+ "then": {
415
+ "required": ["reason_code"],
416
+ "properties": {
417
+ "reason_code": {}
418
+ }
419
+ },
420
+ "else": {
421
+ "properties": {
422
+ "reason_code": false
423
+ }
424
+ }
425
+ }
426
+ ],
427
+ "additionalProperties": false
428
+ }
429
+ }
430
+ }
@@ -0,0 +1,263 @@
1
+ {
2
+ "$schema": "https://json-schema.org/draft/2020-12/schema",
3
+ "$id": "https://whooshbang.flowxo.com/schemas/provider-capabilities-v1.schema.json",
4
+ "x-contract-version": "1.0.0-rc.13",
5
+ "title": "ProviderCapabilitiesV1",
6
+ "description": "Provider-neutral, renderer-facing delivery and interaction capabilities with explicit degradation.",
7
+ "type": "object",
8
+ "required": [
9
+ "schema",
10
+ "provider",
11
+ "text",
12
+ "interaction",
13
+ "streaming",
14
+ "edit",
15
+ "receipts",
16
+ "contexts",
17
+ "rate_limit",
18
+ "degradation"
19
+ ],
20
+ "properties": {
21
+ "schema": {
22
+ "const": "whooshbang.provider-capabilities.v1"
23
+ },
24
+ "provider": {
25
+ "type": "string",
26
+ "minLength": 1,
27
+ "maxLength": 64,
28
+ "pattern": "^[a-z][a-z0-9_-]*$"
29
+ },
30
+ "text": {
31
+ "type": "object",
32
+ "required": ["supported", "maximum_bytes"],
33
+ "properties": {
34
+ "supported": {
35
+ "type": "boolean"
36
+ },
37
+ "maximum_bytes": {
38
+ "type": "integer",
39
+ "minimum": 1,
40
+ "maximum": 1048576
41
+ }
42
+ },
43
+ "additionalProperties": false
44
+ },
45
+ "interaction": {
46
+ "type": "object",
47
+ "required": ["confirm", "select", "input"],
48
+ "properties": {
49
+ "confirm": {
50
+ "$ref": "#/$defs/InteractionCapability"
51
+ },
52
+ "select": {
53
+ "$ref": "#/$defs/InteractionCapability"
54
+ },
55
+ "input": {
56
+ "$ref": "#/$defs/InteractionCapability"
57
+ }
58
+ },
59
+ "additionalProperties": false
60
+ },
61
+ "streaming": {
62
+ "type": "object",
63
+ "required": ["mode"],
64
+ "properties": {
65
+ "mode": {
66
+ "type": "string",
67
+ "enum": [
68
+ "native",
69
+ "edit",
70
+ "typing_then_final",
71
+ "final_only",
72
+ "unsupported"
73
+ ]
74
+ },
75
+ "explanation": {
76
+ "$ref": "#/$defs/SafeExplanation"
77
+ }
78
+ },
79
+ "additionalProperties": false
80
+ },
81
+ "edit": {
82
+ "type": "object",
83
+ "required": ["supported"],
84
+ "properties": {
85
+ "supported": {
86
+ "type": "boolean"
87
+ }
88
+ },
89
+ "additionalProperties": false
90
+ },
91
+ "receipts": {
92
+ "type": "object",
93
+ "required": ["provider_accepted", "delivered", "read"],
94
+ "properties": {
95
+ "provider_accepted": {
96
+ "type": "boolean"
97
+ },
98
+ "delivered": {
99
+ "type": "boolean"
100
+ },
101
+ "read": {
102
+ "type": "boolean"
103
+ }
104
+ },
105
+ "additionalProperties": false
106
+ },
107
+ "contexts": {
108
+ "type": "object",
109
+ "required": ["private_chat", "thread", "group"],
110
+ "properties": {
111
+ "private_chat": {
112
+ "$ref": "#/$defs/ContextSupport"
113
+ },
114
+ "thread": {
115
+ "$ref": "#/$defs/ContextSupport"
116
+ },
117
+ "group": {
118
+ "$ref": "#/$defs/ContextSupport"
119
+ }
120
+ },
121
+ "additionalProperties": false
122
+ },
123
+ "rate_limit": {
124
+ "type": "object",
125
+ "required": ["strategy"],
126
+ "properties": {
127
+ "strategy": {
128
+ "type": "string",
129
+ "enum": [
130
+ "provider_retry_after",
131
+ "token_bucket",
132
+ "fixed_window",
133
+ "adaptive",
134
+ "unknown"
135
+ ]
136
+ },
137
+ "explanation": {
138
+ "$ref": "#/$defs/SafeExplanation"
139
+ }
140
+ },
141
+ "additionalProperties": false
142
+ },
143
+ "degradation": {
144
+ "$ref": "#/$defs/Degradation"
145
+ }
146
+ },
147
+ "$defs": {
148
+ "SafeExplanation": {
149
+ "type": "string",
150
+ "minLength": 1,
151
+ "maxLength": 500
152
+ },
153
+ "InteractionCapability": {
154
+ "type": "object",
155
+ "required": ["mode"],
156
+ "properties": {
157
+ "mode": {
158
+ "type": "string",
159
+ "enum": ["native", "fallback", "unsupported", "conditional"]
160
+ },
161
+ "explanation": {
162
+ "$ref": "#/$defs/SafeExplanation"
163
+ }
164
+ },
165
+ "allOf": [
166
+ {
167
+ "if": {
168
+ "properties": {
169
+ "mode": {
170
+ "enum": ["fallback", "conditional"]
171
+ }
172
+ },
173
+ "required": ["mode"]
174
+ },
175
+ "then": {
176
+ "required": ["explanation"],
177
+ "properties": {
178
+ "explanation": {}
179
+ }
180
+ }
181
+ }
182
+ ],
183
+ "additionalProperties": false
184
+ },
185
+ "ContextSupport": {
186
+ "type": "object",
187
+ "required": ["mode"],
188
+ "properties": {
189
+ "mode": {
190
+ "type": "string",
191
+ "enum": ["supported", "unsupported", "conditional"]
192
+ },
193
+ "explanation": {
194
+ "$ref": "#/$defs/SafeExplanation"
195
+ }
196
+ },
197
+ "allOf": [
198
+ {
199
+ "if": {
200
+ "properties": {
201
+ "mode": {
202
+ "const": "conditional"
203
+ }
204
+ },
205
+ "required": ["mode"]
206
+ },
207
+ "then": {
208
+ "required": ["explanation"],
209
+ "properties": {
210
+ "explanation": {}
211
+ }
212
+ }
213
+ }
214
+ ],
215
+ "additionalProperties": false
216
+ },
217
+ "Degradation": {
218
+ "type": "object",
219
+ "required": ["active"],
220
+ "properties": {
221
+ "active": {
222
+ "type": "boolean"
223
+ },
224
+ "code": {
225
+ "type": "string",
226
+ "minLength": 1,
227
+ "maxLength": 64,
228
+ "pattern": "^[a-z0-9][a-z0-9._-]*$"
229
+ },
230
+ "explanation": {
231
+ "$ref": "#/$defs/SafeExplanation"
232
+ }
233
+ },
234
+ "allOf": [
235
+ {
236
+ "if": {
237
+ "properties": {
238
+ "active": {
239
+ "const": true
240
+ }
241
+ },
242
+ "required": ["active"]
243
+ },
244
+ "then": {
245
+ "required": ["code", "explanation"],
246
+ "properties": {
247
+ "code": {},
248
+ "explanation": {}
249
+ }
250
+ },
251
+ "else": {
252
+ "properties": {
253
+ "code": false,
254
+ "explanation": false
255
+ }
256
+ }
257
+ }
258
+ ],
259
+ "additionalProperties": false
260
+ }
261
+ },
262
+ "additionalProperties": false
263
+ }