@forgesworn/fold-kit 0.0.0-seed.0 → 0.1.0

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.
@@ -0,0 +1,2173 @@
1
+ {
2
+ "protocolVersion": "kithmoot/v1",
3
+ "generatedBy": "vectors/generate-circle.mjs",
4
+ "nostrToolsVersion": "2.25.0",
5
+ "groups": {
6
+ "linkEnvelope": [
7
+ {
8
+ "name": "v2-live-full-envelope",
9
+ "kind": "positive",
10
+ "note": "A version 2 live-rendezvous link carrying every optional field at once: relay and ICE hints, a kith-gated policy, a pairing code (adding a device) and a room name.",
11
+ "input": {
12
+ "base": "https://kithmoot.com/j",
13
+ "link": {
14
+ "invitation": {
15
+ "bearerHex": "c5f153b74aba3605b5bca1064a3154e18bf32a92e800504d8e060205edec4654",
16
+ "inviter": "b5c5ec78f1eb56c0bd4d73f137c08fc49fc41a22257a95a384e60593cb6ac0bf",
17
+ "persistent": null
18
+ },
19
+ "secretHex": null,
20
+ "relays": [
21
+ "wss://relay.damus.io",
22
+ "wss://nos.lol"
23
+ ],
24
+ "iceUrls": [
25
+ "stun:stun.kithmoot.example:3478"
26
+ ],
27
+ "policy": {
28
+ "tier": "kith",
29
+ "admitted": [
30
+ "00a0b8b578de367e65c400cccdb7743e82403d457469d02023b1568a92faadd8"
31
+ ]
32
+ },
33
+ "pairingCodeHex": "91cc040984694a4a4c4701172ddbc693",
34
+ "name": "Weekly town hall"
35
+ }
36
+ },
37
+ "output": {
38
+ "url": "https://kithmoot.com/j#eyJ2IjoyLCJqIjoieGZGVHQwcTZOZ1cxdktFR1NqRlU0WXZ6S3BMb0FGQk5qZ1lDQmUzc1JsUSIsImgiOiJiNWM1ZWM3OGYxZWI1NmMwYmQ0ZDczZjEzN2MwOGZjNDlmYzQxYTIyMjU3YTk1YTM4NGU2MDU5M2NiNmFjMGJmIiwiciI6WyJ3c3M6Ly9yZWxheS5kYW11cy5pbyIsIndzczovL25vcy5sb2wiXSwiaSI6WyJzdHVuOnN0dW4ua2l0aG1vb3QuZXhhbXBsZTozNDc4Il0sImEiOnsidGllciI6ImtpdGgiLCJhZG1pdHRlZCI6WyIwMGEwYjhiNTc4ZGUzNjdlNjVjNDAwY2NjZGI3NzQzZTgyNDAzZDQ1NzQ2OWQwMjAyM2IxNTY4YTkyZmFhZGQ4Il19LCJjIjoiOTFjYzA0MDk4NDY5NGE0YTRjNDcwMTE3MmRkYmM2OTMiLCJuIjoiV2Vla2x5IHRvd24gaGFsbCJ9",
39
+ "decoded": {
40
+ "invitation": {
41
+ "bearerHex": "c5f153b74aba3605b5bca1064a3154e18bf32a92e800504d8e060205edec4654",
42
+ "inviter": "b5c5ec78f1eb56c0bd4d73f137c08fc49fc41a22257a95a384e60593cb6ac0bf",
43
+ "persistent": null
44
+ },
45
+ "secretHex": null,
46
+ "relays": [
47
+ "wss://relay.damus.io",
48
+ "wss://nos.lol"
49
+ ],
50
+ "iceUrls": [
51
+ "stun:stun.kithmoot.example:3478"
52
+ ],
53
+ "policy": {
54
+ "tier": "kith",
55
+ "admitted": [
56
+ "00a0b8b578de367e65c400cccdb7743e82403d457469d02023b1568a92faadd8"
57
+ ]
58
+ },
59
+ "pairingCodeHex": "91cc040984694a4a4c4701172ddbc693",
60
+ "name": "Weekly town hall"
61
+ }
62
+ }
63
+ },
64
+ {
65
+ "name": "v3-persistent-named-no-pairing-code",
66
+ "kind": "positive",
67
+ "note": "A version 3 stored group link: no pairing code, an open policy, and a name. Persistent invitations round-trip through the same envelope as v2, only the version number and the invitation.persistent flag differ.",
68
+ "input": {
69
+ "base": "https://kithmoot.com/j",
70
+ "link": {
71
+ "invitation": {
72
+ "bearerHex": "fe6a6ac8150838c9b16e1bec51ee1006210d73bbaa7530ed7029907f15ed0645",
73
+ "inviter": "b5c5ec78f1eb56c0bd4d73f137c08fc49fc41a22257a95a384e60593cb6ac0bf",
74
+ "persistent": true
75
+ },
76
+ "secretHex": null,
77
+ "relays": [
78
+ "wss://relay.damus.io"
79
+ ],
80
+ "iceUrls": [],
81
+ "policy": {
82
+ "tier": "open"
83
+ },
84
+ "pairingCodeHex": null,
85
+ "name": "Family"
86
+ }
87
+ },
88
+ "output": {
89
+ "url": "https://kithmoot.com/j#eyJ2IjozLCJqIjoiX21wcXlCVUlPTW14Ymh2c1VlNFFCaUVOYzd1cWRURHRjQ21RZnhYdEJrVSIsImgiOiJiNWM1ZWM3OGYxZWI1NmMwYmQ0ZDczZjEzN2MwOGZjNDlmYzQxYTIyMjU3YTk1YTM4NGU2MDU5M2NiNmFjMGJmIiwiciI6WyJ3c3M6Ly9yZWxheS5kYW11cy5pbyJdLCJpIjpbXSwiYSI6eyJ0aWVyIjoib3BlbiJ9LCJuIjoiRmFtaWx5In0",
90
+ "decoded": {
91
+ "invitation": {
92
+ "bearerHex": "fe6a6ac8150838c9b16e1bec51ee1006210d73bbaa7530ed7029907f15ed0645",
93
+ "inviter": "b5c5ec78f1eb56c0bd4d73f137c08fc49fc41a22257a95a384e60593cb6ac0bf",
94
+ "persistent": true
95
+ },
96
+ "secretHex": null,
97
+ "relays": [
98
+ "wss://relay.damus.io"
99
+ ],
100
+ "iceUrls": [],
101
+ "policy": {
102
+ "tier": "open"
103
+ },
104
+ "pairingCodeHex": null,
105
+ "name": "Family"
106
+ }
107
+ }
108
+ },
109
+ {
110
+ "name": "v2-live-no-optional-fields",
111
+ "kind": "positive",
112
+ "note": "A version 2 link with none of the optional fields: no policy, no pairing code, no name. The fragment must carry none of their keys.",
113
+ "input": {
114
+ "base": "https://kithmoot.com/j",
115
+ "link": {
116
+ "invitation": {
117
+ "bearerHex": "c5f153b74aba3605b5bca1064a3154e18bf32a92e800504d8e060205edec4654",
118
+ "inviter": "b5c5ec78f1eb56c0bd4d73f137c08fc49fc41a22257a95a384e60593cb6ac0bf",
119
+ "persistent": null
120
+ },
121
+ "secretHex": null,
122
+ "relays": [],
123
+ "iceUrls": [],
124
+ "policy": null,
125
+ "pairingCodeHex": null,
126
+ "name": null
127
+ }
128
+ },
129
+ "output": {
130
+ "url": "https://kithmoot.com/j#eyJ2IjoyLCJqIjoieGZGVHQwcTZOZ1cxdktFR1NqRlU0WXZ6S3BMb0FGQk5qZ1lDQmUzc1JsUSIsImgiOiJiNWM1ZWM3OGYxZWI1NmMwYmQ0ZDczZjEzN2MwOGZjNDlmYzQxYTIyMjU3YTk1YTM4NGU2MDU5M2NiNmFjMGJmIiwiciI6W10sImkiOltdfQ",
131
+ "decoded": {
132
+ "invitation": {
133
+ "bearerHex": "c5f153b74aba3605b5bca1064a3154e18bf32a92e800504d8e060205edec4654",
134
+ "inviter": "b5c5ec78f1eb56c0bd4d73f137c08fc49fc41a22257a95a384e60593cb6ac0bf",
135
+ "persistent": null
136
+ },
137
+ "secretHex": null,
138
+ "relays": [],
139
+ "iceUrls": [],
140
+ "policy": null,
141
+ "pairingCodeHex": null,
142
+ "name": null
143
+ }
144
+ }
145
+ },
146
+ {
147
+ "name": "v1-legacy-secret-link",
148
+ "kind": "positive",
149
+ "note": "The version-1 shape from before invitations existed: the room traffic secret rides directly in the fragment (`s`), with no `j`/`h` invitation pair. `encodeRoomLink` writes this branch whenever `link.invitation` is absent, and a v1 URL carries no `v` key at all - `parseRoomLink` reads that absence the same way it reads `v: 1` would, which is the whole compatibility story for a link written before versioning existed.",
150
+ "input": {
151
+ "base": "https://kithmoot.com/j",
152
+ "link": {
153
+ "invitation": null,
154
+ "secretHex": "3235bdb7cf4e08d8eb9f1441bd2158825c0e84150ac0fc123a106455130eeecf",
155
+ "relays": [
156
+ "wss://relay.damus.io"
157
+ ],
158
+ "iceUrls": [],
159
+ "policy": null,
160
+ "pairingCodeHex": null,
161
+ "name": null
162
+ }
163
+ },
164
+ "output": {
165
+ "url": "https://kithmoot.com/j#eyJzIjoiTWpXOXQ4OU9DTmpybnhSQnZTRllnbHdPaEJVS3dQd1NPaEJrVlJNTzdzOCIsInIiOlsid3NzOi8vcmVsYXkuZGFtdXMuaW8iXSwiaSI6W119",
166
+ "decoded": {
167
+ "invitation": null,
168
+ "secretHex": "3235bdb7cf4e08d8eb9f1441bd2158825c0e84150ac0fc123a106455130eeecf",
169
+ "relays": [
170
+ "wss://relay.damus.io"
171
+ ],
172
+ "iceUrls": [],
173
+ "policy": null,
174
+ "pairingCodeHex": null,
175
+ "name": null
176
+ }
177
+ }
178
+ },
179
+ {
180
+ "name": "v3-unknown-policy-tier-refused",
181
+ "kind": "negative",
182
+ "note": "A v3 (persistent) link naming an access tier outside open/ken/kith/kin is refused before the invitation itself is even read - a dropped rule would be an open room.",
183
+ "input": {
184
+ "url": "https://kithmoot.com/j#eyJ2IjozLCJqIjoiX21wcXlCVUlPTW14Ymh2c1VlNFFCaUVOYzd1cWRURHRjQ21RZnhYdEJrVSIsImgiOiJiNWM1ZWM3OGYxZWI1NmMwYmQ0ZDczZjEzN2MwOGZjNDlmYzQxYTIyMjU3YTk1YTM4NGU2MDU5M2NiNmFjMGJmIiwiciI6W10sImkiOltdLCJhIjp7InRpZXIiOiJhcmNob24ifX0"
185
+ },
186
+ "output": {
187
+ "throws": true,
188
+ "error": "join URL carries an access policy at an unknown tier"
189
+ }
190
+ },
191
+ {
192
+ "name": "v4-unsupported-version-refused",
193
+ "kind": "negative",
194
+ "note": "A link naming a version number this parser does not know (`v: 4`, one past the newest it understands): refused outright rather than guessed at as v1, v2 or v3.",
195
+ "input": {
196
+ "url": "https://kithmoot.com/j#eyJ2Ijo0LCJqIjoieGZGVHQwcTZOZ1cxdktFR1NqRlU0WXZ6S3BMb0FGQk5qZ1lDQmUzc1JsUSIsImgiOiJiNWM1ZWM3OGYxZWI1NmMwYmQ0ZDczZjEzN2MwOGZjNDlmYzQxYTIyMjU3YTk1YTM4NGU2MDU5M2NiNmFjMGJmIiwiciI6W10sImkiOltdfQ"
197
+ },
198
+ "output": {
199
+ "throws": true,
200
+ "error": "join URL uses an unsupported version"
201
+ }
202
+ },
203
+ {
204
+ "name": "bearer-31-bytes-refused",
205
+ "kind": "negative",
206
+ "note": "A bearer one byte short of the required 32: `roomInvitation` refuses it rather than accepting a link whose rendezvous derivation would not match what a correctly-sized bearer produces.",
207
+ "input": {
208
+ "url": "https://kithmoot.com/j#eyJ2IjoyLCJqIjoiR1luMlBpMW1TVTNPelNiSkx5aTVpSFJGd1RvUXVUWkl1aVJKYnpEUUhnIiwiaCI6ImI1YzVlYzc4ZjFlYjU2YzBiZDRkNzNmMTM3YzA4ZmM0OWZjNDFhMjIyNTdhOTVhMzg0ZTYwNTkzY2I2YWMwYmYiLCJyIjpbXSwiaSI6W119",
209
+ "bearerHex": "1989f63e2d66494dcecd26c92f28b9887445c13a10b93648ba24496f30d01e"
210
+ },
211
+ "output": {
212
+ "throws": true,
213
+ "error": "invitation bearer must be 32 bytes"
214
+ }
215
+ },
216
+ {
217
+ "name": "pairing-code-malformed-refused",
218
+ "kind": "negative",
219
+ "note": "A pairing code field that is not valid hex at all: refused with a named error, not an uncaught parse exception.",
220
+ "input": {
221
+ "url": "https://kithmoot.com/j#eyJ2IjoyLCJqIjoieGZGVHQwcTZOZ1cxdktFR1NqRlU0WXZ6S3BMb0FGQk5qZ1lDQmUzc1JsUSIsImgiOiJiNWM1ZWM3OGYxZWI1NmMwYmQ0ZDczZjEzN2MwOGZjNDlmYzQxYTIyMjU3YTk1YTM4NGU2MDU5M2NiNmFjMGJmIiwiciI6W10sImkiOltdLCJjIjoibm90LWhleC16eiJ9"
222
+ },
223
+ "output": {
224
+ "throws": true,
225
+ "error": "join URL carries a malformed pairing code"
226
+ }
227
+ },
228
+ {
229
+ "name": "nine-relay-hints-refused",
230
+ "kind": "negative",
231
+ "note": "One more than MAX_RELAY_HINTS (8) relay hint: refused outright on encode, rather than silently keeping the first 8 and dropping the rest without saying so.",
232
+ "input": {
233
+ "relays": [
234
+ "wss://relay-0.kithmoot.example",
235
+ "wss://relay-1.kithmoot.example",
236
+ "wss://relay-2.kithmoot.example",
237
+ "wss://relay-3.kithmoot.example",
238
+ "wss://relay-4.kithmoot.example",
239
+ "wss://relay-5.kithmoot.example",
240
+ "wss://relay-6.kithmoot.example",
241
+ "wss://relay-7.kithmoot.example",
242
+ "wss://relay-8.kithmoot.example"
243
+ ]
244
+ },
245
+ "output": {
246
+ "throws": true,
247
+ "error": "join URL carries too many relay hints"
248
+ }
249
+ },
250
+ {
251
+ "name": "oversize-fragment-refused",
252
+ "kind": "negative",
253
+ "note": "A fragment one character past MAX_ROOM_LINK_FRAGMENT_LENGTH (16384): refused on length alone, before the fragment is treated as base64 or JSON at all.",
254
+ "input": {
255
+ "url": "https://kithmoot.com/j#AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA",
256
+ "fragmentLength": 16385
257
+ },
258
+ "output": {
259
+ "throws": true,
260
+ "error": "join URL fragment is too large"
261
+ }
262
+ },
263
+ {
264
+ "name": "hostile-input-normalised",
265
+ "kind": "positive",
266
+ "note": "A link nobody's own encoder produced: duplicate relay and ICE hints, a non-loopback ws:// relay (unsafe - the room requires wss:// off loopback), a loopback ws:// relay (safe - kept for local development and tests), and a name carrying a bidirectional override, a zero-width space and overlong text. `parseRoomLink` is still readable, and every hostile byte is normalised away rather than rejected outright: the invitation itself is genuine, only its envelope is adversarial.",
267
+ "input": {
268
+ "url": "https://kithmoot.com/j#eyJ2IjoyLCJqIjoieGZGVHQwcTZOZ1cxdktFR1NqRlU0WXZ6S3BMb0FGQk5qZ1lDQmUzc1JsUSIsImgiOiJiNWM1ZWM3OGYxZWI1NmMwYmQ0ZDczZjEzN2MwOGZjNDlmYzQxYTIyMjU3YTk1YTM4NGU2MDU5M2NiNmFjMGJmIiwiciI6WyJ3c3M6Ly9yZWxheS5kYW11cy5pbyIsIndzczovL3JlbGF5LmRhbXVzLmlvIiwid3M6Ly90cmFja2VyLmV4YW1wbGUiLCJ3czovL2xvY2FsaG9zdDo0ODY5Il0sImkiOlsic3R1bjpzdHVuLmtpdGhtb290LmV4YW1wbGU6MzQ3OCIsInN0dW46c3R1bi5raXRobW9vdC5leGFtcGxlOjM0NzgiXSwibiI6IlJvYmlu4oCuYWRtaW7igIt4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4In0",
269
+ "rawRelays": [
270
+ "wss://relay.damus.io",
271
+ "wss://relay.damus.io",
272
+ "ws://tracker.example",
273
+ "ws://localhost:4869"
274
+ ],
275
+ "rawIceUrls": [
276
+ "stun:stun.kithmoot.example:3478",
277
+ "stun:stun.kithmoot.example:3478"
278
+ ],
279
+ "rawName": "Robin‮admin​xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
280
+ },
281
+ "output": {
282
+ "decoded": {
283
+ "relays": [
284
+ "wss://relay.damus.io",
285
+ "ws://localhost:4869"
286
+ ],
287
+ "iceUrls": [
288
+ "stun:stun.kithmoot.example:3478"
289
+ ],
290
+ "name": "Robinadminxxxxxxxxxxxxxxxxxxxxxx"
291
+ }
292
+ },
293
+ "expected": {
294
+ "relays": [
295
+ "wss://relay.damus.io",
296
+ "ws://localhost:4869"
297
+ ],
298
+ "iceUrls": [
299
+ "stun:stun.kithmoot.example:3478"
300
+ ],
301
+ "name": "Robinadminxxxxxxxxxxxxxxxxxxxxxx"
302
+ }
303
+ },
304
+ {
305
+ "name": "quiet-room-without-members-refused",
306
+ "kind": "negative",
307
+ "note": "A policy asking for a quiet room (room.ts:83) but naming no members list: refused. A quiet room derives its per-pair keys from the members list, and with none there is nobody to derive them for.",
308
+ "input": {
309
+ "url": "https://kithmoot.com/j#eyJ2IjoyLCJqIjoieGZGVHQwcTZOZ1cxdktFR1NqRlU0WXZ6S3BMb0FGQk5qZ1lDQmUzc1JsUSIsImgiOiJiNWM1ZWM3OGYxZWI1NmMwYmQ0ZDczZjEzN2MwOGZjNDlmYzQxYTIyMjU3YTk1YTM4NGU2MDU5M2NiNmFjMGJmIiwiciI6W10sImkiOltdLCJhIjp7InRpZXIiOiJraXRoIiwicXVpZXQiOnRydWV9fQ"
310
+ },
311
+ "output": {
312
+ "throws": true,
313
+ "error": "join URL asks for a quiet room without a members list"
314
+ }
315
+ },
316
+ {
317
+ "name": "unknown-agent-rule-refused",
318
+ "kind": "negative",
319
+ "note": "A policy naming an agent rule this reader does not know (room.ts:77): refused for the same reason an unknown tier is - dropping it would admit what the room meant to keep out.",
320
+ "input": {
321
+ "url": "https://kithmoot.com/j#eyJ2IjoyLCJqIjoieGZGVHQwcTZOZ1cxdktFR1NqRlU0WXZ6S3BMb0FGQk5qZ1lDQmUzc1JsUSIsImgiOiJiNWM1ZWM3OGYxZWI1NmMwYmQ0ZDczZjEzN2MwOGZjNDlmYzQxYTIyMjU3YTk1YTM4NGU2MDU5M2NiNmFjMGJmIiwiciI6W10sImkiOltdLCJhIjp7InRpZXIiOiJraXRoIiwiYWdlbnRzIjoidW5oZWFyZC1vZi1ydWxlIn19"
322
+ },
323
+ "output": {
324
+ "throws": true,
325
+ "error": "join URL carries an access policy with an unknown agent rule"
326
+ }
327
+ },
328
+ {
329
+ "name": "encoder-normalises-hostile-input",
330
+ "kind": "positive",
331
+ "note": "The real `encodeRoomLink` (link.ts:135-147) filters an unsafe ws:// relay, deduplicates the repeated one, drops an unrecognised ICE scheme, and sanitises an overlong/bidi-override/zero-width name - before the bytes ever reach a QR code, not only when a stranger's link is decoded. Fed the same kind of hostile input `hostile-input-normalised` (above) fakes directly on the wire; the output here is what the real encoder itself already wrote.",
332
+ "input": {
333
+ "base": "https://kithmoot.com/j",
334
+ "invitation": {
335
+ "bearerHex": "c5f153b74aba3605b5bca1064a3154e18bf32a92e800504d8e060205edec4654",
336
+ "inviter": "b5c5ec78f1eb56c0bd4d73f137c08fc49fc41a22257a95a384e60593cb6ac0bf"
337
+ },
338
+ "rawRelays": [
339
+ "wss://relay.damus.io",
340
+ "wss://relay.damus.io",
341
+ "ws://tracker.example",
342
+ "wss://nos.lol"
343
+ ],
344
+ "rawIceUrls": [
345
+ "not-a-real-scheme:nope",
346
+ "stun:stun.kithmoot.example:3478"
347
+ ],
348
+ "rawName": "Rowan‮txet​nedihyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy"
349
+ },
350
+ "output": {
351
+ "url": "https://kithmoot.com/j#eyJ2IjoyLCJqIjoieGZGVHQwcTZOZ1cxdktFR1NqRlU0WXZ6S3BMb0FGQk5qZ1lDQmUzc1JsUSIsImgiOiJiNWM1ZWM3OGYxZWI1NmMwYmQ0ZDczZjEzN2MwOGZjNDlmYzQxYTIyMjU3YTk1YTM4NGU2MDU5M2NiNmFjMGJmIiwiciI6WyJ3c3M6Ly9yZWxheS5kYW11cy5pbyIsIndzczovL25vcy5sb2wiXSwiaSI6WyJzdHVuOnN0dW4ua2l0aG1vb3QuZXhhbXBsZTozNDc4Il0sIm4iOiJSb3dhbnR4ZXRuZWRpaHl5eXl5eXl5eXl5eXl5eXl5eSJ9",
352
+ "decoded": {
353
+ "relays": [
354
+ "wss://relay.damus.io",
355
+ "wss://nos.lol"
356
+ ],
357
+ "iceUrls": [
358
+ "stun:stun.kithmoot.example:3478"
359
+ ],
360
+ "name": "Rowantxetnedihyyyyyyyyyyyyyyyyyy"
361
+ }
362
+ },
363
+ "expected": {
364
+ "relays": [
365
+ "wss://relay.damus.io",
366
+ "wss://nos.lol"
367
+ ],
368
+ "iceUrls": [
369
+ "stun:stun.kithmoot.example:3478"
370
+ ],
371
+ "name": "Rowantxetnedihyyyyyyyyyyyyyyyyyy"
372
+ }
373
+ },
374
+ {
375
+ "name": "encoder-oversize-fragment-refused",
376
+ "kind": "negative",
377
+ "note": "8 relay hints, each near the 2048 per-hint character ceiling, push the WRITTEN fragment past MAX_ROOM_LINK_FRAGMENT_LENGTH: refused at the point of encoding, not only on the way back in.",
378
+ "input": {
379
+ "relays": [
380
+ "wss://rrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrr-0.example",
381
+ "wss://rrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrr-1.example",
382
+ "wss://rrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrr-2.example",
383
+ "wss://rrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrr-3.example",
384
+ "wss://rrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrr-4.example",
385
+ "wss://rrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrr-5.example",
386
+ "wss://rrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrr-6.example",
387
+ "wss://rrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrr-7.example"
388
+ ]
389
+ },
390
+ "output": {
391
+ "throws": true,
392
+ "error": "room link fragment is too large"
393
+ }
394
+ }
395
+ ],
396
+ "invitationEnvelope": [
397
+ {
398
+ "name": "invitation-id-derivation",
399
+ "kind": "positive",
400
+ "note": "The public rendezvous id: HKDF-SHA256 of the bearer alone. Pure - the real function is called directly.",
401
+ "input": {
402
+ "bearerHex": "c5f153b74aba3605b5bca1064a3154e18bf32a92e800504d8e060205edec4654",
403
+ "inviter": "b5c5ec78f1eb56c0bd4d73f137c08fc49fc41a22257a95a384e60593cb6ac0bf"
404
+ },
405
+ "output": {
406
+ "id": "a652671ef5a7edd3f45a472b7456f1711bcfdfa60cdcbae2c5ff3ba08c86f7ba"
407
+ }
408
+ },
409
+ {
410
+ "name": "request-valid",
411
+ "kind": "positive",
412
+ "note": "A request proving possession of the bearer, carrying an asking name and a participant pubkey. Built by calling the real `encodeInvitationRequest` with `crypto.getRandomValues` stubbed to the recorded [nonce, auxRand] queue - the NIP-44 nonce is drawn first (it is part of building `content`, which is evaluated before `finalizeEvent` signs), then the signature aux-rand.",
413
+ "input": {
414
+ "invitation": {
415
+ "bearerHex": "c5f153b74aba3605b5bca1064a3154e18bf32a92e800504d8e060205edec4654",
416
+ "inviter": "b5c5ec78f1eb56c0bd4d73f137c08fc49fc41a22257a95a384e60593cb6ac0bf"
417
+ },
418
+ "requesterSkHex": "87a68ed405197e7910559300549798b288b9215bbcaf5f1d740bb1233bc6691c",
419
+ "createdAt": 1799999970,
420
+ "name": "Rowan",
421
+ "participant": "b07ff66ffca2d5445cfb4a384e94fba8ecc5000283b43f2d5425c85df5032e74",
422
+ "randomnessQueueHex": [
423
+ "d9782ea5832d39bedd8880d5183b13b087b3d36471d5a15a95bd16c70eacc91e",
424
+ "3de767cd22c16f77eef7ec5046a6ae6db63155f2195745c07d02999398051449"
425
+ ]
426
+ },
427
+ "output": {
428
+ "event": {
429
+ "kind": 20466,
430
+ "created_at": 1799999970,
431
+ "tags": [
432
+ [
433
+ "d",
434
+ "a652671ef5a7edd3f45a472b7456f1711bcfdfa60cdcbae2c5ff3ba08c86f7ba"
435
+ ],
436
+ [
437
+ "p",
438
+ "b5c5ec78f1eb56c0bd4d73f137c08fc49fc41a22257a95a384e60593cb6ac0bf"
439
+ ]
440
+ ],
441
+ "content": "Atl4LqWDLTm+3YiA1Rg7E7CHs9NkcdWhWpW9FscOrMkele3rPICChNNZaQXx5FkQzgJBoRF4uXbylYkzZfca3iRcp4zevZytQzCV3aRt/hHVpjaot+tVh2zI5ZLvDkbAu5Mat0pAgY6GBJtHdX/XIb5n8pbY/i2u1QR/0HWmMZoaOoctAlC1ffc5vfQ7Q9Nu9iu/UrLR582aMjdGJT8YpCN1c+uiOlJs0h3Rg8pO1+Pkbr0/eDRV6PhrjtgO5PSyWmmaHmlDTnx8pImp0e8HokWkvhaXKczdcc4ZhjQ26bO5lKPAtHJC5KN4+cwB+ZILJN5DRJC8OCKzBP8QkdHwz94z1Q==",
442
+ "pubkey": "bea24e3c816957292748b718431d23eb94e2529633aa36840ad70fbb3f44228b",
443
+ "id": "cfb190d9bdac0fdeda33efb74740e3f8b44f2c9f38028080a0bcd2439a61038c",
444
+ "sig": "e4f0050b11203a4bef8a47d30ad00af9494af542593027a56f9f9eb6e938cb576a9bdf51c5b9e9eaa8ffc39da09da0160762498678537926bc897c9a82baa6b2"
445
+ }
446
+ },
447
+ "expected": {
448
+ "decode": {
449
+ "invitation": {
450
+ "bearerHex": "c5f153b74aba3605b5bca1064a3154e18bf32a92e800504d8e060205edec4654",
451
+ "inviter": "b5c5ec78f1eb56c0bd4d73f137c08fc49fc41a22257a95a384e60593cb6ac0bf"
452
+ },
453
+ "now": 1800000000
454
+ },
455
+ "result": {
456
+ "device": "bea24e3c816957292748b718431d23eb94e2529633aa36840ad70fbb3f44228b",
457
+ "request": "cfb190d9bdac0fdeda33efb74740e3f8b44f2c9f38028080a0bcd2439a61038c",
458
+ "name": "Rowan",
459
+ "participant": "b07ff66ffca2d5445cfb4a384e94fba8ecc5000283b43f2d5425c85df5032e74"
460
+ }
461
+ }
462
+ },
463
+ {
464
+ "name": "request-stale-refused",
465
+ "kind": "negative",
466
+ "note": "The same request, read long after its 90-second window: refused as stale.",
467
+ "input": {
468
+ "event": {
469
+ "kind": 20466,
470
+ "created_at": 1799999970,
471
+ "tags": [
472
+ [
473
+ "d",
474
+ "a652671ef5a7edd3f45a472b7456f1711bcfdfa60cdcbae2c5ff3ba08c86f7ba"
475
+ ],
476
+ [
477
+ "p",
478
+ "b5c5ec78f1eb56c0bd4d73f137c08fc49fc41a22257a95a384e60593cb6ac0bf"
479
+ ]
480
+ ],
481
+ "content": "Ap+6DnJhGPDjda4NwWrlJc4wueQgI897WswV82KqAnGbbY+mW8BKsJ0pPU12WDdC8gSkHgkw4ghMT0OVbX1UOtZ3nLWtasTXz8nfXFE/2VdaWzdDQHZCRX5JW5k4/LJ8orUOZ0sGzR00G78Ld93zs9gC3cBqHEyMAqQzcggVICGZNqFg4kvT1GeK2b8AZw0dByyZtCuXEFku2B0Ks9XMH3FuZw==",
482
+ "pubkey": "bea24e3c816957292748b718431d23eb94e2529633aa36840ad70fbb3f44228b",
483
+ "id": "60472d77cf1ff3df3167cf9f0c4bf5738f63dbe1e5226cd00d92fe96f2a7440a",
484
+ "sig": "60d3638a2ebc2d9e70a65ad554c4fc70e4408921f8c81a279422f33c103a2183b5746cf1bebe1d62fecf3e3b1cc6a3500cd38c303bf16843954d0234ee818fe4"
485
+ },
486
+ "invitation": {
487
+ "bearerHex": "c5f153b74aba3605b5bca1064a3154e18bf32a92e800504d8e060205edec4654",
488
+ "inviter": "b5c5ec78f1eb56c0bd4d73f137c08fc49fc41a22257a95a384e60593cb6ac0bf"
489
+ },
490
+ "decode": {
491
+ "now": 1800000061
492
+ }
493
+ },
494
+ "output": {
495
+ "result": null
496
+ }
497
+ },
498
+ {
499
+ "name": "request-device-mismatched-signer-refused",
500
+ "kind": "negative",
501
+ "note": "M13: the event is genuinely signed by REQUESTER_A_SK - a real signature, not a zeroed or forged one - but the encrypted body claims a different device (`OTHER_INVITER`'s pubkey) than the key that actually signed it. `decodeInvitationRequest` checks `body.device` against `event.pubkey` and refuses the mismatch, or a stolen signing key could request admission in somebody else's device's name.",
502
+ "input": {
503
+ "event": {
504
+ "kind": 20466,
505
+ "created_at": 1799999970,
506
+ "tags": [
507
+ [
508
+ "d",
509
+ "a652671ef5a7edd3f45a472b7456f1711bcfdfa60cdcbae2c5ff3ba08c86f7ba"
510
+ ],
511
+ [
512
+ "p",
513
+ "b5c5ec78f1eb56c0bd4d73f137c08fc49fc41a22257a95a384e60593cb6ac0bf"
514
+ ]
515
+ ],
516
+ "content": "Aj2rrBL8XztjY2vaVuaENXq8Hg+zQyLTyrxlcRKEfcVot5VFMLq4W0C5Cr0uZY2KkeyQ7qLuUsSIHvgYXnH0clkdWCMNzhTLUAW+IOLDxPX80e7aOY434BW4fY9UfV5x1ZOnBsNstLpKk/443+4SDsMTvKAe1ZrTADjgmzfX46eCH0R6gH7gspOcmQvBnVzFgzpjbgPIjAZ7Dovp4JEI4xDRhg==",
517
+ "pubkey": "bea24e3c816957292748b718431d23eb94e2529633aa36840ad70fbb3f44228b",
518
+ "id": "579a2504c89898a0748ac5f527909eb0cc0d52d6831424e0b4a6b58c71256894",
519
+ "sig": "2b891381f665c52f8aed45bc8a812201b78a35c1c4673efe0259236bba8a861b19c569ed96c24cc4102175a28598f97233dea14de263d6a2549e1e00b98f828c"
520
+ },
521
+ "body": {
522
+ "v": 1,
523
+ "device": "cb948cc3faaf18b2db04bc0970c26bc79d56b0f9a32cf0cdb197597f2a6164e1"
524
+ },
525
+ "signerIsReallyDevice": "bea24e3c816957292748b718431d23eb94e2529633aa36840ad70fbb3f44228b"
526
+ },
527
+ "output": {
528
+ "result": null
529
+ }
530
+ },
531
+ {
532
+ "name": "grant-two-hop-delegation",
533
+ "kind": "positive",
534
+ "note": "A grant signed by a delegated responder (not the root inviter), carrying the full two-hop chain rooted at the inviter. Both hops and both grant events are produced by calling the real `encodeInvitationGrant` twice - hop 1 by the creator, hop 2 by the responder hop 1 itself admitted - with `crypto.getRandomValues` stubbed to each call's own recorded 3-value queue: the new delegation hop's signature aux-rand (drawn inside the not-exported `issueInvitationDelegation`), then the grant body's NIP-44 nonce, then the outer event's signature aux-rand.",
535
+ "input": {
536
+ "hop1": {
537
+ "grantEvent": {
538
+ "kind": 20467,
539
+ "created_at": 1799999970,
540
+ "tags": [
541
+ [
542
+ "d",
543
+ "a652671ef5a7edd3f45a472b7456f1711bcfdfa60cdcbae2c5ff3ba08c86f7ba"
544
+ ],
545
+ [
546
+ "p",
547
+ "0869c418f37accb59f93d6e42327004379d49791e6254d5146fcfe0d6be4b924"
548
+ ]
549
+ ],
550
+ "content": "AjHwpFC6llj8mvtyPhLzL0Y9FssbHVumo3RuwKYfVdTE2dDb/JlaRaT85T27TN268RS+V+5HGCeg1MFOFXOTLZlIXEkoPZBuJMQX1Q8dlkfnv14nj1l8D/tHTs6jzTjlZ10uMuPUj4BivRwlAKdJh+hvIJKfZ6s/cgywcpVaeDe7XURCG0tEdAfsDlD9J63lKeNmscwNOJieaBV1QuKZniOI8XceQZw1wnlVTvNorQ9khrPoTt9vJwFxKoBgbxG95nM7cZzoUg9nHVSWxF6WLJK9LZdYvNDbi5KIUGveoGEfavTF2zC/nxUUPUvzdGJC/K8nXBx3V3xJR+fIURUfqBdALqY7IuupHtFiLma+EueLQP2Mb5zSMOx5yG2qU+QW5jpNkDZh328JxdSDDcWbPKAoPDYXJt9xLmBgVCuJm0xBJrhsVRVlQ5hIOqW62Hm22rx582GEthM5uIJYppk9hupee1+ebDnca7Qum5S3zOyCJceFgduuRcwbi7vIRsRYrNf241iv1GKQ2MPT/+mSRKvzIoNnL8GNfR6VmIr2ZNOsLo0Fefiu4GiKHjLlRcpBP7tdEnSR3N+NeHXsEwxgpYCEra0fjFadviVxLtsnxyXyt/4wtYka+l0IZx8dpSvu7GHcTjBlJdQ+ynH03QhV/sdP065eh493ECTymkzKGOpY0kHtBsYrKSwTbkjQkg2a6FDFqoy0tiPcXUAlaAZDMhFQrW/o6mC3+rnSJk8pbVpGbULt8r0sf/o0AqglWhsAPlyWxPPJTc/ZJnITBDdFGTA+Oju5brxVILoHQDJH+gaxHib5o6hdnk2pSG5RpEp66Ue6220I0+66DS3UcR5goWkltdeZDW+gIG38QKu5xKoH30WcUgokwwix6vGHXQ115ST30Pm+q0Un6VYako8apZNyO9Dg/Ma0oG5Q5pS0LLxE3jE=",
551
+ "pubkey": "b5c5ec78f1eb56c0bd4d73f137c08fc49fc41a22257a95a384e60593cb6ac0bf",
552
+ "id": "c4c362c683df0fa9c3321ced406025c489296b2c8be1cde1b78c9812e735a200",
553
+ "sig": "a4d3e3dc871dc2890543dfffe032497cd189a5a47a9f93c55d1b384642a87b35aca15e6dc4d0d50b37d4e8db6b166d39488a12119e15a0cc04c80e135a72b68b"
554
+ },
555
+ "randomnessQueueHex": [
556
+ "b9e8a069ff33b676cd4b89cbcfb55f5ecc2d5af19a8882d5078416305dc850fc",
557
+ "31f0a450ba9658fc9afb723e12f32f463d16cb1b1d5ba6a3746ec0a61f55d4c4",
558
+ "e498c6ae487e1624d3a162d7999d7cdedabbcbe3848bcc059ce06b4d4206cfcb"
559
+ ],
560
+ "inviterSkHex": "251d103ba0f97308ca785a911e558a49ec9006940b235ab4fb12b9fbd492c6a5",
561
+ "requester": "0869c418f37accb59f93d6e42327004379d49791e6254d5146fcfe0d6be4b924",
562
+ "request": "e17feb5ae4f0b873cd53dafac3c1080b043bec807b1ceec56ce32eb9f5db930c",
563
+ "createdAt": 1799999970
564
+ },
565
+ "hop2": {
566
+ "randomnessQueueHex": [
567
+ "62ffbc1e2b6d29c8eba4072823d7570cf69397881bd7fe3e2545d7602a31f08f",
568
+ "2b1b9794e6a6fb553e056bc3e8932f2c53abf01fe7c69b3767e0deead5f7d0f7",
569
+ "b2b1461d00b37431300adc3f2d15d89515bd1635838c7c3e541313939c1bdd21"
570
+ ],
571
+ "inviterSkHex": "99867032a1991699b8582bd569eb8950e5d975cf86bbfe9eec4ee9309c85ab92",
572
+ "requester": "bea24e3c816957292748b718431d23eb94e2529633aa36840ad70fbb3f44228b",
573
+ "request": "a4b8b6d30d5d9e7e5fd3b1f439a50c3632d2b5fd006def614bd88aec9d38b4ae",
574
+ "createdAt": 1799999990
575
+ }
576
+ },
577
+ "output": {
578
+ "event": {
579
+ "kind": 20467,
580
+ "created_at": 1799999990,
581
+ "tags": [
582
+ [
583
+ "d",
584
+ "a652671ef5a7edd3f45a472b7456f1711bcfdfa60cdcbae2c5ff3ba08c86f7ba"
585
+ ],
586
+ [
587
+ "p",
588
+ "bea24e3c816957292748b718431d23eb94e2529633aa36840ad70fbb3f44228b"
589
+ ]
590
+ ],
591
+ "content": "Aisbl5TmpvtVPgVrw+iTLyxTq/Af58abN2fg3urV99D3NoWMNNJ//rzfGISDpAw5W/o4GIOLXVv2cTAdBUSzjOWr7iAoaa4au3HPe7nwr/Dh5rvXRGLtfo2jH1kvNAtbYdHh7KzEhka5uO55G6k/YAudtLr3CI27gsqOmm5gsJS8EwAKYjnAJpzHQJERHFHPqVSPWtyJryAqxj3Wj4lzc+iajRvUJwY70nPTd7YuWjPgeML+qoiRP5punNe7jkfdxeysDA2w48InqDWnkVKtYzEB+PErfmbTL7w9Vru4Uh4WJLhTJGVKSXYDlFDxZxqNfkYN3GLoJkrbeArlYa6r+qmjz4y/4yFUi1FPoINIfSLE93ISINHr4KRBf0Gr5jXPSWZzrGs+C+9EfGBSZA7hWMhhlyJTD3MbFrFxWN63enq6htF7Ut3cVHsh1sWcICu2nIA6/bD7GsU+GVYPn0WAg5J+17d/j+fHBTR8AMKCmCzWCl/OCCv9LG8baxTOzG7xmxGOnlGHYMikbaNSCSDp3zkd8n6HnxuZ7Tcg7u+m3gHqvzuoCbDyF7xaChWGY+Tv1VRPV9uL4L6Swhh/rIE1jjHE3W/esdTs2o2ECPQUwD0vPIvBZtqlhPifoaJviy2by4IpVwb12q3nzsKzeRLCm1SR1FJrnH/v3L/wGMXPrOIZm1TyqSOz9aiazbdLZzt0DmZFwf+oqXuV3br6fWGiQcSiVO/GYnliPm0U6ETpb2MknKugQ6W7aQQmwWWISHh4LtshC1u6liZ+jYP2Sjher+pv77uvfOzAh5/X85khay1Qbi7aA18yTkWdXFF54TGldOFacGb/FJOJmaC43MEiE/6TKZH7dmPMsO5CNVgrla9Br8C3fwtoU4+kyVoeGHt1FZZsJThQQSCqXyo59WeAGWcd/RGdGR5n2XM/P9n8Al7BD4nIJAceZREdkY0QSXETNkSSf8BxLflJ2QhdbUNTba36Bp80TzL27tNI/h7/fa9ZeZtuorSFOGSbA91e55ZTbmP2fBkXJBpxFgNZuCtu0ZFKtJo51yTtIqr3TzLzEGAs725yN/RWxGvMwnIfOddQtuU2kQpbKPJhXH4wT3d3v/5/DODqvZnZwov14gXV9l1ytWmanQsTZzJtrYbCbu1xPMqZTo5xn/q18jlwxXrD/YXN5u+4aw9PEH70KrensNlM1U1tidMBHZHco0X21OmcJG3R++7zla8yXwBL4volSda20TTCCKX8aKGrJRgon2iGfycaqX380WVGJnu+Da1P8GlxHUebstfDq458idrFy3zBDBR/lShDdHScHDnxrG7wdSWTJvChQVh1uw8bWA1oW7Kb6wS9k4ZNhWi2xfIiGtIcw70z9rFUgdc9AM4qZznk/ZROClugr9dl738CfZ7inC8y4I9F285obMSn2CrT3QGVFGfAX8IJ7xnTTkziqcAECok9mCY38mW2idsbJzcdYDubRumynBfw0pSuPtI4qAayCQ5O0QTTdSXSyLoaHr6CwUYt4uLfAhTgpXa4kkQPpRhvFvnnvSWczC2e95tnYfo/fx/26GwQ2DsKsVs4sYlnmEKAVu36rZTiDnx1c0h9fOxP7ncX/RIJG0XLuh9vE0fRUGB9Nd/HbulfoSlROr4rBHmlgs27jxoeiaMP3r1dj4BzSqk45lzm2PGglaGtyeuassdX4UdzMYBxg158erVDf9F7F2TJ29bG41sneufVl9E7DIYiMF8MXCZ59Q1ockRJR2njWDNv0J70klfEkBW6zd28z9KsxTSHoPWKpnmNK7t/",
592
+ "pubkey": "0869c418f37accb59f93d6e42327004379d49791e6254d5146fcfe0d6be4b924",
593
+ "id": "3f23c4e09dbfdb4c4811452f44457cb087c3a07af141077a45e99fc3e4dc8d1a",
594
+ "sig": "aabcea0169d8435f5fff9e9cf06be75fafd74e2297a3831cc0d3313228225ffabe309450ff6d1252f6808cfd148efee1601a3a868ae139b72a262ae853b5fe58"
595
+ }
596
+ },
597
+ "expected": {
598
+ "decode": {
599
+ "invitation": {
600
+ "bearerHex": "c5f153b74aba3605b5bca1064a3154e18bf32a92e800504d8e060205edec4654",
601
+ "inviter": "b5c5ec78f1eb56c0bd4d73f137c08fc49fc41a22257a95a384e60593cb6ac0bf"
602
+ },
603
+ "requesterSkHex": "87a68ed405197e7910559300549798b288b9215bbcaf5f1d740bb1233bc6691c",
604
+ "request": "a4b8b6d30d5d9e7e5fd3b1f439a50c3632d2b5fd006def614bd88aec9d38b4ae",
605
+ "now": 1799999990
606
+ },
607
+ "result": {
608
+ "secretHex": "3235bdb7cf4e08d8eb9f1441bd2158825c0e84150ac0fc123a106455130eeecf",
609
+ "delegateSkHex": "87a68ed405197e7910559300549798b288b9215bbcaf5f1d740bb1233bc6691c",
610
+ "chain": [
611
+ {
612
+ "invitation": "a652671ef5a7edd3f45a472b7456f1711bcfdfa60cdcbae2c5ff3ba08c86f7ba",
613
+ "room": "2848bdd5c60a79e2dfe667ae9616c1107f61709032b66e556e28f4a96e69450b",
614
+ "issuer": "b5c5ec78f1eb56c0bd4d73f137c08fc49fc41a22257a95a384e60593cb6ac0bf",
615
+ "delegate": "0869c418f37accb59f93d6e42327004379d49791e6254d5146fcfe0d6be4b924",
616
+ "expiresAt": 1800043170,
617
+ "sig": "e9852f80a1b1c75128261ae5204b574a7fe036f37fe18ea20c74192f0082515999659057f0aeab41d73bb948acfd913dd1429877a1f4a13a999a6acf6f170d2a"
618
+ },
619
+ {
620
+ "invitation": "a652671ef5a7edd3f45a472b7456f1711bcfdfa60cdcbae2c5ff3ba08c86f7ba",
621
+ "room": "2848bdd5c60a79e2dfe667ae9616c1107f61709032b66e556e28f4a96e69450b",
622
+ "issuer": "0869c418f37accb59f93d6e42327004379d49791e6254d5146fcfe0d6be4b924",
623
+ "delegate": "bea24e3c816957292748b718431d23eb94e2529633aa36840ad70fbb3f44228b",
624
+ "expiresAt": 1800043170,
625
+ "sig": "47252b0e802ba92107d70d2005d3612157b3b1a6a442d645eb7724f66c553bbc165b04c6c6a9324165ebe3c5ab75e3c22cfe1f1372c52f0df4da1d0e6629d246"
626
+ }
627
+ ],
628
+ "epoch": 0
629
+ },
630
+ "chainVerifiesTo": "bea24e3c816957292748b718431d23eb94e2529633aa36840ad70fbb3f44228b"
631
+ }
632
+ },
633
+ {
634
+ "name": "delegation-chain-tampered-second-hop",
635
+ "kind": "negative",
636
+ "note": "The two-hop chain above with hop 2's signature zeroed out. The whole chain is refused - a member cannot forge the last hop and admit themselves.",
637
+ "input": {
638
+ "chain": [
639
+ {
640
+ "invitation": "a652671ef5a7edd3f45a472b7456f1711bcfdfa60cdcbae2c5ff3ba08c86f7ba",
641
+ "room": "2848bdd5c60a79e2dfe667ae9616c1107f61709032b66e556e28f4a96e69450b",
642
+ "issuer": "b5c5ec78f1eb56c0bd4d73f137c08fc49fc41a22257a95a384e60593cb6ac0bf",
643
+ "delegate": "0869c418f37accb59f93d6e42327004379d49791e6254d5146fcfe0d6be4b924",
644
+ "expiresAt": 1800043170,
645
+ "sig": "e9852f80a1b1c75128261ae5204b574a7fe036f37fe18ea20c74192f0082515999659057f0aeab41d73bb948acfd913dd1429877a1f4a13a999a6acf6f170d2a"
646
+ },
647
+ {
648
+ "invitation": "a652671ef5a7edd3f45a472b7456f1711bcfdfa60cdcbae2c5ff3ba08c86f7ba",
649
+ "room": "2848bdd5c60a79e2dfe667ae9616c1107f61709032b66e556e28f4a96e69450b",
650
+ "issuer": "0869c418f37accb59f93d6e42327004379d49791e6254d5146fcfe0d6be4b924",
651
+ "delegate": "bea24e3c816957292748b718431d23eb94e2529633aa36840ad70fbb3f44228b",
652
+ "expiresAt": 1800043170,
653
+ "sig": "00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"
654
+ }
655
+ ]
656
+ },
657
+ "output": {
658
+ "result": null
659
+ }
660
+ },
661
+ {
662
+ "name": "delegation-hop-wrong-issuer-refused",
663
+ "kind": "negative",
664
+ "note": "M5: hop 2 carries a genuine, validly-verifying schnorr signature - by IMPOSTOR_SK, a real keypair unrelated to this invitation - but IMPOSTOR is not hop 1's delegate (DELEGATE_A is). `verifyInvitationDelegation` walks the chain checking each hop's issuer against the PREVIOUS hop's delegate, so a validly-signed hop from the wrong signer is refused; only checking each hop's own signature in isolation would accept it.",
665
+ "input": {
666
+ "chain": [
667
+ {
668
+ "invitation": "a652671ef5a7edd3f45a472b7456f1711bcfdfa60cdcbae2c5ff3ba08c86f7ba",
669
+ "room": "2848bdd5c60a79e2dfe667ae9616c1107f61709032b66e556e28f4a96e69450b",
670
+ "issuer": "b5c5ec78f1eb56c0bd4d73f137c08fc49fc41a22257a95a384e60593cb6ac0bf",
671
+ "delegate": "0869c418f37accb59f93d6e42327004379d49791e6254d5146fcfe0d6be4b924",
672
+ "expiresAt": 1800043170,
673
+ "sig": "e9852f80a1b1c75128261ae5204b574a7fe036f37fe18ea20c74192f0082515999659057f0aeab41d73bb948acfd913dd1429877a1f4a13a999a6acf6f170d2a"
674
+ },
675
+ {
676
+ "invitation": "a652671ef5a7edd3f45a472b7456f1711bcfdfa60cdcbae2c5ff3ba08c86f7ba",
677
+ "room": "2848bdd5c60a79e2dfe667ae9616c1107f61709032b66e556e28f4a96e69450b",
678
+ "issuer": "1fbe70713a2cb13328af07c3b3ac722f685a9ffb17de5c5e20de97a351e0907d",
679
+ "delegate": "bea24e3c816957292748b718431d23eb94e2529633aa36840ad70fbb3f44228b",
680
+ "expiresAt": 1800001800,
681
+ "sig": "43b0a6614c95521dfc0528c55090dee0df9d7a8b87b0caff5aec0df86e1061df05605366074165c12e669770184cdd40916260c527f2901bd18354d6946d9e46"
682
+ }
683
+ ],
684
+ "forgedByPubkey": "1fbe70713a2cb13328af07c3b3ac722f685a9ffb17de5c5e20de97a351e0907d"
685
+ },
686
+ "output": {
687
+ "result": null
688
+ }
689
+ },
690
+ {
691
+ "name": "grant-signer-not-final-issuer-refused",
692
+ "kind": "negative",
693
+ "note": "M9: the outer event is REALLY signed by IMPOSTOR_SK (a genuine schnorr signature that verifies), and the NIP-44 content REALLY decrypts under the requester's real conversation key with IMPOSTOR - but the delegation chain inside names DELEGATE_A as its final issuer. `decodeRoomAdmissionGrant` checks `body.delegation.at(-1).issuer` against `event.pubkey` and refuses the mismatch; without it, anybody could wrap somebody else's real, valid delegation chain in an event of their own and be believed.",
694
+ "input": {
695
+ "event": {
696
+ "kind": 20467,
697
+ "created_at": 1799999990,
698
+ "tags": [
699
+ [
700
+ "d",
701
+ "a652671ef5a7edd3f45a472b7456f1711bcfdfa60cdcbae2c5ff3ba08c86f7ba"
702
+ ],
703
+ [
704
+ "p",
705
+ "bea24e3c816957292748b718431d23eb94e2529633aa36840ad70fbb3f44228b"
706
+ ]
707
+ ],
708
+ "content": "Av/FgtG9DE+JB5SA0aGBjRB5lbRlzJ4KzXuGMFEXNDC4uL5PRnEDDMvYjZ2UC6s01EIjJh7JgRH9iLgtZTvsXxwUfJfOwF9xdsMsND9/99TLbp36siiAi8IfjqYzeg0UyNcuafCMbfJTKLBea8s/3YwPs9vySOe8Vcs8b3XDRqhEM6KilEET4ArO+NyocH3Oy/8bzlZ+PvriNfkvxd/A6k9CutqfsEyhjTATjJrjCARtpHTkArW2Hdyih6r6g0Bvxu+LfkKj0zoLAyvijxRMtC41yI5Ju3GTl53GTWQG7WZ9UpA+qX2G0CcKCddIx1Z5btFNb6wK383lC30hhkhGsTW4rT0biRD5EEZjXOcc/RX3QjmsdmzjOQdBhyc9RTXjFHJSF7pxaYUJO1AAlw49Er01CALb3TL71Uaa2dNeeiCr0GzHVXNqBeM10T5PiHYQmnPbsnQp7CjW1oweSnqnFdJLEv8COFKLf0+BYuxPQvRFPJiPZ6stmbbHrTMCuvXtcb+NjyT0+noPwdKPIRqBbD//G9R0MeJtvV3ORaJp3COehmVKLjFu/tHDLClS4Xu0179BG7FLC/sOnh1kMZHKx5YgdLcNeD0wr8f3VTkBLn72FVEC8qR9gUXzdt8MgpYfulToXeR09sF/gJSH/LUSJwv6IHK0X/pC2TfZjyPhzx2sMzZUPmm2lRAwmamcSgLXcDstI+THKBHuuuTZpFi+wJHa6iALiUQjnm9Zg/Dpvw4QAU6lGDWeWH9MA3qWuaApPXfaOk+UCifflI3Mb/7hVmt3bXXHGbXVZIDoHVfcSyxnKHj/EV1UITcYvicqixk/cTZOEE7A5c28MforH2Q/wqFv5NFKI5ttHEGIRjPg9L+YANCBwXCO5DiVtncJZRVsAANPnOySHi9CNytlxwZGLzlB6sx9XjHyEZkhOxgE1QuX2GEZfEGZenGqH3UYveThRTF+kx/bUH5/TmXaRjPfj8bWldlmxqJKoPb0ZOCOJ89TtC76mVssNlT4sW6yZ/01cCtJWYK7WVI69bJA/Y0yfBVCuAOsrf0zs9fyiHr8jM3aFiVnVVORPV/au3ZTcv9Ynw8L4iL7nhUog2/nnxWczbpS0JkJQd3BDF5zACdrQZYVBk94BKcBPymmSiDm+BGW2HZ/03Y6RfwSyotzLRblgKZuD9841KDYQcemJFwUnq1cJDw/bjEiGs2M3vDIDpqi4xO5HburNNL+aRgMxLeeAzyQ9KK2fznMluoGQQx2QztNPtx2VhbzWrxPTIuK9ubZj04qivCPzpK4T4UvKeUzAeAJAXe7urthMZqVxly6sW7NJRyuSaNL3ZHi7pWgWKhrVqQgxZER0OZ27A41oXRlP2zIBWxQs4kBHyAnsM4pjljq3TTtp6L6CqsKYvV4v90tX/6ro4DevZ4Mvg4ZkPzUqBGwbSHd1WD0G037flQ9b2oswTeNGW5k2AhwQV1tRc9gRKjQl3Q/KbOscn588tW8OiktnjYxdtwCAq33K4WER1ORzpDGxdGqf0cjGjKj/KVjff2UdiRBeE9VmQDu5OnvXNNIDo62w2ZgFKCdM+e/nmvH975E8NoR6G6AfI4eCyiqyjZ73Iq1kJY7F9bNnXEDn+yPI4I8/4lAtftwssiVdvkMt5MntgkdOZJFZ8A6Eo5SFrHRRuofg4To/BFb8707r1YmkcAw+ghwso0ZiSylXaUcljsXleon0qO1avTSbClFObczBqz6XxcN4qYCR2kkHmyUOOrsy6tsWd4LrObR5jB2biI9L46JESVhJJZ5J7tv/O8K",
709
+ "pubkey": "1fbe70713a2cb13328af07c3b3ac722f685a9ffb17de5c5e20de97a351e0907d",
710
+ "id": "2c44f8ac11a6d9c942b066ed721882d6355b731e7bfa63dcffb5fd70483f2262",
711
+ "sig": "afd3314b9450c933529564c5bce4f546d5110c7950c64d7c92ee0a205a9d8960d65b923959a5b264cbe969278fa55d0266aadbdf4992c50fbd7f385a23e5986c"
712
+ },
713
+ "body": {
714
+ "v": 2,
715
+ "request": "a4b8b6d30d5d9e7e5fd3b1f439a50c3632d2b5fd006def614bd88aec9d38b4ae",
716
+ "secret": "MjW9t89OCNjrnxRBvSFYglwOhBUKwPwSOhBkVRMO7s8",
717
+ "delegation": [
718
+ {
719
+ "invitation": "a652671ef5a7edd3f45a472b7456f1711bcfdfa60cdcbae2c5ff3ba08c86f7ba",
720
+ "room": "2848bdd5c60a79e2dfe667ae9616c1107f61709032b66e556e28f4a96e69450b",
721
+ "issuer": "b5c5ec78f1eb56c0bd4d73f137c08fc49fc41a22257a95a384e60593cb6ac0bf",
722
+ "delegate": "0869c418f37accb59f93d6e42327004379d49791e6254d5146fcfe0d6be4b924",
723
+ "expiresAt": 1800043170,
724
+ "sig": "e9852f80a1b1c75128261ae5204b574a7fe036f37fe18ea20c74192f0082515999659057f0aeab41d73bb948acfd913dd1429877a1f4a13a999a6acf6f170d2a"
725
+ },
726
+ {
727
+ "invitation": "a652671ef5a7edd3f45a472b7456f1711bcfdfa60cdcbae2c5ff3ba08c86f7ba",
728
+ "room": "2848bdd5c60a79e2dfe667ae9616c1107f61709032b66e556e28f4a96e69450b",
729
+ "issuer": "0869c418f37accb59f93d6e42327004379d49791e6254d5146fcfe0d6be4b924",
730
+ "delegate": "bea24e3c816957292748b718431d23eb94e2529633aa36840ad70fbb3f44228b",
731
+ "expiresAt": 1800043170,
732
+ "sig": "47252b0e802ba92107d70d2005d3612157b3b1a6a442d645eb7724f66c553bbc165b04c6c6a9324165ebe3c5ab75e3c22cfe1f1372c52f0df4da1d0e6629d246"
733
+ }
734
+ ],
735
+ "epoch": 0
736
+ },
737
+ "actualSigner": "1fbe70713a2cb13328af07c3b3ac722f685a9ffb17de5c5e20de97a351e0907d"
738
+ },
739
+ "output": {
740
+ "result": null
741
+ }
742
+ },
743
+ {
744
+ "name": "grant-secret-room-mismatch-refused",
745
+ "kind": "negative",
746
+ "note": "M19: genuinely signed by the real root inviter, carrying the real hop-1 delegation chain (rooted and bound to fx.ROOM_SECRET_1's room) - but the sealed secret is fx.ROOM_SECRET_2's, a different room entirely. `decodeRoomAdmissionGrant` checks `body.delegation[0].room` against `deriveRoom(secret).roomId` and refuses the mismatch; without it, a chain authorised for one room could be reused to open a different one.",
747
+ "input": {
748
+ "event": {
749
+ "kind": 20467,
750
+ "created_at": 1799999970,
751
+ "tags": [
752
+ [
753
+ "d",
754
+ "a652671ef5a7edd3f45a472b7456f1711bcfdfa60cdcbae2c5ff3ba08c86f7ba"
755
+ ],
756
+ [
757
+ "p",
758
+ "0869c418f37accb59f93d6e42327004379d49791e6254d5146fcfe0d6be4b924"
759
+ ]
760
+ ],
761
+ "content": "AvwNXhVAKPureLAXbAvHEuFb8fA1vgYXlvlOlN/hNj+6UO9FMmwtys43bjy4YzPU1iuTTgFm0/yyPgcZxfdoqORzAEU8zpT1uAKf4ufhnOi8EsE7Y9kJ2wxxr0THLnIvwjAMt8yC4i+4nn2AqO3Ft2CSI/3bOfqsz/YtuK7/lzW465SDvQprpi07eUVjiP555CYYb/LuARL64Ix8MI7TGh8HOXmPP1ILdGw3YNXQj3NOLzX7vohXOgL1TYsYnp+jCikgOiaWw02IIqC37aT0H8zWWob862Ai8d9mmwNw/ensg+R06c1maEKVbu5GFTkO89i8oBwYW/BupCwrWaus+HJ68exQ4VO0G2WrS+D0JFJOzccREjPUnaEhhFjnaQ/1roH1P004q6JttOUy1yIBYeHWiEV7iZtloWc0xjNjS3+tcAJzexT2bg2FuYBpX5SC0M7U3djqPyGXUayLKOm/c4qPX4iJ3e4g7muz5lgQW5Y4HY26UzbvcPqniZqFDxoGGn4Mi0NPoAYZsVBuGRg0wNCGh6xGEZiuChXqaJ8NcziINTnAc03oRkDks5w8ZW1TpN4SMCHxwsbwUK973WNH43+vUJJlzHpqS4e8UZBxwhdlUBLxUl9+Hc7GVJRm25mfCWMr+70hGaaTWhgZlTjfAUJ/trYXMhb+Y9+rB9qJqYTf5YZF7o37P3UXTKWaf5rlvyJVf8+zgwX16ibvBf/D7Iit5VvwC7TGL1bVUYbILuq/uzo/8o3AgpyG6MY39NvAvTqJpXQhlPicTI/BNzUfn/BLoIJH6/vil2wbBecPaVnLxqr90vjnK8Sfo1I4fqB+7pZvqt9J65etX0l4/GM0M30eaBPmKtR+HHjFfzM8vfjzi3xpZN4MPDH1m5ZY5CLE4K8rpaYvSAdMsaSwunP487K+oI3h0bLwlCE1gTIKxiZknmA=",
762
+ "pubkey": "b5c5ec78f1eb56c0bd4d73f137c08fc49fc41a22257a95a384e60593cb6ac0bf",
763
+ "id": "46b9d452a4d4bf6c2f6668ad07ea2dd297c64dfef6bd8f5f7a565e2615d9ba5f",
764
+ "sig": "c9123d34878335db2a96c2ea4e6492fda9871f27a01cabe93c879f8b615593e4cf10b2c6d83bd9fd13dbed1762ee4abd10a1c3c124331a23e99257bee88346fb"
765
+ },
766
+ "body": {
767
+ "v": 2,
768
+ "request": "e17feb5ae4f0b873cd53dafac3c1080b043bec807b1ceec56ce32eb9f5db930c",
769
+ "secret": "1l6jjWVicNnuvLlJdZ3sRZnK3jIL1TzyvOMB4sI_1y0",
770
+ "delegation": [
771
+ {
772
+ "invitation": "a652671ef5a7edd3f45a472b7456f1711bcfdfa60cdcbae2c5ff3ba08c86f7ba",
773
+ "room": "2848bdd5c60a79e2dfe667ae9616c1107f61709032b66e556e28f4a96e69450b",
774
+ "issuer": "b5c5ec78f1eb56c0bd4d73f137c08fc49fc41a22257a95a384e60593cb6ac0bf",
775
+ "delegate": "0869c418f37accb59f93d6e42327004379d49791e6254d5146fcfe0d6be4b924",
776
+ "expiresAt": 1800043170,
777
+ "sig": "e9852f80a1b1c75128261ae5204b574a7fe036f37fe18ea20c74192f0082515999659057f0aeab41d73bb948acfd913dd1429877a1f4a13a999a6acf6f170d2a"
778
+ }
779
+ ],
780
+ "epoch": 0
781
+ },
782
+ "chainRoom": "2848bdd5c60a79e2dfe667ae9616c1107f61709032b66e556e28f4a96e69450b",
783
+ "secretDerivesToRoom": "fcdc853ddc1be7f7d978367e1a5156b55f11e4c22a49db949f5bb939a303762a"
784
+ },
785
+ "output": {
786
+ "result": null
787
+ }
788
+ },
789
+ {
790
+ "name": "grant-delegation-expired-refused",
791
+ "kind": "negative",
792
+ "note": "M21: hop 1's real, validly-signed delegation names an expiry of 1800043170. Checked one second after that instant, the whole chain is refused - an expired hop is no hop, however good its signature.",
793
+ "input": {
794
+ "chain": [
795
+ {
796
+ "invitation": "a652671ef5a7edd3f45a472b7456f1711bcfdfa60cdcbae2c5ff3ba08c86f7ba",
797
+ "room": "2848bdd5c60a79e2dfe667ae9616c1107f61709032b66e556e28f4a96e69450b",
798
+ "issuer": "b5c5ec78f1eb56c0bd4d73f137c08fc49fc41a22257a95a384e60593cb6ac0bf",
799
+ "delegate": "0869c418f37accb59f93d6e42327004379d49791e6254d5146fcfe0d6be4b924",
800
+ "expiresAt": 1800043170,
801
+ "sig": "e9852f80a1b1c75128261ae5204b574a7fe036f37fe18ea20c74192f0082515999659057f0aeab41d73bb948acfd913dd1429877a1f4a13a999a6acf6f170d2a"
802
+ }
803
+ ],
804
+ "now": 1800043171
805
+ },
806
+ "output": {
807
+ "result": null
808
+ }
809
+ },
810
+ {
811
+ "name": "retirement-plain",
812
+ "kind": "positive",
813
+ "note": "An ordinary retirement: the link was replaced, not the room ended. Built by calling the real `encodeInvitationRetirement`.",
814
+ "input": {
815
+ "invitation": {
816
+ "bearerHex": "c5f153b74aba3605b5bca1064a3154e18bf32a92e800504d8e060205edec4654",
817
+ "inviter": "b5c5ec78f1eb56c0bd4d73f137c08fc49fc41a22257a95a384e60593cb6ac0bf"
818
+ },
819
+ "inviterSkHex": "251d103ba0f97308ca785a911e558a49ec9006940b235ab4fb12b9fbd492c6a5",
820
+ "createdAt": 1800000100,
821
+ "randomnessQueueHex": [
822
+ "38e9efe888bb9c463cd1a6ed93604b58de99e6882d646e54c39401a8d4387cf8"
823
+ ]
824
+ },
825
+ "output": {
826
+ "event": {
827
+ "kind": 1461,
828
+ "created_at": 1800000100,
829
+ "tags": [
830
+ [
831
+ "d",
832
+ "a652671ef5a7edd3f45a472b7456f1711bcfdfa60cdcbae2c5ff3ba08c86f7ba"
833
+ ]
834
+ ],
835
+ "content": "{\"v\":1}",
836
+ "pubkey": "b5c5ec78f1eb56c0bd4d73f137c08fc49fc41a22257a95a384e60593cb6ac0bf",
837
+ "id": "880531840c250ee3f58e2ce97aa8dca5125a2684d9469e13b0b23feda42ca7b0",
838
+ "sig": "204e8f9685596ab822eaaa92c97c2fc4d3dd902e57409ab1c36844f0b4a5e1188d94b4d189f96beb15a73b7b1f0d8d8ee591ce11346cf122494c78ee65612937"
839
+ }
840
+ },
841
+ "expected": {
842
+ "result": {
843
+ "ended": false
844
+ }
845
+ }
846
+ },
847
+ {
848
+ "name": "retirement-room-ended",
849
+ "kind": "positive",
850
+ "note": "A retirement that also says the room itself was ended, not just this link replaced.",
851
+ "input": {
852
+ "invitation": {
853
+ "bearerHex": "c5f153b74aba3605b5bca1064a3154e18bf32a92e800504d8e060205edec4654",
854
+ "inviter": "b5c5ec78f1eb56c0bd4d73f137c08fc49fc41a22257a95a384e60593cb6ac0bf"
855
+ },
856
+ "inviterSkHex": "251d103ba0f97308ca785a911e558a49ec9006940b235ab4fb12b9fbd492c6a5",
857
+ "createdAt": 1800000100,
858
+ "randomnessQueueHex": [
859
+ "21691ccd0c845ab6f743b4794697c94a56021a25fa34063602fa691adf0867e3"
860
+ ]
861
+ },
862
+ "output": {
863
+ "event": {
864
+ "kind": 1461,
865
+ "created_at": 1800000100,
866
+ "tags": [
867
+ [
868
+ "d",
869
+ "a652671ef5a7edd3f45a472b7456f1711bcfdfa60cdcbae2c5ff3ba08c86f7ba"
870
+ ]
871
+ ],
872
+ "content": "{\"v\":1,\"ended\":true}",
873
+ "pubkey": "b5c5ec78f1eb56c0bd4d73f137c08fc49fc41a22257a95a384e60593cb6ac0bf",
874
+ "id": "c81e4d448b2cc8736fb1c1796006398e3ffeed6dae453b1aaf4fac0bc6db1b70",
875
+ "sig": "8c5047d60d12e08bd1fce0bd70d6592807645d5f3ff5dc7ff056856920b1563ce30fd4b9909b14e442c8ad71218c08ad7bede7d544c79459d8cf388c4d207258"
876
+ }
877
+ },
878
+ "expected": {
879
+ "result": {
880
+ "ended": true
881
+ }
882
+ }
883
+ },
884
+ {
885
+ "name": "retirement-wrong-signer-refused",
886
+ "kind": "negative",
887
+ "note": "A retirement signed by somebody other than the inviter pinned in the link: refused, even though the event itself verifies.",
888
+ "input": {
889
+ "event": {
890
+ "kind": 1461,
891
+ "created_at": 1800000100,
892
+ "tags": [
893
+ [
894
+ "d",
895
+ "a652671ef5a7edd3f45a472b7456f1711bcfdfa60cdcbae2c5ff3ba08c86f7ba"
896
+ ]
897
+ ],
898
+ "content": "{\"v\":1}",
899
+ "pubkey": "cb948cc3faaf18b2db04bc0970c26bc79d56b0f9a32cf0cdb197597f2a6164e1",
900
+ "id": "d30a0cf32c79b0c5b706199137d3bee4ad1641188a1e8b92cddc13f3ecf9d165",
901
+ "sig": "630fcb4e5b1fd1ae91bf878236812877db93f1d81f467d8855f764ea59f60b9c08a8a2308669fc381e4059ad96e72c8648f77f07414bb3e0f5d4d0b930f09260"
902
+ }
903
+ },
904
+ "output": {
905
+ "result": null
906
+ }
907
+ }
908
+ ],
909
+ "persistentInvitation": [
910
+ {
911
+ "name": "valid",
912
+ "kind": "positive",
913
+ "note": "A stored group invitation (kind 1463), published once and readable weeks later with nobody online. Built by calling the real `encodePersistentInvitation`.",
914
+ "input": {
915
+ "invitation": {
916
+ "bearerHex": "fe6a6ac8150838c9b16e1bec51ee1006210d73bbaa7530ed7029907f15ed0645",
917
+ "inviter": "b5c5ec78f1eb56c0bd4d73f137c08fc49fc41a22257a95a384e60593cb6ac0bf"
918
+ },
919
+ "inviterSkHex": "251d103ba0f97308ca785a911e558a49ec9006940b235ab4fb12b9fbd492c6a5",
920
+ "roomSecretHex": "3235bdb7cf4e08d8eb9f1441bd2158825c0e84150ac0fc123a106455130eeecf",
921
+ "createdAt": 1797408000,
922
+ "randomnessQueueHex": [
923
+ "8bf9a9191fefbadaf122e0dd8dffdf2120d2769575aa35515810d1821af8b0d8",
924
+ "61bda7113bc18d3ab3d75a49c44f99e9720b6f5a29e3f7409f0c6d82f0b5fa79"
925
+ ]
926
+ },
927
+ "output": {
928
+ "event": {
929
+ "kind": 1463,
930
+ "created_at": 1797408000,
931
+ "tags": [
932
+ [
933
+ "d",
934
+ "6ed1ec2f259cf24b084ff980423a112fc7b5e4407c933836cca0c2a64a1189a3"
935
+ ]
936
+ ],
937
+ "content": "Aov5qRkf77ra8SLg3Y3/3yEg0naVdao1UVgQ0YIa+LDYu1YThimv8PPsLeOMBRB+6T39yZVh/3TEwS+jbDyfngQaxc7HXgY9krKnRLj7qmaWWzSeiETKDvtb0KcSpZhO+PTHcWFshByvdwc6GjzZBErFRIrTcAVJZMKZ0pOvbHh9Wu/Tm5vF6MyEqVmZxwi1N0fzsAFrrPTGpiMTN3kIal8BZVlbgHDXJ3tcmZZXXZieYA3NGVp6+wedc0I7/xFKdgCm0js8GJ9ax2FMfEELKq6uwucnrUkV6D7sYqZgPaFWZDo=",
938
+ "pubkey": "b5c5ec78f1eb56c0bd4d73f137c08fc49fc41a22257a95a384e60593cb6ac0bf",
939
+ "id": "ed024a9678e2ec1727ecdb8c2fda35574d4908948a36809ab710151724a54e66",
940
+ "sig": "ed8b713e38a01d8ab31fc9b51a54538a7bed94c0e52fe8448122271fef1b2c07406fa925251477afbd13667f59eaba58245aec95ef9746668256a37dd16873c4"
941
+ }
942
+ },
943
+ "expected": {
944
+ "result": {
945
+ "secretHex": "3235bdb7cf4e08d8eb9f1441bd2158825c0e84150ac0fc123a106455130eeecf",
946
+ "persistent": true,
947
+ "epoch": 0
948
+ }
949
+ }
950
+ },
951
+ {
952
+ "name": "tampered-ciphertext-refused",
953
+ "kind": "negative",
954
+ "note": "The valid event above with its final ciphertext bytes flipped: NIP-44's MAC check fails and the decoder must return null.",
955
+ "input": {
956
+ "event": {
957
+ "kind": 1463,
958
+ "created_at": 1797408000,
959
+ "tags": [
960
+ [
961
+ "d",
962
+ "6ed1ec2f259cf24b084ff980423a112fc7b5e4407c933836cca0c2a64a1189a3"
963
+ ]
964
+ ],
965
+ "content": "Aov5qRkf77ra8SLg3Y3/3yEg0naVdao1UVgQ0YIa+LDYu1YThimv8PPsLeOMBRB+6T39yZVh/3TEwS+jbDyfngQaxc7HXgY9krKnRLj7qmaWWzSeiETKDvtb0KcSpZhO+PTHcWFshByvdwc6GjzZBErFRIrTcAVJZMKZ0pOvbHh9Wu/Tm5vF6MyEqVmZxwi1N0fzsAFrrPTGpiMTN3kIal8BZVlbgHDXJ3tcmZZXXZieYA3NGVp6+wedc0I7/xFKdgCm0js8GJ9ax2FMfEELKq6uwucnrUkV6D7sYqZgPaFWAAAA",
966
+ "pubkey": "b5c5ec78f1eb56c0bd4d73f137c08fc49fc41a22257a95a384e60593cb6ac0bf",
967
+ "id": "ed024a9678e2ec1727ecdb8c2fda35574d4908948a36809ab710151724a54e66",
968
+ "sig": "ed8b713e38a01d8ab31fc9b51a54538a7bed94c0e52fe8448122271fef1b2c07406fa925251477afbd13667f59eaba58245aec95ef9746668256a37dd16873c4"
969
+ }
970
+ },
971
+ "output": {
972
+ "result": null
973
+ }
974
+ },
975
+ {
976
+ "name": "non-persistent-invitation-refused",
977
+ "kind": "negative",
978
+ "note": "The same event, decoded against the same bearer and inviter but without the `persistent` flag set: refused - a v2 (live) invitation must never be readable as a stored v3 group welcome.",
979
+ "input": {
980
+ "event": {
981
+ "kind": 1463,
982
+ "created_at": 1797408000,
983
+ "tags": [
984
+ [
985
+ "d",
986
+ "6ed1ec2f259cf24b084ff980423a112fc7b5e4407c933836cca0c2a64a1189a3"
987
+ ]
988
+ ],
989
+ "content": "Aov5qRkf77ra8SLg3Y3/3yEg0naVdao1UVgQ0YIa+LDYu1YThimv8PPsLeOMBRB+6T39yZVh/3TEwS+jbDyfngQaxc7HXgY9krKnRLj7qmaWWzSeiETKDvtb0KcSpZhO+PTHcWFshByvdwc6GjzZBErFRIrTcAVJZMKZ0pOvbHh9Wu/Tm5vF6MyEqVmZxwi1N0fzsAFrrPTGpiMTN3kIal8BZVlbgHDXJ3tcmZZXXZieYA3NGVp6+wedc0I7/xFKdgCm0js8GJ9ax2FMfEELKq6uwucnrUkV6D7sYqZgPaFWZDo=",
990
+ "pubkey": "b5c5ec78f1eb56c0bd4d73f137c08fc49fc41a22257a95a384e60593cb6ac0bf",
991
+ "id": "ed024a9678e2ec1727ecdb8c2fda35574d4908948a36809ab710151724a54e66",
992
+ "sig": "ed8b713e38a01d8ab31fc9b51a54538a7bed94c0e52fe8448122271fef1b2c07406fa925251477afbd13667f59eaba58245aec95ef9746668256a37dd16873c4"
993
+ },
994
+ "invitationPersistent": false
995
+ },
996
+ "output": {
997
+ "result": null
998
+ }
999
+ },
1000
+ {
1001
+ "name": "room-mismatch-refused",
1002
+ "kind": "negative",
1003
+ "note": "M20: genuinely signed by the real inviter, genuinely encrypted under the real welcome key - but the body's `room` field (fcdc853ddc1be7f7d978367e1a5156b55f11e4c22a49db949f5bb939a303762a) does not match what its own sealed secret derives to (2848bdd5c60a79e2dfe667ae9616c1107f61709032b66e556e28f4a96e69450b). `decodePersistentInvitation` checks `deriveRoom(secret).roomId === body.room` and refuses the mismatch.",
1004
+ "input": {
1005
+ "event": {
1006
+ "kind": 1463,
1007
+ "created_at": 1797408000,
1008
+ "tags": [
1009
+ [
1010
+ "d",
1011
+ "6ed1ec2f259cf24b084ff980423a112fc7b5e4407c933836cca0c2a64a1189a3"
1012
+ ]
1013
+ ],
1014
+ "content": "AhdbTHbAg7mI401kpAn2y9gLtzgANrff/oakuUSw8hWACXnqHwXwCtjtL/A4Eci8agMD+l6o+sPiOOVtU7b0ca/x7ni/H0SYLSbPdzYnx3Gyy+D3Jsz0aV5qaRLNyXLIgFG2iqnjqWg7wbAunGI+pa8msWC/21L5Cntt4BDSNhLuTPtxe/mdG8pYQ6ovO+CFUFnmifglxO9WrmjRM/BSNhF7K00o8dt7F/TXQ/bluxeRwy+6wcanaeuv7miWKYGR4wCuGqEoyzr4Dp/L25ej0EmLfJ0wCPdiSBzj3JIWhwTVdYs=",
1015
+ "pubkey": "b5c5ec78f1eb56c0bd4d73f137c08fc49fc41a22257a95a384e60593cb6ac0bf",
1016
+ "id": "216b6c7d975b5d84a77395e6d4bdd8ea79511a485e4d288f182726cfe8e65a03",
1017
+ "sig": "ff5330a79c395d81213bd5e5ef610c0b973b46d1c9c82b9b2d8027eb80b33c9a6a71d6ad5971d30ce951ee7f1c691a982193ed0fd15f6e11c30ccc75e030b6a6"
1018
+ },
1019
+ "roomInBody": "fcdc853ddc1be7f7d978367e1a5156b55f11e4c22a49db949f5bb939a303762a",
1020
+ "roomFromSecret": "2848bdd5c60a79e2dfe667ae9616c1107f61709032b66e556e28f4a96e69450b"
1021
+ },
1022
+ "output": {
1023
+ "result": null
1024
+ }
1025
+ },
1026
+ {
1027
+ "name": "wrong-signer-refused",
1028
+ "kind": "negative",
1029
+ "note": "N7: genuinely signed and genuinely encrypted (the SAME bearer as INVITATION_3, so the same welcome key and `d` tag) - but by OTHER_INVITER_SK rather than the pinned inviter. `decodePersistentInvitation` (persistent-invitation.ts:49) checks `event.pubkey === invitation.inviter` and refuses: holding the bearer is not authority to publish as the inviter.",
1030
+ "input": {
1031
+ "event": {
1032
+ "kind": 1463,
1033
+ "created_at": 1797408000,
1034
+ "tags": [
1035
+ [
1036
+ "d",
1037
+ "6ed1ec2f259cf24b084ff980423a112fc7b5e4407c933836cca0c2a64a1189a3"
1038
+ ]
1039
+ ],
1040
+ "content": "AhWNtyV9JmzgrVGWT3x2PTuSFxJAZqtC2i+LWN+16lzDN9XZeZ5CK7kOc62oWMGnwDPmyc/9ta3qhSFk1vM9UGTzkdijGF8sz4SGLg0c/mzyTNoDhHzaLnd/oVquD+ohxJZy6o9xjQV3QSEK81x1cDI6UTNK5qZRYPqKD2LM3UVmKqL3VJndlf5N4B3JDCkWyEQdw2oaWVYcApwpdxtkxrjsLcjMgQaAoaTwrwfCR6ErPqGTzL1XVMDwrEl+0ptRjNh/obWGNhAVMWO+5MF8KivIn1dSt1zTqkP/XVjSPQCOwew=",
1041
+ "pubkey": "cb948cc3faaf18b2db04bc0970c26bc79d56b0f9a32cf0cdb197597f2a6164e1",
1042
+ "id": "e695387048ea034b5663f07c0a74fb4275e0e842f094473b3c512ea9672ad558",
1043
+ "sig": "e98c97ca4554b45400f96d1652cd5c12bd6be463989f576d90031d59cbac8f9a7a5befd383e67ace6563e35053560455010245a4c7f473d3b7a2ef20a758c0fe"
1044
+ },
1045
+ "actualSigner": "cb948cc3faaf18b2db04bc0970c26bc79d56b0f9a32cf0cdb197597f2a6164e1",
1046
+ "actualSignerSkHex": "ae14893547df6477321935808b939d737035acf2013e84731dc9931b445c6c61",
1047
+ "bearerHex": "fe6a6ac8150838c9b16e1bec51ee1006210d73bbaa7530ed7029907f15ed0645",
1048
+ "roomSecretHex": "3235bdb7cf4e08d8eb9f1441bd2158825c0e84150ac0fc123a106455130eeecf",
1049
+ "createdAt": 1797408000,
1050
+ "randomnessQueueHex": [
1051
+ "158db7257d266ce0ad51964f7c763d3b9217124066ab42da2f8b58dfb5ea5cc3",
1052
+ "19b025f0e56f8b711fda5c92e8b8cfc45b92fd879e77bd23a606a793248c689f"
1053
+ ]
1054
+ },
1055
+ "output": {
1056
+ "result": null
1057
+ }
1058
+ }
1059
+ ],
1060
+ "epochGrant": [
1061
+ {
1062
+ "name": "grant-with-secret-at-epoch-1",
1063
+ "kind": "positive",
1064
+ "note": "The authority answers a caught-up request: the room has moved to epoch 1, and the secret that opens it is sealed to the asking device. Built by calling the real `encodeEpochGrant`.",
1065
+ "input": {
1066
+ "roomId": "2848bdd5c60a79e2dfe667ae9616c1107f61709032b66e556e28f4a96e69450b",
1067
+ "authoritySkHex": "e407c0989f606d8165f63d104e1674a462b191e1df99a29ae9be3f2907deca32",
1068
+ "authority": "47ab2a9f89f155b277f1e847d7d4eba664d28324ee903ffc051bdc9e14869f86",
1069
+ "device": "fcd74d122f0a212a673839482f69ad973f6d38735faeeb3e57929c2b916492fe",
1070
+ "deviceSkHex": "751627289895e0df520a348eed03006ac69522989ce970c8a4926268de6f69de",
1071
+ "request": "287540adb10059739e98e187d5cc2bb4ea4cb795b8621e29b68d75b3a7f919b2",
1072
+ "createdAt": 1799999950,
1073
+ "epoch": 1,
1074
+ "secretHex": "3d3480782bd9eabca24b6f9a541531aa2ca4dc535342d8abf1c2347d58ab26cb",
1075
+ "removed": [
1076
+ "5defbe2990a67eb3589071a06ddf03c405276fa90373f9028be03b8fdc666428"
1077
+ ],
1078
+ "randomnessQueueHex": [
1079
+ "c813887618a0763964f1a2a6d2bb03619b31fc1fb52abba11b771ccb1c7fc8d3",
1080
+ "8280023fb5c6ece513190e157577b3f266f66c9b90e05493473ac270cbacdb33"
1081
+ ]
1082
+ },
1083
+ "output": {
1084
+ "event": {
1085
+ "kind": 20469,
1086
+ "created_at": 1799999950,
1087
+ "tags": [
1088
+ [
1089
+ "d",
1090
+ "2848bdd5c60a79e2dfe667ae9616c1107f61709032b66e556e28f4a96e69450b"
1091
+ ],
1092
+ [
1093
+ "p",
1094
+ "fcd74d122f0a212a673839482f69ad973f6d38735faeeb3e57929c2b916492fe"
1095
+ ]
1096
+ ],
1097
+ "content": "AsgTiHYYoHY5ZPGiptK7A2GbMfwftSq7oRt3HMscf8jTM89VlEdtW+5ApFpOKm8E6jmGpLlB4ouraLex3RPbKdvKLD18tM4iWTvDB1lA6xSWTddCZUq6LrKptED6Nduapq4ut5SZNyYXWQLLQpbYYcTjegiUPAgHq74/yA99uj53aZQvH/oEp2CfhnI3AEVEX9VEIBjD8JAftiN0gdWq6o9MqaV7LAFCJqgvi035tk0lwIQuIEE+fwR8BwTKVFnhcV+sBLti8zwHhlv8qxsz6FhMtjJiFGfFM/JxFrt2c2bMnX7jxwhjnX3Ik+Wg6Yqiab1zIokUpdv38yHHLuNtK5SFTFn3evAm0yBWtIVbadwUSQqI11kKyQlXf0Huy6V/uM0Hbg5CBUZoBQUv43HMqi4v9spwMp+cVUQ9ARUaHwhvHfM=",
1098
+ "pubkey": "47ab2a9f89f155b277f1e847d7d4eba664d28324ee903ffc051bdc9e14869f86",
1099
+ "id": "12c6e9ae0b3ffd359f09dbde9f0d5a923738e5bdc6aa699b6eaf57054f116fd1",
1100
+ "sig": "6ae258a5fd26d7f9822463ee898db95857b7ff15182e0b33bfc2b7c930c70801f0e1366a61733697100f395f9ab0ceb6c612c17a45705fcf80eee12df762667d"
1101
+ }
1102
+ },
1103
+ "expected": {
1104
+ "result": {
1105
+ "epoch": {
1106
+ "epoch": 1,
1107
+ "secretHex": "3d3480782bd9eabca24b6f9a541531aa2ca4dc535342d8abf1c2347d58ab26cb"
1108
+ },
1109
+ "removed": [
1110
+ "5defbe2990a67eb3589071a06ddf03c405276fa90373f9028be03b8fdc666428"
1111
+ ]
1112
+ }
1113
+ }
1114
+ },
1115
+ {
1116
+ "name": "grant-wrong-request-id-refused",
1117
+ "kind": "negative",
1118
+ "note": "The same event, but the device asked with a different request id than the one the grant answers: refused.",
1119
+ "input": {
1120
+ "event": {
1121
+ "kind": 20469,
1122
+ "created_at": 1799999950,
1123
+ "tags": [
1124
+ [
1125
+ "d",
1126
+ "2848bdd5c60a79e2dfe667ae9616c1107f61709032b66e556e28f4a96e69450b"
1127
+ ],
1128
+ [
1129
+ "p",
1130
+ "fcd74d122f0a212a673839482f69ad973f6d38735faeeb3e57929c2b916492fe"
1131
+ ]
1132
+ ],
1133
+ "content": "AsgTiHYYoHY5ZPGiptK7A2GbMfwftSq7oRt3HMscf8jTM89VlEdtW+5ApFpOKm8E6jmGpLlB4ouraLex3RPbKdvKLD18tM4iWTvDB1lA6xSWTddCZUq6LrKptED6Nduapq4ut5SZNyYXWQLLQpbYYcTjegiUPAgHq74/yA99uj53aZQvH/oEp2CfhnI3AEVEX9VEIBjD8JAftiN0gdWq6o9MqaV7LAFCJqgvi035tk0lwIQuIEE+fwR8BwTKVFnhcV+sBLti8zwHhlv8qxsz6FhMtjJiFGfFM/JxFrt2c2bMnX7jxwhjnX3Ik+Wg6Yqiab1zIokUpdv38yHHLuNtK5SFTFn3evAm0yBWtIVbadwUSQqI11kKyQlXf0Huy6V/uM0Hbg5CBUZoBQUv43HMqi4v9spwMp+cVUQ9ARUaHwhvHfM=",
1134
+ "pubkey": "47ab2a9f89f155b277f1e847d7d4eba664d28324ee903ffc051bdc9e14869f86",
1135
+ "id": "12c6e9ae0b3ffd359f09dbde9f0d5a923738e5bdc6aa699b6eaf57054f116fd1",
1136
+ "sig": "6ae258a5fd26d7f9822463ee898db95857b7ff15182e0b33bfc2b7c930c70801f0e1366a61733697100f395f9ab0ceb6c612c17a45705fcf80eee12df762667d"
1137
+ },
1138
+ "roomId": "2848bdd5c60a79e2dfe667ae9616c1107f61709032b66e556e28f4a96e69450b",
1139
+ "authority": "47ab2a9f89f155b277f1e847d7d4eba664d28324ee903ffc051bdc9e14869f86",
1140
+ "deviceSkHex": "751627289895e0df520a348eed03006ac69522989ce970c8a4926268de6f69de",
1141
+ "request": "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
1142
+ "now": 1799999950
1143
+ },
1144
+ "output": {
1145
+ "result": null
1146
+ }
1147
+ },
1148
+ {
1149
+ "name": "grant-stale-refused",
1150
+ "kind": "negative",
1151
+ "note": "M18: the same genuinely-signed, genuinely-sealed grant, read 91 seconds after it was made (one past the 90-second window `decodeEpochGrant` allows): refused as stale, the same freshness rule `decodeInvitationRequest` applies.",
1152
+ "input": {
1153
+ "event": {
1154
+ "kind": 20469,
1155
+ "created_at": 1799999950,
1156
+ "tags": [
1157
+ [
1158
+ "d",
1159
+ "2848bdd5c60a79e2dfe667ae9616c1107f61709032b66e556e28f4a96e69450b"
1160
+ ],
1161
+ [
1162
+ "p",
1163
+ "fcd74d122f0a212a673839482f69ad973f6d38735faeeb3e57929c2b916492fe"
1164
+ ]
1165
+ ],
1166
+ "content": "AsgTiHYYoHY5ZPGiptK7A2GbMfwftSq7oRt3HMscf8jTM89VlEdtW+5ApFpOKm8E6jmGpLlB4ouraLex3RPbKdvKLD18tM4iWTvDB1lA6xSWTddCZUq6LrKptED6Nduapq4ut5SZNyYXWQLLQpbYYcTjegiUPAgHq74/yA99uj53aZQvH/oEp2CfhnI3AEVEX9VEIBjD8JAftiN0gdWq6o9MqaV7LAFCJqgvi035tk0lwIQuIEE+fwR8BwTKVFnhcV+sBLti8zwHhlv8qxsz6FhMtjJiFGfFM/JxFrt2c2bMnX7jxwhjnX3Ik+Wg6Yqiab1zIokUpdv38yHHLuNtK5SFTFn3evAm0yBWtIVbadwUSQqI11kKyQlXf0Huy6V/uM0Hbg5CBUZoBQUv43HMqi4v9spwMp+cVUQ9ARUaHwhvHfM=",
1167
+ "pubkey": "47ab2a9f89f155b277f1e847d7d4eba664d28324ee903ffc051bdc9e14869f86",
1168
+ "id": "12c6e9ae0b3ffd359f09dbde9f0d5a923738e5bdc6aa699b6eaf57054f116fd1",
1169
+ "sig": "6ae258a5fd26d7f9822463ee898db95857b7ff15182e0b33bfc2b7c930c70801f0e1366a61733697100f395f9ab0ceb6c612c17a45705fcf80eee12df762667d"
1170
+ },
1171
+ "decode": {
1172
+ "roomId": "2848bdd5c60a79e2dfe667ae9616c1107f61709032b66e556e28f4a96e69450b",
1173
+ "authority": "47ab2a9f89f155b277f1e847d7d4eba664d28324ee903ffc051bdc9e14869f86",
1174
+ "deviceSkHex": "751627289895e0df520a348eed03006ac69522989ce970c8a4926268de6f69de",
1175
+ "request": "287540adb10059739e98e187d5cc2bb4ea4cb795b8621e29b68d75b3a7f919b2",
1176
+ "now": 1800000041
1177
+ }
1178
+ },
1179
+ "output": {
1180
+ "result": null
1181
+ }
1182
+ },
1183
+ {
1184
+ "name": "grant-epoch-zero-no-secret",
1185
+ "kind": "positive",
1186
+ "note": "A grant answering \"the room is still at epoch 0\": no secret rides in the body, because the epoch-0 room key is already what the link handed out.",
1187
+ "input": {
1188
+ "roomId": "2848bdd5c60a79e2dfe667ae9616c1107f61709032b66e556e28f4a96e69450b",
1189
+ "authoritySkHex": "e407c0989f606d8165f63d104e1674a462b191e1df99a29ae9be3f2907deca32",
1190
+ "authority": "47ab2a9f89f155b277f1e847d7d4eba664d28324ee903ffc051bdc9e14869f86",
1191
+ "device": "fcd74d122f0a212a673839482f69ad973f6d38735faeeb3e57929c2b916492fe",
1192
+ "deviceSkHex": "751627289895e0df520a348eed03006ac69522989ce970c8a4926268de6f69de",
1193
+ "request": "287540adb10059739e98e187d5cc2bb4ea4cb795b8621e29b68d75b3a7f919b2",
1194
+ "createdAt": 1799999950,
1195
+ "randomnessQueueHex": [
1196
+ "4795a4da22aba367a0bd5e20ad0ecc293b1173c70bc7eaa7913203683f268b33",
1197
+ "b59b83a97def9f1c46d8efa9673d8caee0812fba4c2b84150e174d97f7116d46"
1198
+ ]
1199
+ },
1200
+ "output": {
1201
+ "event": {
1202
+ "kind": 20469,
1203
+ "created_at": 1799999950,
1204
+ "tags": [
1205
+ [
1206
+ "d",
1207
+ "2848bdd5c60a79e2dfe667ae9616c1107f61709032b66e556e28f4a96e69450b"
1208
+ ],
1209
+ [
1210
+ "p",
1211
+ "fcd74d122f0a212a673839482f69ad973f6d38735faeeb3e57929c2b916492fe"
1212
+ ]
1213
+ ],
1214
+ "content": "AkeVpNoiq6NnoL1eIK0OzCk7EXPHC8fqp5EyA2g/JoszPvtjyBs8pr0HAlMX8nrGszy2LzT9mh4RVqHTDrya6Exto48hCjaJxCnEAb8vayuAf/VDHxRwiFCrwcKpx4boZPWpQb8yBPJW9yBi0P1hGValPy10Igh7FGGMv0aeoW1R7Nn6as+ChhS6Grs0suhDqKZz6wUdsZeVBfGiwjSHrnTsxb+voYLMmFg36zCro6IXah4VtEc3zXA+bYdT3BfPnAUL",
1215
+ "pubkey": "47ab2a9f89f155b277f1e847d7d4eba664d28324ee903ffc051bdc9e14869f86",
1216
+ "id": "a126ccc2559b9cef2ea04f9bbe0adccf0dfe68619337216b14d5d9935df078c9",
1217
+ "sig": "c28c12c7bd1ddabde9ad9a1f80ea1c602262c148c6e0e7f4953c5542cdbe0a0555f2e9d23c026f7d381fbfb3319029b0adfce3c9831cf547f945b5bc099a04c7"
1218
+ }
1219
+ },
1220
+ "expected": {
1221
+ "result": {
1222
+ "epoch": {
1223
+ "epoch": 0
1224
+ },
1225
+ "removed": []
1226
+ }
1227
+ }
1228
+ },
1229
+ {
1230
+ "name": "grant-refused-removed",
1231
+ "kind": "negative",
1232
+ "note": "The authority refuses the epoch request because the device's participant was removed from the room. Sealed like an ordinary grant, so only the asking device learns why.",
1233
+ "input": {
1234
+ "roomId": "2848bdd5c60a79e2dfe667ae9616c1107f61709032b66e556e28f4a96e69450b",
1235
+ "authoritySkHex": "e407c0989f606d8165f63d104e1674a462b191e1df99a29ae9be3f2907deca32",
1236
+ "authority": "47ab2a9f89f155b277f1e847d7d4eba664d28324ee903ffc051bdc9e14869f86",
1237
+ "device": "5defbe2990a67eb3589071a06ddf03c405276fa90373f9028be03b8fdc666428",
1238
+ "deviceSkHex": "f785badbca3915e8138c6bb54bc5cf69e8798485d7ea084daec5bae58db6d9e6",
1239
+ "request": "287540adb10059739e98e187d5cc2bb4ea4cb795b8621e29b68d75b3a7f919b2",
1240
+ "createdAt": 1799999950,
1241
+ "randomnessQueueHex": [
1242
+ "917d2cb1d60554d7d47906cf446d6acc8ab16a87f17b2d16ba7b8ea1182ccad0",
1243
+ "825ad03b5cb99487691ab5a5aa3ce9048d4a073883ca9d307ddac4dd9ab36838"
1244
+ ]
1245
+ },
1246
+ "output": {
1247
+ "event": {
1248
+ "kind": 20469,
1249
+ "created_at": 1799999950,
1250
+ "tags": [
1251
+ [
1252
+ "d",
1253
+ "2848bdd5c60a79e2dfe667ae9616c1107f61709032b66e556e28f4a96e69450b"
1254
+ ],
1255
+ [
1256
+ "p",
1257
+ "5defbe2990a67eb3589071a06ddf03c405276fa90373f9028be03b8fdc666428"
1258
+ ]
1259
+ ],
1260
+ "content": "ApF9LLHWBVTX1HkGz0RtasyKsWqH8XstFrp7jqEYLMrQ/oReYcTUv0i+IYK3NX+TZ1Nw3xXp4ZbVZ5JI1ILmeOs7GLwCcDG370BUAjg9nI56Ry4jLv0hmQ5Dy4s4pBuSe/UfupkNaK6X6PHi+7+O7L92YudIqgvcpFMFY/9g+Tmvoay7odwhGtHTN38iV/vLuQGt9Npp3LhoybLea8cBFeD0BrtepZKhkCfVcUQbweRAANjM6BHbm20F2khUIPQbyHVj",
1261
+ "pubkey": "47ab2a9f89f155b277f1e847d7d4eba664d28324ee903ffc051bdc9e14869f86",
1262
+ "id": "981df1be6fcf57919a857434cf98a5d0858b951aa702656dd0855d4649207319",
1263
+ "sig": "455513c7bca2f3805ab625802493e8e43d425083a3b2774cac6f2b61047db4c4e2b2afc0995c0a6daf94e1158a2841d35bef5dfb2c9b0f11a336930c722e0df2"
1264
+ }
1265
+ },
1266
+ "expected": {
1267
+ "result": {
1268
+ "refused": "removed"
1269
+ }
1270
+ }
1271
+ },
1272
+ {
1273
+ "name": "grant-refused-closed",
1274
+ "kind": "negative",
1275
+ "note": "The authority refuses the epoch request because the device's participant was the room has been closed. Sealed like an ordinary grant, so only the asking device learns why.",
1276
+ "input": {
1277
+ "roomId": "2848bdd5c60a79e2dfe667ae9616c1107f61709032b66e556e28f4a96e69450b",
1278
+ "authoritySkHex": "e407c0989f606d8165f63d104e1674a462b191e1df99a29ae9be3f2907deca32",
1279
+ "authority": "47ab2a9f89f155b277f1e847d7d4eba664d28324ee903ffc051bdc9e14869f86",
1280
+ "device": "5defbe2990a67eb3589071a06ddf03c405276fa90373f9028be03b8fdc666428",
1281
+ "deviceSkHex": "f785badbca3915e8138c6bb54bc5cf69e8798485d7ea084daec5bae58db6d9e6",
1282
+ "request": "287540adb10059739e98e187d5cc2bb4ea4cb795b8621e29b68d75b3a7f919b2",
1283
+ "createdAt": 1799999950,
1284
+ "randomnessQueueHex": [
1285
+ "09c6d6dec8da84f34df923c79eb8f8a52e3b43d1e15c8634b9a1f026cdc352a2",
1286
+ "46dfffd5fa3d38477939ba69e445bc2075579f42b3818d4e1e244fd9ab7d11b5"
1287
+ ]
1288
+ },
1289
+ "output": {
1290
+ "event": {
1291
+ "kind": 20469,
1292
+ "created_at": 1799999950,
1293
+ "tags": [
1294
+ [
1295
+ "d",
1296
+ "2848bdd5c60a79e2dfe667ae9616c1107f61709032b66e556e28f4a96e69450b"
1297
+ ],
1298
+ [
1299
+ "p",
1300
+ "5defbe2990a67eb3589071a06ddf03c405276fa90373f9028be03b8fdc666428"
1301
+ ]
1302
+ ],
1303
+ "content": "AgnG1t7I2oTzTfkjx564+KUuO0PR4VyGNLmh8CbNw1KiCQlZz+yi9Kl6S73oqLm7R3J/mFiFj5+pa13hgPqe3WXTSfYH5+o1fnz2TAaxbfW6CNE6dnL5A9L94wUhpPJHiZGxhpgGeBQqPWk3BbJImQiy+nVoOFP89Bg6jM9XobFyfx3bDdj11KHl5L5e2NWwjyeyr/0vJ3gSCFrrmPQ4v+AYd0A187WjbTdwTkSovHrQcuggXqbbociMv0sr1DCQtZ6Z",
1304
+ "pubkey": "47ab2a9f89f155b277f1e847d7d4eba664d28324ee903ffc051bdc9e14869f86",
1305
+ "id": "7730c8ffde42c8738c67f7d5d842fd8ba7a9037a1008a4c5cf06ee534d922204",
1306
+ "sig": "7c273386568f2aeaa27d2831296bc4f8fe74335aefac5c72a94b0660a0f936956939da71642c97c4d0e16c6e5b2b761b7fafbfa5446a4e6023338a8000bfaee8"
1307
+ }
1308
+ },
1309
+ "expected": {
1310
+ "result": {
1311
+ "refused": "closed"
1312
+ }
1313
+ }
1314
+ },
1315
+ {
1316
+ "name": "grant-wrong-authority-signer-refused",
1317
+ "kind": "negative",
1318
+ "note": "M6: a grant genuinely signed and genuinely sealed by IMPOSTOR_SK - a real keypair, not the room authority. `decodeEpochGrant` checks `event.pubkey` against the caller-supplied `authority` and refuses before decryption is even attempted; holding a valid signature over SOME key is not holding authority over this room.",
1319
+ "input": {
1320
+ "event": {
1321
+ "kind": 20469,
1322
+ "created_at": 1799999950,
1323
+ "tags": [
1324
+ [
1325
+ "d",
1326
+ "2848bdd5c60a79e2dfe667ae9616c1107f61709032b66e556e28f4a96e69450b"
1327
+ ],
1328
+ [
1329
+ "p",
1330
+ "fcd74d122f0a212a673839482f69ad973f6d38735faeeb3e57929c2b916492fe"
1331
+ ]
1332
+ ],
1333
+ "content": "AuE89EQZbKOh6Q6atmHSV8z2I7pligwvRSPPP348nwEskkOISAn4mCrIh5ehqvWD6afpqk4HV0KSGlzIW/tRbVz0g1QJGaCo55NiIg3a1vPgW30NfY9b43q4s9RfFSp+uUE3PVXlEtuM7nmTOIOwfozciRtUB4cGxtfVCtANy1qOdlx7MzN9/QfAqIyWLURHatavnsYRNALvOPlBiB/Q3mCo/u2S55oWmIxH0wSpauuny7FsYGolbUpl/jFhpJNxNYKNtQOqIz8tqsxXfDCPw7/F2ABwYy5m0ArGUfuhJUcHkQFuLYXCY0bwvJ76InzHTFiKAEdguEEgReSJdi9hNwB+pA==",
1334
+ "pubkey": "1fbe70713a2cb13328af07c3b3ac722f685a9ffb17de5c5e20de97a351e0907d",
1335
+ "id": "17c8189d8019279c9b6731b45cf50934168a03999394b6b169eda9699ee14408",
1336
+ "sig": "013ad835187408ab3df5babb0c4801803891dfa71899aee26a41a9cabe87c9a08a363afdf91e528ebc2c2ab6f8e9c5ef7724575cadfbd062cb52ca92beddb145"
1337
+ },
1338
+ "actualSigner": "1fbe70713a2cb13328af07c3b3ac722f685a9ffb17de5c5e20de97a351e0907d",
1339
+ "request": "287540adb10059739e98e187d5cc2bb4ea4cb795b8621e29b68d75b3a7f919b2"
1340
+ },
1341
+ "output": {
1342
+ "result": null
1343
+ }
1344
+ },
1345
+ {
1346
+ "name": "grant-wrong-room-refused",
1347
+ "kind": "negative",
1348
+ "note": "M18: a genuinely-signed grant whose `d` tag names a different room (fcdc853ddc1be7f7d978367e1a5156b55f11e4c22a49db949f5bb939a303762a) than the one being asked about (2848bdd5c60a79e2dfe667ae9616c1107f61709032b66e556e28f4a96e69450b). Refused on the tag alone, before decryption.",
1349
+ "input": {
1350
+ "event": {
1351
+ "kind": 20469,
1352
+ "created_at": 1799999950,
1353
+ "tags": [
1354
+ [
1355
+ "d",
1356
+ "fcdc853ddc1be7f7d978367e1a5156b55f11e4c22a49db949f5bb939a303762a"
1357
+ ],
1358
+ [
1359
+ "p",
1360
+ "fcd74d122f0a212a673839482f69ad973f6d38735faeeb3e57929c2b916492fe"
1361
+ ]
1362
+ ],
1363
+ "content": "AmJh0Bp/ONNUKKtXc7OfVfZskhW/rLNwxlDWtxylN6Ij4JUH2L7GsRyRq9l3DZXTQY6ELh7D+fXoKz3gzXNA/qTmTjV/gViyeLnmdNMXkewix3PSoAnP6ipHADRqXHD+NwHYPnJkKXKxZyUN/0HJoRJrXw+Ai4xDhMKh7C8iOtiQlQye3DiQvqyJYDeNoTjLxdTCJB6x2+tUv08V+5GoswHzmz/xMhCdnF+BM9pg+Chu2JaWH+V9Z5T4V1heHkeioXPjAk4EBGB2/M7s6iKjy+C6o7En8zIzC3XGGCsg/M2IU4tF0i3TN5cZ0d80bHwxWPCCUY70pMNwdWYl5LKzBYNrrw==",
1364
+ "pubkey": "47ab2a9f89f155b277f1e847d7d4eba664d28324ee903ffc051bdc9e14869f86",
1365
+ "id": "a300b8d11810ef7e9c63cc2c1fd5118a45c23374ec3424fca9534f7cd92646e0",
1366
+ "sig": "14bee8c75b1d807df9c6b64d81d5edd57ca92db8f829cd9d5ac2c5ef29e7d484937ed1db56421cf62bb6c5ed1f03771eda1236833c5e21393fa8452b730e8ae5"
1367
+ },
1368
+ "grantedForRoom": "fcdc853ddc1be7f7d978367e1a5156b55f11e4c22a49db949f5bb939a303762a",
1369
+ "askedAboutRoom": "2848bdd5c60a79e2dfe667ae9616c1107f61709032b66e556e28f4a96e69450b",
1370
+ "request": "287540adb10059739e98e187d5cc2bb4ea4cb795b8621e29b68d75b3a7f919b2"
1371
+ },
1372
+ "output": {
1373
+ "result": null
1374
+ }
1375
+ },
1376
+ {
1377
+ "name": "epoch-1-id-independent-check",
1378
+ "kind": "positive",
1379
+ "note": "`deriveEpoch` for epoch 1 from EPOCH_SECRET_1, called directly (pure, no signing) - confirms the secret sealed in `grant-with-secret-at-epoch-1` really does derive to that epoch's id and key.",
1380
+ "input": {
1381
+ "epoch": 1,
1382
+ "secretHex": "3d3480782bd9eabca24b6f9a541531aa2ca4dc535342d8abf1c2347d58ab26cb"
1383
+ },
1384
+ "output": {
1385
+ "id": "73ff3428fa59018aeea0bbdbb768a208f305736c1f3702a99406c7e6a39836ea",
1386
+ "keyHex": "1376c99d11c91603ba3904328d3fd6c857b098c62a187e4a1322c84e832d63b7"
1387
+ }
1388
+ },
1389
+ {
1390
+ "name": "grant-epoch-above-max-refused",
1391
+ "kind": "negative",
1392
+ "note": "Genuinely signed and genuinely sealed by the real authority key, naming epoch 1000001 - one past MAX_EPOCH (1000000). The real `encodeEpochGrant` refuses to build this itself (`requireEpochNumber` throws at encode time), so this pins the decode-side bound (epoch.ts:571) directly: an authority that was tricked, or a second implementation with a looser encoder, must still be refused on read.",
1393
+ "input": {
1394
+ "event": {
1395
+ "kind": 20469,
1396
+ "created_at": 1799999950,
1397
+ "tags": [
1398
+ [
1399
+ "d",
1400
+ "2848bdd5c60a79e2dfe667ae9616c1107f61709032b66e556e28f4a96e69450b"
1401
+ ],
1402
+ [
1403
+ "p",
1404
+ "fcd74d122f0a212a673839482f69ad973f6d38735faeeb3e57929c2b916492fe"
1405
+ ]
1406
+ ],
1407
+ "content": "AkrtvKmYDlDkNrpx/apt+4pUq7xEN87WRrxPca1aiqA7EObxSHliihQOM//jH/SJyenNgOU/8xKuDcjdHoJCwfBMpEfOGRAJo39LU0KXqsR0L2muURJSdXesx6y4FnjVBwskn/K/JPL0ekq0FbcxNTgosjLadW08z7y0+VL+3sPtZ21ENReBBj3W6Ng8cp0KDDwf2thzFrATrwjvQoo7nIdT1Byv4ScdAtXGbu2QJTikQMk+txCIEpCzcdaDvVvkvt1ZUHoxDap6jMPybc6geW3b117Zz0kUSb6hymzXsePgtfDAXfzqnheAN+qGbMI7SuZ5yjkC9dNqKs2Vqk22YDyDDA==",
1408
+ "pubkey": "47ab2a9f89f155b277f1e847d7d4eba664d28324ee903ffc051bdc9e14869f86",
1409
+ "id": "e3aedcd1107728c70fe571429fbea82768fa7d0be4b193f632fd323a73d07a33",
1410
+ "sig": "2baaee2f0d40e6e450b6d4a8c6e73509f1882dcf0e40d3b99d927b39c4a1b41329a5ae0a4977c36716bfc1363d01eb455643a6f0433f8a37277b6475dd3529d9"
1411
+ },
1412
+ "roomId": "2848bdd5c60a79e2dfe667ae9616c1107f61709032b66e556e28f4a96e69450b",
1413
+ "request": "287540adb10059739e98e187d5cc2bb4ea4cb795b8621e29b68d75b3a7f919b2",
1414
+ "epoch": 1000001
1415
+ },
1416
+ "output": {
1417
+ "result": null
1418
+ }
1419
+ },
1420
+ {
1421
+ "name": "rekey-epoch-tag-zero-refused",
1422
+ "kind": "negative",
1423
+ "note": "Genuinely signed and sealed by the real `encodeRekeyEvent`, called with a `current` naming epoch -1 (a value the real epoch-following path never holds, but that `encodeRekeyEvent` itself does not refuse) so that `next.epoch` (0) satisfies its `current.epoch + 1` check. Epoch 0 is the room's own secret, byte-identical to before any rekey, and is never itself announced by a rekey event. `peekRekeyEvent`'s regex (`/^[1-9][0-9]{0,6}$/`) refuses a leading zero outright, before the signature is even checked.",
1424
+ "input": {
1425
+ "roomId": "2848bdd5c60a79e2dfe667ae9616c1107f61709032b66e556e28f4a96e69450b",
1426
+ "authoritySkHex": "e407c0989f606d8165f63d104e1674a462b191e1df99a29ae9be3f2907deca32",
1427
+ "createdAt": 1799999000,
1428
+ "randomnessQueueHex": [
1429
+ "2fbc4fdee70858dacbb0923b43973ea8d3fb438670f0ec49f53d409d72bfaf03",
1430
+ "61692ffe419fc79b62572943c32dff1585aefe999e594374a3dcb1aafccfde7a"
1431
+ ]
1432
+ },
1433
+ "output": {
1434
+ "event": {
1435
+ "kind": 1462,
1436
+ "created_at": 1799999000,
1437
+ "tags": [
1438
+ [
1439
+ "d",
1440
+ "2848bdd5c60a79e2dfe667ae9616c1107f61709032b66e556e28f4a96e69450b"
1441
+ ],
1442
+ [
1443
+ "epoch",
1444
+ "0"
1445
+ ]
1446
+ ],
1447
+ "content": "Ai+8T97nCFjay7CSO0OXPqjT+0OGcPDsSfU9QJ1yv68DdsVWTk7K9B1elQuiYvHFPpYmZ5Zj+mxQPA2z5c9PZUyG/VUu0U2EiFodYbAJ6EA2s1+yrz3gSDmGdC+63ILty3BIPhdrRXP31Q7ysXmGp7XYUumfDf1G2ielvPLTXzzfiQA=",
1448
+ "pubkey": "47ab2a9f89f155b277f1e847d7d4eba664d28324ee903ffc051bdc9e14869f86",
1449
+ "id": "5607d788211092d50ebf097de05e4ae774dc23dc8a54e4a39934f7c56aa1c5cf",
1450
+ "sig": "2a379fbc3d270a130f0041d839fc00454b253a5261fcdb4541e3e21699565145e7dba07ad523d4f491818d999259be62fcb4b9fb2063258227ae80b1064f6894"
1451
+ },
1452
+ "peek": null
1453
+ }
1454
+ },
1455
+ {
1456
+ "name": "rekey-epoch-tag-leading-zero-refused",
1457
+ "kind": "negative",
1458
+ "note": "Genuinely signed by the real authority key, `epoch` tag the literal string \"01\". No real `encodeRekeyEvent` call writes this (`String(epoch)` never carries a leading zero for a non-negative integer), so this is hand-built. Refused by the regex's `^[1-9]` requirement - a leading-zero-tolerant regex, or an unanchored one, would wrongly accept it.",
1459
+ "input": {
1460
+ "event": {
1461
+ "kind": 1462,
1462
+ "created_at": 1799999000,
1463
+ "tags": [
1464
+ [
1465
+ "d",
1466
+ "2848bdd5c60a79e2dfe667ae9616c1107f61709032b66e556e28f4a96e69450b"
1467
+ ],
1468
+ [
1469
+ "epoch",
1470
+ "01"
1471
+ ]
1472
+ ],
1473
+ "content": "AA==",
1474
+ "pubkey": "47ab2a9f89f155b277f1e847d7d4eba664d28324ee903ffc051bdc9e14869f86",
1475
+ "id": "10252a005149e73b72445cec0ba7553f312bc306fa2ca3cd26f125bbdc7ddf1f",
1476
+ "sig": "cc49db967d84bd71ea1024b0a3a31f9f91f7f6134402942754a877f193bcfddbbcb9f09d95ad9aacc0040f8a7994d87f0d893d037408cbd05709b32c5c759546"
1477
+ },
1478
+ "roomId": "2848bdd5c60a79e2dfe667ae9616c1107f61709032b66e556e28f4a96e69450b"
1479
+ },
1480
+ "output": {
1481
+ "peek": null
1482
+ }
1483
+ },
1484
+ {
1485
+ "name": "rekey-epoch-tag-above-max-refused",
1486
+ "kind": "negative",
1487
+ "note": "Genuinely signed by the real authority key, `epoch` tag \"1000001\" - one past MAX_EPOCH (1000000), and a shape (7 digits, no leading zero) the regex alone accepts. Hand-built because the real `encodeRekeyEvent` refuses to build an epoch this large itself. Refused by the separate epoch.ts:260 bound, independent of the regex.",
1488
+ "input": {
1489
+ "event": {
1490
+ "kind": 1462,
1491
+ "created_at": 1799999000,
1492
+ "tags": [
1493
+ [
1494
+ "d",
1495
+ "2848bdd5c60a79e2dfe667ae9616c1107f61709032b66e556e28f4a96e69450b"
1496
+ ],
1497
+ [
1498
+ "epoch",
1499
+ "1000001"
1500
+ ]
1501
+ ],
1502
+ "content": "AA==",
1503
+ "pubkey": "47ab2a9f89f155b277f1e847d7d4eba664d28324ee903ffc051bdc9e14869f86",
1504
+ "id": "10c5d21dcd2351c17ca0690fc7a9b34def33dad8762eec86e0da886364dfe796",
1505
+ "sig": "4b9247aa8b7ab0d95bb84a4d4b13e45b151a4846707c4c1bfac2cd009252720eac90739ec0da2303749b2469972af62a3bb844d72fb1bc06449739a19177fe30"
1506
+ },
1507
+ "roomId": "2848bdd5c60a79e2dfe667ae9616c1107f61709032b66e556e28f4a96e69450b",
1508
+ "epoch": 1000001
1509
+ },
1510
+ "output": {
1511
+ "peek": null
1512
+ }
1513
+ }
1514
+ ],
1515
+ "epochRequest": [
1516
+ {
1517
+ "name": "credential-device-not-signer-refused",
1518
+ "kind": "negative",
1519
+ "note": "N2: the outer event is genuinely signed by KEPT_DEVICE_SK, and the embedded credential is genuinely signed by PARTICIPANT_A_SK and genuinely names REMOVED_DEVICE. Refused by TWO independent checks: the device check (epoch.ts:457) and the admission proof, which `encodeEpochRequest` always binds to its own real signer and so also disagrees with REMOVED_DEVICE. See `credential-device-not-signer-refused-admission-matches` below for a vector that isolates the device check alone.",
1520
+ "input": {
1521
+ "roomId": "2848bdd5c60a79e2dfe667ae9616c1107f61709032b66e556e28f4a96e69450b",
1522
+ "roomKeyHex": "593a3bdd10ea8589533c31ce5860e1f2698fcbc6dc9a7b64713cc94c0c38713c",
1523
+ "authority": "47ab2a9f89f155b277f1e847d7d4eba664d28324ee903ffc051bdc9e14869f86",
1524
+ "authoritySkHex": "e407c0989f606d8165f63d104e1674a462b191e1df99a29ae9be3f2907deca32",
1525
+ "deviceSkHex": "751627289895e0df520a348eed03006ac69522989ce970c8a4926268de6f69de",
1526
+ "credential": {
1527
+ "kind": 20460,
1528
+ "created_at": 1799990000,
1529
+ "tags": [
1530
+ [
1531
+ "d",
1532
+ "2848bdd5c60a79e2dfe667ae9616c1107f61709032b66e556e28f4a96e69450b"
1533
+ ],
1534
+ [
1535
+ "device",
1536
+ "5defbe2990a67eb3589071a06ddf03c405276fa90373f9028be03b8fdc666428"
1537
+ ],
1538
+ [
1539
+ "expiration",
1540
+ "1800003550"
1541
+ ]
1542
+ ],
1543
+ "content": "",
1544
+ "pubkey": "b07ff66ffca2d5445cfb4a384e94fba8ecc5000283b43f2d5425c85df5032e74",
1545
+ "id": "8e56120d8e0a8d1ad2443d84b6779c1d608ddff75f0b178f95664fd74d9abf78",
1546
+ "sig": "2815bc32c327bea9b421db1d7bd731a7a68aa3d0b1f2a4ada91c1a035411969e8aa4ef58c7cf579992638cb92ca39d1f06276f3433c5200b334f95bf778e7161"
1547
+ },
1548
+ "createdAt": 1799999950,
1549
+ "randomnessQueueHex": [
1550
+ "a461013c41ed09fd4a950828969475e6279b64077662803f271b49015b6ff229",
1551
+ "146d474c119dcae2d9c3e4694f9cf8457c2a8b31f23436ce0a9113e60c0727ee"
1552
+ ]
1553
+ },
1554
+ "output": {
1555
+ "event": {
1556
+ "kind": 20468,
1557
+ "created_at": 1799999950,
1558
+ "tags": [
1559
+ [
1560
+ "d",
1561
+ "2848bdd5c60a79e2dfe667ae9616c1107f61709032b66e556e28f4a96e69450b"
1562
+ ],
1563
+ [
1564
+ "p",
1565
+ "47ab2a9f89f155b277f1e847d7d4eba664d28324ee903ffc051bdc9e14869f86"
1566
+ ]
1567
+ ],
1568
+ "content": "AqRhATxB7Qn9SpUIKJaUdeYnm2QHdmKAPycbSQFbb/Ip8d9PNLoK5YZTjPxR0RcPFd5bKWN/i77IGTqnQk4KQ2OX5bQZdNdyK0L2NhnIFmWTpBFdhJotHbF8CE5HhRRkCw5w9/2EQD+OTuOl6Ac8Vwr59nyWwgnR2aVRwVa+TVURQ2og6vU3XmnVbiAMBDgqu7EvUWKUU9ycZFrgB1fNrl2ZjLAKu4s1ydyjlUNHxAP/pc/8L+69YjUDf3hbKFA9hcMAx/RRL6/RsULUhAHNjrO74LI/NyiVMBZhH1Gd8U3m541AmU955ShTTGJ5zE5QhyYRBh2YLiNTRjmaDI3/aSk1rwg9aK+nmiYA/yVSPDgtb/YRzVoMtxCvqKwx8OR2dtUzvux1k8K15RSoKXt65JLMkh/u5D94oZiwKfFKZrjeUzV3Xt0MvjOynV0UUAkMA2k6cUsfzHLsl8KWErjNkzF8B4RBmVUpnFUKtIF5pZtNGR2MppkjPBwtMKca3SOpwxqzFij6m/hNYxwEHk5+uslet8EquKHn6NFyrQyENHfGlkPY7Pa+LpvhNqLVkJBxro+p2nALYlsf5T560qhtnvyfp41yCUTzi3SoqQVNxVEx+YyJ55THQMtsZMjYxCNpdgpNQKFM7FQ+iXxEEhE2Nz6e28uQJgP8+9GmlpjABrFh6Oyw95yClYbmavHMlYf+JVOvJ+VoDikBIH3yXMP+lnEsmRrGiOBq9ILpachm9JkqVdn4dGKA/l/y0j6E/atBdozO6pz+9IoD0hc0Y8y9F2Y2YTwnYKprwZz2PT/vCDUxfZ6bsnuyeyrblS8d1Qm10x9SDdUiHJomy4G5S1WQSdnek2+ys6Bohke4fwE66Mso+G7R2W2oop3JAcRFfK8BwcfRQQ/WiVYO7E5d1V+Sa/PxuthKTqvNiAr5sxlc/uZgCZA=",
1569
+ "pubkey": "fcd74d122f0a212a673839482f69ad973f6d38735faeeb3e57929c2b916492fe",
1570
+ "id": "fa3cd10bb899f073a7ec835f61d0d0105143344c0cb1fd333e822959748ef4ad",
1571
+ "sig": "01d1328ca976b00eb9df7baa4768c9ab96d6e982ff55b4087eaa68cc1f2ab33095a712a6f90d939b351bfad8772bee2024c5302008da5140aabd1902a24ea1c6"
1572
+ },
1573
+ "result": null
1574
+ }
1575
+ },
1576
+ {
1577
+ "name": "credential-device-not-signer-refused-admission-matches",
1578
+ "kind": "negative",
1579
+ "note": "N2 (isolated): the SAME credential-device mismatch as above, but the admission proof is hand-computed to match REMOVED_DEVICE (the credential's claim) rather than the real signer - so the admission check alone would pass this. Only `decodeEpochRequest`'s device check (epoch.ts:457) refuses it. Genuinely signed and genuinely encrypted throughout; only the admission field is deliberately built to defeat the OTHER check, isolating this one.",
1580
+ "input": {
1581
+ "roomId": "2848bdd5c60a79e2dfe667ae9616c1107f61709032b66e556e28f4a96e69450b",
1582
+ "roomKeyHex": "593a3bdd10ea8589533c31ce5860e1f2698fcbc6dc9a7b64713cc94c0c38713c",
1583
+ "authority": "47ab2a9f89f155b277f1e847d7d4eba664d28324ee903ffc051bdc9e14869f86",
1584
+ "authoritySkHex": "e407c0989f606d8165f63d104e1674a462b191e1df99a29ae9be3f2907deca32",
1585
+ "credential": {
1586
+ "kind": 20460,
1587
+ "created_at": 1799990000,
1588
+ "tags": [
1589
+ [
1590
+ "d",
1591
+ "2848bdd5c60a79e2dfe667ae9616c1107f61709032b66e556e28f4a96e69450b"
1592
+ ],
1593
+ [
1594
+ "device",
1595
+ "5defbe2990a67eb3589071a06ddf03c405276fa90373f9028be03b8fdc666428"
1596
+ ],
1597
+ [
1598
+ "expiration",
1599
+ "1800003550"
1600
+ ]
1601
+ ],
1602
+ "content": "",
1603
+ "pubkey": "b07ff66ffca2d5445cfb4a384e94fba8ecc5000283b43f2d5425c85df5032e74",
1604
+ "id": "8e56120d8e0a8d1ad2443d84b6779c1d608ddff75f0b178f95664fd74d9abf78",
1605
+ "sig": "2815bc32c327bea9b421db1d7bd731a7a68aa3d0b1f2a4ada91c1a035411969e8aa4ef58c7cf579992638cb92ca39d1f06276f3433c5200b334f95bf778e7161"
1606
+ },
1607
+ "admission": "441aa5cda04213dbc1d91f05ac3e7a07c6fe49b7932f167dcf1d7ed045bd4c73",
1608
+ "createdAt": 1799999950,
1609
+ "event": {
1610
+ "kind": 20468,
1611
+ "created_at": 1799999950,
1612
+ "tags": [
1613
+ [
1614
+ "d",
1615
+ "2848bdd5c60a79e2dfe667ae9616c1107f61709032b66e556e28f4a96e69450b"
1616
+ ],
1617
+ [
1618
+ "p",
1619
+ "47ab2a9f89f155b277f1e847d7d4eba664d28324ee903ffc051bdc9e14869f86"
1620
+ ]
1621
+ ],
1622
+ "content": "Avu7RLJLwchbWSJiyC7PNN01LPAz961dhiJjc0MqiG/d4EmpY1QVyoewJRxrKBM5jWaTX7KiIEdtCytl0RW9T1mvGGc/MRwsIgRpi7FGNjM/G2EzjJ8pT3rDcQiev0dExbiZJ1wKfUy5nWnRXtlfh7mcz72eFJ+bxZdDxgmM4a8UmdOFvG7zzclaqVmIEVRASOqE8ai/gNJ5DaBd2BKEHRltJmbTZZCHku4PmFVaZ6R0sJnoVIaR7xodJD7RCeDzl7PJAgKh3J79/DDGgUFhKul8VP0AcukmrHKehTDbvHUygULIMJx7NOSLjnl+JLNpyEBgvJMlyQRF2diSIKAMpGLzTWZVKvt3y9N2YGHOxyG09Zmu3QBThBWPlXDoMq26zphSvNRCjFuyd3zoouzM6MhY38II25ETsEJGCwG0zvxJyGXlvPy53ZK4eWyHiv6CgiXlq61pTJN2kD9TJnOc6neV09qcGwLh45mJEYKzQDgY5mS13xCvncluIgUSwqC/HqBXDBi7z7zaG6Jr1c8lB3EiBfXG1rnW1daTt7eHUwRKL39aw/c5QB1JAyKgoBK3wR4wS7Rk4jYl5OZRm6v8k7Urk0su/t+m6V2OnIQa/hAcGhM6ka3HWvXVXsOnbS+a9Ua5m8cFSgJr4rt5yB5fVkowrL6mwyAqRy2pIBO2U/xTs8ArJq0wjlAzINkH59W6mZpnnRtuqsduX6BljJtDKHdLXKGLMQpcjCujmXBnuV70ByKtP+4IaZMZaetCL312qBgUJk5FhmphbzFHQYNJoCA023GIcCQ60U1mHqPvlsPxmCPLU3qD18tpMune5s7PUzrD9dtyCugezWSCh797P2ul4GDZ/nQ2f7XdjApx0N1+5igvyb0xBq7kakye/K7CVFhVDxH89TILRKiJmsexLyqLP77fv6r7+K3mJxFhElQbdmE=",
1623
+ "pubkey": "fcd74d122f0a212a673839482f69ad973f6d38735faeeb3e57929c2b916492fe",
1624
+ "id": "3a73c74859a9ecca1eb43c88fa839a8bfaf70c470161b08d1c719f1361a095e9",
1625
+ "sig": "d15219cf30123c4544f37ee08cd7e6222d76ab9a1c8b6875ad124fa4cf8522ba4686187ac9064cc81e632e5f0d110cd425235be66134b9500a99e3142a6b976e"
1626
+ }
1627
+ },
1628
+ "output": {
1629
+ "event": {
1630
+ "kind": 20468,
1631
+ "created_at": 1799999950,
1632
+ "tags": [
1633
+ [
1634
+ "d",
1635
+ "2848bdd5c60a79e2dfe667ae9616c1107f61709032b66e556e28f4a96e69450b"
1636
+ ],
1637
+ [
1638
+ "p",
1639
+ "47ab2a9f89f155b277f1e847d7d4eba664d28324ee903ffc051bdc9e14869f86"
1640
+ ]
1641
+ ],
1642
+ "content": "Avu7RLJLwchbWSJiyC7PNN01LPAz961dhiJjc0MqiG/d4EmpY1QVyoewJRxrKBM5jWaTX7KiIEdtCytl0RW9T1mvGGc/MRwsIgRpi7FGNjM/G2EzjJ8pT3rDcQiev0dExbiZJ1wKfUy5nWnRXtlfh7mcz72eFJ+bxZdDxgmM4a8UmdOFvG7zzclaqVmIEVRASOqE8ai/gNJ5DaBd2BKEHRltJmbTZZCHku4PmFVaZ6R0sJnoVIaR7xodJD7RCeDzl7PJAgKh3J79/DDGgUFhKul8VP0AcukmrHKehTDbvHUygULIMJx7NOSLjnl+JLNpyEBgvJMlyQRF2diSIKAMpGLzTWZVKvt3y9N2YGHOxyG09Zmu3QBThBWPlXDoMq26zphSvNRCjFuyd3zoouzM6MhY38II25ETsEJGCwG0zvxJyGXlvPy53ZK4eWyHiv6CgiXlq61pTJN2kD9TJnOc6neV09qcGwLh45mJEYKzQDgY5mS13xCvncluIgUSwqC/HqBXDBi7z7zaG6Jr1c8lB3EiBfXG1rnW1daTt7eHUwRKL39aw/c5QB1JAyKgoBK3wR4wS7Rk4jYl5OZRm6v8k7Urk0su/t+m6V2OnIQa/hAcGhM6ka3HWvXVXsOnbS+a9Ua5m8cFSgJr4rt5yB5fVkowrL6mwyAqRy2pIBO2U/xTs8ArJq0wjlAzINkH59W6mZpnnRtuqsduX6BljJtDKHdLXKGLMQpcjCujmXBnuV70ByKtP+4IaZMZaetCL312qBgUJk5FhmphbzFHQYNJoCA023GIcCQ60U1mHqPvlsPxmCPLU3qD18tpMune5s7PUzrD9dtyCugezWSCh797P2ul4GDZ/nQ2f7XdjApx0N1+5igvyb0xBq7kakye/K7CVFhVDxH89TILRKiJmsexLyqLP77fv6r7+K3mJxFhElQbdmE=",
1643
+ "pubkey": "fcd74d122f0a212a673839482f69ad973f6d38735faeeb3e57929c2b916492fe",
1644
+ "id": "3a73c74859a9ecca1eb43c88fa839a8bfaf70c470161b08d1c719f1361a095e9",
1645
+ "sig": "d15219cf30123c4544f37ee08cd7e6222d76ab9a1c8b6875ad124fa4cf8522ba4686187ac9064cc81e632e5f0d110cd425235be66134b9500a99e3142a6b976e"
1646
+ },
1647
+ "result": null
1648
+ }
1649
+ }
1650
+ ],
1651
+ "personCredential": [
1652
+ {
1653
+ "name": "valid-accepted-with-acceptPerson",
1654
+ "kind": "positive",
1655
+ "note": "A person-scope credential (device authorised for every room, not one) is refused as a room credential by default, and accepted only when the caller opts in with `acceptPerson`. Built by calling the real, async `createDeviceCredential` with an injected `ParticipantIdentity` whose `signEvent` is `finalizeDeterministic` under the recorded aux-rand.",
1656
+ "input": {
1657
+ "participantSkHex": "826f7335cca1f25633dbc6efc43131a651feb9b7d419c9b1fdc35b2e115d2180",
1658
+ "devicePubkey": "b4814eb28f92350f362af5eb7a1dc6b9bdd1d27e789f5d97ad3b8c7653753076",
1659
+ "createdAt": 1799990000,
1660
+ "expiresAt": 1800594800,
1661
+ "label": "phone",
1662
+ "auxRandHex": "74686fc1c937eed1cfead9975cd9c2dd250d1343f7c17c498d1d3a3b55a6b262"
1663
+ },
1664
+ "output": {
1665
+ "event": {
1666
+ "kind": 20460,
1667
+ "created_at": 1799990000,
1668
+ "tags": [
1669
+ [
1670
+ "d",
1671
+ "b07ff66ffca2d5445cfb4a384e94fba8ecc5000283b43f2d5425c85df5032e74"
1672
+ ],
1673
+ [
1674
+ "device",
1675
+ "b4814eb28f92350f362af5eb7a1dc6b9bdd1d27e789f5d97ad3b8c7653753076"
1676
+ ],
1677
+ [
1678
+ "expiration",
1679
+ "1800594800"
1680
+ ],
1681
+ [
1682
+ "scope",
1683
+ "person"
1684
+ ],
1685
+ [
1686
+ "label",
1687
+ "phone"
1688
+ ]
1689
+ ],
1690
+ "content": "",
1691
+ "pubkey": "b07ff66ffca2d5445cfb4a384e94fba8ecc5000283b43f2d5425c85df5032e74",
1692
+ "id": "3207aab2f8e17686635271bce3fc905676494ea2b043dc38477adb2a02c1a28f",
1693
+ "sig": "1dff8e09bedbee097e7f1b3fde7303fe5c3e15b43b492f2ed93f5dc7c98d4e236f697eab067f63ac0ac98a46940556ec0c106e123729fea97f10e5f292a04dfb"
1694
+ }
1695
+ },
1696
+ "expected": {
1697
+ "asPerson": {
1698
+ "ok": true,
1699
+ "participant": "b07ff66ffca2d5445cfb4a384e94fba8ecc5000283b43f2d5425c85df5032e74",
1700
+ "device": "b4814eb28f92350f362af5eb7a1dc6b9bdd1d27e789f5d97ad3b8c7653753076"
1701
+ },
1702
+ "asRoomWithoutAcceptPerson": {
1703
+ "ok": false,
1704
+ "reason": "person credential where a room credential was expected"
1705
+ },
1706
+ "asRoomWithAcceptPerson": {
1707
+ "ok": true,
1708
+ "participant": "b07ff66ffca2d5445cfb4a384e94fba8ecc5000283b43f2d5425c85df5032e74",
1709
+ "device": "b4814eb28f92350f362af5eb7a1dc6b9bdd1d27e789f5d97ad3b8c7653753076"
1710
+ }
1711
+ }
1712
+ },
1713
+ {
1714
+ "name": "valid-at-exactly-30-day-boundary",
1715
+ "kind": "positive",
1716
+ "note": "M15 (accepted side): expiresAt is exactly 2592000 seconds (30 days) past createdAt - the boundary itself. Both `createDeviceCredential` (mint time) and `verifyDeviceCredential` (read time) use a strict `>`, so this is accepted; past the boundary (\"refused-over-30-days\" below) is refused. Minted through the real, async `createDeviceCredential`.",
1717
+ "input": {
1718
+ "participantSkHex": "826f7335cca1f25633dbc6efc43131a651feb9b7d419c9b1fdc35b2e115d2180",
1719
+ "devicePubkey": "b4814eb28f92350f362af5eb7a1dc6b9bdd1d27e789f5d97ad3b8c7653753076",
1720
+ "createdAt": 1799990000,
1721
+ "expiresAt": 1802582000,
1722
+ "auxRandHex": "78baace609f0afbfc3e3260f6d9fff49f72e43457544e683e0fd399b0a4a2c7b"
1723
+ },
1724
+ "output": {
1725
+ "event": {
1726
+ "kind": 20460,
1727
+ "created_at": 1799990000,
1728
+ "tags": [
1729
+ [
1730
+ "d",
1731
+ "b07ff66ffca2d5445cfb4a384e94fba8ecc5000283b43f2d5425c85df5032e74"
1732
+ ],
1733
+ [
1734
+ "device",
1735
+ "b4814eb28f92350f362af5eb7a1dc6b9bdd1d27e789f5d97ad3b8c7653753076"
1736
+ ],
1737
+ [
1738
+ "expiration",
1739
+ "1802582000"
1740
+ ],
1741
+ [
1742
+ "scope",
1743
+ "person"
1744
+ ]
1745
+ ],
1746
+ "content": "",
1747
+ "pubkey": "b07ff66ffca2d5445cfb4a384e94fba8ecc5000283b43f2d5425c85df5032e74",
1748
+ "id": "c02d92da1d5c60259acb6539950c46e39be32d1cf6926754e4696fbfed334571",
1749
+ "sig": "9180b2e0ad2d69ed30d28c40ffa2b3cbc18c86db9a180d6c125f6ab22bc83797cfdffb34c42c905570668304517914751deb410e2595d0319011965083b59990"
1750
+ },
1751
+ "result": {
1752
+ "ok": true,
1753
+ "participant": "b07ff66ffca2d5445cfb4a384e94fba8ecc5000283b43f2d5425c85df5032e74",
1754
+ "device": "b4814eb28f92350f362af5eb7a1dc6b9bdd1d27e789f5d97ad3b8c7653753076"
1755
+ }
1756
+ }
1757
+ },
1758
+ {
1759
+ "name": "refused-over-30-days",
1760
+ "kind": "negative",
1761
+ "note": "M15 (refused side): the real `createDeviceCredential`'s mint-time check passes (expiry is exactly 2592000 seconds past the requested `now`, not more) - but the injected identity restamps the signed event's `created_at` ten seconds earlier than `now`, so the credential that actually results runs 2592010 seconds from its own real `created_at`. `verifyDeviceCredential` refuses it on read.",
1762
+ "input": {
1763
+ "participantSkHex": "826f7335cca1f25633dbc6efc43131a651feb9b7d419c9b1fdc35b2e115d2180",
1764
+ "devicePubkey": "b4814eb28f92350f362af5eb7a1dc6b9bdd1d27e789f5d97ad3b8c7653753076",
1765
+ "mintTimeNow": 1799990000,
1766
+ "restampedCreatedAt": 1799989990,
1767
+ "expiresAt": 1802582000,
1768
+ "auxRandHex": "1a6b3cb1178e0a776ae079a8354df951446dc8c430939c91f98f126ae5f6f772",
1769
+ "verify": {
1770
+ "identity": "b07ff66ffca2d5445cfb4a384e94fba8ecc5000283b43f2d5425c85df5032e74",
1771
+ "now": 1799989990
1772
+ }
1773
+ },
1774
+ "output": {
1775
+ "event": {
1776
+ "kind": 20460,
1777
+ "created_at": 1799989990,
1778
+ "tags": [
1779
+ [
1780
+ "d",
1781
+ "b07ff66ffca2d5445cfb4a384e94fba8ecc5000283b43f2d5425c85df5032e74"
1782
+ ],
1783
+ [
1784
+ "device",
1785
+ "b4814eb28f92350f362af5eb7a1dc6b9bdd1d27e789f5d97ad3b8c7653753076"
1786
+ ],
1787
+ [
1788
+ "expiration",
1789
+ "1802582000"
1790
+ ],
1791
+ [
1792
+ "scope",
1793
+ "person"
1794
+ ]
1795
+ ],
1796
+ "content": "",
1797
+ "pubkey": "b07ff66ffca2d5445cfb4a384e94fba8ecc5000283b43f2d5425c85df5032e74",
1798
+ "id": "9bd88ebb54f04e165750c068de3de21d0c1066b9533ccc5cb769884ac50fdcf1",
1799
+ "sig": "dbe6ab29a8eee6c163b16273f7953920cb5b51140edfc954db42892214c601415ddb315e44144ffacdaceaca2670c0e8d8a07e70c3d7c32c92d9a541ff76fe13"
1800
+ },
1801
+ "result": {
1802
+ "ok": false,
1803
+ "reason": "longer than 30 days"
1804
+ }
1805
+ }
1806
+ },
1807
+ {
1808
+ "name": "wrong-person-identity-path-refused",
1809
+ "kind": "negative",
1810
+ "note": "N9: genuinely signed by PARTICIPANT_B_SK, but its `d` tag names PARTICIPANT_A - claiming to be a device credential for someone else while signing with your own key. Checked via the `identity` path (credential.ts:136): refused, because `d` must equal BOTH the identity asked for AND the credential's own real signer - checking only the first half would accept this.",
1811
+ "input": {
1812
+ "participantSkHex": "da87e41f0507d613d2c2c7885821e4eda3d64ecc24f941c12ffcb97760273645",
1813
+ "claimedIdentity": "b07ff66ffca2d5445cfb4a384e94fba8ecc5000283b43f2d5425c85df5032e74",
1814
+ "devicePubkey": "b4814eb28f92350f362af5eb7a1dc6b9bdd1d27e789f5d97ad3b8c7653753076",
1815
+ "createdAt": 1799990000,
1816
+ "expiresAt": 1800594800,
1817
+ "auxRandHex": "6ce217723d4f68cdea507f48d799cdb854f797dbfdc15e4a57b42770f963b932"
1818
+ },
1819
+ "output": {
1820
+ "event": {
1821
+ "kind": 20460,
1822
+ "created_at": 1799990000,
1823
+ "tags": [
1824
+ [
1825
+ "d",
1826
+ "b07ff66ffca2d5445cfb4a384e94fba8ecc5000283b43f2d5425c85df5032e74"
1827
+ ],
1828
+ [
1829
+ "device",
1830
+ "b4814eb28f92350f362af5eb7a1dc6b9bdd1d27e789f5d97ad3b8c7653753076"
1831
+ ],
1832
+ [
1833
+ "expiration",
1834
+ "1800594800"
1835
+ ],
1836
+ [
1837
+ "scope",
1838
+ "person"
1839
+ ]
1840
+ ],
1841
+ "content": "",
1842
+ "pubkey": "e062bd3bb36508cc94edafc132a9f2edfb690fb369b7ea8dd7f62e38b8f4d8ea",
1843
+ "id": "a5975b01beef501b5dccd85dbfc9b717df7699dadfdedb73aeef5be0ca0b5b6e",
1844
+ "sig": "04c51c485c94eadc3077c2ed606e0d3b2ef67b0f9048dcc3f8966badef044defd26797829fb6eb80857b892eeebde1100e7acfa2a81dbeeccf91fdf1b6a4288e"
1845
+ },
1846
+ "result": {
1847
+ "ok": false,
1848
+ "reason": "wrong person"
1849
+ }
1850
+ }
1851
+ },
1852
+ {
1853
+ "name": "wrong-person-acceptperson-path-refused",
1854
+ "kind": "negative",
1855
+ "note": "N9b: the SAME event, checked via the room-credential-with-acceptPerson path instead (credential.ts:139): refused for the same reason - `d` (PARTICIPANT_A) does not match the real signer (PARTICIPANT_B), and this path checks nothing else about `d`.",
1856
+ "input": {
1857
+ "event": {
1858
+ "kind": 20460,
1859
+ "created_at": 1799990000,
1860
+ "tags": [
1861
+ [
1862
+ "d",
1863
+ "b07ff66ffca2d5445cfb4a384e94fba8ecc5000283b43f2d5425c85df5032e74"
1864
+ ],
1865
+ [
1866
+ "device",
1867
+ "b4814eb28f92350f362af5eb7a1dc6b9bdd1d27e789f5d97ad3b8c7653753076"
1868
+ ],
1869
+ [
1870
+ "expiration",
1871
+ "1800594800"
1872
+ ],
1873
+ [
1874
+ "scope",
1875
+ "person"
1876
+ ]
1877
+ ],
1878
+ "content": "",
1879
+ "pubkey": "e062bd3bb36508cc94edafc132a9f2edfb690fb369b7ea8dd7f62e38b8f4d8ea",
1880
+ "id": "a5975b01beef501b5dccd85dbfc9b717df7699dadfdedb73aeef5be0ca0b5b6e",
1881
+ "sig": "04c51c485c94eadc3077c2ed606e0d3b2ef67b0f9048dcc3f8966badef044defd26797829fb6eb80857b892eeebde1100e7acfa2a81dbeeccf91fdf1b6a4288e"
1882
+ },
1883
+ "roomId": "2848bdd5c60a79e2dfe667ae9616c1107f61709032b66e556e28f4a96e69450b",
1884
+ "acceptPerson": true
1885
+ },
1886
+ "output": {
1887
+ "result": {
1888
+ "ok": false,
1889
+ "reason": "wrong person"
1890
+ }
1891
+ }
1892
+ }
1893
+ ],
1894
+ "channelsSignature": [
1895
+ {
1896
+ "name": "valid-at-epoch-1",
1897
+ "kind": "positive",
1898
+ "note": "The authority signs the room's channel list at epoch 1. Canonicalised (deduplicated, sorted) before signing, and verified with the real `verifyChannels`, in either list order. Built by calling the real `signChannels` with `crypto.getRandomValues` stubbed to the recorded aux-rand.",
1899
+ "input": {
1900
+ "roomId": "2848bdd5c60a79e2dfe667ae9616c1107f61709032b66e556e28f4a96e69450b",
1901
+ "epoch": 1,
1902
+ "channels": [
1903
+ "planning",
1904
+ "social"
1905
+ ],
1906
+ "authoritySkHex": "e407c0989f606d8165f63d104e1674a462b191e1df99a29ae9be3f2907deca32",
1907
+ "randomnessQueueHex": [
1908
+ "0b34d41dbe7b9e9d49c1f430f6cb26c7c44162cbdbe8a7522f48fbc313e329ac"
1909
+ ]
1910
+ },
1911
+ "output": {
1912
+ "canonical": [
1913
+ "planning",
1914
+ "social"
1915
+ ],
1916
+ "sig": "b1456ad9a47fc4436bc4073e24a783277afdd5606bb888b47837c6e2eecae8efae221b586a8c0bc5983c95c842e345d79fc20edc9cfaf56ca3db918532140293"
1917
+ },
1918
+ "expected": {
1919
+ "verifiesInGivenOrder": true,
1920
+ "verifiesReversed": true
1921
+ }
1922
+ },
1923
+ {
1924
+ "name": "refused-at-another-epoch",
1925
+ "kind": "negative",
1926
+ "note": "The same signature, checked against epoch 2 instead of the epoch it was made for: refused - a channel list valid at one epoch is not replayable into the next.",
1927
+ "input": {
1928
+ "roomId": "2848bdd5c60a79e2dfe667ae9616c1107f61709032b66e556e28f4a96e69450b",
1929
+ "epoch": 2,
1930
+ "channels": [
1931
+ "planning",
1932
+ "social"
1933
+ ],
1934
+ "sig": "b1456ad9a47fc4436bc4073e24a783277afdd5606bb888b47837c6e2eecae8efae221b586a8c0bc5983c95c842e345d79fc20edc9cfaf56ca3db918532140293",
1935
+ "authority": "47ab2a9f89f155b277f1e847d7d4eba664d28324ee903ffc051bdc9e14869f86"
1936
+ },
1937
+ "output": {
1938
+ "result": false
1939
+ }
1940
+ },
1941
+ {
1942
+ "name": "refused-wrong-authority",
1943
+ "kind": "negative",
1944
+ "note": "The same genuinely-signed message, checked against a different (real) pubkey than the one that actually signed it: refused. A member who holds the room key cannot present somebody else's signed channel list as if the authority had signed it for them.",
1945
+ "input": {
1946
+ "roomId": "2848bdd5c60a79e2dfe667ae9616c1107f61709032b66e556e28f4a96e69450b",
1947
+ "epoch": 1,
1948
+ "channels": [
1949
+ "planning",
1950
+ "social"
1951
+ ],
1952
+ "sig": "b1456ad9a47fc4436bc4073e24a783277afdd5606bb888b47837c6e2eecae8efae221b586a8c0bc5983c95c842e345d79fc20edc9cfaf56ca3db918532140293",
1953
+ "wrongAuthority": "cb948cc3faaf18b2db04bc0970c26bc79d56b0f9a32cf0cdb197597f2a6164e1"
1954
+ },
1955
+ "output": {
1956
+ "result": false
1957
+ }
1958
+ },
1959
+ {
1960
+ "name": "refused-wrong-room",
1961
+ "kind": "negative",
1962
+ "note": "The same genuinely-signed message, checked against a different room's id: refused. A channel list signed for one room is not replayable into another, even under the same authority and epoch number.",
1963
+ "input": {
1964
+ "roomId": "2848bdd5c60a79e2dfe667ae9616c1107f61709032b66e556e28f4a96e69450b",
1965
+ "epoch": 1,
1966
+ "channels": [
1967
+ "planning",
1968
+ "social"
1969
+ ],
1970
+ "sig": "b1456ad9a47fc4436bc4073e24a783277afdd5606bb888b47837c6e2eecae8efae221b586a8c0bc5983c95c842e345d79fc20edc9cfaf56ca3db918532140293",
1971
+ "authority": "47ab2a9f89f155b277f1e847d7d4eba664d28324ee903ffc051bdc9e14869f86",
1972
+ "wrongRoomId": "fcdc853ddc1be7f7d978367e1a5156b55f11e4c22a49db949f5bb939a303762a"
1973
+ },
1974
+ "output": {
1975
+ "result": false
1976
+ }
1977
+ },
1978
+ {
1979
+ "name": "refused-reserved-channel-name",
1980
+ "kind": "negative",
1981
+ "note": "`agents`, `minutes` and `transcript` are reserved: the room already means something else by them, so `canonicalChannels` throws rather than letting them into a signed registry.",
1982
+ "input": {
1983
+ "channels": [
1984
+ "planning",
1985
+ "agents"
1986
+ ]
1987
+ },
1988
+ "output": {
1989
+ "throws": true,
1990
+ "error": "reserved channel name: agents"
1991
+ }
1992
+ }
1993
+ ],
1994
+ "accessEvaluation": [
1995
+ {
1996
+ "name": "kindred-proof-names-another-participant-refused",
1997
+ "kind": "negative",
1998
+ "note": "N11: a real, validly-signed kindred proof for GUEST, checked against PARTICIPANT_A instead. `evaluateAccess` (access.ts:96) refuses before it ever reaches the signature check - a proof is a grant to the one participant it names, not a bearer token any holder can present.",
1999
+ "input": {
2000
+ "policy": {
2001
+ "tier": "kith",
2002
+ "admitted": [
2003
+ "00a0b8b578de367e65c400cccdb7743e82403d457469d02023b1568a92faadd8"
2004
+ ]
2005
+ },
2006
+ "proof": {
2007
+ "tier": "kith",
2008
+ "participant": "49ebb8e92de99c03390bb88ab02704ab2a66332101ff895c512756ad7648e525",
2009
+ "issuer": "00a0b8b578de367e65c400cccdb7743e82403d457469d02023b1568a92faadd8",
2010
+ "room": "2848bdd5c60a79e2dfe667ae9616c1107f61709032b66e556e28f4a96e69450b",
2011
+ "nonce": "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
2012
+ "sig": "41549a6d0928ed383c2f9df776516b6bb98f7eebe62298fa6b116203adf5b8ffefefa5718be6bce0e4cac2ddb97fb684ed3088cacff28e5b0bc0662d5af85d86",
2013
+ "expiresAt": 1800003600
2014
+ },
2015
+ "checkedParticipant": "b07ff66ffca2d5445cfb4a384e94fba8ecc5000283b43f2d5425c85df5032e74",
2016
+ "now": 1800000000,
2017
+ "roomId": "2848bdd5c60a79e2dfe667ae9616c1107f61709032b66e556e28f4a96e69450b",
2018
+ "randomnessQueueHex": [
2019
+ "167d7a20c55fb2439ccf6fffba15cc37848c55cf47459f6f4e9e84e8ea3eead1"
2020
+ ]
2021
+ },
2022
+ "output": {
2023
+ "result": {
2024
+ "admitted": false,
2025
+ "reason": "proof names another participant"
2026
+ }
2027
+ }
2028
+ },
2029
+ {
2030
+ "name": "kindred-proof-expiry-at-boundary-refused",
2031
+ "kind": "negative",
2032
+ "note": "N10 (refused side): a real kindred proof checked at exactly its own `expiresAt`: refused. Proves the check is `<=`, not `<` - a boundary shifted by one would accept this.",
2033
+ "input": {
2034
+ "policy": {
2035
+ "tier": "kith",
2036
+ "admitted": [
2037
+ "00a0b8b578de367e65c400cccdb7743e82403d457469d02023b1568a92faadd8"
2038
+ ]
2039
+ },
2040
+ "proof": {
2041
+ "tier": "kith",
2042
+ "participant": "49ebb8e92de99c03390bb88ab02704ab2a66332101ff895c512756ad7648e525",
2043
+ "issuer": "00a0b8b578de367e65c400cccdb7743e82403d457469d02023b1568a92faadd8",
2044
+ "room": "2848bdd5c60a79e2dfe667ae9616c1107f61709032b66e556e28f4a96e69450b",
2045
+ "nonce": "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb",
2046
+ "sig": "5fe58ba856bbe03d0b17be0a0e8313dc330c10bbfa314e19b59f8993d487cf944a1ae503efb95006bf0a058518eb2e5b90255fe2159b61d3c8dcf53e8cd82811",
2047
+ "expiresAt": 1800000000
2048
+ },
2049
+ "now": 1800000000,
2050
+ "roomId": "2848bdd5c60a79e2dfe667ae9616c1107f61709032b66e556e28f4a96e69450b",
2051
+ "randomnessQueueHex": [
2052
+ "d097fd12b45c061caded195862ae92bdbae982cbe55fffbbeafa358dd8203d97"
2053
+ ]
2054
+ },
2055
+ "output": {
2056
+ "result": {
2057
+ "admitted": false,
2058
+ "reason": "expired"
2059
+ }
2060
+ }
2061
+ },
2062
+ {
2063
+ "name": "kindred-proof-one-second-before-expiry-accepted",
2064
+ "kind": "positive",
2065
+ "note": "N10 (accepted side): the SAME proof, checked one second before its own `expiresAt`: accepted. Together with the refused-side vector above, this pins the boundary exactly, in both directions.",
2066
+ "input": {
2067
+ "policy": {
2068
+ "tier": "kith",
2069
+ "admitted": [
2070
+ "00a0b8b578de367e65c400cccdb7743e82403d457469d02023b1568a92faadd8"
2071
+ ]
2072
+ },
2073
+ "proof": {
2074
+ "tier": "kith",
2075
+ "participant": "49ebb8e92de99c03390bb88ab02704ab2a66332101ff895c512756ad7648e525",
2076
+ "issuer": "00a0b8b578de367e65c400cccdb7743e82403d457469d02023b1568a92faadd8",
2077
+ "room": "2848bdd5c60a79e2dfe667ae9616c1107f61709032b66e556e28f4a96e69450b",
2078
+ "nonce": "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb",
2079
+ "sig": "5fe58ba856bbe03d0b17be0a0e8313dc330c10bbfa314e19b59f8993d487cf944a1ae503efb95006bf0a058518eb2e5b90255fe2159b61d3c8dcf53e8cd82811",
2080
+ "expiresAt": 1800000000
2081
+ },
2082
+ "now": 1799999999,
2083
+ "roomId": "2848bdd5c60a79e2dfe667ae9616c1107f61709032b66e556e28f4a96e69450b"
2084
+ },
2085
+ "output": {
2086
+ "result": {
2087
+ "admitted": true,
2088
+ "reason": "kindred proof accepted"
2089
+ }
2090
+ }
2091
+ },
2092
+ {
2093
+ "name": "device-credential-expiry-at-boundary-refused",
2094
+ "kind": "negative",
2095
+ "note": "N8 (refused side): a real room-scope device credential checked at exactly its own `expiration`: refused (credential.ts:155, the same `<=` rule the kindred proof uses).",
2096
+ "input": {
2097
+ "event": {
2098
+ "kind": 20460,
2099
+ "created_at": 1799990000,
2100
+ "tags": [
2101
+ [
2102
+ "d",
2103
+ "2848bdd5c60a79e2dfe667ae9616c1107f61709032b66e556e28f4a96e69450b"
2104
+ ],
2105
+ [
2106
+ "device",
2107
+ "b4814eb28f92350f362af5eb7a1dc6b9bdd1d27e789f5d97ad3b8c7653753076"
2108
+ ],
2109
+ [
2110
+ "expiration",
2111
+ "1800000000"
2112
+ ]
2113
+ ],
2114
+ "content": "",
2115
+ "pubkey": "b07ff66ffca2d5445cfb4a384e94fba8ecc5000283b43f2d5425c85df5032e74",
2116
+ "id": "fd90215d7918c90444bff0a76aad33f610d89009b14f4f5bbfb564c3ba9fe99a",
2117
+ "sig": "b6b8288debc3091305e3dcc62dfa7161603a31918978da3a63216c6e5676a1c2d9749d54a5d5ff9e493e63248bf98a123cec67180d3588bec96ca55594dede51"
2118
+ },
2119
+ "roomId": "2848bdd5c60a79e2dfe667ae9616c1107f61709032b66e556e28f4a96e69450b",
2120
+ "now": 1800000000,
2121
+ "createdAt": 1799990000,
2122
+ "expiresAt": 1800000000,
2123
+ "devicePubkey": "b4814eb28f92350f362af5eb7a1dc6b9bdd1d27e789f5d97ad3b8c7653753076",
2124
+ "auxRandHex": "b5b4f354069404c441b6eba79c0c47847eb6cd77627b67d419268ec7b04f352d"
2125
+ },
2126
+ "output": {
2127
+ "result": {
2128
+ "ok": false,
2129
+ "reason": "expired"
2130
+ }
2131
+ }
2132
+ },
2133
+ {
2134
+ "name": "device-credential-one-second-before-expiry-accepted",
2135
+ "kind": "positive",
2136
+ "note": "N8 (accepted side): the SAME credential, checked one second before its own `expiration`: accepted.",
2137
+ "input": {
2138
+ "event": {
2139
+ "kind": 20460,
2140
+ "created_at": 1799990000,
2141
+ "tags": [
2142
+ [
2143
+ "d",
2144
+ "2848bdd5c60a79e2dfe667ae9616c1107f61709032b66e556e28f4a96e69450b"
2145
+ ],
2146
+ [
2147
+ "device",
2148
+ "b4814eb28f92350f362af5eb7a1dc6b9bdd1d27e789f5d97ad3b8c7653753076"
2149
+ ],
2150
+ [
2151
+ "expiration",
2152
+ "1800000000"
2153
+ ]
2154
+ ],
2155
+ "content": "",
2156
+ "pubkey": "b07ff66ffca2d5445cfb4a384e94fba8ecc5000283b43f2d5425c85df5032e74",
2157
+ "id": "fd90215d7918c90444bff0a76aad33f610d89009b14f4f5bbfb564c3ba9fe99a",
2158
+ "sig": "b6b8288debc3091305e3dcc62dfa7161603a31918978da3a63216c6e5676a1c2d9749d54a5d5ff9e493e63248bf98a123cec67180d3588bec96ca55594dede51"
2159
+ },
2160
+ "roomId": "2848bdd5c60a79e2dfe667ae9616c1107f61709032b66e556e28f4a96e69450b",
2161
+ "now": 1799999999
2162
+ },
2163
+ "output": {
2164
+ "result": {
2165
+ "ok": true,
2166
+ "participant": "b07ff66ffca2d5445cfb4a384e94fba8ecc5000283b43f2d5425c85df5032e74",
2167
+ "device": "b4814eb28f92350f362af5eb7a1dc6b9bdd1d27e789f5d97ad3b8c7653753076"
2168
+ }
2169
+ }
2170
+ }
2171
+ ]
2172
+ }
2173
+ }