@consiliency/agent-board-schema 1.60.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 +86 -0
- package/fixtures/already-applied.json +16 -0
- package/migrations/20261011000100_agent_board_session_identities.sql +1964 -0
- package/migrations/20261012000100_agent_board_sidowner.sql +209 -0
- package/migrations/20261014000100_agent_board_grant_target_role.sql +218 -0
- package/migrations/20261014000200_agent_board_last_owner.sql +239 -0
- package/package.json +1 -1
- package/schema-manifest.json +39 -3
- package/src/tooling.test.mjs +10 -2
- package/tests/agent_board_atomic_fleet_onboarding.test.sql +15 -4
- package/tests/agent_board_atomic_fleet_onboarding_runtime.test.sql +7 -0
- package/tests/agent_board_consent_emission.test.sql +30 -11
- package/tests/agent_board_consent_gating.test.sql +16 -2
- package/tests/agent_board_delegate_role_class.test.sql +1 -1
- package/tests/agent_board_delegation_cap_ceiling.test.sql +26 -15
- package/tests/agent_board_delegation_enforcement.test.sql +1 -1
- package/tests/agent_board_enroll_resumption.test.sql +22 -4
- package/tests/agent_board_enroll_token_single_use.test.sql +18 -3
- package/tests/agent_board_federated_lock_order_class.test.sql +2 -2
- package/tests/agent_board_fk_lock_edges.test.sql +77 -16
- package/tests/agent_board_grant_target_role.test.sql +1118 -0
- package/tests/agent_board_hosted_delegates.test.sql +5 -3
- package/tests/agent_board_invite_no_downgrade.test.sql +15 -11
- package/tests/agent_board_ledger_authority.test.sql +77 -12
- package/tests/agent_board_membership_current_row_class.test.sql +9 -1
- package/tests/agent_board_mint_fleet_agent_session.test.sql +2 -2
- package/tests/agent_board_mint_harden.test.sql +38 -27
- package/tests/agent_board_role_guard.test.sql +319 -0
- package/tests/agent_board_rolereset.test.sql +25 -29
- package/tests/agent_board_roomdeleg.test.sql +8 -0
- package/tests/agent_board_roomdeleg_lane_b.test.sql +6 -6
- package/tests/agent_board_roomown.test.sql +3 -1
- package/tests/agent_board_rowid.test.sql +7 -2
- package/tests/agent_board_session_identity_approval_revocation.test.sql +334 -0
- package/tests/agent_board_session_identity_backfill.test.sql +82 -0
- package/tests/agent_board_session_identity_backfill_refusal.test.sql +14 -0
- package/tests/agent_board_session_identity_behavior_classes.test.sql +176 -0
- package/tests/agent_board_session_identity_class.test.sql +118 -0
- package/tests/agent_board_session_identity_fingerprint.test.sql +271 -0
- package/tests/agent_board_session_identity_labels_limits.test.sql +205 -0
- package/tests/agent_board_session_identity_lease.test.sql +235 -0
- package/tests/agent_board_session_identity_lifetime.test.sql +230 -0
- package/tests/agent_board_session_identity_limits.test.sql +208 -0
- package/tests/agent_board_session_identity_lineage.test.sql +64 -0
- package/tests/agent_board_session_identity_link.test.sql +201 -0
- package/tests/agent_board_session_identity_mint.test.sql +233 -0
- package/tests/agent_board_session_identity_panel_r1.test.sql +194 -0
- package/tests/agent_board_session_identity_panel_r2.test.sql +174 -0
- package/tests/agent_board_session_identity_protected_actions.test.sql +156 -0
- package/tests/agent_board_session_identity_revoke_closure.test.sql +131 -0
- package/tests/agent_board_sidowner_leases.test.sql +107 -0
- package/tests/agent_board_sidowner_owner_required.test.sql +97 -0
- package/tests/agent_board_sidowner_read_class.test.sql +171 -0
- package/tests/agent_board_sidowner_reads.test.sql +136 -0
- package/tests/agent_board_signer_lifecycle.test.sql +26 -4
- package/tests/agent_board_signing_challenge_pending_cap.test.sql +1 -1
- package/tests/agent_board_write_enforcement_class.test.sql +74 -15
- package/tests/catalog/function_execute_privileges.json +227 -2
- package/tests/catalog/p_metadata_parameters.json +102 -2
- package/tests/isolation/expected/grant_target_role_race.out +348 -0
- package/tests/isolation/expected/last_owner_departure.out +562 -0
- package/tests/isolation/expected/session_identity_limits.out +165 -0
- package/tests/isolation/expected/session_identity_links.out +235 -0
- package/tests/isolation/expected/session_identity_reclaim.out +253 -0
- package/tests/isolation/expected/session_identity_renew_revoke.out +115 -0
- package/tests/isolation/expected/session_identity_renew_revoke_key_gate.out +138 -0
- package/tests/isolation/expected/session_identity_tombstone_onboarding.out +247 -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 +206 -0
- 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_limits.spec +81 -0
- package/tests/isolation/specs/session_identity_links.spec +82 -0
- package/tests/isolation/specs/session_identity_reclaim.spec +125 -0
- package/tests/isolation/specs/session_identity_renew_revoke.spec +84 -0
- package/tests/isolation/specs/session_identity_renew_revoke_key_gate.spec +94 -0
- package/tests/isolation/specs/session_identity_tombstone_onboarding.spec +107 -0
- package/tests/isolation/specs/signed_grant_onboarding_deadlock.spec +0 -1
- package/tests/isolation/specs/signer_lifecycle_revoke.spec +0 -1
- package/tests/seeds/20261011000100_agent_board_session_identities.sql.pre.sql +47 -0
|
@@ -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
|
+
|