@consiliency/agent-board-schema 1.63.0 → 1.64.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.
- package/README.md +6 -0
- package/fixtures/already-applied.json +4 -0
- package/migrations/20261014000200_agent_board_last_owner.sql +239 -0
- package/package.json +1 -1
- package/schema-manifest.json +12 -3
- package/src/tooling.test.mjs +6 -2
- package/tests/agent_board_atomic_fleet_onboarding.test.sql +3 -1
- package/tests/agent_board_atomic_fleet_onboarding_runtime.test.sql +7 -0
- package/tests/agent_board_fk_lock_edges.test.sql +3 -2
- package/tests/agent_board_grant_target_role.test.sql +4 -4
- package/tests/agent_board_hosted_delegates.test.sql +5 -3
- package/tests/agent_board_invite_no_downgrade.test.sql +5 -3
- package/tests/agent_board_ledger_authority.test.sql +7 -0
- package/tests/agent_board_role_guard.test.sql +319 -0
- package/tests/agent_board_rolereset.test.sql +17 -27
- package/tests/agent_board_roomdeleg.test.sql +8 -0
- package/tests/agent_board_roomown.test.sql +3 -1
- package/tests/agent_board_rowid.test.sql +4 -1
- package/tests/catalog/function_execute_privileges.json +9 -0
- package/tests/catalog/p_metadata_parameters.json +4 -0
- package/tests/isolation/expected/last_owner_departure.out +562 -0
- package/tests/isolation/specs/atomic_fleet_authority_races.spec +8 -3
- package/tests/isolation/specs/atomic_fleet_binding_revoke.spec +0 -3
- package/tests/isolation/specs/atomic_fleet_board_archive.spec +0 -3
- package/tests/isolation/specs/atomic_fleet_human_fresh_revoke.spec +0 -3
- package/tests/isolation/specs/atomic_fleet_identity_disposition.spec +0 -3
- package/tests/isolation/specs/atomic_fleet_lifecycle_races.spec +0 -3
- package/tests/isolation/specs/atomic_fleet_subtree_lock_order.spec +0 -3
- package/tests/isolation/specs/ceiling_setter_lock_before_upsert.spec +0 -3
- package/tests/isolation/specs/claimpolicy_acquire_revert_race.spec +0 -2
- package/tests/isolation/specs/claimpolicy_board_scope.spec +0 -2
- package/tests/isolation/specs/claimpolicy_claimrow_lock_order.spec +0 -2
- package/tests/isolation/specs/claimpolicy_isolation_refusal.spec +0 -2
- package/tests/isolation/specs/claimpolicy_renew_revert_race.spec +0 -2
- package/tests/isolation/specs/claimpolicy_writer_keyshare.spec +0 -2
- package/tests/isolation/specs/consent_approval_lock.spec +0 -1
- package/tests/isolation/specs/consent_emit_actual_state.spec +0 -1
- package/tests/isolation/specs/grant_target_role_race.spec +0 -1
- package/tests/isolation/specs/hosted_delegate_add_tombstone_race.spec +0 -1
- package/tests/isolation/specs/hosted_delegate_tombstone_revoke_race.spec +0 -1
- package/tests/isolation/specs/hosted_delegate_withdraw_evict_race.spec +0 -1
- package/tests/isolation/specs/last_owner_departure.spec +137 -0
- package/tests/isolation/specs/ledger_authority_revoke.spec +0 -3
- package/tests/isolation/specs/onboarding_ceiling_lock_order.spec +0 -3
- package/tests/isolation/specs/outbox_wake_ordering.spec +0 -1
- package/tests/isolation/specs/session_identity_links.spec +3 -1
- package/tests/isolation/specs/session_identity_tombstone_onboarding.spec +0 -1
- package/tests/isolation/specs/signed_grant_onboarding_deadlock.spec +0 -1
- package/tests/isolation/specs/signer_lifecycle_revoke.spec +0 -1
|
@@ -0,0 +1,562 @@
|
|
|
1
|
+
Parsed test spec with 3 sessions
|
|
2
|
+
|
|
3
|
+
starting permutation: a_begin a_leave b_begin b_leave a_commit b_commit owners
|
|
4
|
+
step a_begin:
|
|
5
|
+
begin;
|
|
6
|
+
set local role authenticated;
|
|
7
|
+
select set_config('request.jwt.claims', json_build_object('role','authenticated','sub','67500000-0000-0000-0000-000000000001')::text,true) is not null as authenticated;
|
|
8
|
+
|
|
9
|
+
authenticated
|
|
10
|
+
-------------
|
|
11
|
+
t
|
|
12
|
+
(1 row)
|
|
13
|
+
|
|
14
|
+
step a_leave:
|
|
15
|
+
select membership_state from agent_board.leave_board(
|
|
16
|
+
'67520000-0000-4000-8000-000000000099','67510000-0000-4000-8000-000000000001');
|
|
17
|
+
|
|
18
|
+
membership_state
|
|
19
|
+
----------------
|
|
20
|
+
left
|
|
21
|
+
(1 row)
|
|
22
|
+
|
|
23
|
+
step b_begin:
|
|
24
|
+
begin;
|
|
25
|
+
set local role authenticated;
|
|
26
|
+
select set_config('request.jwt.claims', json_build_object('role','authenticated','sub','67500000-0000-0000-0000-000000000002')::text,true) is not null as authenticated;
|
|
27
|
+
|
|
28
|
+
authenticated
|
|
29
|
+
-------------
|
|
30
|
+
t
|
|
31
|
+
(1 row)
|
|
32
|
+
|
|
33
|
+
step b_leave:
|
|
34
|
+
select membership_state from agent_board.leave_board(
|
|
35
|
+
'67520000-0000-4000-8000-000000000099','67510000-0000-4000-8000-000000000002');
|
|
36
|
+
<waiting ...>
|
|
37
|
+
step a_commit: commit;
|
|
38
|
+
step b_leave: <... completed>
|
|
39
|
+
ERROR: last_active_board_owner: cannot remove the last active owner
|
|
40
|
+
step b_commit: commit;
|
|
41
|
+
step owners:
|
|
42
|
+
select count(*) as active_owners from agent_board.board_memberships
|
|
43
|
+
where board_id='67520000-0000-4000-8000-000000000099'
|
|
44
|
+
and role='owner' and membership_state in ('joined','subscribed');
|
|
45
|
+
|
|
46
|
+
active_owners
|
|
47
|
+
-------------
|
|
48
|
+
1
|
|
49
|
+
(1 row)
|
|
50
|
+
|
|
51
|
+
|
|
52
|
+
starting permutation: b_begin b_leave a_begin a_leave b_commit a_commit owners
|
|
53
|
+
step b_begin:
|
|
54
|
+
begin;
|
|
55
|
+
set local role authenticated;
|
|
56
|
+
select set_config('request.jwt.claims', json_build_object('role','authenticated','sub','67500000-0000-0000-0000-000000000002')::text,true) is not null as authenticated;
|
|
57
|
+
|
|
58
|
+
authenticated
|
|
59
|
+
-------------
|
|
60
|
+
t
|
|
61
|
+
(1 row)
|
|
62
|
+
|
|
63
|
+
step b_leave:
|
|
64
|
+
select membership_state from agent_board.leave_board(
|
|
65
|
+
'67520000-0000-4000-8000-000000000099','67510000-0000-4000-8000-000000000002');
|
|
66
|
+
|
|
67
|
+
membership_state
|
|
68
|
+
----------------
|
|
69
|
+
left
|
|
70
|
+
(1 row)
|
|
71
|
+
|
|
72
|
+
step a_begin:
|
|
73
|
+
begin;
|
|
74
|
+
set local role authenticated;
|
|
75
|
+
select set_config('request.jwt.claims', json_build_object('role','authenticated','sub','67500000-0000-0000-0000-000000000001')::text,true) is not null as authenticated;
|
|
76
|
+
|
|
77
|
+
authenticated
|
|
78
|
+
-------------
|
|
79
|
+
t
|
|
80
|
+
(1 row)
|
|
81
|
+
|
|
82
|
+
step a_leave:
|
|
83
|
+
select membership_state from agent_board.leave_board(
|
|
84
|
+
'67520000-0000-4000-8000-000000000099','67510000-0000-4000-8000-000000000001');
|
|
85
|
+
<waiting ...>
|
|
86
|
+
step b_commit: commit;
|
|
87
|
+
step a_leave: <... completed>
|
|
88
|
+
ERROR: last_active_board_owner: cannot remove the last active owner
|
|
89
|
+
step a_commit: commit;
|
|
90
|
+
step owners:
|
|
91
|
+
select count(*) as active_owners from agent_board.board_memberships
|
|
92
|
+
where board_id='67520000-0000-4000-8000-000000000099'
|
|
93
|
+
and role='owner' and membership_state in ('joined','subscribed');
|
|
94
|
+
|
|
95
|
+
active_owners
|
|
96
|
+
-------------
|
|
97
|
+
1
|
|
98
|
+
(1 row)
|
|
99
|
+
|
|
100
|
+
|
|
101
|
+
starting permutation: a_begin a_demote b_begin b_demote a_commit b_commit owners
|
|
102
|
+
step a_begin:
|
|
103
|
+
begin;
|
|
104
|
+
set local role authenticated;
|
|
105
|
+
select set_config('request.jwt.claims', json_build_object('role','authenticated','sub','67500000-0000-0000-0000-000000000001')::text,true) is not null as authenticated;
|
|
106
|
+
|
|
107
|
+
authenticated
|
|
108
|
+
-------------
|
|
109
|
+
t
|
|
110
|
+
(1 row)
|
|
111
|
+
|
|
112
|
+
step a_demote:
|
|
113
|
+
select role from agent_board.grant_board_role(
|
|
114
|
+
'67520000-0000-4000-8000-000000000099','67510000-0000-4000-8000-000000000001','member');
|
|
115
|
+
|
|
116
|
+
role
|
|
117
|
+
------
|
|
118
|
+
member
|
|
119
|
+
(1 row)
|
|
120
|
+
|
|
121
|
+
step b_begin:
|
|
122
|
+
begin;
|
|
123
|
+
set local role authenticated;
|
|
124
|
+
select set_config('request.jwt.claims', json_build_object('role','authenticated','sub','67500000-0000-0000-0000-000000000002')::text,true) is not null as authenticated;
|
|
125
|
+
|
|
126
|
+
authenticated
|
|
127
|
+
-------------
|
|
128
|
+
t
|
|
129
|
+
(1 row)
|
|
130
|
+
|
|
131
|
+
step b_demote:
|
|
132
|
+
select role from agent_board.grant_board_role(
|
|
133
|
+
'67520000-0000-4000-8000-000000000099','67510000-0000-4000-8000-000000000002','member');
|
|
134
|
+
<waiting ...>
|
|
135
|
+
step a_commit: commit;
|
|
136
|
+
step b_demote: <... completed>
|
|
137
|
+
ERROR: last_active_board_owner: cannot remove the last active owner
|
|
138
|
+
step b_commit: commit;
|
|
139
|
+
step owners:
|
|
140
|
+
select count(*) as active_owners from agent_board.board_memberships
|
|
141
|
+
where board_id='67520000-0000-4000-8000-000000000099'
|
|
142
|
+
and role='owner' and membership_state in ('joined','subscribed');
|
|
143
|
+
|
|
144
|
+
active_owners
|
|
145
|
+
-------------
|
|
146
|
+
1
|
|
147
|
+
(1 row)
|
|
148
|
+
|
|
149
|
+
|
|
150
|
+
starting permutation: b_begin b_demote a_begin a_demote b_commit a_commit owners
|
|
151
|
+
step b_begin:
|
|
152
|
+
begin;
|
|
153
|
+
set local role authenticated;
|
|
154
|
+
select set_config('request.jwt.claims', json_build_object('role','authenticated','sub','67500000-0000-0000-0000-000000000002')::text,true) is not null as authenticated;
|
|
155
|
+
|
|
156
|
+
authenticated
|
|
157
|
+
-------------
|
|
158
|
+
t
|
|
159
|
+
(1 row)
|
|
160
|
+
|
|
161
|
+
step b_demote:
|
|
162
|
+
select role from agent_board.grant_board_role(
|
|
163
|
+
'67520000-0000-4000-8000-000000000099','67510000-0000-4000-8000-000000000002','member');
|
|
164
|
+
|
|
165
|
+
role
|
|
166
|
+
------
|
|
167
|
+
member
|
|
168
|
+
(1 row)
|
|
169
|
+
|
|
170
|
+
step a_begin:
|
|
171
|
+
begin;
|
|
172
|
+
set local role authenticated;
|
|
173
|
+
select set_config('request.jwt.claims', json_build_object('role','authenticated','sub','67500000-0000-0000-0000-000000000001')::text,true) is not null as authenticated;
|
|
174
|
+
|
|
175
|
+
authenticated
|
|
176
|
+
-------------
|
|
177
|
+
t
|
|
178
|
+
(1 row)
|
|
179
|
+
|
|
180
|
+
step a_demote:
|
|
181
|
+
select role from agent_board.grant_board_role(
|
|
182
|
+
'67520000-0000-4000-8000-000000000099','67510000-0000-4000-8000-000000000001','member');
|
|
183
|
+
<waiting ...>
|
|
184
|
+
step b_commit: commit;
|
|
185
|
+
step a_demote: <... completed>
|
|
186
|
+
ERROR: last_active_board_owner: cannot remove the last active owner
|
|
187
|
+
step a_commit: commit;
|
|
188
|
+
step owners:
|
|
189
|
+
select count(*) as active_owners from agent_board.board_memberships
|
|
190
|
+
where board_id='67520000-0000-4000-8000-000000000099'
|
|
191
|
+
and role='owner' and membership_state in ('joined','subscribed');
|
|
192
|
+
|
|
193
|
+
active_owners
|
|
194
|
+
-------------
|
|
195
|
+
1
|
|
196
|
+
(1 row)
|
|
197
|
+
|
|
198
|
+
|
|
199
|
+
starting permutation: a_begin a_leave b_begin b_demote a_commit b_commit owners
|
|
200
|
+
step a_begin:
|
|
201
|
+
begin;
|
|
202
|
+
set local role authenticated;
|
|
203
|
+
select set_config('request.jwt.claims', json_build_object('role','authenticated','sub','67500000-0000-0000-0000-000000000001')::text,true) is not null as authenticated;
|
|
204
|
+
|
|
205
|
+
authenticated
|
|
206
|
+
-------------
|
|
207
|
+
t
|
|
208
|
+
(1 row)
|
|
209
|
+
|
|
210
|
+
step a_leave:
|
|
211
|
+
select membership_state from agent_board.leave_board(
|
|
212
|
+
'67520000-0000-4000-8000-000000000099','67510000-0000-4000-8000-000000000001');
|
|
213
|
+
|
|
214
|
+
membership_state
|
|
215
|
+
----------------
|
|
216
|
+
left
|
|
217
|
+
(1 row)
|
|
218
|
+
|
|
219
|
+
step b_begin:
|
|
220
|
+
begin;
|
|
221
|
+
set local role authenticated;
|
|
222
|
+
select set_config('request.jwt.claims', json_build_object('role','authenticated','sub','67500000-0000-0000-0000-000000000002')::text,true) is not null as authenticated;
|
|
223
|
+
|
|
224
|
+
authenticated
|
|
225
|
+
-------------
|
|
226
|
+
t
|
|
227
|
+
(1 row)
|
|
228
|
+
|
|
229
|
+
step b_demote:
|
|
230
|
+
select role from agent_board.grant_board_role(
|
|
231
|
+
'67520000-0000-4000-8000-000000000099','67510000-0000-4000-8000-000000000002','member');
|
|
232
|
+
<waiting ...>
|
|
233
|
+
step a_commit: commit;
|
|
234
|
+
step b_demote: <... completed>
|
|
235
|
+
ERROR: last_active_board_owner: cannot remove the last active owner
|
|
236
|
+
step b_commit: commit;
|
|
237
|
+
step owners:
|
|
238
|
+
select count(*) as active_owners from agent_board.board_memberships
|
|
239
|
+
where board_id='67520000-0000-4000-8000-000000000099'
|
|
240
|
+
and role='owner' and membership_state in ('joined','subscribed');
|
|
241
|
+
|
|
242
|
+
active_owners
|
|
243
|
+
-------------
|
|
244
|
+
1
|
|
245
|
+
(1 row)
|
|
246
|
+
|
|
247
|
+
|
|
248
|
+
starting permutation: b_begin b_demote a_begin a_leave b_commit a_commit owners
|
|
249
|
+
step b_begin:
|
|
250
|
+
begin;
|
|
251
|
+
set local role authenticated;
|
|
252
|
+
select set_config('request.jwt.claims', json_build_object('role','authenticated','sub','67500000-0000-0000-0000-000000000002')::text,true) is not null as authenticated;
|
|
253
|
+
|
|
254
|
+
authenticated
|
|
255
|
+
-------------
|
|
256
|
+
t
|
|
257
|
+
(1 row)
|
|
258
|
+
|
|
259
|
+
step b_demote:
|
|
260
|
+
select role from agent_board.grant_board_role(
|
|
261
|
+
'67520000-0000-4000-8000-000000000099','67510000-0000-4000-8000-000000000002','member');
|
|
262
|
+
|
|
263
|
+
role
|
|
264
|
+
------
|
|
265
|
+
member
|
|
266
|
+
(1 row)
|
|
267
|
+
|
|
268
|
+
step a_begin:
|
|
269
|
+
begin;
|
|
270
|
+
set local role authenticated;
|
|
271
|
+
select set_config('request.jwt.claims', json_build_object('role','authenticated','sub','67500000-0000-0000-0000-000000000001')::text,true) is not null as authenticated;
|
|
272
|
+
|
|
273
|
+
authenticated
|
|
274
|
+
-------------
|
|
275
|
+
t
|
|
276
|
+
(1 row)
|
|
277
|
+
|
|
278
|
+
step a_leave:
|
|
279
|
+
select membership_state from agent_board.leave_board(
|
|
280
|
+
'67520000-0000-4000-8000-000000000099','67510000-0000-4000-8000-000000000001');
|
|
281
|
+
<waiting ...>
|
|
282
|
+
step b_commit: commit;
|
|
283
|
+
step a_leave: <... completed>
|
|
284
|
+
ERROR: last_active_board_owner: cannot remove the last active owner
|
|
285
|
+
step a_commit: commit;
|
|
286
|
+
step owners:
|
|
287
|
+
select count(*) as active_owners from agent_board.board_memberships
|
|
288
|
+
where board_id='67520000-0000-4000-8000-000000000099'
|
|
289
|
+
and role='owner' and membership_state in ('joined','subscribed');
|
|
290
|
+
|
|
291
|
+
active_owners
|
|
292
|
+
-------------
|
|
293
|
+
1
|
|
294
|
+
(1 row)
|
|
295
|
+
|
|
296
|
+
|
|
297
|
+
starting permutation: a_begin a_raw b_begin b_raw a_commit b_commit owners
|
|
298
|
+
step a_begin:
|
|
299
|
+
begin;
|
|
300
|
+
set local role authenticated;
|
|
301
|
+
select set_config('request.jwt.claims', json_build_object('role','authenticated','sub','67500000-0000-0000-0000-000000000001')::text,true) is not null as authenticated;
|
|
302
|
+
|
|
303
|
+
authenticated
|
|
304
|
+
-------------
|
|
305
|
+
t
|
|
306
|
+
(1 row)
|
|
307
|
+
|
|
308
|
+
step a_raw:
|
|
309
|
+
reset role;
|
|
310
|
+
select agent_board._lock_board_authority_ceiling('67520000-0000-4000-8000-000000000099');
|
|
311
|
+
update agent_board.board_memberships set membership_state='left',left_at=now()
|
|
312
|
+
where board_id='67520000-0000-4000-8000-000000000099'
|
|
313
|
+
and agent_id='67510000-0000-4000-8000-000000000001';
|
|
314
|
+
|
|
315
|
+
_lock_board_authority_ceiling
|
|
316
|
+
-----------------------------
|
|
317
|
+
|
|
318
|
+
(1 row)
|
|
319
|
+
|
|
320
|
+
step b_begin:
|
|
321
|
+
begin;
|
|
322
|
+
set local role authenticated;
|
|
323
|
+
select set_config('request.jwt.claims', json_build_object('role','authenticated','sub','67500000-0000-0000-0000-000000000002')::text,true) is not null as authenticated;
|
|
324
|
+
|
|
325
|
+
authenticated
|
|
326
|
+
-------------
|
|
327
|
+
t
|
|
328
|
+
(1 row)
|
|
329
|
+
|
|
330
|
+
step b_raw:
|
|
331
|
+
reset role;
|
|
332
|
+
delete from agent_board.board_memberships
|
|
333
|
+
where board_id='67520000-0000-4000-8000-000000000099'
|
|
334
|
+
and agent_id='67510000-0000-4000-8000-000000000002';
|
|
335
|
+
|
|
336
|
+
ERROR: last_active_board_owner: acquire board authority lock before owner transition
|
|
337
|
+
step a_commit: commit;
|
|
338
|
+
step b_commit: commit;
|
|
339
|
+
step owners:
|
|
340
|
+
select count(*) as active_owners from agent_board.board_memberships
|
|
341
|
+
where board_id='67520000-0000-4000-8000-000000000099'
|
|
342
|
+
and role='owner' and membership_state in ('joined','subscribed');
|
|
343
|
+
|
|
344
|
+
active_owners
|
|
345
|
+
-------------
|
|
346
|
+
1
|
|
347
|
+
(1 row)
|
|
348
|
+
|
|
349
|
+
|
|
350
|
+
starting permutation: b_begin b_lock b_raw a_begin a_raw b_commit a_commit owners
|
|
351
|
+
step b_begin:
|
|
352
|
+
begin;
|
|
353
|
+
set local role authenticated;
|
|
354
|
+
select set_config('request.jwt.claims', json_build_object('role','authenticated','sub','67500000-0000-0000-0000-000000000002')::text,true) is not null as authenticated;
|
|
355
|
+
|
|
356
|
+
authenticated
|
|
357
|
+
-------------
|
|
358
|
+
t
|
|
359
|
+
(1 row)
|
|
360
|
+
|
|
361
|
+
step b_lock:
|
|
362
|
+
reset role;
|
|
363
|
+
select agent_board._lock_board_authority_ceiling('67520000-0000-4000-8000-000000000099');
|
|
364
|
+
|
|
365
|
+
_lock_board_authority_ceiling
|
|
366
|
+
-----------------------------
|
|
367
|
+
|
|
368
|
+
(1 row)
|
|
369
|
+
|
|
370
|
+
step b_raw:
|
|
371
|
+
reset role;
|
|
372
|
+
delete from agent_board.board_memberships
|
|
373
|
+
where board_id='67520000-0000-4000-8000-000000000099'
|
|
374
|
+
and agent_id='67510000-0000-4000-8000-000000000002';
|
|
375
|
+
|
|
376
|
+
step a_begin:
|
|
377
|
+
begin;
|
|
378
|
+
set local role authenticated;
|
|
379
|
+
select set_config('request.jwt.claims', json_build_object('role','authenticated','sub','67500000-0000-0000-0000-000000000001')::text,true) is not null as authenticated;
|
|
380
|
+
|
|
381
|
+
authenticated
|
|
382
|
+
-------------
|
|
383
|
+
t
|
|
384
|
+
(1 row)
|
|
385
|
+
|
|
386
|
+
step a_raw:
|
|
387
|
+
reset role;
|
|
388
|
+
select agent_board._lock_board_authority_ceiling('67520000-0000-4000-8000-000000000099');
|
|
389
|
+
update agent_board.board_memberships set membership_state='left',left_at=now()
|
|
390
|
+
where board_id='67520000-0000-4000-8000-000000000099'
|
|
391
|
+
and agent_id='67510000-0000-4000-8000-000000000001';
|
|
392
|
+
<waiting ...>
|
|
393
|
+
step b_commit: commit;
|
|
394
|
+
step a_raw: <... completed>
|
|
395
|
+
_lock_board_authority_ceiling
|
|
396
|
+
-----------------------------
|
|
397
|
+
|
|
398
|
+
(1 row)
|
|
399
|
+
|
|
400
|
+
ERROR: last_active_board_owner: cannot remove the last active owner
|
|
401
|
+
step a_commit: commit;
|
|
402
|
+
step owners:
|
|
403
|
+
select count(*) as active_owners from agent_board.board_memberships
|
|
404
|
+
where board_id='67520000-0000-4000-8000-000000000099'
|
|
405
|
+
and role='owner' and membership_state in ('joined','subscribed');
|
|
406
|
+
|
|
407
|
+
active_owners
|
|
408
|
+
-------------
|
|
409
|
+
1
|
|
410
|
+
(1 row)
|
|
411
|
+
|
|
412
|
+
|
|
413
|
+
starting permutation: a_repeatable a_leave_code a_commit owners
|
|
414
|
+
step a_repeatable:
|
|
415
|
+
begin isolation level repeatable read;
|
|
416
|
+
set local role authenticated;
|
|
417
|
+
select set_config('request.jwt.claims', json_build_object('role','authenticated','sub','67500000-0000-0000-0000-000000000001')::text,true) is not null as authenticated;
|
|
418
|
+
|
|
419
|
+
authenticated
|
|
420
|
+
-------------
|
|
421
|
+
t
|
|
422
|
+
(1 row)
|
|
423
|
+
|
|
424
|
+
step a_leave_code:
|
|
425
|
+
select public.roleguard_isolation_refusal($probe$
|
|
426
|
+
select agent_board.leave_board(
|
|
427
|
+
'67520000-0000-4000-8000-000000000099','67510000-0000-4000-8000-000000000001')
|
|
428
|
+
$probe$) as error_code;
|
|
429
|
+
|
|
430
|
+
error_code
|
|
431
|
+
----------
|
|
432
|
+
25001
|
|
433
|
+
(1 row)
|
|
434
|
+
|
|
435
|
+
step a_commit: commit;
|
|
436
|
+
step owners:
|
|
437
|
+
select count(*) as active_owners from agent_board.board_memberships
|
|
438
|
+
where board_id='67520000-0000-4000-8000-000000000099'
|
|
439
|
+
and role='owner' and membership_state in ('joined','subscribed');
|
|
440
|
+
|
|
441
|
+
active_owners
|
|
442
|
+
-------------
|
|
443
|
+
2
|
|
444
|
+
(1 row)
|
|
445
|
+
|
|
446
|
+
|
|
447
|
+
starting permutation: a_session_begin a_session_leave a_session_unlock b_begin b_leave a_commit b_commit owners
|
|
448
|
+
step a_session_begin:
|
|
449
|
+
begin;
|
|
450
|
+
select pg_advisory_lock(hashtextextended(
|
|
451
|
+
'agent_board.board_authority_ceilings:67520000-0000-4000-8000-000000000099',0));
|
|
452
|
+
|
|
453
|
+
pg_advisory_lock
|
|
454
|
+
----------------
|
|
455
|
+
|
|
456
|
+
(1 row)
|
|
457
|
+
|
|
458
|
+
step a_session_leave:
|
|
459
|
+
update agent_board.board_memberships set membership_state='left',left_at=now()
|
|
460
|
+
where board_id='67520000-0000-4000-8000-000000000099'
|
|
461
|
+
and agent_id='67510000-0000-4000-8000-000000000001';
|
|
462
|
+
|
|
463
|
+
step a_session_unlock:
|
|
464
|
+
select pg_advisory_unlock(hashtextextended(
|
|
465
|
+
'agent_board.board_authority_ceilings:67520000-0000-4000-8000-000000000099',0));
|
|
466
|
+
|
|
467
|
+
pg_advisory_unlock
|
|
468
|
+
------------------
|
|
469
|
+
t
|
|
470
|
+
(1 row)
|
|
471
|
+
|
|
472
|
+
step b_begin:
|
|
473
|
+
begin;
|
|
474
|
+
set local role authenticated;
|
|
475
|
+
select set_config('request.jwt.claims', json_build_object('role','authenticated','sub','67500000-0000-0000-0000-000000000002')::text,true) is not null as authenticated;
|
|
476
|
+
|
|
477
|
+
authenticated
|
|
478
|
+
-------------
|
|
479
|
+
t
|
|
480
|
+
(1 row)
|
|
481
|
+
|
|
482
|
+
step b_leave:
|
|
483
|
+
select membership_state from agent_board.leave_board(
|
|
484
|
+
'67520000-0000-4000-8000-000000000099','67510000-0000-4000-8000-000000000002');
|
|
485
|
+
<waiting ...>
|
|
486
|
+
step a_commit: commit;
|
|
487
|
+
step b_leave: <... completed>
|
|
488
|
+
ERROR: last_active_board_owner: cannot remove the last active owner
|
|
489
|
+
step b_commit: commit;
|
|
490
|
+
step owners:
|
|
491
|
+
select count(*) as active_owners from agent_board.board_memberships
|
|
492
|
+
where board_id='67520000-0000-4000-8000-000000000099'
|
|
493
|
+
and role='owner' and membership_state in ('joined','subscribed');
|
|
494
|
+
|
|
495
|
+
active_owners
|
|
496
|
+
-------------
|
|
497
|
+
1
|
|
498
|
+
(1 row)
|
|
499
|
+
|
|
500
|
+
|
|
501
|
+
starting permutation: a_repeatable a_snapshot b_begin b_leave a_leave_code b_commit a_commit owners
|
|
502
|
+
step a_repeatable:
|
|
503
|
+
begin isolation level repeatable read;
|
|
504
|
+
set local role authenticated;
|
|
505
|
+
select set_config('request.jwt.claims', json_build_object('role','authenticated','sub','67500000-0000-0000-0000-000000000001')::text,true) is not null as authenticated;
|
|
506
|
+
|
|
507
|
+
authenticated
|
|
508
|
+
-------------
|
|
509
|
+
t
|
|
510
|
+
(1 row)
|
|
511
|
+
|
|
512
|
+
step a_snapshot:
|
|
513
|
+
select count(*) as snapshot_owners from agent_board.board_memberships where board_id='67520000-0000-4000-8000-000000000099' and role='owner' and membership_state in ('joined','subscribed');
|
|
514
|
+
|
|
515
|
+
snapshot_owners
|
|
516
|
+
---------------
|
|
517
|
+
1
|
|
518
|
+
(1 row)
|
|
519
|
+
|
|
520
|
+
step b_begin:
|
|
521
|
+
begin;
|
|
522
|
+
set local role authenticated;
|
|
523
|
+
select set_config('request.jwt.claims', json_build_object('role','authenticated','sub','67500000-0000-0000-0000-000000000002')::text,true) is not null as authenticated;
|
|
524
|
+
|
|
525
|
+
authenticated
|
|
526
|
+
-------------
|
|
527
|
+
t
|
|
528
|
+
(1 row)
|
|
529
|
+
|
|
530
|
+
step b_leave:
|
|
531
|
+
select membership_state from agent_board.leave_board(
|
|
532
|
+
'67520000-0000-4000-8000-000000000099','67510000-0000-4000-8000-000000000002');
|
|
533
|
+
|
|
534
|
+
membership_state
|
|
535
|
+
----------------
|
|
536
|
+
left
|
|
537
|
+
(1 row)
|
|
538
|
+
|
|
539
|
+
step a_leave_code:
|
|
540
|
+
select public.roleguard_isolation_refusal($probe$
|
|
541
|
+
select agent_board.leave_board(
|
|
542
|
+
'67520000-0000-4000-8000-000000000099','67510000-0000-4000-8000-000000000001')
|
|
543
|
+
$probe$) as error_code;
|
|
544
|
+
<waiting ...>
|
|
545
|
+
step b_commit: commit;
|
|
546
|
+
step a_leave_code: <... completed>
|
|
547
|
+
error_code
|
|
548
|
+
----------
|
|
549
|
+
25001
|
|
550
|
+
(1 row)
|
|
551
|
+
|
|
552
|
+
step a_commit: commit;
|
|
553
|
+
step owners:
|
|
554
|
+
select count(*) as active_owners from agent_board.board_memberships
|
|
555
|
+
where board_id='67520000-0000-4000-8000-000000000099'
|
|
556
|
+
and role='owner' and membership_state in ('joined','subscribed');
|
|
557
|
+
|
|
558
|
+
active_owners
|
|
559
|
+
-------------
|
|
560
|
+
1
|
|
561
|
+
(1 row)
|
|
562
|
+
|
|
@@ -49,6 +49,10 @@ setup
|
|
|
49
49
|
values ('16250000-0000-0000-0000-000000000001', 'agent', 'agent',
|
|
50
50
|
'atomic-authority-owner', 'Atomic Authority Owner', 'active',
|
|
51
51
|
'16250000-0000-0000-0000-0000000000a1');
|
|
52
|
+
-- ROLEGUARD: isolate creator authority loss while another owner preserves the board.
|
|
53
|
+
insert into agent_board.agents(id, agent_type, kind, handle, display_name, status)
|
|
54
|
+
values ('16250000-0000-0000-0000-000000000004', 'agent', 'agent',
|
|
55
|
+
'atomic-authority-coowner', 'Atomic Authority Coowner', 'active');
|
|
52
56
|
|
|
53
57
|
select count(*) from agent_board.create_board(
|
|
54
58
|
'16250000-0000-0000-0000-000000000001',
|
|
@@ -56,6 +60,9 @@ setup
|
|
|
56
60
|
'Consiliency/message-board#162 authority isolation proof',
|
|
57
61
|
jsonb_build_object(), 'private'
|
|
58
62
|
);
|
|
63
|
+
insert into agent_board.board_memberships(board_id, agent_id, role, membership_state)
|
|
64
|
+
values ((select id from agent_board.boards where slug='atomic-authority-board'),
|
|
65
|
+
'16250000-0000-0000-0000-000000000004', 'owner', 'joined');
|
|
59
66
|
insert into agent_board.fleet_trust_domains(
|
|
60
67
|
id, slug, display_name, domain_kind, owner_agent_id, lifecycle_state, approved_at
|
|
61
68
|
) values (
|
|
@@ -120,9 +127,6 @@ teardown
|
|
|
120
127
|
delete from agent_board.board_authority_ceilings where board_id in (
|
|
121
128
|
select id from agent_board.boards where slug='atomic-authority-board'
|
|
122
129
|
);
|
|
123
|
-
delete from agent_board.board_memberships where board_id in (
|
|
124
|
-
select id from agent_board.boards where slug='atomic-authority-board'
|
|
125
|
-
);
|
|
126
130
|
delete from agent_board.enrollment_federation_audit where agent_id in (
|
|
127
131
|
select id from agent_board.agents where handle='atomic-authority-agent'
|
|
128
132
|
);
|
|
@@ -134,6 +138,7 @@ teardown
|
|
|
134
138
|
delete from agent_board.fleet_machines where id='16250000-0000-0000-0000-000000000003';
|
|
135
139
|
delete from agent_board.fleet_trust_domains where id='16250000-0000-0000-0000-000000000002';
|
|
136
140
|
delete from agent_board.agents where id='16250000-0000-0000-0000-000000000001';
|
|
141
|
+
delete from agent_board.agents where id='16250000-0000-0000-0000-000000000004';
|
|
137
142
|
delete from auth.users where id='16250000-0000-0000-0000-0000000000a1';
|
|
138
143
|
delete from agent_board.identity_providers where issuer='https://atomic-authority.test';
|
|
139
144
|
}
|
|
@@ -70,9 +70,6 @@ teardown
|
|
|
70
70
|
);
|
|
71
71
|
truncate agent_board.fleet_onboarding_invite_bounds;
|
|
72
72
|
delete from agent_board.board_invite_tokens where created_by_agent_id='16230000-0000-0000-0000-000000000001';
|
|
73
|
-
delete from agent_board.board_memberships where board_id in (
|
|
74
|
-
select id from agent_board.boards where slug='atomic-binding-board'
|
|
75
|
-
);
|
|
76
73
|
delete from agent_board.enrollment_federation_audit where agent_id in (
|
|
77
74
|
select id from agent_board.agents where handle='atomic-binding-agent'
|
|
78
75
|
);
|
|
@@ -70,9 +70,6 @@ teardown
|
|
|
70
70
|
);
|
|
71
71
|
truncate agent_board.fleet_onboarding_invite_bounds;
|
|
72
72
|
delete from agent_board.board_invite_tokens where created_by_agent_id='16290000-0000-0000-0000-000000000001';
|
|
73
|
-
delete from agent_board.board_memberships where board_id in (
|
|
74
|
-
select id from agent_board.boards where slug='atomic-archive-board'
|
|
75
|
-
);
|
|
76
73
|
delete from agent_board.enrollment_federation_audit where issuer='https://atomic-archive.test';
|
|
77
74
|
delete from agent_board.agent_signing_keys where agent_id in (
|
|
78
75
|
select id from agent_board.agents where handle='atomic-archive-agent'
|
|
@@ -68,9 +68,6 @@ teardown
|
|
|
68
68
|
);
|
|
69
69
|
truncate agent_board.fleet_onboarding_invite_bounds;
|
|
70
70
|
delete from agent_board.board_invite_tokens where created_by_agent_id='16280000-0000-0000-0000-000000000001';
|
|
71
|
-
delete from agent_board.board_memberships where board_id in (
|
|
72
|
-
select id from agent_board.boards where slug='atomic-human-board'
|
|
73
|
-
);
|
|
74
71
|
delete from agent_board.enrollment_federation_audit where issuer='https://atomic-human.test';
|
|
75
72
|
delete from agent_board.agent_signing_keys where agent_id in (
|
|
76
73
|
select id from agent_board.agents where handle in ('atomic-human-existing','atomic-human-fresh')
|
|
@@ -57,9 +57,6 @@ teardown
|
|
|
57
57
|
);
|
|
58
58
|
truncate agent_board.fleet_onboarding_invite_bounds;
|
|
59
59
|
delete from agent_board.board_invite_tokens where created_by_agent_id='16260000-0000-0000-0000-000000000001';
|
|
60
|
-
delete from agent_board.board_memberships where board_id in (
|
|
61
|
-
select id from agent_board.boards where slug='atomic-disposition-board'
|
|
62
|
-
);
|
|
63
60
|
delete from agent_board.enrollment_federation_audit where issuer='https://atomic-disposition.test';
|
|
64
61
|
delete from agent_board.agent_signing_keys where agent_id in (
|
|
65
62
|
select id from agent_board.agents where handle='atomic-disposition-agent'
|
|
@@ -83,9 +83,6 @@ teardown
|
|
|
83
83
|
);
|
|
84
84
|
truncate agent_board.fleet_onboarding_invite_bounds;
|
|
85
85
|
delete from agent_board.board_invite_tokens where created_by_agent_id='16240000-0000-0000-0000-000000000001';
|
|
86
|
-
delete from agent_board.board_memberships where board_id in (
|
|
87
|
-
select id from agent_board.boards where slug='atomic-lifecycle-board'
|
|
88
|
-
);
|
|
89
86
|
delete from agent_board.enrollment_federation_audit where agent_id in (
|
|
90
87
|
select id from agent_board.agents where handle='atomic-lifecycle-agent'
|
|
91
88
|
);
|
|
@@ -81,9 +81,6 @@ teardown
|
|
|
81
81
|
);
|
|
82
82
|
truncate agent_board.fleet_onboarding_invite_bounds;
|
|
83
83
|
delete from agent_board.board_invite_tokens where created_by_agent_id='ffffffff-ffff-ffff-ffff-ffffffffff01';
|
|
84
|
-
delete from agent_board.board_memberships where board_id in (
|
|
85
|
-
select id from agent_board.boards where slug='atomic-subtree-board'
|
|
86
|
-
);
|
|
87
84
|
delete from agent_board.enrollment_federation_audit where issuer='https://atomic-subtree.test';
|
|
88
85
|
delete from agent_board.agent_signing_keys where agent_id in (
|
|
89
86
|
select id from agent_board.agents where handle='atomic-subtree-agent'
|
|
@@ -53,9 +53,6 @@ teardown
|
|
|
53
53
|
delete from agent_board.board_authority_ceilings where board_id in (
|
|
54
54
|
select id from agent_board.boards where slug='ceiling-order-board'
|
|
55
55
|
);
|
|
56
|
-
delete from agent_board.board_memberships where board_id in (
|
|
57
|
-
select id from agent_board.boards where slug='ceiling-order-board'
|
|
58
|
-
);
|
|
59
56
|
delete from agent_board.boards where slug='ceiling-order-board';
|
|
60
57
|
delete from agent_board.agents where id='19600000-0000-0000-0000-000000000001';
|
|
61
58
|
delete from auth.users where id='19600000-0000-0000-0000-0000000000a1';
|
|
@@ -68,8 +68,6 @@ teardown
|
|
|
68
68
|
delete from agent_board.threads where id = '40500000-0000-4000-8000-000000000010';
|
|
69
69
|
delete from agent_board.board_membership_events where board_id in (
|
|
70
70
|
select id from agent_board.boards where slug = 'cpr-acq-board');
|
|
71
|
-
delete from agent_board.board_memberships where board_id in (
|
|
72
|
-
select id from agent_board.boards where slug = 'cpr-acq-board');
|
|
73
71
|
delete from agent_board.boards where slug = 'cpr-acq-board';
|
|
74
72
|
delete from agent_board.agents where id = '40500000-0000-4000-8000-000000000001';
|
|
75
73
|
delete from auth.users where id = '40500000-0000-4000-8000-0000000000a1';
|
|
@@ -60,8 +60,6 @@ teardown
|
|
|
60
60
|
'40500000-0000-4000-8000-000000000042');
|
|
61
61
|
delete from agent_board.board_membership_events where board_id in (
|
|
62
62
|
select id from agent_board.boards where slug in ('cpr-scope-b1', 'cpr-scope-b2'));
|
|
63
|
-
delete from agent_board.board_memberships where board_id in (
|
|
64
|
-
select id from agent_board.boards where slug in ('cpr-scope-b1', 'cpr-scope-b2'));
|
|
65
63
|
delete from agent_board.boards where slug in ('cpr-scope-b1', 'cpr-scope-b2');
|
|
66
64
|
delete from agent_board.agents where id = '40500000-0000-4000-8000-000000000003';
|
|
67
65
|
delete from auth.users where id = '40500000-0000-4000-8000-0000000000c1';
|