@consiliency/agent-board-schema 1.45.0 → 1.50.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/fixtures/already-applied.json +24 -0
- package/migrations/20260926000100_agent_board_ownerless_quota_census.sql +268 -0
- package/migrations/20260927000100_agent_board_fleet_domain_no_downgrade.sql +393 -0
- package/migrations/20260928000100_agent_board_ownerless_quota_renew_convergence.sql +562 -0
- package/migrations/20260929000100_agent_board_advisory_revert_cap_reset.sql +371 -0
- package/migrations/20260930000100_agent_board_claim_policy_race.sql +922 -0
- package/migrations/20261001000100_agent_board_claimpolicy_lock_grant_revoke.sql +158 -0
- package/package.json +1 -1
- package/schema-manifest.json +57 -3
- package/src/tooling.test.mjs +52 -2
- package/tests/agent_board_board_claim_policy.test.sql +261 -1
- package/tests/agent_board_claim_subject_gate.test.sql +11 -2
- package/tests/agent_board_claimkey.test.sql +17 -2
- package/tests/agent_board_claimpolicy_race.test.sql +1374 -0
- package/tests/agent_board_fleet_machine_hijack.test.sql +270 -1
- package/tests/agent_board_fleet_machine_reclaim.test.sql +28 -2
- package/tests/agent_board_ownerless_quota_census.test.sql +406 -0
- package/tests/agent_board_ownerless_renew_quota.test.sql +580 -0
- package/tests/catalog/p_metadata_parameters.json +28 -0
- package/tests/fixtures/test-prereqs.sql +186 -0
- package/tests/isolation/expected/claimpolicy_acquire_revert_race.out +66 -0
- package/tests/isolation/expected/claimpolicy_board_scope.out +73 -0
- package/tests/isolation/expected/claimpolicy_claimrow_lock_order.out +80 -0
- package/tests/isolation/expected/claimpolicy_isolation_refusal.out +114 -0
- package/tests/isolation/expected/claimpolicy_renew_revert_race.out +66 -0
- package/tests/isolation/expected/claimpolicy_writer_keyshare.out +49 -0
- package/tests/isolation/expected/fleet_domain_no_downgrade_demote_race.out +447 -0
- package/tests/isolation/specs/claimpolicy_acquire_revert_race.spec +118 -0
- package/tests/isolation/specs/claimpolicy_board_scope.spec +115 -0
- package/tests/isolation/specs/claimpolicy_claimrow_lock_order.spec +200 -0
- package/tests/isolation/specs/claimpolicy_isolation_refusal.spec +162 -0
- package/tests/isolation/specs/claimpolicy_renew_revert_race.spec +150 -0
- package/tests/isolation/specs/claimpolicy_writer_keyshare.spec +107 -0
- package/tests/isolation/specs/fleet_domain_no_downgrade_demote_race.spec +292 -0
- package/tests/seeds/20261001000100_agent_board_claimpolicy_lock_grant_revoke.sql.pre.sql +99 -0
|
@@ -0,0 +1,447 @@
|
|
|
1
|
+
Parsed test spec with 7 sessions
|
|
2
|
+
|
|
3
|
+
starting permutation: rl_begin rl_lock rm_begin rm_move rl_demote rl_commit rm_commit chk
|
|
4
|
+
step rl_begin: BEGIN; SET LOCAL "request.jwt.claim.role" = 'service_role';
|
|
5
|
+
step rl_lock:
|
|
6
|
+
select id from agent_board.fleet_machines
|
|
7
|
+
where id = 'c3970000-0000-4000-8000-000000000001' for update;
|
|
8
|
+
|
|
9
|
+
id
|
|
10
|
+
------------------------------------
|
|
11
|
+
c3970000-0000-4000-8000-000000000001
|
|
12
|
+
(1 row)
|
|
13
|
+
|
|
14
|
+
step rm_begin: BEGIN; SET LOCAL "request.jwt.claim.role" = 'service_role';
|
|
15
|
+
step rm_move:
|
|
16
|
+
select trust_domain_id
|
|
17
|
+
from agent_board.register_fleet_machine(
|
|
18
|
+
'a3970000-0000-4000-8000-000000000001', 'd3970000-0000-4000-8000-000000000002',
|
|
19
|
+
'nodowngrade-iso-machine-moved', 'sha256:nodowngrade-iso', 'portal',
|
|
20
|
+
jsonb_build_object('redacted', true));
|
|
21
|
+
<waiting ...>
|
|
22
|
+
step rl_demote:
|
|
23
|
+
update agent_board.fleet_trust_domains
|
|
24
|
+
set lifecycle_state = 'pending', approved_at = null, updated_at = now()
|
|
25
|
+
where id = 'd3970000-0000-4000-8000-000000000002';
|
|
26
|
+
|
|
27
|
+
step rl_commit: COMMIT;
|
|
28
|
+
step rm_move: <... completed>
|
|
29
|
+
ERROR: re-registration would move machine into a less approved trust domain (destination d3970000-0000-4000-8000-000000000002, current d3970000-0000-4000-8000-000000000001) — measured after the move, from one snapshot
|
|
30
|
+
step rm_commit: COMMIT;
|
|
31
|
+
step chk:
|
|
32
|
+
select fm.trust_domain_id, fm.owner_agent_id, fm.lifecycle_state as machine_state,
|
|
33
|
+
ftd.lifecycle_state as domain_state
|
|
34
|
+
from agent_board.fleet_machines fm
|
|
35
|
+
join agent_board.fleet_trust_domains ftd on ftd.id = fm.trust_domain_id
|
|
36
|
+
where fm.id = 'c3970000-0000-4000-8000-000000000001';
|
|
37
|
+
|
|
38
|
+
trust_domain_id |owner_agent_id |machine_state|domain_state
|
|
39
|
+
------------------------------------+------------------------------------+-------------+------------
|
|
40
|
+
d3970000-0000-4000-8000-000000000001|a3970000-0000-4000-8000-000000000001|active |active
|
|
41
|
+
(1 row)
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
starting permutation: rm_begin rm_move rm_commit chk
|
|
45
|
+
step rm_begin: BEGIN; SET LOCAL "request.jwt.claim.role" = 'service_role';
|
|
46
|
+
step rm_move:
|
|
47
|
+
select trust_domain_id
|
|
48
|
+
from agent_board.register_fleet_machine(
|
|
49
|
+
'a3970000-0000-4000-8000-000000000001', 'd3970000-0000-4000-8000-000000000002',
|
|
50
|
+
'nodowngrade-iso-machine-moved', 'sha256:nodowngrade-iso', 'portal',
|
|
51
|
+
jsonb_build_object('redacted', true));
|
|
52
|
+
|
|
53
|
+
trust_domain_id
|
|
54
|
+
------------------------------------
|
|
55
|
+
d3970000-0000-4000-8000-000000000002
|
|
56
|
+
(1 row)
|
|
57
|
+
|
|
58
|
+
step rm_commit: COMMIT;
|
|
59
|
+
step chk:
|
|
60
|
+
select fm.trust_domain_id, fm.owner_agent_id, fm.lifecycle_state as machine_state,
|
|
61
|
+
ftd.lifecycle_state as domain_state
|
|
62
|
+
from agent_board.fleet_machines fm
|
|
63
|
+
join agent_board.fleet_trust_domains ftd on ftd.id = fm.trust_domain_id
|
|
64
|
+
where fm.id = 'c3970000-0000-4000-8000-000000000001';
|
|
65
|
+
|
|
66
|
+
trust_domain_id |owner_agent_id |machine_state|domain_state
|
|
67
|
+
------------------------------------+------------------------------------+-------------+------------
|
|
68
|
+
d3970000-0000-4000-8000-000000000002|a3970000-0000-4000-8000-000000000001|active |active
|
|
69
|
+
(1 row)
|
|
70
|
+
|
|
71
|
+
|
|
72
|
+
starting permutation: rl_begin rl_relocate_dest rm_begin rm_move_current rl_demote_current rl_commit rm_commit chk
|
|
73
|
+
step rl_begin: BEGIN; SET LOCAL "request.jwt.claim.role" = 'service_role';
|
|
74
|
+
step rl_relocate_dest:
|
|
75
|
+
update agent_board.fleet_machines
|
|
76
|
+
set trust_domain_id = 'd3970000-0000-4000-8000-000000000002', updated_at = now()
|
|
77
|
+
where id = 'c3970000-0000-4000-8000-000000000001';
|
|
78
|
+
|
|
79
|
+
step rm_begin: BEGIN; SET LOCAL "request.jwt.claim.role" = 'service_role';
|
|
80
|
+
step rm_move_current:
|
|
81
|
+
select trust_domain_id
|
|
82
|
+
from agent_board.register_fleet_machine(
|
|
83
|
+
'a3970000-0000-4000-8000-000000000001', 'd3970000-0000-4000-8000-000000000001',
|
|
84
|
+
'nodowngrade-iso-machine-relabelled', 'sha256:nodowngrade-iso', 'portal',
|
|
85
|
+
jsonb_build_object('redacted', true));
|
|
86
|
+
<waiting ...>
|
|
87
|
+
step rl_demote_current:
|
|
88
|
+
update agent_board.fleet_trust_domains
|
|
89
|
+
set lifecycle_state = 'pending', approved_at = null, updated_at = now()
|
|
90
|
+
where id = 'd3970000-0000-4000-8000-000000000001';
|
|
91
|
+
|
|
92
|
+
step rl_commit: COMMIT;
|
|
93
|
+
step rm_move_current: <... completed>
|
|
94
|
+
ERROR: re-registration would move machine into a less approved trust domain (destination d3970000-0000-4000-8000-000000000001, current d3970000-0000-4000-8000-000000000002) — measured after the move, from one snapshot
|
|
95
|
+
step rm_commit: COMMIT;
|
|
96
|
+
step chk:
|
|
97
|
+
select fm.trust_domain_id, fm.owner_agent_id, fm.lifecycle_state as machine_state,
|
|
98
|
+
ftd.lifecycle_state as domain_state
|
|
99
|
+
from agent_board.fleet_machines fm
|
|
100
|
+
join agent_board.fleet_trust_domains ftd on ftd.id = fm.trust_domain_id
|
|
101
|
+
where fm.id = 'c3970000-0000-4000-8000-000000000001';
|
|
102
|
+
|
|
103
|
+
trust_domain_id |owner_agent_id |machine_state|domain_state
|
|
104
|
+
------------------------------------+------------------------------------+-------------+------------
|
|
105
|
+
d3970000-0000-4000-8000-000000000002|a3970000-0000-4000-8000-000000000001|active |active
|
|
106
|
+
(1 row)
|
|
107
|
+
|
|
108
|
+
|
|
109
|
+
starting permutation: rl_begin rl_relocate_dest rm_begin rm_move_current rl_commit rm_commit chk
|
|
110
|
+
step rl_begin: BEGIN; SET LOCAL "request.jwt.claim.role" = 'service_role';
|
|
111
|
+
step rl_relocate_dest:
|
|
112
|
+
update agent_board.fleet_machines
|
|
113
|
+
set trust_domain_id = 'd3970000-0000-4000-8000-000000000002', updated_at = now()
|
|
114
|
+
where id = 'c3970000-0000-4000-8000-000000000001';
|
|
115
|
+
|
|
116
|
+
step rm_begin: BEGIN; SET LOCAL "request.jwt.claim.role" = 'service_role';
|
|
117
|
+
step rm_move_current:
|
|
118
|
+
select trust_domain_id
|
|
119
|
+
from agent_board.register_fleet_machine(
|
|
120
|
+
'a3970000-0000-4000-8000-000000000001', 'd3970000-0000-4000-8000-000000000001',
|
|
121
|
+
'nodowngrade-iso-machine-relabelled', 'sha256:nodowngrade-iso', 'portal',
|
|
122
|
+
jsonb_build_object('redacted', true));
|
|
123
|
+
<waiting ...>
|
|
124
|
+
step rl_commit: COMMIT;
|
|
125
|
+
step rm_move_current: <... completed>
|
|
126
|
+
trust_domain_id
|
|
127
|
+
------------------------------------
|
|
128
|
+
d3970000-0000-4000-8000-000000000001
|
|
129
|
+
(1 row)
|
|
130
|
+
|
|
131
|
+
step rm_commit: COMMIT;
|
|
132
|
+
step chk:
|
|
133
|
+
select fm.trust_domain_id, fm.owner_agent_id, fm.lifecycle_state as machine_state,
|
|
134
|
+
ftd.lifecycle_state as domain_state
|
|
135
|
+
from agent_board.fleet_machines fm
|
|
136
|
+
join agent_board.fleet_trust_domains ftd on ftd.id = fm.trust_domain_id
|
|
137
|
+
where fm.id = 'c3970000-0000-4000-8000-000000000001';
|
|
138
|
+
|
|
139
|
+
trust_domain_id |owner_agent_id |machine_state|domain_state
|
|
140
|
+
------------------------------------+------------------------------------+-------------+------------
|
|
141
|
+
d3970000-0000-4000-8000-000000000001|a3970000-0000-4000-8000-000000000001|active |active
|
|
142
|
+
(1 row)
|
|
143
|
+
|
|
144
|
+
|
|
145
|
+
starting permutation: rl_begin rl_lock rm_begin rm_move_current rl_relocate_x rl_demote_current rl_commit rm_commit chk
|
|
146
|
+
step rl_begin: BEGIN; SET LOCAL "request.jwt.claim.role" = 'service_role';
|
|
147
|
+
step rl_lock:
|
|
148
|
+
select id from agent_board.fleet_machines
|
|
149
|
+
where id = 'c3970000-0000-4000-8000-000000000001' for update;
|
|
150
|
+
|
|
151
|
+
id
|
|
152
|
+
------------------------------------
|
|
153
|
+
c3970000-0000-4000-8000-000000000001
|
|
154
|
+
(1 row)
|
|
155
|
+
|
|
156
|
+
step rm_begin: BEGIN; SET LOCAL "request.jwt.claim.role" = 'service_role';
|
|
157
|
+
step rm_move_current:
|
|
158
|
+
select trust_domain_id
|
|
159
|
+
from agent_board.register_fleet_machine(
|
|
160
|
+
'a3970000-0000-4000-8000-000000000001', 'd3970000-0000-4000-8000-000000000001',
|
|
161
|
+
'nodowngrade-iso-machine-relabelled', 'sha256:nodowngrade-iso', 'portal',
|
|
162
|
+
jsonb_build_object('redacted', true));
|
|
163
|
+
<waiting ...>
|
|
164
|
+
step rl_relocate_x:
|
|
165
|
+
update agent_board.fleet_machines
|
|
166
|
+
set trust_domain_id = 'd3970000-0000-4000-8000-000000000003', updated_at = now()
|
|
167
|
+
where id = 'c3970000-0000-4000-8000-000000000001';
|
|
168
|
+
|
|
169
|
+
step rl_demote_current:
|
|
170
|
+
update agent_board.fleet_trust_domains
|
|
171
|
+
set lifecycle_state = 'pending', approved_at = null, updated_at = now()
|
|
172
|
+
where id = 'd3970000-0000-4000-8000-000000000001';
|
|
173
|
+
|
|
174
|
+
step rl_commit: COMMIT;
|
|
175
|
+
step rm_move_current: <... completed>
|
|
176
|
+
ERROR: re-registration would move machine into a less approved trust domain (destination d3970000-0000-4000-8000-000000000001, current d3970000-0000-4000-8000-000000000003) — measured after the move, from one snapshot
|
|
177
|
+
step rm_commit: COMMIT;
|
|
178
|
+
step chk:
|
|
179
|
+
select fm.trust_domain_id, fm.owner_agent_id, fm.lifecycle_state as machine_state,
|
|
180
|
+
ftd.lifecycle_state as domain_state
|
|
181
|
+
from agent_board.fleet_machines fm
|
|
182
|
+
join agent_board.fleet_trust_domains ftd on ftd.id = fm.trust_domain_id
|
|
183
|
+
where fm.id = 'c3970000-0000-4000-8000-000000000001';
|
|
184
|
+
|
|
185
|
+
trust_domain_id |owner_agent_id |machine_state|domain_state
|
|
186
|
+
------------------------------------+------------------------------------+-------------+------------
|
|
187
|
+
d3970000-0000-4000-8000-000000000003|a3970000-0000-4000-8000-000000000001|active |active
|
|
188
|
+
(1 row)
|
|
189
|
+
|
|
190
|
+
|
|
191
|
+
starting permutation: rl_begin rl_lock rm_begin rm_move_current rl_relocate_x rl_commit rm_commit chk
|
|
192
|
+
step rl_begin: BEGIN; SET LOCAL "request.jwt.claim.role" = 'service_role';
|
|
193
|
+
step rl_lock:
|
|
194
|
+
select id from agent_board.fleet_machines
|
|
195
|
+
where id = 'c3970000-0000-4000-8000-000000000001' for update;
|
|
196
|
+
|
|
197
|
+
id
|
|
198
|
+
------------------------------------
|
|
199
|
+
c3970000-0000-4000-8000-000000000001
|
|
200
|
+
(1 row)
|
|
201
|
+
|
|
202
|
+
step rm_begin: BEGIN; SET LOCAL "request.jwt.claim.role" = 'service_role';
|
|
203
|
+
step rm_move_current:
|
|
204
|
+
select trust_domain_id
|
|
205
|
+
from agent_board.register_fleet_machine(
|
|
206
|
+
'a3970000-0000-4000-8000-000000000001', 'd3970000-0000-4000-8000-000000000001',
|
|
207
|
+
'nodowngrade-iso-machine-relabelled', 'sha256:nodowngrade-iso', 'portal',
|
|
208
|
+
jsonb_build_object('redacted', true));
|
|
209
|
+
<waiting ...>
|
|
210
|
+
step rl_relocate_x:
|
|
211
|
+
update agent_board.fleet_machines
|
|
212
|
+
set trust_domain_id = 'd3970000-0000-4000-8000-000000000003', updated_at = now()
|
|
213
|
+
where id = 'c3970000-0000-4000-8000-000000000001';
|
|
214
|
+
|
|
215
|
+
step rl_commit: COMMIT;
|
|
216
|
+
step rm_move_current: <... completed>
|
|
217
|
+
trust_domain_id
|
|
218
|
+
------------------------------------
|
|
219
|
+
d3970000-0000-4000-8000-000000000001
|
|
220
|
+
(1 row)
|
|
221
|
+
|
|
222
|
+
step rm_commit: COMMIT;
|
|
223
|
+
step chk:
|
|
224
|
+
select fm.trust_domain_id, fm.owner_agent_id, fm.lifecycle_state as machine_state,
|
|
225
|
+
ftd.lifecycle_state as domain_state
|
|
226
|
+
from agent_board.fleet_machines fm
|
|
227
|
+
join agent_board.fleet_trust_domains ftd on ftd.id = fm.trust_domain_id
|
|
228
|
+
where fm.id = 'c3970000-0000-4000-8000-000000000001';
|
|
229
|
+
|
|
230
|
+
trust_domain_id |owner_agent_id |machine_state|domain_state
|
|
231
|
+
------------------------------------+------------------------------------+-------------+------------
|
|
232
|
+
d3970000-0000-4000-8000-000000000001|a3970000-0000-4000-8000-000000000001|active |active
|
|
233
|
+
(1 row)
|
|
234
|
+
|
|
235
|
+
|
|
236
|
+
starting permutation: rc_begin rc_reclaim rm_begin rm_move_current rc_commit rm_commit chk
|
|
237
|
+
step rc_begin: BEGIN; SET LOCAL "request.jwt.claim.role" = 'service_role';
|
|
238
|
+
step rc_reclaim:
|
|
239
|
+
select owner_agent_id, trust_domain_id
|
|
240
|
+
from agent_board.reclaim_fleet_machine(
|
|
241
|
+
'c3970000-0000-4000-8000-000000000001', 'a3970000-0000-4000-8000-000000000003',
|
|
242
|
+
'a3970000-0000-4000-8000-000000000002', 'iso reclaim vs register',
|
|
243
|
+
'd3970000-0000-4000-8000-000000000004');
|
|
244
|
+
|
|
245
|
+
owner_agent_id |trust_domain_id
|
|
246
|
+
------------------------------------+------------------------------------
|
|
247
|
+
a3970000-0000-4000-8000-000000000003|d3970000-0000-4000-8000-000000000004
|
|
248
|
+
(1 row)
|
|
249
|
+
|
|
250
|
+
step rm_begin: BEGIN; SET LOCAL "request.jwt.claim.role" = 'service_role';
|
|
251
|
+
step rm_move_current:
|
|
252
|
+
select trust_domain_id
|
|
253
|
+
from agent_board.register_fleet_machine(
|
|
254
|
+
'a3970000-0000-4000-8000-000000000001', 'd3970000-0000-4000-8000-000000000001',
|
|
255
|
+
'nodowngrade-iso-machine-relabelled', 'sha256:nodowngrade-iso', 'portal',
|
|
256
|
+
jsonb_build_object('redacted', true));
|
|
257
|
+
<waiting ...>
|
|
258
|
+
step rc_commit: COMMIT;
|
|
259
|
+
step rm_move_current: <... completed>
|
|
260
|
+
ERROR: machine fingerprint is registered to another owner
|
|
261
|
+
step rm_commit: COMMIT;
|
|
262
|
+
step chk:
|
|
263
|
+
select fm.trust_domain_id, fm.owner_agent_id, fm.lifecycle_state as machine_state,
|
|
264
|
+
ftd.lifecycle_state as domain_state
|
|
265
|
+
from agent_board.fleet_machines fm
|
|
266
|
+
join agent_board.fleet_trust_domains ftd on ftd.id = fm.trust_domain_id
|
|
267
|
+
where fm.id = 'c3970000-0000-4000-8000-000000000001';
|
|
268
|
+
|
|
269
|
+
trust_domain_id |owner_agent_id |machine_state|domain_state
|
|
270
|
+
------------------------------------+------------------------------------+-------------+------------
|
|
271
|
+
d3970000-0000-4000-8000-000000000004|a3970000-0000-4000-8000-000000000003|active |active
|
|
272
|
+
(1 row)
|
|
273
|
+
|
|
274
|
+
|
|
275
|
+
starting permutation: rm_begin rm_move_current rc_begin rc_reclaim rm_commit rc_commit chk
|
|
276
|
+
step rm_begin: BEGIN; SET LOCAL "request.jwt.claim.role" = 'service_role';
|
|
277
|
+
step rm_move_current:
|
|
278
|
+
select trust_domain_id
|
|
279
|
+
from agent_board.register_fleet_machine(
|
|
280
|
+
'a3970000-0000-4000-8000-000000000001', 'd3970000-0000-4000-8000-000000000001',
|
|
281
|
+
'nodowngrade-iso-machine-relabelled', 'sha256:nodowngrade-iso', 'portal',
|
|
282
|
+
jsonb_build_object('redacted', true));
|
|
283
|
+
|
|
284
|
+
trust_domain_id
|
|
285
|
+
------------------------------------
|
|
286
|
+
d3970000-0000-4000-8000-000000000001
|
|
287
|
+
(1 row)
|
|
288
|
+
|
|
289
|
+
step rc_begin: BEGIN; SET LOCAL "request.jwt.claim.role" = 'service_role';
|
|
290
|
+
step rc_reclaim:
|
|
291
|
+
select owner_agent_id, trust_domain_id
|
|
292
|
+
from agent_board.reclaim_fleet_machine(
|
|
293
|
+
'c3970000-0000-4000-8000-000000000001', 'a3970000-0000-4000-8000-000000000003',
|
|
294
|
+
'a3970000-0000-4000-8000-000000000002', 'iso reclaim vs register',
|
|
295
|
+
'd3970000-0000-4000-8000-000000000004');
|
|
296
|
+
<waiting ...>
|
|
297
|
+
step rm_commit: COMMIT;
|
|
298
|
+
step rc_reclaim: <... completed>
|
|
299
|
+
owner_agent_id |trust_domain_id
|
|
300
|
+
------------------------------------+------------------------------------
|
|
301
|
+
a3970000-0000-4000-8000-000000000003|d3970000-0000-4000-8000-000000000004
|
|
302
|
+
(1 row)
|
|
303
|
+
|
|
304
|
+
step rc_commit: COMMIT;
|
|
305
|
+
step chk:
|
|
306
|
+
select fm.trust_domain_id, fm.owner_agent_id, fm.lifecycle_state as machine_state,
|
|
307
|
+
ftd.lifecycle_state as domain_state
|
|
308
|
+
from agent_board.fleet_machines fm
|
|
309
|
+
join agent_board.fleet_trust_domains ftd on ftd.id = fm.trust_domain_id
|
|
310
|
+
where fm.id = 'c3970000-0000-4000-8000-000000000001';
|
|
311
|
+
|
|
312
|
+
trust_domain_id |owner_agent_id |machine_state|domain_state
|
|
313
|
+
------------------------------------+------------------------------------+-------------+------------
|
|
314
|
+
d3970000-0000-4000-8000-000000000004|a3970000-0000-4000-8000-000000000003|active |active
|
|
315
|
+
(1 row)
|
|
316
|
+
|
|
317
|
+
|
|
318
|
+
starting permutation: rf_begin rf_register rm2_begin rm2_register rl_begin rl_demote_race_dest rl_commit rf_commit rm2_commit chkf
|
|
319
|
+
step rf_begin: BEGIN; SET LOCAL "request.jwt.claim.role" = 'service_role';
|
|
320
|
+
step rf_register:
|
|
321
|
+
select trust_domain_id
|
|
322
|
+
from agent_board.register_fleet_machine(
|
|
323
|
+
'a3970000-0000-4000-8000-000000000001', 'd3970000-0000-4000-8000-000000000005',
|
|
324
|
+
'nodowngrade-iso-fresh-winner', 'sha256:nodowngrade-iso-fresh', 'portal',
|
|
325
|
+
jsonb_build_object('redacted', true));
|
|
326
|
+
|
|
327
|
+
trust_domain_id
|
|
328
|
+
------------------------------------
|
|
329
|
+
d3970000-0000-4000-8000-000000000005
|
|
330
|
+
(1 row)
|
|
331
|
+
|
|
332
|
+
step rm2_begin: BEGIN; SET LOCAL "request.jwt.claim.role" = 'service_role';
|
|
333
|
+
step rm2_register:
|
|
334
|
+
select trust_domain_id
|
|
335
|
+
from agent_board.register_fleet_machine(
|
|
336
|
+
'a3970000-0000-4000-8000-000000000001', 'd3970000-0000-4000-8000-000000000006',
|
|
337
|
+
'nodowngrade-iso-fresh-loser', 'sha256:nodowngrade-iso-fresh', 'portal',
|
|
338
|
+
jsonb_build_object('redacted', true));
|
|
339
|
+
<waiting ...>
|
|
340
|
+
step rl_begin: BEGIN; SET LOCAL "request.jwt.claim.role" = 'service_role';
|
|
341
|
+
step rl_demote_race_dest:
|
|
342
|
+
update agent_board.fleet_trust_domains
|
|
343
|
+
set lifecycle_state = 'quarantined', approved_at = null, updated_at = now()
|
|
344
|
+
where id = 'd3970000-0000-4000-8000-000000000006';
|
|
345
|
+
|
|
346
|
+
step rl_commit: COMMIT;
|
|
347
|
+
step rf_commit: COMMIT;
|
|
348
|
+
step rm2_register: <... completed>
|
|
349
|
+
ERROR: concurrent registration of machine fingerprint sha256:nodowngrade-iso-fresh — retry
|
|
350
|
+
step rm2_commit: COMMIT;
|
|
351
|
+
step chkf:
|
|
352
|
+
select fm.trust_domain_id, fm.lifecycle_state as machine_state, ftd.lifecycle_state as domain_state
|
|
353
|
+
from agent_board.fleet_machines fm
|
|
354
|
+
join agent_board.fleet_trust_domains ftd on ftd.id = fm.trust_domain_id
|
|
355
|
+
where fm.machine_fingerprint = 'sha256:nodowngrade-iso-fresh';
|
|
356
|
+
|
|
357
|
+
trust_domain_id |machine_state|domain_state
|
|
358
|
+
------------------------------------+-------------+------------
|
|
359
|
+
d3970000-0000-4000-8000-000000000005|active |pending
|
|
360
|
+
(1 row)
|
|
361
|
+
|
|
362
|
+
|
|
363
|
+
starting permutation: rf_begin rf_register rm2_begin rm2_register rl_begin rl_promote_race_src rl_commit rf_commit rm2_commit chkf
|
|
364
|
+
step rf_begin: BEGIN; SET LOCAL "request.jwt.claim.role" = 'service_role';
|
|
365
|
+
step rf_register:
|
|
366
|
+
select trust_domain_id
|
|
367
|
+
from agent_board.register_fleet_machine(
|
|
368
|
+
'a3970000-0000-4000-8000-000000000001', 'd3970000-0000-4000-8000-000000000005',
|
|
369
|
+
'nodowngrade-iso-fresh-winner', 'sha256:nodowngrade-iso-fresh', 'portal',
|
|
370
|
+
jsonb_build_object('redacted', true));
|
|
371
|
+
|
|
372
|
+
trust_domain_id
|
|
373
|
+
------------------------------------
|
|
374
|
+
d3970000-0000-4000-8000-000000000005
|
|
375
|
+
(1 row)
|
|
376
|
+
|
|
377
|
+
step rm2_begin: BEGIN; SET LOCAL "request.jwt.claim.role" = 'service_role';
|
|
378
|
+
step rm2_register:
|
|
379
|
+
select trust_domain_id
|
|
380
|
+
from agent_board.register_fleet_machine(
|
|
381
|
+
'a3970000-0000-4000-8000-000000000001', 'd3970000-0000-4000-8000-000000000006',
|
|
382
|
+
'nodowngrade-iso-fresh-loser', 'sha256:nodowngrade-iso-fresh', 'portal',
|
|
383
|
+
jsonb_build_object('redacted', true));
|
|
384
|
+
<waiting ...>
|
|
385
|
+
step rl_begin: BEGIN; SET LOCAL "request.jwt.claim.role" = 'service_role';
|
|
386
|
+
step rl_promote_race_src:
|
|
387
|
+
update agent_board.fleet_trust_domains
|
|
388
|
+
set lifecycle_state = 'active', approved_at = now(), updated_at = now()
|
|
389
|
+
where id = 'd3970000-0000-4000-8000-000000000005';
|
|
390
|
+
|
|
391
|
+
step rl_commit: COMMIT;
|
|
392
|
+
step rf_commit: COMMIT;
|
|
393
|
+
step rm2_register: <... completed>
|
|
394
|
+
ERROR: concurrent registration of machine fingerprint sha256:nodowngrade-iso-fresh — retry
|
|
395
|
+
step rm2_commit: COMMIT;
|
|
396
|
+
step chkf:
|
|
397
|
+
select fm.trust_domain_id, fm.lifecycle_state as machine_state, ftd.lifecycle_state as domain_state
|
|
398
|
+
from agent_board.fleet_machines fm
|
|
399
|
+
join agent_board.fleet_trust_domains ftd on ftd.id = fm.trust_domain_id
|
|
400
|
+
where fm.machine_fingerprint = 'sha256:nodowngrade-iso-fresh';
|
|
401
|
+
|
|
402
|
+
trust_domain_id |machine_state|domain_state
|
|
403
|
+
------------------------------------+-------------+------------
|
|
404
|
+
d3970000-0000-4000-8000-000000000005|active |active
|
|
405
|
+
(1 row)
|
|
406
|
+
|
|
407
|
+
|
|
408
|
+
starting permutation: rf_begin rf_register rf_commit rm2_begin rm2_register rm2_commit chkf
|
|
409
|
+
step rf_begin: BEGIN; SET LOCAL "request.jwt.claim.role" = 'service_role';
|
|
410
|
+
step rf_register:
|
|
411
|
+
select trust_domain_id
|
|
412
|
+
from agent_board.register_fleet_machine(
|
|
413
|
+
'a3970000-0000-4000-8000-000000000001', 'd3970000-0000-4000-8000-000000000005',
|
|
414
|
+
'nodowngrade-iso-fresh-winner', 'sha256:nodowngrade-iso-fresh', 'portal',
|
|
415
|
+
jsonb_build_object('redacted', true));
|
|
416
|
+
|
|
417
|
+
trust_domain_id
|
|
418
|
+
------------------------------------
|
|
419
|
+
d3970000-0000-4000-8000-000000000005
|
|
420
|
+
(1 row)
|
|
421
|
+
|
|
422
|
+
step rf_commit: COMMIT;
|
|
423
|
+
step rm2_begin: BEGIN; SET LOCAL "request.jwt.claim.role" = 'service_role';
|
|
424
|
+
step rm2_register:
|
|
425
|
+
select trust_domain_id
|
|
426
|
+
from agent_board.register_fleet_machine(
|
|
427
|
+
'a3970000-0000-4000-8000-000000000001', 'd3970000-0000-4000-8000-000000000006',
|
|
428
|
+
'nodowngrade-iso-fresh-loser', 'sha256:nodowngrade-iso-fresh', 'portal',
|
|
429
|
+
jsonb_build_object('redacted', true));
|
|
430
|
+
|
|
431
|
+
trust_domain_id
|
|
432
|
+
------------------------------------
|
|
433
|
+
d3970000-0000-4000-8000-000000000006
|
|
434
|
+
(1 row)
|
|
435
|
+
|
|
436
|
+
step rm2_commit: COMMIT;
|
|
437
|
+
step chkf:
|
|
438
|
+
select fm.trust_domain_id, fm.lifecycle_state as machine_state, ftd.lifecycle_state as domain_state
|
|
439
|
+
from agent_board.fleet_machines fm
|
|
440
|
+
join agent_board.fleet_trust_domains ftd on ftd.id = fm.trust_domain_id
|
|
441
|
+
where fm.machine_fingerprint = 'sha256:nodowngrade-iso-fresh';
|
|
442
|
+
|
|
443
|
+
trust_domain_id |machine_state|domain_state
|
|
444
|
+
------------------------------------+-------------+------------
|
|
445
|
+
d3970000-0000-4000-8000-000000000006|active |pending
|
|
446
|
+
(1 row)
|
|
447
|
+
|
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
# Consiliency/message-board#405 — an acquire whose snapshot predates a committed
|
|
2
|
+
# advisory -> inherit revert must NOT bank a full-horizon ownerless lease.
|
|
3
|
+
#
|
|
4
|
+
# WHY ACQUIRE IS THE WORSE HALF OF THIS FAMILY. #406's cap reset clamps the
|
|
5
|
+
# board's EXISTING ownerless claims on a revert. On this path there is no claim
|
|
6
|
+
# yet: the acquire inserts AFTER the revert committed, so there is nothing for
|
|
7
|
+
# the reset to reach even in principle. Whatever horizon a stale 'advisory' read
|
|
8
|
+
# lets through is banked outright.
|
|
9
|
+
#
|
|
10
|
+
# AND IT IS THE PATH THE FIRST DESIGN MISSED. That design said the board lock
|
|
11
|
+
# goes "before the agent-scoped lock". acquire_claim's agent-scoped quota lock
|
|
12
|
+
# lives INSIDE the branch that a stale 'advisory' read SKIPS ENTIRELY, so on the
|
|
13
|
+
# dangerous path it is never reached and ordering against it means nothing. This
|
|
14
|
+
# spec drives exactly that branch: the acquirer reads 'advisory' unless it is
|
|
15
|
+
# made to wait, and if it reads 'advisory' it takes no lock at all.
|
|
16
|
+
#
|
|
17
|
+
# THE INTERLEAVE. w (the board owner) opens a transaction and reverts the board
|
|
18
|
+
# to 'inherit', holding the board-scoped advisory lock until commit. a then asks
|
|
19
|
+
# for a 400-day 'file' lease. Under READ COMMITTED a's snapshot at that moment
|
|
20
|
+
# still shows 'advisory'.
|
|
21
|
+
#
|
|
22
|
+
# WHAT THE FIX PRODUCES (this golden): a's acquire prints `<waiting ...>` on w's
|
|
23
|
+
# lock; after w commits, a RE-READS the policy in a fresh statement, sees
|
|
24
|
+
# 'inherit', and the ownerless TTL cap rejects the 400-day horizon with
|
|
25
|
+
# `ERROR: ownerless claim lease horizon exceeds cap`. The checker sees ZERO
|
|
26
|
+
# claims.
|
|
27
|
+
#
|
|
28
|
+
# MUTATION SIGNAL (verified in the PR): delete the `perform
|
|
29
|
+
# agent_board._claimgate_lock_board_policy(v_board_id)` line from acquire_claim
|
|
30
|
+
# -> a never waits, resolves the stale 'advisory', skips the whole ownerless
|
|
31
|
+
# block and INSERTS. The golden diverges on the missing `<waiting ...>`, on the
|
|
32
|
+
# missing error, and on the checker (1 claim, over-cap lease = t).
|
|
33
|
+
#
|
|
34
|
+
# THE TWIN IS NOT OPTIONAL. A guard that simply over-serialises — or one that
|
|
35
|
+
# resolved every board to 'inherit' — would pass the race permutation and break
|
|
36
|
+
# the feature. The second permutation runs the SAME acquire with no writer at
|
|
37
|
+
# all: the board is still 'advisory', so the 400-day lease must be GRANTED, with
|
|
38
|
+
# no wait anywhere in the trace.
|
|
39
|
+
#
|
|
40
|
+
# Sessions run as `authenticated` (service_role is exempt from these guards
|
|
41
|
+
# entirely, so a service_role probe would prove nothing).
|
|
42
|
+
|
|
43
|
+
setup
|
|
44
|
+
{
|
|
45
|
+
insert into agent_board.claimgate_enforcement_flags(scope_key, enabled) values ('ownerless_guards', true)
|
|
46
|
+
on conflict (scope_key) do update set enabled = true;
|
|
47
|
+
insert into auth.users (id) values ('40500000-0000-4000-8000-0000000000a1');
|
|
48
|
+
insert into agent_board.agents(id, agent_type, kind, handle, display_name, status, auth_user_id, owner_user_id)
|
|
49
|
+
values ('40500000-0000-4000-8000-000000000001', 'agent', 'agent',
|
|
50
|
+
'cpr-acq-owner', 'CPR Acquire Owner', 'active',
|
|
51
|
+
'40500000-0000-4000-8000-0000000000a1', '40500000-0000-4000-8000-0000000000a1');
|
|
52
|
+
select count(*) from agent_board.create_board(
|
|
53
|
+
'40500000-0000-4000-8000-000000000001',
|
|
54
|
+
'cpr-acq-board', 'CPR Acquire Board',
|
|
55
|
+
'message-board#405 acquire stale-policy probe', jsonb_build_object(), 'private');
|
|
56
|
+
insert into agent_board.threads(id, thread_type, created_by_agent_id, subject, board_id)
|
|
57
|
+
values ('40500000-0000-4000-8000-000000000010', 'coordination',
|
|
58
|
+
'40500000-0000-4000-8000-000000000001', 'CPR acquire thread',
|
|
59
|
+
(select id from agent_board.boards where slug = 'cpr-acq-board'));
|
|
60
|
+
-- The board starts OPTED OUT. Written directly rather than through the RPC so the setup does not
|
|
61
|
+
-- depend on the very gate this spec exercises; the RPC's own transitions are BCP's job.
|
|
62
|
+
update agent_board.boards set claim_policy = 'advisory' where slug = 'cpr-acq-board';
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
teardown
|
|
66
|
+
{
|
|
67
|
+
delete from agent_board.claims where agent_id = '40500000-0000-4000-8000-000000000001';
|
|
68
|
+
delete from agent_board.threads where id = '40500000-0000-4000-8000-000000000010';
|
|
69
|
+
delete from agent_board.board_membership_events where board_id in (
|
|
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
|
+
delete from agent_board.boards where slug = 'cpr-acq-board';
|
|
74
|
+
delete from agent_board.agents where id = '40500000-0000-4000-8000-000000000001';
|
|
75
|
+
delete from auth.users where id = '40500000-0000-4000-8000-0000000000a1';
|
|
76
|
+
delete from agent_board.claimgate_enforcement_flags where scope_key = 'ownerless_guards';
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
# w: the board owner reverting the opt-out. Holds the board policy lock until commit.
|
|
80
|
+
session "w"
|
|
81
|
+
step "w_begin" { BEGIN; SET LOCAL ROLE authenticated; SET LOCAL "request.jwt.claim.role" = 'authenticated'; SET LOCAL "request.jwt.claim.sub" = '40500000-0000-4000-8000-0000000000a1'; }
|
|
82
|
+
step "w_flip" {
|
|
83
|
+
select claim_policy
|
|
84
|
+
from agent_board.set_board_claim_policy(
|
|
85
|
+
(select id from agent_board.boards where slug = 'cpr-acq-board'), 'inherit');
|
|
86
|
+
}
|
|
87
|
+
step "w_commit" { COMMIT; }
|
|
88
|
+
|
|
89
|
+
# a: the in-flight acquire. 400 days is far past the 30-day ownerless TTL cap, so the horizon it
|
|
90
|
+
# gets is a direct readout of which policy it resolved.
|
|
91
|
+
session "a"
|
|
92
|
+
step "a_begin" { BEGIN; SET LOCAL ROLE authenticated; SET LOCAL "request.jwt.claim.role" = 'authenticated'; SET LOCAL "request.jwt.claim.sub" = '40500000-0000-4000-8000-0000000000a1'; }
|
|
93
|
+
step "a_acq" {
|
|
94
|
+
select resource_key
|
|
95
|
+
from agent_board.acquire_claim(null, 'file', 'cpr-acq-key', now() + interval '400 days',
|
|
96
|
+
null, '40500000-0000-4000-8000-000000000010');
|
|
97
|
+
}
|
|
98
|
+
step "a_commit" { COMMIT; }
|
|
99
|
+
|
|
100
|
+
# checker: a count and a boolean, never a timestamp — a golden with a clock in it is not a golden.
|
|
101
|
+
session "chk"
|
|
102
|
+
step "chk" {
|
|
103
|
+
select count(*)::int as active_claims,
|
|
104
|
+
coalesce(bool_or(lease_expires_at > now() + interval '31 days'), false) as over_cap_lease
|
|
105
|
+
from agent_board.claims
|
|
106
|
+
where agent_id = '40500000-0000-4000-8000-000000000001'
|
|
107
|
+
and resource_kind = 'file'
|
|
108
|
+
and status = 'active'
|
|
109
|
+
and released_at is null;
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
# THE RACE: the acquire is issued while the revert is uncommitted.
|
|
113
|
+
permutation "w_begin" "w_flip" "a_begin" "a_acq" "w_commit" "a_commit" "chk"
|
|
114
|
+
|
|
115
|
+
# THE TWIN: no revert at all. The board is advisory, so the opt-out must still WORK — the 400-day
|
|
116
|
+
# lease is granted and nothing waits. A guard that over-serialises, or one that resolved every
|
|
117
|
+
# board to 'inherit', fails here and passes the permutation above.
|
|
118
|
+
permutation "a_begin" "a_acq" "a_commit" "chk"
|