@consiliency/agent-board-schema 1.22.0 → 1.24.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 +75 -1
- package/fixtures/already-applied.json +40 -0
- package/migrations/20260901000100_agent_board_atomic_fleet_onboarding.sql +1496 -0
- package/migrations/20260901000110_agent_board_fleet_onboarding_ceiling_lock.sql +604 -0
- package/migrations/20260901000120_agent_board_human_revocation_evidence_completeness.sql +78 -0
- package/migrations/20260901000130_agent_board_fedsession_human_revocation_gate.sql +74 -0
- package/migrations/20260901000140_agent_board_fedsession_board_owner_lock_order.sql +102 -0
- package/migrations/20260902000100_agent_board_outbox_wake_ordering.sql +184 -0
- package/migrations/20260903000100_agent_board_enroll_identity_board_owner_lock_order.sql +604 -0
- package/migrations/20260903000200_agent_board_fedsession_provider_absence_gate.sql +177 -0
- package/migrations/20260904000100_agent_board_wake_recovery_surface.sql +155 -0
- package/migrations/20260905000100_agent_board_consent_gating_reconcile.sql +151 -0
- package/package.json +1 -1
- package/schema-manifest.json +93 -3
- package/src/check.js +23 -0
- package/src/index.js +20 -0
- package/src/plan.js +79 -5
- package/src/tooling.test.mjs +237 -4
- package/tests/agent_board_atomic_fleet_onboarding.test.sql +623 -0
- package/tests/agent_board_atomic_fleet_onboarding_backfill.test.sql +142 -0
- package/tests/agent_board_atomic_fleet_onboarding_runtime.test.sql +1250 -0
- package/tests/agent_board_enroll_federated_identity.test.sql +3 -3
- package/tests/agent_board_enroll_pop_binding.test.sql +13 -3
- package/tests/agent_board_enrollment_audit_content.test.sql +11 -7
- package/tests/agent_board_federated_lock_order_class.test.sql +390 -0
- package/tests/agent_board_fedsession.test.sql +46 -2
- package/tests/agent_board_fedsession_provider_absence_gate.test.sql +170 -0
- package/tests/agent_board_inbox_reads.test.sql +16 -19
- package/tests/agent_board_outbox_wake_ordering.test.sql +452 -0
- package/tests/agent_board_portal_offline_invariant.test.sql +1 -1
- package/tests/agent_board_roomlink.test.sql +2 -2
- package/tests/agent_board_wake_recovery.test.sql +756 -0
- package/tests/isolation/expected/atomic_fedsession_fleet_lock_order.out +79 -0
- package/tests/isolation/expected/atomic_fedsession_human_revoke.out +87 -0
- package/tests/isolation/expected/atomic_fleet_authority_races.out +469 -0
- package/tests/isolation/expected/atomic_fleet_binding_revoke.out +103 -0
- package/tests/isolation/expected/atomic_fleet_board_archive.out +117 -0
- package/tests/isolation/expected/atomic_fleet_human_fresh_revoke.out +136 -0
- package/tests/isolation/expected/atomic_fleet_identity_disposition.out +61 -0
- package/tests/isolation/expected/atomic_fleet_lifecycle_races.out +1479 -0
- package/tests/isolation/expected/atomic_fleet_onboarding.out +75 -0
- package/tests/isolation/expected/atomic_fleet_subtree_lock_order.out +60 -0
- package/tests/isolation/expected/ceiling_setter_lock_before_upsert.out +95 -0
- package/tests/isolation/expected/enroll_identity_board_owner_lock_order.out +55 -0
- package/tests/isolation/expected/fedsession_provider_absent_owner_lock.out +37 -0
- package/tests/isolation/expected/onboarding_ceiling_lock_order.out +123 -0
- package/tests/isolation/expected/outbox_wake_ordering.out +86 -0
- package/tests/isolation/expected/wake_recovery_late_commit.out +89 -0
- package/tests/isolation/specs/atomic_fedsession_fleet_lock_order.spec +117 -0
- package/tests/isolation/specs/atomic_fedsession_human_revoke.spec +66 -0
- package/tests/isolation/specs/atomic_fleet_authority_races.spec +235 -0
- package/tests/isolation/specs/atomic_fleet_binding_revoke.spec +127 -0
- package/tests/isolation/specs/atomic_fleet_board_archive.spec +134 -0
- package/tests/isolation/specs/atomic_fleet_human_fresh_revoke.spec +142 -0
- package/tests/isolation/specs/atomic_fleet_identity_disposition.spec +118 -0
- package/tests/isolation/specs/atomic_fleet_lifecycle_races.spec +244 -0
- package/tests/isolation/specs/atomic_fleet_onboarding.spec +106 -0
- package/tests/isolation/specs/atomic_fleet_subtree_lock_order.spec +147 -0
- package/tests/isolation/specs/ceiling_setter_lock_before_upsert.spec +117 -0
- package/tests/isolation/specs/enroll_identity_board_owner_lock_order.spec +117 -0
- package/tests/isolation/specs/fedsession_provider_absent_owner_lock.spec +63 -0
- package/tests/isolation/specs/onboarding_ceiling_lock_order.spec +183 -0
- package/tests/isolation/specs/outbox_wake_ordering.spec +202 -0
- package/tests/isolation/specs/wake_recovery_late_commit.spec +207 -0
- package/tests/seeds/20260901000100_agent_board_atomic_fleet_onboarding.sql.pre.sql +110 -0
|
@@ -0,0 +1,1250 @@
|
|
|
1
|
+
create extension if not exists pgtap with schema extensions;
|
|
2
|
+
set search_path = extensions, public, agent_board;
|
|
3
|
+
|
|
4
|
+
begin;
|
|
5
|
+
select plan(103);
|
|
6
|
+
|
|
7
|
+
create temp table _atomic_cfg(
|
|
8
|
+
owner_id uuid,
|
|
9
|
+
board_id uuid,
|
|
10
|
+
machine_id uuid,
|
|
11
|
+
invite_id uuid,
|
|
12
|
+
invite_code text
|
|
13
|
+
) on commit drop;
|
|
14
|
+
|
|
15
|
+
create temp table _atomic_result(
|
|
16
|
+
attempt text,
|
|
17
|
+
agent_id uuid,
|
|
18
|
+
signing_key_id uuid,
|
|
19
|
+
board_id uuid,
|
|
20
|
+
harness_registration_id uuid,
|
|
21
|
+
repo_scope_id uuid,
|
|
22
|
+
fleet_machine_agent_id uuid,
|
|
23
|
+
binding_signing_key_id uuid,
|
|
24
|
+
identity_disposition text,
|
|
25
|
+
membership_disposition text,
|
|
26
|
+
harness_disposition text,
|
|
27
|
+
repo_scope_disposition text,
|
|
28
|
+
binding_disposition text
|
|
29
|
+
) on commit drop;
|
|
30
|
+
|
|
31
|
+
create temp table _recovery_cfg(
|
|
32
|
+
legacy_agent_id uuid,
|
|
33
|
+
legacy_signing_key_id uuid,
|
|
34
|
+
invite_id uuid,
|
|
35
|
+
invite_code text
|
|
36
|
+
) on commit drop;
|
|
37
|
+
|
|
38
|
+
create temp table _recovery_result(
|
|
39
|
+
agent_id uuid,
|
|
40
|
+
signing_key_id uuid,
|
|
41
|
+
identity_disposition text,
|
|
42
|
+
membership_disposition text,
|
|
43
|
+
harness_disposition text,
|
|
44
|
+
repo_scope_disposition text,
|
|
45
|
+
binding_disposition text
|
|
46
|
+
) on commit drop;
|
|
47
|
+
|
|
48
|
+
create temp table _collision_cfg(invite_id uuid, invite_code text) on commit drop;
|
|
49
|
+
create temp table _human_revocation_cfg(owner_user_id uuid) on commit drop;
|
|
50
|
+
|
|
51
|
+
do $$
|
|
52
|
+
declare
|
|
53
|
+
v_owner uuid := '16210000-0000-0000-0000-000000000001';
|
|
54
|
+
v_board uuid;
|
|
55
|
+
v_domain uuid;
|
|
56
|
+
v_machine uuid;
|
|
57
|
+
v_invite uuid;
|
|
58
|
+
v_code text;
|
|
59
|
+
begin
|
|
60
|
+
insert into agent_board.agents(id, agent_type, handle, display_name, status)
|
|
61
|
+
values (v_owner, 'agent', 'atomic-runtime-owner', 'Atomic Runtime Owner', 'active');
|
|
62
|
+
|
|
63
|
+
select board_id
|
|
64
|
+
into v_board
|
|
65
|
+
from agent_board.create_board(
|
|
66
|
+
v_owner, 'atomic-runtime-board', 'Atomic Runtime Board',
|
|
67
|
+
'Consiliency/message-board#162 runtime proof', '{}'::jsonb, 'private'
|
|
68
|
+
);
|
|
69
|
+
|
|
70
|
+
insert into agent_board.fleet_trust_domains(
|
|
71
|
+
slug, display_name, domain_kind, owner_agent_id, lifecycle_state, approved_at
|
|
72
|
+
) values (
|
|
73
|
+
'atomic-runtime-domain', 'Atomic Runtime Domain', 'tailnet', v_owner, 'active', now()
|
|
74
|
+
) returning id into v_domain;
|
|
75
|
+
|
|
76
|
+
insert into agent_board.fleet_machines(
|
|
77
|
+
trust_domain_id, owner_agent_id, machine_label, machine_fingerprint,
|
|
78
|
+
lifecycle_state, enrollment_source, enrolled_at
|
|
79
|
+
) values (
|
|
80
|
+
v_domain, v_owner, 'claw', 'sha256:atomic-runtime-machine',
|
|
81
|
+
'active', 'portal', now()
|
|
82
|
+
) returning id into v_machine;
|
|
83
|
+
|
|
84
|
+
insert into agent_board.identity_providers(
|
|
85
|
+
issuer, audience, supported, policy_approved,
|
|
86
|
+
allowed_scopes, allowed_board_scopes, allowed_agent_kinds
|
|
87
|
+
) values (
|
|
88
|
+
'https://atomic-runtime.test', 'message-board', true, true,
|
|
89
|
+
'{board:send}', '{}', '{agent}'
|
|
90
|
+
);
|
|
91
|
+
|
|
92
|
+
select invite_id, code
|
|
93
|
+
into v_invite, v_code
|
|
94
|
+
from agent_board.create_fleet_onboarding_invite(
|
|
95
|
+
v_board, v_machine, 'codex', 'phase-loop', 'message-board',
|
|
96
|
+
'sha256:atomic-runtime-repo', 'worker', 'phase_worker',
|
|
97
|
+
'atomic-runtime-agent', 1, now() + interval '1 hour', v_owner, '{}'::jsonb
|
|
98
|
+
);
|
|
99
|
+
|
|
100
|
+
insert into _atomic_cfg values (v_owner, v_board, v_machine, v_invite, v_code);
|
|
101
|
+
|
|
102
|
+
insert into _atomic_result
|
|
103
|
+
select 'first', r.agent_id, r.signing_key_id, r.board_id,
|
|
104
|
+
r.harness_registration_id, r.repo_scope_id, r.fleet_machine_agent_id,
|
|
105
|
+
r.binding_signing_key_id,
|
|
106
|
+
r.identity_disposition, r.membership_disposition,
|
|
107
|
+
r.harness_disposition, r.repo_scope_disposition, r.binding_disposition
|
|
108
|
+
from agent_board.onboard_federated_fleet_agent(
|
|
109
|
+
'https://atomic-runtime.test', 'message-board', 'human-runtime',
|
|
110
|
+
'{"iss":"https://atomic-runtime.test","aud":"message-board","sub":"human-runtime","iat":100}'::jsonb,
|
|
111
|
+
'atomic-runtime-agent',
|
|
112
|
+
'eRHZmllEy_TZHAG2zB-Qe_a5BFLkaavMTazWWfaE3f0',
|
|
113
|
+
'raw_ed25519_base64url',
|
|
114
|
+
'sha256:z8d5LQPfBMYnfZfvu8wVz684_jkp578-SPDU2OMObS8',
|
|
115
|
+
true, null, 'agent', '{board:send}', '{}', v_code, v_board, v_machine,
|
|
116
|
+
'codex', 'phase-loop', 'message-board', 'sha256:atomic-runtime-repo',
|
|
117
|
+
'worker', 'phase_worker', 'atomic-runtime-agent'
|
|
118
|
+
) r;
|
|
119
|
+
|
|
120
|
+
insert into _atomic_result
|
|
121
|
+
select 'replay', r.agent_id, r.signing_key_id, r.board_id,
|
|
122
|
+
r.harness_registration_id, r.repo_scope_id, r.fleet_machine_agent_id,
|
|
123
|
+
r.binding_signing_key_id,
|
|
124
|
+
r.identity_disposition, r.membership_disposition,
|
|
125
|
+
r.harness_disposition, r.repo_scope_disposition, r.binding_disposition
|
|
126
|
+
from agent_board.onboard_federated_fleet_agent(
|
|
127
|
+
'https://atomic-runtime.test', 'message-board', 'human-runtime',
|
|
128
|
+
'{"iss":"https://atomic-runtime.test","aud":"message-board","sub":"human-runtime","iat":200,"jti":"rotated"}'::jsonb,
|
|
129
|
+
'atomic-runtime-agent',
|
|
130
|
+
'eRHZmllEy_TZHAG2zB-Qe_a5BFLkaavMTazWWfaE3f0',
|
|
131
|
+
'raw_ed25519_base64url',
|
|
132
|
+
'sha256:z8d5LQPfBMYnfZfvu8wVz684_jkp578-SPDU2OMObS8',
|
|
133
|
+
true, null, 'agent', '{board:send}', '{}', v_code, v_board, v_machine,
|
|
134
|
+
'codex', 'phase-loop', 'message-board', 'sha256:atomic-runtime-repo',
|
|
135
|
+
'worker', 'phase_worker', 'atomic-runtime-agent'
|
|
136
|
+
) r;
|
|
137
|
+
end
|
|
138
|
+
$$;
|
|
139
|
+
|
|
140
|
+
select is((select count(*)::int from _atomic_result where attempt='first'), 1,
|
|
141
|
+
'first atomic onboarding returns one complete receipt');
|
|
142
|
+
select is((select count(*)::int from _atomic_result where attempt='replay'), 1,
|
|
143
|
+
'exact replay returns one complete receipt');
|
|
144
|
+
select is((select agent_id from _atomic_result where attempt='replay'),
|
|
145
|
+
(select agent_id from _atomic_result where attempt='first'),
|
|
146
|
+
'exact replay returns the same agent');
|
|
147
|
+
select is((select signing_key_id from _atomic_result where attempt='replay'),
|
|
148
|
+
(select signing_key_id from _atomic_result where attempt='first'),
|
|
149
|
+
'exact replay returns the same proven key');
|
|
150
|
+
select is((select fleet_machine_agent_id from _atomic_result where attempt='replay'),
|
|
151
|
+
(select fleet_machine_agent_id from _atomic_result where attempt='first'),
|
|
152
|
+
'exact replay returns the same fleet binding');
|
|
153
|
+
select is((select identity_disposition from _atomic_result where attempt='first'), 'created',
|
|
154
|
+
'first identity disposition is created');
|
|
155
|
+
select is((select identity_disposition from _atomic_result where attempt='replay'), 'reused',
|
|
156
|
+
'replay identity disposition is reused');
|
|
157
|
+
select is((select uses_count from agent_board.board_invite_tokens
|
|
158
|
+
where id=(select invite_id from _atomic_cfg)), 1,
|
|
159
|
+
'exact replay consumes no second invite use');
|
|
160
|
+
select is((select count(*)::int from agent_board.board_invite_redemptions
|
|
161
|
+
where invite_id=(select invite_id from _atomic_cfg)), 1,
|
|
162
|
+
'exact replay keeps one redemption ledger row');
|
|
163
|
+
select is((select count(*)::int from agent_board.agents where handle='atomic-runtime-agent'), 1,
|
|
164
|
+
'atomic onboarding creates exactly one agent');
|
|
165
|
+
select is((select count(*)::int from agent_board.agent_signing_keys
|
|
166
|
+
where id=(select signing_key_id from _atomic_result where attempt='first')), 1,
|
|
167
|
+
'atomic onboarding creates exactly one proven key');
|
|
168
|
+
select is((select role || '/' || membership_state from agent_board.board_memberships
|
|
169
|
+
where board_id=(select board_id from _atomic_cfg)
|
|
170
|
+
and agent_id=(select agent_id from _atomic_result where attempt='first')),
|
|
171
|
+
'member/joined',
|
|
172
|
+
'atomic onboarding creates the bounded member membership');
|
|
173
|
+
select is((select count(*)::int from agent_board.fleet_harness_registrations
|
|
174
|
+
where id=(select harness_registration_id from _atomic_result where attempt='first')), 1,
|
|
175
|
+
'atomic onboarding creates one harness registration');
|
|
176
|
+
select is((select count(*)::int from agent_board.fleet_repo_scopes
|
|
177
|
+
where id=(select repo_scope_id from _atomic_result where attempt='first')), 1,
|
|
178
|
+
'atomic onboarding creates one repo scope');
|
|
179
|
+
select is((select fma.signing_key_id from agent_board.fleet_machine_agents fma
|
|
180
|
+
where fma.id=(select fleet_machine_agent_id from _atomic_result where attempt='first')),
|
|
181
|
+
(select signing_key_id from _atomic_result where attempt='first'),
|
|
182
|
+
'fleet binding pins the exact proven signing key');
|
|
183
|
+
select is((select binding_signing_key_id from _atomic_result where attempt='first'),
|
|
184
|
+
(select signing_key_id from _atomic_result where attempt='first'),
|
|
185
|
+
'receipt independently returns the signing key pinned by the fleet binding');
|
|
186
|
+
|
|
187
|
+
create function pg_temp._atomic_history_attempt(p_iat integer)
|
|
188
|
+
returns text
|
|
189
|
+
language plpgsql
|
|
190
|
+
as $$
|
|
191
|
+
begin
|
|
192
|
+
perform * from agent_board.onboard_federated_fleet_agent(
|
|
193
|
+
'https://atomic-runtime.test', 'message-board', 'human-runtime',
|
|
194
|
+
jsonb_build_object('iss','https://atomic-runtime.test','aud','message-board','sub','human-runtime','iat',p_iat),
|
|
195
|
+
'atomic-runtime-agent',
|
|
196
|
+
'eRHZmllEy_TZHAG2zB-Qe_a5BFLkaavMTazWWfaE3f0', 'raw_ed25519_base64url',
|
|
197
|
+
'sha256:z8d5LQPfBMYnfZfvu8wVz684_jkp578-SPDU2OMObS8', true, null, 'agent',
|
|
198
|
+
'{board:send}', '{}', (select invite_code from _atomic_cfg),
|
|
199
|
+
(select board_id from _atomic_cfg), (select machine_id from _atomic_cfg),
|
|
200
|
+
'codex', 'phase-loop', 'message-board', 'sha256:atomic-runtime-repo',
|
|
201
|
+
'worker', 'phase_worker', 'atomic-runtime-agent'
|
|
202
|
+
);
|
|
203
|
+
return 'lived';
|
|
204
|
+
exception when others then
|
|
205
|
+
return sqlstate;
|
|
206
|
+
end
|
|
207
|
+
$$;
|
|
208
|
+
|
|
209
|
+
insert into agent_board.fleet_harness_registrations(
|
|
210
|
+
id, machine_id, harness_kind, harness_label, lifecycle_state, revoked_at
|
|
211
|
+
) values (
|
|
212
|
+
'ffffffff-ffff-ffff-ffff-fffffffffff1', (select machine_id from _atomic_cfg),
|
|
213
|
+
'codex', 'phase-loop', 'revoked', now()
|
|
214
|
+
);
|
|
215
|
+
select is(pg_temp._atomic_history_attempt(210), '42501',
|
|
216
|
+
'a later-sorting revoked harness tombstone blocks active-row replay');
|
|
217
|
+
delete from agent_board.fleet_harness_registrations where id='ffffffff-ffff-ffff-ffff-fffffffffff1';
|
|
218
|
+
insert into agent_board.fleet_harness_registrations(
|
|
219
|
+
id, machine_id, harness_kind, harness_label, lifecycle_state, revoked_at
|
|
220
|
+
) values (
|
|
221
|
+
'00000000-0000-0000-0000-000000000001', (select machine_id from _atomic_cfg),
|
|
222
|
+
'codex', 'phase-loop', 'revoked', now()
|
|
223
|
+
);
|
|
224
|
+
select is(pg_temp._atomic_history_attempt(211), '42501',
|
|
225
|
+
'an earlier-sorting revoked harness tombstone blocks active-row replay');
|
|
226
|
+
delete from agent_board.fleet_harness_registrations where id='00000000-0000-0000-0000-000000000001';
|
|
227
|
+
|
|
228
|
+
insert into agent_board.fleet_repo_scopes(
|
|
229
|
+
id, harness_registration_id, repo_slug, repo_fingerprint, scope_role,
|
|
230
|
+
lifecycle_state, revoked_at
|
|
231
|
+
) values (
|
|
232
|
+
'ffffffff-ffff-ffff-ffff-fffffffffff2',
|
|
233
|
+
(select harness_registration_id from _atomic_result where attempt='first'),
|
|
234
|
+
'message-board', 'sha256:atomic-runtime-repo', 'worker', 'revoked', now()
|
|
235
|
+
);
|
|
236
|
+
select is(pg_temp._atomic_history_attempt(212), '42501',
|
|
237
|
+
'a later-sorting revoked repo tombstone blocks active-row replay');
|
|
238
|
+
delete from agent_board.fleet_repo_scopes where id='ffffffff-ffff-ffff-ffff-fffffffffff2';
|
|
239
|
+
insert into agent_board.fleet_repo_scopes(
|
|
240
|
+
id, harness_registration_id, repo_slug, repo_fingerprint, scope_role,
|
|
241
|
+
lifecycle_state, revoked_at
|
|
242
|
+
) values (
|
|
243
|
+
'00000000-0000-0000-0000-000000000002',
|
|
244
|
+
(select harness_registration_id from _atomic_result where attempt='first'),
|
|
245
|
+
'message-board', 'sha256:atomic-runtime-repo', 'worker', 'revoked', now()
|
|
246
|
+
);
|
|
247
|
+
select is(pg_temp._atomic_history_attempt(213), '42501',
|
|
248
|
+
'an earlier-sorting revoked repo tombstone blocks active-row replay');
|
|
249
|
+
delete from agent_board.fleet_repo_scopes where id='00000000-0000-0000-0000-000000000002';
|
|
250
|
+
|
|
251
|
+
insert into agent_board.fleet_machine_agents(
|
|
252
|
+
id, machine_id, agent_id, repo_scope_id, signing_key_id, agent_role,
|
|
253
|
+
lifecycle_state, revoked_at
|
|
254
|
+
) values (
|
|
255
|
+
'ffffffff-ffff-ffff-ffff-fffffffffff3', (select machine_id from _atomic_cfg),
|
|
256
|
+
(select agent_id from _atomic_result where attempt='first'),
|
|
257
|
+
(select repo_scope_id from _atomic_result where attempt='first'),
|
|
258
|
+
(select signing_key_id from _atomic_result where attempt='first'),
|
|
259
|
+
'phase_worker', 'revoked', now()
|
|
260
|
+
);
|
|
261
|
+
select is(pg_temp._atomic_history_attempt(214), '42501',
|
|
262
|
+
'a later-sorting revoked binding tombstone blocks active-row replay');
|
|
263
|
+
delete from agent_board.fleet_machine_agents where id='ffffffff-ffff-ffff-ffff-fffffffffff3';
|
|
264
|
+
insert into agent_board.fleet_machine_agents(
|
|
265
|
+
id, machine_id, agent_id, repo_scope_id, signing_key_id, agent_role,
|
|
266
|
+
lifecycle_state, revoked_at
|
|
267
|
+
) values (
|
|
268
|
+
'00000000-0000-0000-0000-000000000003', (select machine_id from _atomic_cfg),
|
|
269
|
+
(select agent_id from _atomic_result where attempt='first'),
|
|
270
|
+
(select repo_scope_id from _atomic_result where attempt='first'),
|
|
271
|
+
(select signing_key_id from _atomic_result where attempt='first'),
|
|
272
|
+
'phase_worker', 'revoked', now()
|
|
273
|
+
);
|
|
274
|
+
select is(pg_temp._atomic_history_attempt(215), '42501',
|
|
275
|
+
'an earlier-sorting revoked binding tombstone blocks active-row replay');
|
|
276
|
+
delete from agent_board.fleet_machine_agents where id='00000000-0000-0000-0000-000000000003';
|
|
277
|
+
|
|
278
|
+
update agent_board.board_invite_tokens
|
|
279
|
+
set expires_at = now() - interval '1 minute'
|
|
280
|
+
where id = (select invite_id from _atomic_cfg);
|
|
281
|
+
select lives_ok(
|
|
282
|
+
$$insert into _atomic_result
|
|
283
|
+
select 'expired-complete-replay', r.agent_id, r.signing_key_id, r.board_id,
|
|
284
|
+
r.harness_registration_id, r.repo_scope_id, r.fleet_machine_agent_id,
|
|
285
|
+
r.binding_signing_key_id,
|
|
286
|
+
r.identity_disposition, r.membership_disposition,
|
|
287
|
+
r.harness_disposition, r.repo_scope_disposition, r.binding_disposition
|
|
288
|
+
from agent_board.onboard_federated_fleet_agent(
|
|
289
|
+
'https://atomic-runtime.test', 'message-board', 'human-runtime',
|
|
290
|
+
'{"iss":"https://atomic-runtime.test","aud":"message-board","sub":"human-runtime","iat":250}'::jsonb,
|
|
291
|
+
'atomic-runtime-agent',
|
|
292
|
+
'eRHZmllEy_TZHAG2zB-Qe_a5BFLkaavMTazWWfaE3f0', 'raw_ed25519_base64url',
|
|
293
|
+
'sha256:z8d5LQPfBMYnfZfvu8wVz684_jkp578-SPDU2OMObS8', true, null, 'agent',
|
|
294
|
+
'{board:send}', '{}', (select invite_code from _atomic_cfg),
|
|
295
|
+
(select board_id from _atomic_cfg), (select machine_id from _atomic_cfg),
|
|
296
|
+
'codex', 'phase-loop', 'message-board', 'sha256:atomic-runtime-repo',
|
|
297
|
+
'worker', 'phase_worker', 'atomic-runtime-agent') r$$,
|
|
298
|
+
'a fully complete active replay may bypass only expiry and its consumed use cap'
|
|
299
|
+
);
|
|
300
|
+
select is((select count(*)::int from _atomic_result where attempt='expired-complete-replay'), 1,
|
|
301
|
+
'expired complete replay returns the exact receipt');
|
|
302
|
+
select is((select uses_count from agent_board.board_invite_tokens
|
|
303
|
+
where id=(select invite_id from _atomic_cfg)), 1,
|
|
304
|
+
'expired complete replay consumes no additional use');
|
|
305
|
+
update agent_board.board_invite_tokens
|
|
306
|
+
set expires_at = now() + interval '1 hour'
|
|
307
|
+
where id = (select invite_id from _atomic_cfg);
|
|
308
|
+
|
|
309
|
+
select throws_ok(
|
|
310
|
+
$$select * from agent_board._redeem_invite_for_agent(
|
|
311
|
+
(select invite_code from _atomic_cfg),
|
|
312
|
+
(select agent_id from _atomic_result where attempt='first'))$$,
|
|
313
|
+
'42501', null,
|
|
314
|
+
'generic redemption rejects the bounded invite'
|
|
315
|
+
);
|
|
316
|
+
select throws_ok(
|
|
317
|
+
$$select * from agent_board.enroll_federated_identity(
|
|
318
|
+
'https://atomic-runtime.test', 'message-board', 'human-runtime',
|
|
319
|
+
'{"iss":"https://atomic-runtime.test","aud":"message-board","sub":"human-runtime","iat":300}'::jsonb, 'atomic-runtime-agent',
|
|
320
|
+
'eRHZmllEy_TZHAG2zB-Qe_a5BFLkaavMTazWWfaE3f0', 'raw_ed25519_base64url',
|
|
321
|
+
'sha256:z8d5LQPfBMYnfZfvu8wVz684_jkp578-SPDU2OMObS8', true, null, 'agent',
|
|
322
|
+
'{board:send}', '{}', (select invite_code from _atomic_cfg))$$,
|
|
323
|
+
'42501', null,
|
|
324
|
+
'legacy enrollment rejects the bounded invite before replay'
|
|
325
|
+
);
|
|
326
|
+
select throws_ok(
|
|
327
|
+
$$select * from agent_board.onboard_federated_fleet_agent(
|
|
328
|
+
'https://atomic-runtime.test', 'message-board', 'human-runtime',
|
|
329
|
+
'{"iss":"https://atomic-runtime.test","aud":"message-board","sub":"human-runtime","iat":300}'::jsonb, 'atomic-runtime-agent',
|
|
330
|
+
'eRHZmllEy_TZHAG2zB-Qe_a5BFLkaavMTazWWfaE3f0', 'raw_ed25519_base64url',
|
|
331
|
+
'sha256:z8d5LQPfBMYnfZfvu8wVz684_jkp578-SPDU2OMObS8', true, null, 'agent',
|
|
332
|
+
'{board:send}', '{}', (select invite_code from _atomic_cfg),
|
|
333
|
+
(select board_id from _atomic_cfg), (select machine_id from _atomic_cfg), 'codex', 'substituted-label',
|
|
334
|
+
'message-board', 'sha256:atomic-runtime-repo', 'worker', 'phase_worker',
|
|
335
|
+
'atomic-runtime-agent')$$,
|
|
336
|
+
'42501', null,
|
|
337
|
+
'altered bound tuple is rejected before replay writes'
|
|
338
|
+
);
|
|
339
|
+
select throws_ok(
|
|
340
|
+
$$select * from agent_board.onboard_federated_fleet_agent(
|
|
341
|
+
'https://atomic-runtime.test', 'message-board', 'human-runtime',
|
|
342
|
+
'{"iss":"https://atomic-runtime.test","aud":"message-board","sub":"human-runtime","iat":350}'::jsonb, 'atomic-runtime-agent',
|
|
343
|
+
'eRHZmllEy_TZHAG2zB-Qe_a5BFLkaavMTazWWfaE3f0', 'raw_ed25519_base64url',
|
|
344
|
+
'sha256:z8d5LQPfBMYnfZfvu8wVz684_jkp578-SPDU2OMObS8', true, null, 'agent',
|
|
345
|
+
'{board:send}', '{}', (select invite_code from _atomic_cfg),
|
|
346
|
+
gen_random_uuid(), (select machine_id from _atomic_cfg), 'codex', 'phase-loop',
|
|
347
|
+
'message-board', 'sha256:atomic-runtime-repo', 'worker', 'phase_worker',
|
|
348
|
+
'atomic-runtime-agent')$$,
|
|
349
|
+
'42501', null,
|
|
350
|
+
'wrong board id is rejected against the locked invite before replay writes'
|
|
351
|
+
);
|
|
352
|
+
select throws_ok(
|
|
353
|
+
$$select * from agent_board.onboard_federated_fleet_agent(
|
|
354
|
+
'https://atomic-runtime.test', 'message-board', 'human-runtime',
|
|
355
|
+
'{"iss":"https://atomic-runtime.test","aud":"message-board","sub":"human-runtime","iat":351}'::jsonb, 'atomic-runtime-agent',
|
|
356
|
+
'eRHZmllEy_TZHAG2zB-Qe_a5BFLkaavMTazWWfaE3f0', 'raw_ed25519_base64url',
|
|
357
|
+
'sha256:z8d5LQPfBMYnfZfvu8wVz684_jkp578-SPDU2OMObS8', true, null, 'agent',
|
|
358
|
+
'{board:send}', '{}', (select invite_code from _atomic_cfg),
|
|
359
|
+
(select board_id from _atomic_cfg), gen_random_uuid(), 'codex', 'phase-loop',
|
|
360
|
+
'message-board', 'sha256:atomic-runtime-repo', 'worker', 'phase_worker',
|
|
361
|
+
'atomic-runtime-agent')$$,
|
|
362
|
+
'42501', null, 'altered machine bound is rejected before replay writes'
|
|
363
|
+
);
|
|
364
|
+
select throws_ok(
|
|
365
|
+
$$select * from agent_board.onboard_federated_fleet_agent(
|
|
366
|
+
'https://atomic-runtime.test', 'message-board', 'human-runtime',
|
|
367
|
+
'{"iss":"https://atomic-runtime.test","aud":"message-board","sub":"human-runtime","iat":352}'::jsonb, 'atomic-runtime-agent',
|
|
368
|
+
'eRHZmllEy_TZHAG2zB-Qe_a5BFLkaavMTazWWfaE3f0', 'raw_ed25519_base64url',
|
|
369
|
+
'sha256:z8d5LQPfBMYnfZfvu8wVz684_jkp578-SPDU2OMObS8', true, null, 'agent',
|
|
370
|
+
'{board:send}', '{}', (select invite_code from _atomic_cfg),
|
|
371
|
+
(select board_id from _atomic_cfg), (select machine_id from _atomic_cfg), 'claude', 'phase-loop',
|
|
372
|
+
'message-board', 'sha256:atomic-runtime-repo', 'worker', 'phase_worker',
|
|
373
|
+
'atomic-runtime-agent')$$,
|
|
374
|
+
'42501', null, 'altered harness-kind bound is rejected before replay writes'
|
|
375
|
+
);
|
|
376
|
+
select throws_ok(
|
|
377
|
+
$$select * from agent_board.onboard_federated_fleet_agent(
|
|
378
|
+
'https://atomic-runtime.test', 'message-board', 'human-runtime',
|
|
379
|
+
'{"iss":"https://atomic-runtime.test","aud":"message-board","sub":"human-runtime","iat":353}'::jsonb, 'atomic-runtime-agent',
|
|
380
|
+
'eRHZmllEy_TZHAG2zB-Qe_a5BFLkaavMTazWWfaE3f0', 'raw_ed25519_base64url',
|
|
381
|
+
'sha256:z8d5LQPfBMYnfZfvu8wVz684_jkp578-SPDU2OMObS8', true, null, 'agent',
|
|
382
|
+
'{board:send}', '{}', (select invite_code from _atomic_cfg),
|
|
383
|
+
(select board_id from _atomic_cfg), (select machine_id from _atomic_cfg), 'codex', 'phase-loop',
|
|
384
|
+
'other-repo', 'sha256:atomic-runtime-repo', 'worker', 'phase_worker',
|
|
385
|
+
'atomic-runtime-agent')$$,
|
|
386
|
+
'42501', null, 'altered repo-slug bound is rejected before replay writes'
|
|
387
|
+
);
|
|
388
|
+
select throws_ok(
|
|
389
|
+
$$select * from agent_board.onboard_federated_fleet_agent(
|
|
390
|
+
'https://atomic-runtime.test', 'message-board', 'human-runtime',
|
|
391
|
+
'{"iss":"https://atomic-runtime.test","aud":"message-board","sub":"human-runtime","iat":354}'::jsonb, 'atomic-runtime-agent',
|
|
392
|
+
'eRHZmllEy_TZHAG2zB-Qe_a5BFLkaavMTazWWfaE3f0', 'raw_ed25519_base64url',
|
|
393
|
+
'sha256:z8d5LQPfBMYnfZfvu8wVz684_jkp578-SPDU2OMObS8', true, null, 'agent',
|
|
394
|
+
'{board:send}', '{}', (select invite_code from _atomic_cfg),
|
|
395
|
+
(select board_id from _atomic_cfg), (select machine_id from _atomic_cfg), 'codex', 'phase-loop',
|
|
396
|
+
'message-board', 'sha256:substituted-repo', 'worker', 'phase_worker',
|
|
397
|
+
'atomic-runtime-agent')$$,
|
|
398
|
+
'42501', null, 'altered repo-fingerprint bound is rejected before replay writes'
|
|
399
|
+
);
|
|
400
|
+
select throws_ok(
|
|
401
|
+
$$select * from agent_board.onboard_federated_fleet_agent(
|
|
402
|
+
'https://atomic-runtime.test', 'message-board', 'human-runtime',
|
|
403
|
+
'{"iss":"https://atomic-runtime.test","aud":"message-board","sub":"human-runtime","iat":355}'::jsonb, 'atomic-runtime-agent',
|
|
404
|
+
'eRHZmllEy_TZHAG2zB-Qe_a5BFLkaavMTazWWfaE3f0', 'raw_ed25519_base64url',
|
|
405
|
+
'sha256:z8d5LQPfBMYnfZfvu8wVz684_jkp578-SPDU2OMObS8', true, null, 'agent',
|
|
406
|
+
'{board:send}', '{}', (select invite_code from _atomic_cfg),
|
|
407
|
+
(select board_id from _atomic_cfg), (select machine_id from _atomic_cfg), 'codex', 'phase-loop',
|
|
408
|
+
'message-board', 'sha256:atomic-runtime-repo', 'reviewer', 'reviewer',
|
|
409
|
+
'atomic-runtime-agent')$$,
|
|
410
|
+
'42501', null, 'altered role-pair bound is rejected before replay writes'
|
|
411
|
+
);
|
|
412
|
+
select throws_ok(
|
|
413
|
+
$$select * from agent_board.onboard_federated_fleet_agent(
|
|
414
|
+
'https://atomic-runtime.test', 'message-board', 'human-runtime',
|
|
415
|
+
'{"iss":"https://atomic-runtime.test","aud":"message-board","sub":"human-runtime","iat":356}'::jsonb, 'atomic-runtime-agent',
|
|
416
|
+
'eRHZmllEy_TZHAG2zB-Qe_a5BFLkaavMTazWWfaE3f0', 'raw_ed25519_base64url',
|
|
417
|
+
'sha256:z8d5LQPfBMYnfZfvu8wVz684_jkp578-SPDU2OMObS8', true, null, 'agent',
|
|
418
|
+
'{board:send}', '{}', (select invite_code from _atomic_cfg),
|
|
419
|
+
(select board_id from _atomic_cfg), (select machine_id from _atomic_cfg), 'codex', 'phase-loop',
|
|
420
|
+
'message-board', 'sha256:atomic-runtime-repo', 'worker', 'phase_worker',
|
|
421
|
+
'substituted-handle')$$,
|
|
422
|
+
'42501', null, 'altered expected-handle bound is rejected before replay writes'
|
|
423
|
+
);
|
|
424
|
+
select throws_ok(
|
|
425
|
+
$$select * from agent_board.onboard_federated_fleet_agent(
|
|
426
|
+
'https://atomic-runtime.test', 'message-board', 'human-runtime',
|
|
427
|
+
'{"iss":"https://atomic-runtime.test","aud":"message-board","sub":"human-runtime","iat":357}'::jsonb, 'atomic-runtime-agent',
|
|
428
|
+
'eRHZmllEy_TZHAG2zB-Qe_a5BFLkaavMTazWWfaE3f0', 'raw_ed25519_base64url',
|
|
429
|
+
'sha256:z8d5LQPfBMYnfZfvu8wVz684_jkp578-SPDU2OMObS8', true, null, 'agent',
|
|
430
|
+
'{board:send}', '{}', (select invite_code from _atomic_cfg),
|
|
431
|
+
(select board_id from _atomic_cfg), (select machine_id from _atomic_cfg), 'codex', 'phase-loop',
|
|
432
|
+
'message-board', 'sha256:atomic-runtime-repo', 'worker', 'reviewer',
|
|
433
|
+
'atomic-runtime-agent')$$,
|
|
434
|
+
'42501', null, 'altered agent-role bound is rejected before replay writes'
|
|
435
|
+
);
|
|
436
|
+
select is(
|
|
437
|
+
(select count(*)::text from agent_board.agents where handle='atomic-runtime-agent') || '/' ||
|
|
438
|
+
(select count(*)::text from agent_board.board_invite_redemptions where invite_id=(select invite_id from _atomic_cfg)) || '/' ||
|
|
439
|
+
(select count(*)::text from agent_board.fleet_machine_agents where agent_id=(select agent_id from _atomic_result where attempt='first')),
|
|
440
|
+
'1/1/1',
|
|
441
|
+
'wrong-board rejection leaves identity, redemption, and fleet counts unchanged'
|
|
442
|
+
);
|
|
443
|
+
select is((select count(*)::int from agent_board.fleet_machine_agents
|
|
444
|
+
where agent_id=(select agent_id from _atomic_result where attempt='first')), 1,
|
|
445
|
+
'rejected legacy and altered-bound paths leave one fleet binding');
|
|
446
|
+
select throws_ok(
|
|
447
|
+
$$update agent_board.fleet_onboarding_invite_bounds
|
|
448
|
+
set harness_label='mutated'
|
|
449
|
+
where invite_id=(select invite_id from _atomic_cfg)$$,
|
|
450
|
+
'55000', null,
|
|
451
|
+
'creator-authorized bounds remain immutable'
|
|
452
|
+
);
|
|
453
|
+
|
|
454
|
+
create temp table _cascade_invite as
|
|
455
|
+
select invite_id
|
|
456
|
+
from agent_board.create_fleet_onboarding_invite(
|
|
457
|
+
(select board_id from _atomic_cfg), (select machine_id from _atomic_cfg),
|
|
458
|
+
'codex', 'cascade-proof', 'message-board', 'sha256:cascade-proof',
|
|
459
|
+
'worker', 'phase_worker', 'agent-board/cascade-proof/codex',
|
|
460
|
+
1, now() + interval '1 hour', (select owner_id from _atomic_cfg), '{}'::jsonb
|
|
461
|
+
);
|
|
462
|
+
delete from agent_board.board_invite_tokens where id=(select invite_id from _cascade_invite);
|
|
463
|
+
select is(
|
|
464
|
+
(select count(*)::int from agent_board.fleet_onboarding_invite_bounds
|
|
465
|
+
where invite_id=(select invite_id from _cascade_invite)),
|
|
466
|
+
0,
|
|
467
|
+
'deleting an unused invite reaches the declared bounds cascade'
|
|
468
|
+
);
|
|
469
|
+
|
|
470
|
+
update agent_board.board_invite_tokens
|
|
471
|
+
set revoked_at = now()
|
|
472
|
+
where id = (select invite_id from _atomic_cfg);
|
|
473
|
+
select throws_ok(
|
|
474
|
+
$$select * from agent_board.onboard_federated_fleet_agent(
|
|
475
|
+
'https://atomic-runtime.test', 'message-board', 'human-runtime',
|
|
476
|
+
'{"iss":"https://atomic-runtime.test","aud":"message-board","sub":"human-runtime","iat":360}'::jsonb, 'atomic-runtime-agent',
|
|
477
|
+
'eRHZmllEy_TZHAG2zB-Qe_a5BFLkaavMTazWWfaE3f0', 'raw_ed25519_base64url',
|
|
478
|
+
'sha256:z8d5LQPfBMYnfZfvu8wVz684_jkp578-SPDU2OMObS8', true, null, 'agent',
|
|
479
|
+
'{board:send}', '{}', (select invite_code from _atomic_cfg),
|
|
480
|
+
(select board_id from _atomic_cfg), (select machine_id from _atomic_cfg), 'codex', 'phase-loop',
|
|
481
|
+
'message-board', 'sha256:atomic-runtime-repo', 'worker', 'phase_worker',
|
|
482
|
+
'atomic-runtime-agent')$$,
|
|
483
|
+
'42501', null,
|
|
484
|
+
'even a complete replay cannot bypass explicit invite revocation'
|
|
485
|
+
);
|
|
486
|
+
|
|
487
|
+
delete from agent_board.fleet_machine_agents
|
|
488
|
+
where id = (select fleet_machine_agent_id from _atomic_result where attempt='first');
|
|
489
|
+
select throws_ok(
|
|
490
|
+
$$select * from agent_board.onboard_federated_fleet_agent(
|
|
491
|
+
'https://atomic-runtime.test', 'message-board', 'human-runtime',
|
|
492
|
+
'{"iss":"https://atomic-runtime.test","aud":"message-board","sub":"human-runtime","iat":361}'::jsonb, 'atomic-runtime-agent',
|
|
493
|
+
'eRHZmllEy_TZHAG2zB-Qe_a5BFLkaavMTazWWfaE3f0', 'raw_ed25519_base64url',
|
|
494
|
+
'sha256:z8d5LQPfBMYnfZfvu8wVz684_jkp578-SPDU2OMObS8', true, null, 'agent',
|
|
495
|
+
'{board:send}', '{}', (select invite_code from _atomic_cfg),
|
|
496
|
+
(select board_id from _atomic_cfg), (select machine_id from _atomic_cfg), 'codex', 'phase-loop',
|
|
497
|
+
'message-board', 'sha256:atomic-runtime-repo', 'worker', 'phase_worker',
|
|
498
|
+
'atomic-runtime-agent')$$,
|
|
499
|
+
'42501', null,
|
|
500
|
+
'a revoked invite cannot repair a partial fleet suffix'
|
|
501
|
+
);
|
|
502
|
+
select is((select count(*)::int from agent_board.fleet_machine_agents
|
|
503
|
+
where agent_id=(select agent_id from _atomic_result where attempt='first')), 0,
|
|
504
|
+
'revoked partial recovery rolls back without a replacement binding');
|
|
505
|
+
|
|
506
|
+
update agent_board.board_invite_tokens
|
|
507
|
+
set revoked_at = null
|
|
508
|
+
where id = (select invite_id from _atomic_cfg);
|
|
509
|
+
select throws_ok(
|
|
510
|
+
$$select * from agent_board.onboard_federated_fleet_agent(
|
|
511
|
+
'https://atomic-runtime.test', 'message-board', 'human-runtime',
|
|
512
|
+
'{"iss":"https://atomic-runtime.test","aud":"message-board","sub":"human-runtime","iat":362}'::jsonb, 'atomic-runtime-agent',
|
|
513
|
+
'eRHZmllEy_TZHAG2zB-Qe_a5BFLkaavMTazWWfaE3f0', 'raw_ed25519_base64url',
|
|
514
|
+
'sha256:z8d5LQPfBMYnfZfvu8wVz684_jkp578-SPDU2OMObS8', true, null, 'agent',
|
|
515
|
+
'{board:send}', '{}', (select invite_code from _atomic_cfg),
|
|
516
|
+
(select board_id from _atomic_cfg), (select machine_id from _atomic_cfg), 'codex', 'phase-loop',
|
|
517
|
+
'message-board', 'sha256:atomic-runtime-repo', 'worker', 'phase_worker',
|
|
518
|
+
'atomic-runtime-agent')$$,
|
|
519
|
+
'42501', null,
|
|
520
|
+
'an exhausted invite cannot repair a partial fleet suffix'
|
|
521
|
+
);
|
|
522
|
+
|
|
523
|
+
update agent_board.board_invite_tokens
|
|
524
|
+
set max_uses = 2, expires_at = now() - interval '1 minute'
|
|
525
|
+
where id = (select invite_id from _atomic_cfg);
|
|
526
|
+
select throws_ok(
|
|
527
|
+
$$select * from agent_board.onboard_federated_fleet_agent(
|
|
528
|
+
'https://atomic-runtime.test', 'message-board', 'human-runtime',
|
|
529
|
+
'{"iss":"https://atomic-runtime.test","aud":"message-board","sub":"human-runtime","iat":363}'::jsonb, 'atomic-runtime-agent',
|
|
530
|
+
'eRHZmllEy_TZHAG2zB-Qe_a5BFLkaavMTazWWfaE3f0', 'raw_ed25519_base64url',
|
|
531
|
+
'sha256:z8d5LQPfBMYnfZfvu8wVz684_jkp578-SPDU2OMObS8', true, null, 'agent',
|
|
532
|
+
'{board:send}', '{}', (select invite_code from _atomic_cfg),
|
|
533
|
+
(select board_id from _atomic_cfg), (select machine_id from _atomic_cfg), 'codex', 'phase-loop',
|
|
534
|
+
'message-board', 'sha256:atomic-runtime-repo', 'worker', 'phase_worker',
|
|
535
|
+
'atomic-runtime-agent')$$,
|
|
536
|
+
'42501', null,
|
|
537
|
+
'an expired invite cannot repair a partial fleet suffix'
|
|
538
|
+
);
|
|
539
|
+
|
|
540
|
+
update agent_board.board_invite_tokens
|
|
541
|
+
set expires_at = now() + interval '1 hour'
|
|
542
|
+
where id = (select invite_id from _atomic_cfg);
|
|
543
|
+
update agent_board.agents set status = 'suspended'
|
|
544
|
+
where id = (select owner_id from _atomic_cfg);
|
|
545
|
+
select throws_ok(
|
|
546
|
+
$$select * from agent_board.onboard_federated_fleet_agent(
|
|
547
|
+
'https://atomic-runtime.test', 'message-board', 'human-runtime',
|
|
548
|
+
'{"iss":"https://atomic-runtime.test","aud":"message-board","sub":"human-runtime","iat":364}'::jsonb, 'atomic-runtime-agent',
|
|
549
|
+
'eRHZmllEy_TZHAG2zB-Qe_a5BFLkaavMTazWWfaE3f0', 'raw_ed25519_base64url',
|
|
550
|
+
'sha256:z8d5LQPfBMYnfZfvu8wVz684_jkp578-SPDU2OMObS8', true, null, 'agent',
|
|
551
|
+
'{board:send}', '{}', (select invite_code from _atomic_cfg),
|
|
552
|
+
(select board_id from _atomic_cfg), (select machine_id from _atomic_cfg), 'codex', 'phase-loop',
|
|
553
|
+
'message-board', 'sha256:atomic-runtime-repo', 'worker', 'phase_worker',
|
|
554
|
+
'atomic-runtime-agent')$$,
|
|
555
|
+
'42501', null,
|
|
556
|
+
'an inactive invite creator cannot repair a partial fleet suffix'
|
|
557
|
+
);
|
|
558
|
+
|
|
559
|
+
update agent_board.agents set status = 'active'
|
|
560
|
+
where id = (select owner_id from _atomic_cfg);
|
|
561
|
+
select lives_ok(
|
|
562
|
+
$$insert into _atomic_result
|
|
563
|
+
select 'partial-recovery', r.agent_id, r.signing_key_id, r.board_id,
|
|
564
|
+
r.harness_registration_id, r.repo_scope_id, r.fleet_machine_agent_id,
|
|
565
|
+
r.binding_signing_key_id,
|
|
566
|
+
r.identity_disposition, r.membership_disposition,
|
|
567
|
+
r.harness_disposition, r.repo_scope_disposition, r.binding_disposition
|
|
568
|
+
from agent_board.onboard_federated_fleet_agent(
|
|
569
|
+
'https://atomic-runtime.test', 'message-board', 'human-runtime',
|
|
570
|
+
'{"iss":"https://atomic-runtime.test","aud":"message-board","sub":"human-runtime","iat":365}'::jsonb,
|
|
571
|
+
'atomic-runtime-agent',
|
|
572
|
+
'eRHZmllEy_TZHAG2zB-Qe_a5BFLkaavMTazWWfaE3f0', 'raw_ed25519_base64url',
|
|
573
|
+
'sha256:z8d5LQPfBMYnfZfvu8wVz684_jkp578-SPDU2OMObS8', true, null, 'agent',
|
|
574
|
+
'{board:send}', '{}', (select invite_code from _atomic_cfg),
|
|
575
|
+
(select board_id from _atomic_cfg), (select machine_id from _atomic_cfg),
|
|
576
|
+
'codex', 'phase-loop', 'message-board', 'sha256:atomic-runtime-repo',
|
|
577
|
+
'worker', 'phase_worker', 'atomic-runtime-agent') r$$,
|
|
578
|
+
'a current authorized invite repairs an exact partial suffix'
|
|
579
|
+
);
|
|
580
|
+
select is((select count(*)::int from agent_board.fleet_machine_agents
|
|
581
|
+
where agent_id=(select agent_id from _atomic_result where attempt='first')), 1,
|
|
582
|
+
'authorized partial recovery creates exactly one replacement binding');
|
|
583
|
+
select is((select binding_disposition from _atomic_result where attempt='partial-recovery'), 'recovered',
|
|
584
|
+
'authorized partial recovery reports recovered disposition');
|
|
585
|
+
select is(
|
|
586
|
+
(select count(*)::text from agent_board.board_invite_redemptions
|
|
587
|
+
where invite_id=(select invite_id from _atomic_cfg)) || '/' ||
|
|
588
|
+
(select count(*)::text from agent_board.board_memberships
|
|
589
|
+
where board_id=(select board_id from _atomic_cfg)
|
|
590
|
+
and agent_id=(select agent_id from _atomic_result where attempt='first')
|
|
591
|
+
and membership_state in ('joined','subscribed')),
|
|
592
|
+
'1/1',
|
|
593
|
+
'partial recovery preserves one redemption and one active membership'
|
|
594
|
+
);
|
|
595
|
+
update _atomic_result
|
|
596
|
+
set fleet_machine_agent_id = (
|
|
597
|
+
select fleet_machine_agent_id from _atomic_result where attempt='partial-recovery'
|
|
598
|
+
)
|
|
599
|
+
where attempt in ('first', 'replay', 'expired-complete-replay');
|
|
600
|
+
|
|
601
|
+
select lives_ok(
|
|
602
|
+
format(
|
|
603
|
+
'select * from agent_board.revoke_fleet_machine_agent_binding(%L::uuid,%L::uuid,%L,%L::jsonb)',
|
|
604
|
+
(select fleet_machine_agent_id from _atomic_result where attempt='first'),
|
|
605
|
+
(select owner_id from _atomic_cfg), 'runtime test', '{}'
|
|
606
|
+
),
|
|
607
|
+
'the exact-binding sole writer permanently revokes the binding'
|
|
608
|
+
);
|
|
609
|
+
select is((select lifecycle_state from agent_board.fleet_machine_agents
|
|
610
|
+
where id=(select fleet_machine_agent_id from _atomic_result where attempt='first')),
|
|
611
|
+
'revoked',
|
|
612
|
+
'the exact binding remains a revoked tombstone');
|
|
613
|
+
select throws_ok(
|
|
614
|
+
$$select * from agent_board.onboard_federated_fleet_agent(
|
|
615
|
+
'https://atomic-runtime.test', 'message-board', 'human-runtime',
|
|
616
|
+
'{"iss":"https://atomic-runtime.test","aud":"message-board","sub":"human-runtime","iat":400}'::jsonb, 'atomic-runtime-agent',
|
|
617
|
+
'eRHZmllEy_TZHAG2zB-Qe_a5BFLkaavMTazWWfaE3f0', 'raw_ed25519_base64url',
|
|
618
|
+
'sha256:z8d5LQPfBMYnfZfvu8wVz684_jkp578-SPDU2OMObS8', true, null, 'agent',
|
|
619
|
+
'{board:send}', '{}', (select invite_code from _atomic_cfg),
|
|
620
|
+
(select board_id from _atomic_cfg), (select machine_id from _atomic_cfg), 'codex', 'phase-loop',
|
|
621
|
+
'message-board', 'sha256:atomic-runtime-repo', 'worker', 'phase_worker',
|
|
622
|
+
'atomic-runtime-agent')$$,
|
|
623
|
+
'42501', null,
|
|
624
|
+
'post-revocation exact replay cannot create replacement authority'
|
|
625
|
+
);
|
|
626
|
+
select is((select count(*)::int from agent_board.fleet_machine_agents
|
|
627
|
+
where agent_id=(select agent_id from _atomic_result where attempt='first')), 1,
|
|
628
|
+
'post-revocation replay leaves only the original tombstone');
|
|
629
|
+
|
|
630
|
+
do $$
|
|
631
|
+
declare
|
|
632
|
+
v_agent uuid;
|
|
633
|
+
v_key uuid;
|
|
634
|
+
v_invite uuid;
|
|
635
|
+
v_code text;
|
|
636
|
+
begin
|
|
637
|
+
select e.agent_id, e.signing_key_id
|
|
638
|
+
into v_agent, v_key
|
|
639
|
+
from agent_board.enroll_federated_identity(
|
|
640
|
+
'https://atomic-runtime.test', 'message-board', 'human-recovery',
|
|
641
|
+
'{"iss":"https://atomic-runtime.test","aud":"message-board","sub":"human-recovery","iat":500}'::jsonb,
|
|
642
|
+
'atomic-recovery-agent',
|
|
643
|
+
'yd_DIFGWGusVg3SbktDJQ1bE5UWvtR33xln4b05JIhk',
|
|
644
|
+
'raw_ed25519_base64url',
|
|
645
|
+
'sha256:NeVC2vx1MbTY56jUwJcLLr6YwB4IKCERsXWbUwhf5pA',
|
|
646
|
+
true, null, 'agent', '{board:send}', '{}', null
|
|
647
|
+
) e;
|
|
648
|
+
|
|
649
|
+
select invite_id, code into v_invite, v_code
|
|
650
|
+
from agent_board.create_fleet_onboarding_invite(
|
|
651
|
+
(select board_id from _atomic_cfg), (select machine_id from _atomic_cfg),
|
|
652
|
+
'codex', 'recovery-harness', 'message-board', 'sha256:recovery-repo',
|
|
653
|
+
'worker', 'phase_worker', 'atomic-recovery-agent', 1,
|
|
654
|
+
now() + interval '1 hour', (select owner_id from _atomic_cfg), '{}'::jsonb
|
|
655
|
+
);
|
|
656
|
+
insert into _recovery_cfg values (v_agent, v_key, v_invite, v_code);
|
|
657
|
+
end
|
|
658
|
+
$$;
|
|
659
|
+
|
|
660
|
+
select lives_ok(
|
|
661
|
+
$$insert into _recovery_result
|
|
662
|
+
select r.agent_id, r.signing_key_id, r.identity_disposition,
|
|
663
|
+
r.membership_disposition, r.harness_disposition,
|
|
664
|
+
r.repo_scope_disposition, r.binding_disposition
|
|
665
|
+
from agent_board.onboard_federated_fleet_agent(
|
|
666
|
+
'https://atomic-runtime.test', 'message-board', 'human-recovery',
|
|
667
|
+
'{"iss":"https://atomic-runtime.test","aud":"message-board","sub":"human-recovery","iat":501,"jti":"rotated"}'::jsonb,
|
|
668
|
+
'atomic-recovery-agent',
|
|
669
|
+
'yd_DIFGWGusVg3SbktDJQ1bE5UWvtR33xln4b05JIhk', 'raw_ed25519_base64url',
|
|
670
|
+
'sha256:NeVC2vx1MbTY56jUwJcLLr6YwB4IKCERsXWbUwhf5pA', true, null, 'agent',
|
|
671
|
+
'{board:send}', '{}', (select invite_code from _recovery_cfg),
|
|
672
|
+
(select board_id from _atomic_cfg), (select machine_id from _atomic_cfg),
|
|
673
|
+
'codex', 'recovery-harness', 'message-board', 'sha256:recovery-repo',
|
|
674
|
+
'worker', 'phase_worker', 'atomic-recovery-agent') r$$,
|
|
675
|
+
'an exact legacy identity recovers its missing membership and fleet suffix'
|
|
676
|
+
);
|
|
677
|
+
select is((select agent_id from _recovery_result),
|
|
678
|
+
(select legacy_agent_id from _recovery_cfg),
|
|
679
|
+
'legacy recovery reuses the exact principal');
|
|
680
|
+
select is((select signing_key_id from _recovery_result),
|
|
681
|
+
(select legacy_signing_key_id from _recovery_cfg),
|
|
682
|
+
'legacy recovery reuses the exact proven signing key');
|
|
683
|
+
select is(
|
|
684
|
+
(select identity_disposition || '/' || membership_disposition || '/' ||
|
|
685
|
+
harness_disposition || '/' || repo_scope_disposition || '/' || binding_disposition
|
|
686
|
+
from _recovery_result),
|
|
687
|
+
'reused/created/recovered/recovered/recovered',
|
|
688
|
+
'legacy recovery reports the created and recovered suffix components');
|
|
689
|
+
select is(
|
|
690
|
+
(select count(*)::text from agent_board.board_invite_redemptions
|
|
691
|
+
where invite_id=(select invite_id from _recovery_cfg)) || '/' ||
|
|
692
|
+
(select count(*)::text from agent_board.board_memberships
|
|
693
|
+
where board_id=(select board_id from _atomic_cfg)
|
|
694
|
+
and agent_id=(select legacy_agent_id from _recovery_cfg)
|
|
695
|
+
and membership_state in ('joined','subscribed')) || '/' ||
|
|
696
|
+
(select count(*)::text from agent_board.fleet_machine_agents
|
|
697
|
+
where agent_id=(select legacy_agent_id from _recovery_cfg)),
|
|
698
|
+
'1/1/1',
|
|
699
|
+
'legacy recovery creates exactly one redemption, membership, and binding');
|
|
700
|
+
|
|
701
|
+
insert into agent_board.agents(
|
|
702
|
+
id, agent_type, handle, display_name, status
|
|
703
|
+
) values (
|
|
704
|
+
'16210000-0000-0000-0000-000000000099', 'agent',
|
|
705
|
+
'atomic-collision-agent', 'Atomic Collision Occupant', 'active'
|
|
706
|
+
);
|
|
707
|
+
insert into _collision_cfg
|
|
708
|
+
select invite_id, code
|
|
709
|
+
from agent_board.create_fleet_onboarding_invite(
|
|
710
|
+
(select board_id from _atomic_cfg), (select machine_id from _atomic_cfg),
|
|
711
|
+
'codex', 'collision-harness', 'message-board', 'sha256:collision-repo',
|
|
712
|
+
'worker', 'phase_worker', 'atomic-collision-agent', 1,
|
|
713
|
+
now() + interval '1 hour', (select owner_id from _atomic_cfg), '{}'::jsonb
|
|
714
|
+
);
|
|
715
|
+
select throws_ok(
|
|
716
|
+
$$select * from agent_board.onboard_federated_fleet_agent(
|
|
717
|
+
'https://atomic-runtime.test', 'message-board', 'human-collision',
|
|
718
|
+
'{"iss":"https://atomic-runtime.test","aud":"message-board","sub":"human-collision","iat":600}'::jsonb,
|
|
719
|
+
'atomic-collision-agent',
|
|
720
|
+
'4KAcBIlVxExOCkFemWSjOREACgi90CE_2-EFbmRYAzM', 'raw_ed25519_base64url',
|
|
721
|
+
'sha256:M-L7uu74kuf1rPVyZcW9Ar-LD1ZULN3E36HKqy93O3Q', true, null, 'agent',
|
|
722
|
+
'{board:send}', '{}', (select invite_code from _collision_cfg),
|
|
723
|
+
(select board_id from _atomic_cfg), (select machine_id from _atomic_cfg),
|
|
724
|
+
'codex', 'collision-harness', 'message-board', 'sha256:collision-repo',
|
|
725
|
+
'worker', 'phase_worker', 'atomic-collision-agent')$$,
|
|
726
|
+
'23505', null,
|
|
727
|
+
'server handle disambiguation is a late failure, not committed substitution'
|
|
728
|
+
);
|
|
729
|
+
select is((select count(*)::int from agent_board.agent_signing_keys
|
|
730
|
+
where fingerprint='sha256:M-L7uu74kuf1rPVyZcW9Ar-LD1ZULN3E36HKqy93O3Q'), 0,
|
|
731
|
+
'late handle collision rolls back the newly proven key');
|
|
732
|
+
select is((select count(*)::int from agent_board.enrollment_federation_audit
|
|
733
|
+
where issuer='https://atomic-runtime.test' and subject='human-collision'), 0,
|
|
734
|
+
'late handle collision rolls back enrollment audit evidence');
|
|
735
|
+
select is(
|
|
736
|
+
(select uses_count::text from agent_board.board_invite_tokens
|
|
737
|
+
where id=(select invite_id from _collision_cfg)) || '/' ||
|
|
738
|
+
(select count(*)::text from agent_board.board_invite_redemptions
|
|
739
|
+
where invite_id=(select invite_id from _collision_cfg)) || '/' ||
|
|
740
|
+
(select count(*)::text from agent_board.fleet_harness_registrations
|
|
741
|
+
where harness_label='collision-harness'),
|
|
742
|
+
'0/0/0',
|
|
743
|
+
'late handle collision rolls back invite, redemption, and fleet writes');
|
|
744
|
+
|
|
745
|
+
insert into agent_board.agents(id, agent_type, handle, display_name, status)
|
|
746
|
+
values ('16210000-0000-0000-0000-000000000098', 'agent',
|
|
747
|
+
'atomic-wrong-creator', 'Atomic Wrong Creator', 'active');
|
|
748
|
+
select throws_ok(
|
|
749
|
+
$$select * from agent_board.create_fleet_onboarding_invite(
|
|
750
|
+
(select board_id from _atomic_cfg), (select machine_id from _atomic_cfg),
|
|
751
|
+
'codex', 'wrong-creator', 'message-board', 'sha256:wrong-creator',
|
|
752
|
+
'worker', 'phase_worker', 'wrong-creator-agent', 1,
|
|
753
|
+
now() + interval '1 hour',
|
|
754
|
+
'16210000-0000-0000-0000-000000000098'::uuid, '{}'::jsonb)$$,
|
|
755
|
+
'42501', null,
|
|
756
|
+
'an agent that does not own the machine cannot mint its bounded invite'
|
|
757
|
+
);
|
|
758
|
+
|
|
759
|
+
update agent_board.fleet_machines
|
|
760
|
+
set lifecycle_state='revoked', revoked_at=now()
|
|
761
|
+
where id=(select machine_id from _atomic_cfg);
|
|
762
|
+
select is(pg_temp._atomic_history_attempt(650), '42501',
|
|
763
|
+
'composed fleet replay rejects a revoked machine');
|
|
764
|
+
select throws_ok(
|
|
765
|
+
$$select * from agent_board.create_fleet_onboarding_invite(
|
|
766
|
+
(select board_id from _atomic_cfg), (select machine_id from _atomic_cfg),
|
|
767
|
+
'codex', 'inactive-machine', 'message-board', 'sha256:inactive-machine',
|
|
768
|
+
'worker', 'phase_worker', 'inactive-machine-agent', 1,
|
|
769
|
+
now() + interval '1 hour', (select owner_id from _atomic_cfg), '{}'::jsonb)$$,
|
|
770
|
+
'42501', null,
|
|
771
|
+
'a revoked machine cannot mint a bounded fleet invite'
|
|
772
|
+
);
|
|
773
|
+
update agent_board.fleet_machines
|
|
774
|
+
set lifecycle_state='active', revoked_at=null
|
|
775
|
+
where id=(select machine_id from _atomic_cfg);
|
|
776
|
+
|
|
777
|
+
update agent_board.fleet_trust_domains
|
|
778
|
+
set lifecycle_state='revoked', revoked_at=now()
|
|
779
|
+
where id=(select trust_domain_id from agent_board.fleet_machines
|
|
780
|
+
where id=(select machine_id from _atomic_cfg));
|
|
781
|
+
select is(pg_temp._atomic_history_attempt(651), '42501',
|
|
782
|
+
'composed fleet replay rejects a revoked trust domain');
|
|
783
|
+
select throws_ok(
|
|
784
|
+
$$select * from agent_board.create_fleet_onboarding_invite(
|
|
785
|
+
(select board_id from _atomic_cfg), (select machine_id from _atomic_cfg),
|
|
786
|
+
'codex', 'inactive-domain', 'message-board', 'sha256:inactive-domain',
|
|
787
|
+
'worker', 'phase_worker', 'inactive-domain-agent', 1,
|
|
788
|
+
now() + interval '1 hour', (select owner_id from _atomic_cfg), '{}'::jsonb)$$,
|
|
789
|
+
'42501', null,
|
|
790
|
+
'an inactive trust domain cannot mint a bounded fleet invite'
|
|
791
|
+
);
|
|
792
|
+
update agent_board.fleet_trust_domains
|
|
793
|
+
set lifecycle_state='active', revoked_at=null
|
|
794
|
+
where id=(select trust_domain_id from agent_board.fleet_machines
|
|
795
|
+
where id=(select machine_id from _atomic_cfg));
|
|
796
|
+
|
|
797
|
+
select throws_ok(
|
|
798
|
+
$$select * from agent_board.create_fleet_onboarding_invite(
|
|
799
|
+
(select board_id from _atomic_cfg), (select machine_id from _atomic_cfg),
|
|
800
|
+
'../bad-kind', 'malformed', 'message-board', 'sha256:malformed',
|
|
801
|
+
'worker', 'phase_worker', 'malformed-agent', 1,
|
|
802
|
+
now() + interval '1 hour', (select owner_id from _atomic_cfg), '{}'::jsonb)$$,
|
|
803
|
+
'22023', null,
|
|
804
|
+
'malformed fleet descriptors are rejected before invite creation'
|
|
805
|
+
);
|
|
806
|
+
|
|
807
|
+
create temp table _matrix_invites(
|
|
808
|
+
case_name text primary key,
|
|
809
|
+
invite_id uuid not null,
|
|
810
|
+
invite_code text not null
|
|
811
|
+
);
|
|
812
|
+
|
|
813
|
+
insert into _matrix_invites
|
|
814
|
+
select 'generic', invite_id, code
|
|
815
|
+
from agent_board.create_invite_link(
|
|
816
|
+
(select board_id from _atomic_cfg), 'member', 'joined', 1,
|
|
817
|
+
now() + interval '1 hour', (select owner_id from _atomic_cfg), '{}'::jsonb
|
|
818
|
+
);
|
|
819
|
+
select throws_ok(
|
|
820
|
+
$$select * from agent_board.onboard_federated_fleet_agent(
|
|
821
|
+
'https://atomic-runtime.test', 'message-board', 'human-runtime',
|
|
822
|
+
'{"iss":"https://atomic-runtime.test","aud":"message-board","sub":"human-runtime","iat":700}'::jsonb,
|
|
823
|
+
'atomic-runtime-agent',
|
|
824
|
+
'eRHZmllEy_TZHAG2zB-Qe_a5BFLkaavMTazWWfaE3f0', 'raw_ed25519_base64url',
|
|
825
|
+
'sha256:z8d5LQPfBMYnfZfvu8wVz684_jkp578-SPDU2OMObS8', true, null, 'agent',
|
|
826
|
+
'{board:send}', '{}', (select invite_code from _matrix_invites where case_name='generic'),
|
|
827
|
+
(select board_id from _atomic_cfg), (select machine_id from _atomic_cfg),
|
|
828
|
+
'codex', 'phase-loop', 'message-board', 'sha256:atomic-runtime-repo',
|
|
829
|
+
'worker', 'phase_worker', 'atomic-runtime-agent')$$,
|
|
830
|
+
'42501', null, 'a generic invite cannot enter the composed fleet path'
|
|
831
|
+
);
|
|
832
|
+
select is(
|
|
833
|
+
(select uses_count::text from agent_board.board_invite_tokens
|
|
834
|
+
where id=(select invite_id from _matrix_invites where case_name='generic')) || '/' ||
|
|
835
|
+
(select count(*)::text from agent_board.board_invite_redemptions
|
|
836
|
+
where invite_id=(select invite_id from _matrix_invites where case_name='generic')),
|
|
837
|
+
'0/0', 'generic-invite rejection leaves uses and redemption counts unchanged'
|
|
838
|
+
);
|
|
839
|
+
|
|
840
|
+
update agent_board.board_memberships
|
|
841
|
+
set membership_state='removed', left_at=now(), updated_at=now()
|
|
842
|
+
where board_id=(select board_id from _atomic_cfg)
|
|
843
|
+
and agent_id=(select owner_id from _atomic_cfg)
|
|
844
|
+
and membership_state in ('joined','subscribed');
|
|
845
|
+
select throws_ok(
|
|
846
|
+
$$select * from agent_board.onboard_federated_fleet_agent(
|
|
847
|
+
'https://atomic-runtime.test', 'message-board', 'human-runtime',
|
|
848
|
+
'{"iss":"https://atomic-runtime.test","aud":"message-board","sub":"human-runtime","iat":701}'::jsonb,
|
|
849
|
+
'atomic-runtime-agent',
|
|
850
|
+
'eRHZmllEy_TZHAG2zB-Qe_a5BFLkaavMTazWWfaE3f0', 'raw_ed25519_base64url',
|
|
851
|
+
'sha256:z8d5LQPfBMYnfZfvu8wVz684_jkp578-SPDU2OMObS8', true, null, 'agent',
|
|
852
|
+
'{board:send}', '{}', (select invite_code from _atomic_cfg),
|
|
853
|
+
(select board_id from _atomic_cfg), (select machine_id from _atomic_cfg),
|
|
854
|
+
'codex', 'phase-loop', 'message-board', 'sha256:atomic-runtime-repo',
|
|
855
|
+
'worker', 'phase_worker', 'atomic-runtime-agent')$$,
|
|
856
|
+
'42501', null, 'an invite whose creator is no longer a board member fails closed'
|
|
857
|
+
);
|
|
858
|
+
select is((select uses_count from agent_board.board_invite_tokens where id=(select invite_id from _atomic_cfg)), 1,
|
|
859
|
+
'non-member creator rejection does not consume another invite use');
|
|
860
|
+
update agent_board.board_memberships
|
|
861
|
+
set membership_state='joined', role='owner', left_at=null, updated_at=now()
|
|
862
|
+
where board_id=(select board_id from _atomic_cfg)
|
|
863
|
+
and agent_id=(select owner_id from _atomic_cfg)
|
|
864
|
+
and membership_state='removed';
|
|
865
|
+
|
|
866
|
+
select throws_ok(
|
|
867
|
+
$$select * from agent_board.create_fleet_onboarding_invite(
|
|
868
|
+
(select board_id from _atomic_cfg), (select machine_id from _atomic_cfg),
|
|
869
|
+
'codex', 'elevated-role', 'message-board', 'sha256:elevated-role',
|
|
870
|
+
'worker', 'reviewer', 'elevated-role-agent', 1,
|
|
871
|
+
now() + interval '1 hour', (select owner_id from _atomic_cfg), '{}'::jsonb)$$,
|
|
872
|
+
'22023', null, 'an elevated or mismatched role pair cannot mint a fleet invite'
|
|
873
|
+
);
|
|
874
|
+
|
|
875
|
+
insert into _matrix_invites
|
|
876
|
+
select 'conflict', invite_id, code
|
|
877
|
+
from agent_board.create_fleet_onboarding_invite(
|
|
878
|
+
(select board_id from _atomic_cfg), (select machine_id from _atomic_cfg),
|
|
879
|
+
'codex', 'conflict-harness', 'message-board', 'sha256:conflict-repo',
|
|
880
|
+
'worker', 'phase_worker', 'atomic-conflict-agent', 1,
|
|
881
|
+
now() + interval '1 hour', (select owner_id from _atomic_cfg), '{}'::jsonb
|
|
882
|
+
);
|
|
883
|
+
insert into agent_board.fleet_harness_registrations(machine_id, harness_kind, harness_label)
|
|
884
|
+
values ((select machine_id from _atomic_cfg), 'codex', 'conflict-harness');
|
|
885
|
+
insert into agent_board.fleet_repo_scopes(
|
|
886
|
+
harness_registration_id, repo_slug, repo_fingerprint, scope_role
|
|
887
|
+
) select id, 'other-repo', 'sha256:conflict-repo', 'worker'
|
|
888
|
+
from agent_board.fleet_harness_registrations
|
|
889
|
+
where machine_id=(select machine_id from _atomic_cfg)
|
|
890
|
+
and harness_kind='codex' and harness_label='conflict-harness';
|
|
891
|
+
select throws_ok(
|
|
892
|
+
$$select * from agent_board.onboard_federated_fleet_agent(
|
|
893
|
+
'https://atomic-runtime.test', 'message-board', 'human-conflict',
|
|
894
|
+
'{"iss":"https://atomic-runtime.test","aud":"message-board","sub":"human-conflict","iat":702}'::jsonb,
|
|
895
|
+
'atomic-conflict-agent',
|
|
896
|
+
'5TG73fnNhqeYkoSvPf9QwmWkvKWe0yA7B8YinAWQ8m4', 'raw_ed25519_base64url',
|
|
897
|
+
'sha256:qhjEQe9R_x26TBZyBsd-LrpR1fh7Mvnz86rbsCKtjz8', true, null, 'agent',
|
|
898
|
+
'{board:send}', '{}', (select invite_code from _matrix_invites where case_name='conflict'),
|
|
899
|
+
(select board_id from _atomic_cfg), (select machine_id from _atomic_cfg),
|
|
900
|
+
'codex', 'conflict-harness', 'message-board', 'sha256:conflict-repo',
|
|
901
|
+
'worker', 'phase_worker', 'atomic-conflict-agent')$$,
|
|
902
|
+
'42501', null, 'a conflicting active repo registration rejects atomic onboarding'
|
|
903
|
+
);
|
|
904
|
+
select is(
|
|
905
|
+
(select count(*)::text from agent_board.agent_signing_keys
|
|
906
|
+
where fingerprint='sha256:qhjEQe9R_x26TBZyBsd-LrpR1fh7Mvnz86rbsCKtjz8') || '/' ||
|
|
907
|
+
(select count(*)::text from agent_board.board_invite_redemptions
|
|
908
|
+
where invite_id=(select invite_id from _matrix_invites where case_name='conflict')),
|
|
909
|
+
'0/0', 'conflicting active registration rolls back identity and redemption writes'
|
|
910
|
+
);
|
|
911
|
+
|
|
912
|
+
do $$
|
|
913
|
+
declare
|
|
914
|
+
v_agent uuid;
|
|
915
|
+
v_invite uuid;
|
|
916
|
+
v_code text;
|
|
917
|
+
begin
|
|
918
|
+
select agent_id into v_agent from agent_board.enroll_federated_identity(
|
|
919
|
+
'https://atomic-runtime.test', 'message-board', 'human-blocked',
|
|
920
|
+
'{"iss":"https://atomic-runtime.test","aud":"message-board","sub":"human-blocked","iat":703}'::jsonb,
|
|
921
|
+
'atomic-blocked-agent',
|
|
922
|
+
'HdUqLbj-jcUwvwE4rf9WXeDQrjrAtYUT6YmnsGMKcNQ', 'raw_ed25519_base64url',
|
|
923
|
+
'sha256:d115bUBikhOk-QFOCc-lItU2nRZMKf79kAHmvgLsKng', true, null, 'agent',
|
|
924
|
+
'{board:send}', '{}', null
|
|
925
|
+
);
|
|
926
|
+
insert into agent_board.board_memberships(
|
|
927
|
+
board_id, agent_id, membership_state, role, left_at, created_by_agent_id
|
|
928
|
+
) values (
|
|
929
|
+
(select board_id from _atomic_cfg), v_agent, 'removed', 'member', now(),
|
|
930
|
+
(select owner_id from _atomic_cfg)
|
|
931
|
+
);
|
|
932
|
+
select invite_id, code into v_invite, v_code
|
|
933
|
+
from agent_board.create_fleet_onboarding_invite(
|
|
934
|
+
(select board_id from _atomic_cfg), (select machine_id from _atomic_cfg),
|
|
935
|
+
'codex', 'blocked-harness', 'message-board', 'sha256:blocked-repo',
|
|
936
|
+
'worker', 'phase_worker', 'atomic-blocked-agent', 1,
|
|
937
|
+
now() + interval '1 hour', (select owner_id from _atomic_cfg), '{}'::jsonb
|
|
938
|
+
);
|
|
939
|
+
insert into _matrix_invites values ('blocked', v_invite, v_code);
|
|
940
|
+
end
|
|
941
|
+
$$;
|
|
942
|
+
select throws_ok(
|
|
943
|
+
$$select * from agent_board.onboard_federated_fleet_agent(
|
|
944
|
+
'https://atomic-runtime.test', 'message-board', 'human-blocked',
|
|
945
|
+
'{"iss":"https://atomic-runtime.test","aud":"message-board","sub":"human-blocked","iat":704}'::jsonb,
|
|
946
|
+
'atomic-blocked-agent',
|
|
947
|
+
'HdUqLbj-jcUwvwE4rf9WXeDQrjrAtYUT6YmnsGMKcNQ', 'raw_ed25519_base64url',
|
|
948
|
+
'sha256:d115bUBikhOk-QFOCc-lItU2nRZMKf79kAHmvgLsKng', true, null, 'agent',
|
|
949
|
+
'{board:send}', '{}', (select invite_code from _matrix_invites where case_name='blocked'),
|
|
950
|
+
(select board_id from _atomic_cfg), (select machine_id from _atomic_cfg),
|
|
951
|
+
'codex', 'blocked-harness', 'message-board', 'sha256:blocked-repo',
|
|
952
|
+
'worker', 'phase_worker', 'atomic-blocked-agent')$$,
|
|
953
|
+
'42501', null, 'a removed target membership blocks fleet invite redemption'
|
|
954
|
+
);
|
|
955
|
+
select is(
|
|
956
|
+
(select uses_count::text from agent_board.board_invite_tokens
|
|
957
|
+
where id=(select invite_id from _matrix_invites where case_name='blocked')) || '/' ||
|
|
958
|
+
(select count(*)::text from agent_board.fleet_harness_registrations where harness_label='blocked-harness'),
|
|
959
|
+
'0/0', 'blocked invite leaves invite and fleet counts unchanged'
|
|
960
|
+
);
|
|
961
|
+
|
|
962
|
+
insert into _matrix_invites
|
|
963
|
+
select 'late-failure', invite_id, code
|
|
964
|
+
from agent_board.create_fleet_onboarding_invite(
|
|
965
|
+
(select board_id from _atomic_cfg), (select machine_id from _atomic_cfg),
|
|
966
|
+
'codex', 'late-failure-harness', 'message-board', 'sha256:late-failure-repo',
|
|
967
|
+
'worker', 'phase_worker', 'atomic-late-failure-agent', 1,
|
|
968
|
+
now() + interval '1 hour', (select owner_id from _atomic_cfg), '{}'::jsonb
|
|
969
|
+
);
|
|
970
|
+
create function pg_temp._atomic_late_binding_failure() returns trigger
|
|
971
|
+
language plpgsql as $$
|
|
972
|
+
begin
|
|
973
|
+
if new.agent_role = 'phase_worker' then
|
|
974
|
+
raise exception 'injected late fleet constraint failure' using errcode = '23514';
|
|
975
|
+
end if;
|
|
976
|
+
return new;
|
|
977
|
+
end
|
|
978
|
+
$$;
|
|
979
|
+
create trigger atomic_late_binding_failure
|
|
980
|
+
before insert on agent_board.fleet_machine_agents
|
|
981
|
+
for each row execute function pg_temp._atomic_late_binding_failure();
|
|
982
|
+
select throws_ok(
|
|
983
|
+
$$select * from agent_board.onboard_federated_fleet_agent(
|
|
984
|
+
'https://atomic-runtime.test', 'message-board', 'human-late-failure',
|
|
985
|
+
'{"iss":"https://atomic-runtime.test","aud":"message-board","sub":"human-late-failure","iat":705}'::jsonb,
|
|
986
|
+
'atomic-late-failure-agent',
|
|
987
|
+
'TDyof3w0SMg4SDYuj-qenolHC_n05cZbrLSckKVGtMo', 'raw_ed25519_base64url',
|
|
988
|
+
'sha256:lSBZnHvmPvQONy8aoygp-fmTg26iZenrZC-L5LN9m7M', true, null, 'agent',
|
|
989
|
+
'{board:send}', '{}', (select invite_code from _matrix_invites where case_name='late-failure'),
|
|
990
|
+
(select board_id from _atomic_cfg), (select machine_id from _atomic_cfg),
|
|
991
|
+
'codex', 'late-failure-harness', 'message-board', 'sha256:late-failure-repo',
|
|
992
|
+
'worker', 'phase_worker', 'atomic-late-failure-agent')$$,
|
|
993
|
+
'23514', null, 'an injected late binding constraint aborts the composed transaction'
|
|
994
|
+
);
|
|
995
|
+
drop trigger atomic_late_binding_failure on agent_board.fleet_machine_agents;
|
|
996
|
+
select is(
|
|
997
|
+
(select count(*)::text from agent_board.agent_signing_keys
|
|
998
|
+
where fingerprint='sha256:lSBZnHvmPvQONy8aoygp-fmTg26iZenrZC-L5LN9m7M') || '/' ||
|
|
999
|
+
(select count(*)::text from agent_board.enrollment_federation_audit
|
|
1000
|
+
where subject='human-late-failure') || '/' ||
|
|
1001
|
+
(select count(*)::text from agent_board.board_invite_redemptions
|
|
1002
|
+
where invite_id=(select invite_id from _matrix_invites where case_name='late-failure')) || '/' ||
|
|
1003
|
+
(select count(*)::text from agent_board.fleet_harness_registrations where harness_label='late-failure-harness'),
|
|
1004
|
+
'0/0/0/0', 'late fleet failure rolls back identity, audit, redemption, and fleet writes'
|
|
1005
|
+
);
|
|
1006
|
+
select is(
|
|
1007
|
+
(select uses_count::text from agent_board.board_invite_tokens
|
|
1008
|
+
where id=(select invite_id from _matrix_invites where case_name='late-failure')) || '/' ||
|
|
1009
|
+
(select count(*)::text from agent_board.board_memberships
|
|
1010
|
+
where agent_id in (select id from agent_board.agents where handle='atomic-late-failure-agent')),
|
|
1011
|
+
'0/0', 'late fleet failure preserves invite use and membership counts'
|
|
1012
|
+
);
|
|
1013
|
+
|
|
1014
|
+
update agent_board.boards set status='archived'
|
|
1015
|
+
where id=(select board_id from _atomic_cfg);
|
|
1016
|
+
select throws_ok(
|
|
1017
|
+
$$select * from agent_board.create_fleet_onboarding_invite(
|
|
1018
|
+
(select board_id from _atomic_cfg), (select machine_id from _atomic_cfg),
|
|
1019
|
+
'codex', 'archived-board', 'message-board', 'sha256:archived-board',
|
|
1020
|
+
'worker', 'phase_worker', 'archived-board-agent', 1,
|
|
1021
|
+
now() + interval '1 hour', (select owner_id from _atomic_cfg), '{}'::jsonb)$$,
|
|
1022
|
+
'42501', null, 'an archived board cannot mint a bounded fleet invite'
|
|
1023
|
+
);
|
|
1024
|
+
select is(pg_temp._atomic_history_attempt(800), '42501',
|
|
1025
|
+
'an archived board cannot redeem an existing bounded fleet invite');
|
|
1026
|
+
select is((select uses_count from agent_board.board_invite_tokens
|
|
1027
|
+
where id=(select invite_id from _atomic_cfg)), 1,
|
|
1028
|
+
'archived-board rejection consumes no invite use');
|
|
1029
|
+
update agent_board.boards set status='active'
|
|
1030
|
+
where id=(select board_id from _atomic_cfg);
|
|
1031
|
+
|
|
1032
|
+
select set_config('request.jwt.claim.role', 'authenticated', true);
|
|
1033
|
+
select set_config(
|
|
1034
|
+
'request.jwt.claim.sub',
|
|
1035
|
+
(select auth_user_id::text from agent_board.agents
|
|
1036
|
+
where id=(select agent_id from _atomic_result where attempt='first')),
|
|
1037
|
+
true
|
|
1038
|
+
);
|
|
1039
|
+
select throws_ok(
|
|
1040
|
+
$$select * from agent_board.register_agent(
|
|
1041
|
+
'agent', 'atomic-runtime-agent', 'Atomic Runtime Agent', 'active',
|
|
1042
|
+
'{"federation":{"replay":{"subject":"forged"}}}'::jsonb)$$,
|
|
1043
|
+
'42501', null, 'authenticated register_agent cannot rewrite frozen federation metadata'
|
|
1044
|
+
);
|
|
1045
|
+
select throws_ok(
|
|
1046
|
+
$$select * from agent_board.register_agent(
|
|
1047
|
+
'agent', 'atomic-runtime-agent-renamed', 'Atomic Runtime Agent', 'active', '{}'::jsonb)$$,
|
|
1048
|
+
'42501', null, 'authenticated register_agent cannot rename a frozen replay principal'
|
|
1049
|
+
);
|
|
1050
|
+
select set_config('request.jwt.claim.role', 'service_role', true);
|
|
1051
|
+
select set_config('request.jwt.claim.sub', '', true);
|
|
1052
|
+
select is(
|
|
1053
|
+
(select handle || '/' || (metadata #>> '{federation,replay,subject}')
|
|
1054
|
+
from agent_board.agents
|
|
1055
|
+
where id=(select agent_id from _atomic_result where attempt='first')),
|
|
1056
|
+
'atomic-runtime-agent/human-runtime',
|
|
1057
|
+
'rejected authenticated mutations leave the frozen replay projection unchanged'
|
|
1058
|
+
);
|
|
1059
|
+
|
|
1060
|
+
insert into _matrix_invites
|
|
1061
|
+
select 'human-revoked', invite_id, code
|
|
1062
|
+
from agent_board.create_fleet_onboarding_invite(
|
|
1063
|
+
(select board_id from _atomic_cfg), (select machine_id from _atomic_cfg),
|
|
1064
|
+
'codex', 'human-revoked', 'message-board', 'sha256:human-revoked',
|
|
1065
|
+
'worker', 'phase_worker', 'atomic-revoked-future', 1,
|
|
1066
|
+
now() + interval '1 hour', (select owner_id from _atomic_cfg), '{}'::jsonb
|
|
1067
|
+
);
|
|
1068
|
+
select lives_ok(
|
|
1069
|
+
format(
|
|
1070
|
+
'select * from agent_board.revoke_human_subtree(%L::uuid,%L::uuid,%L)',
|
|
1071
|
+
(select owner_user_id from agent_board.agents
|
|
1072
|
+
where id=(select agent_id from _atomic_result where attempt='first')),
|
|
1073
|
+
(select owner_id from _atomic_cfg), 'runtime total human revoke'
|
|
1074
|
+
),
|
|
1075
|
+
'total human revocation durably marks and revokes the existing subtree'
|
|
1076
|
+
);
|
|
1077
|
+
insert into _human_revocation_cfg
|
|
1078
|
+
select owner_user_id from agent_board.agents
|
|
1079
|
+
where id=(select agent_id from _atomic_result where attempt='first');
|
|
1080
|
+
select is(
|
|
1081
|
+
(select count(*)::int from agent_board.fleet_human_revocations
|
|
1082
|
+
where owner_user_id=(select owner_user_id from agent_board.agents
|
|
1083
|
+
where id=(select agent_id from _atomic_result where attempt='first'))),
|
|
1084
|
+
1, 'total human revocation stores one durable owner marker'
|
|
1085
|
+
);
|
|
1086
|
+
select throws_ok(
|
|
1087
|
+
$$select * from agent_board.onboard_federated_fleet_agent(
|
|
1088
|
+
'https://atomic-runtime.test', 'message-board', 'human-runtime',
|
|
1089
|
+
'{"iss":"https://atomic-runtime.test","aud":"message-board","sub":"human-runtime","iat":801}'::jsonb,
|
|
1090
|
+
'atomic-revoked-future',
|
|
1091
|
+
'TDyof3w0SMg4SDYuj-qenolHC_n05cZbrLSckKVGtMo', 'raw_ed25519_base64url',
|
|
1092
|
+
'sha256:lSBZnHvmPvQONy8aoygp-fmTg26iZenrZC-L5LN9m7M', true, null, 'agent',
|
|
1093
|
+
'{board:send}', '{}', (select invite_code from _matrix_invites where case_name='human-revoked'),
|
|
1094
|
+
(select board_id from _atomic_cfg), (select machine_id from _atomic_cfg),
|
|
1095
|
+
'codex', 'human-revoked', 'message-board', 'sha256:human-revoked',
|
|
1096
|
+
'worker', 'phase_worker', 'atomic-revoked-future')$$,
|
|
1097
|
+
'42501', null, 'a durably revoked human cannot onboard a fresh key'
|
|
1098
|
+
);
|
|
1099
|
+
select is(
|
|
1100
|
+
(select count(*)::int from agent_board.agent_signing_keys
|
|
1101
|
+
where fingerprint='sha256:lSBZnHvmPvQONy8aoygp-fmTg26iZenrZC-L5LN9m7M'),
|
|
1102
|
+
0, 'revoked-human fresh onboarding creates no signing key'
|
|
1103
|
+
);
|
|
1104
|
+
|
|
1105
|
+
insert into auth.users(id, instance_id, aud, role, email, created_at, updated_at)
|
|
1106
|
+
values (
|
|
1107
|
+
'16200000-0000-0000-0000-000000000098',
|
|
1108
|
+
'00000000-0000-0000-0000-000000000000',
|
|
1109
|
+
'authenticated', 'authenticated', 'atomic-audit-owner@example.test', now(), now()
|
|
1110
|
+
);
|
|
1111
|
+
insert into agent_board.agents(
|
|
1112
|
+
id, agent_type, kind, handle, display_name, status, auth_user_id, owner_user_id, metadata
|
|
1113
|
+
) values (
|
|
1114
|
+
'16200000-0000-0000-0000-000000000198', 'agent', 'agent',
|
|
1115
|
+
'atomic-audit-owner', 'Atomic Audit Owner', 'active',
|
|
1116
|
+
'16200000-0000-0000-0000-000000000098',
|
|
1117
|
+
'16200000-0000-0000-0000-000000000098',
|
|
1118
|
+
'{"federation":{"issuer":"https://forged-metadata.test","subject":"forged-metadata-subject"}}'::jsonb
|
|
1119
|
+
);
|
|
1120
|
+
insert into agent_board.enrollment_federation_audit(
|
|
1121
|
+
issuer, audience, subject, human_identity_claim, provider_id,
|
|
1122
|
+
agent_id, auth_user_id, requested_scopes, granted_scopes
|
|
1123
|
+
) values (
|
|
1124
|
+
'https://immutable-audit.test', 'message-board', 'immutable-audit-subject',
|
|
1125
|
+
'{"iss":"https://immutable-audit.test","aud":"message-board","sub":"immutable-audit-subject"}'::jsonb,
|
|
1126
|
+
null, '16200000-0000-0000-0000-000000000198',
|
|
1127
|
+
'16200000-0000-0000-0000-000000000098', '{}', '{}'
|
|
1128
|
+
);
|
|
1129
|
+
select lives_ok(
|
|
1130
|
+
$$select * from agent_board.revoke_human_subtree(
|
|
1131
|
+
'16200000-0000-0000-0000-000000000098',
|
|
1132
|
+
(select owner_id from _atomic_cfg), 'immutable evidence runtime')$$,
|
|
1133
|
+
'total human revocation accepts stable audit evidence even when metadata is forged'
|
|
1134
|
+
);
|
|
1135
|
+
select is(
|
|
1136
|
+
(select count(*)::int from agent_board.fleet_human_revocations
|
|
1137
|
+
where issuer='https://immutable-audit.test' and subject='immutable-audit-subject'),
|
|
1138
|
+
1, 'human revocation marker is derived from append-only audit evidence'
|
|
1139
|
+
);
|
|
1140
|
+
select is(
|
|
1141
|
+
(select count(*)::int from agent_board.fleet_human_revocations
|
|
1142
|
+
where issuer='https://forged-metadata.test' or subject='forged-metadata-subject'),
|
|
1143
|
+
0, 'historically mutable federation metadata cannot choose the revocation marker'
|
|
1144
|
+
);
|
|
1145
|
+
|
|
1146
|
+
insert into auth.users(id, instance_id, aud, role, email, created_at, updated_at)
|
|
1147
|
+
values (
|
|
1148
|
+
'16200000-0000-0000-0000-000000000097',
|
|
1149
|
+
'00000000-0000-0000-0000-000000000000',
|
|
1150
|
+
'authenticated', 'authenticated', 'atomic-missing-audit@example.test', now(), now()
|
|
1151
|
+
);
|
|
1152
|
+
insert into agent_board.agents(
|
|
1153
|
+
id, agent_type, kind, handle, display_name, status, auth_user_id, owner_user_id, metadata
|
|
1154
|
+
) values (
|
|
1155
|
+
'16200000-0000-0000-0000-000000000197', 'agent', 'agent',
|
|
1156
|
+
'atomic-missing-audit', 'Atomic Missing Audit', 'active',
|
|
1157
|
+
'16200000-0000-0000-0000-000000000097',
|
|
1158
|
+
'16200000-0000-0000-0000-000000000097',
|
|
1159
|
+
'{"federation":{"issuer":"https://missing-audit.test","subject":"missing-audit-subject"}}'::jsonb
|
|
1160
|
+
);
|
|
1161
|
+
select throws_ok(
|
|
1162
|
+
$$select * from agent_board.revoke_human_subtree(
|
|
1163
|
+
'16200000-0000-0000-0000-000000000097',
|
|
1164
|
+
(select owner_id from _atomic_cfg), 'missing evidence runtime')$$,
|
|
1165
|
+
'P0002', null, 'federation-linked human revocation fails closed without stable audit evidence'
|
|
1166
|
+
);
|
|
1167
|
+
select is(
|
|
1168
|
+
(select status from agent_board.agents where id='16200000-0000-0000-0000-000000000197'),
|
|
1169
|
+
'active', 'missing-evidence failure commits no partial subtree revocation'
|
|
1170
|
+
);
|
|
1171
|
+
|
|
1172
|
+
insert into auth.users(id, instance_id, aud, role, email, created_at, updated_at)
|
|
1173
|
+
values (
|
|
1174
|
+
'16200000-0000-0000-0000-000000000096',
|
|
1175
|
+
'00000000-0000-0000-0000-000000000000',
|
|
1176
|
+
'authenticated', 'authenticated', 'atomic-mixed-audit@example.test', now(), now()
|
|
1177
|
+
);
|
|
1178
|
+
insert into agent_board.agents(
|
|
1179
|
+
id, agent_type, kind, handle, display_name, status, auth_user_id, owner_user_id, metadata
|
|
1180
|
+
) values
|
|
1181
|
+
(
|
|
1182
|
+
'16200000-0000-0000-0000-000000000196', 'agent', 'agent',
|
|
1183
|
+
'atomic-mixed-audited', 'Atomic Mixed Audited', 'active',
|
|
1184
|
+
'16200000-0000-0000-0000-000000000096',
|
|
1185
|
+
'16200000-0000-0000-0000-000000000096',
|
|
1186
|
+
'{"federation":{"issuer":"https://mixed-audit.test","subject":"mixed-audited"}}'::jsonb
|
|
1187
|
+
),
|
|
1188
|
+
(
|
|
1189
|
+
'16200000-0000-0000-0000-000000000296', 'agent', 'agent',
|
|
1190
|
+
'atomic-mixed-unaudited', 'Atomic Mixed Unaudited', 'active',
|
|
1191
|
+
null, '16200000-0000-0000-0000-000000000096',
|
|
1192
|
+
'{"federation":{"issuer":"https://mixed-audit.test","subject":"mixed-unaudited"}}'::jsonb
|
|
1193
|
+
);
|
|
1194
|
+
insert into agent_board.enrollment_federation_audit(
|
|
1195
|
+
issuer, audience, subject, human_identity_claim, provider_id,
|
|
1196
|
+
agent_id, auth_user_id, requested_scopes, granted_scopes
|
|
1197
|
+
) values (
|
|
1198
|
+
'https://mixed-audit.test', 'message-board', 'mixed-audited',
|
|
1199
|
+
'{"iss":"https://mixed-audit.test","aud":"message-board","sub":"mixed-audited"}'::jsonb,
|
|
1200
|
+
null, '16200000-0000-0000-0000-000000000196',
|
|
1201
|
+
'16200000-0000-0000-0000-000000000096', '{}', '{}'
|
|
1202
|
+
);
|
|
1203
|
+
select throws_ok(
|
|
1204
|
+
$$select * from agent_board.revoke_human_subtree(
|
|
1205
|
+
'16200000-0000-0000-0000-000000000096',
|
|
1206
|
+
(select owner_id from _atomic_cfg), 'mixed evidence runtime')$$,
|
|
1207
|
+
'P0002', null, 'mixed federation owner fails closed when any linked agent lacks stable audit evidence'
|
|
1208
|
+
);
|
|
1209
|
+
select is(
|
|
1210
|
+
(select count(*)::int from agent_board.agents
|
|
1211
|
+
where owner_user_id='16200000-0000-0000-0000-000000000096' and status='active'),
|
|
1212
|
+
2, 'mixed-evidence failure commits no partial subtree revocation'
|
|
1213
|
+
);
|
|
1214
|
+
select is(
|
|
1215
|
+
(select count(*)::int from agent_board.fleet_human_revocations
|
|
1216
|
+
where issuer='https://mixed-audit.test'),
|
|
1217
|
+
0, 'mixed-evidence failure commits no partial durable marker'
|
|
1218
|
+
);
|
|
1219
|
+
|
|
1220
|
+
select lives_ok(
|
|
1221
|
+
$$delete from auth.users where id=(select owner_user_id from _human_revocation_cfg)$$,
|
|
1222
|
+
'auth-user cleanup does not erase the stable federation revocation marker'
|
|
1223
|
+
);
|
|
1224
|
+
select is(
|
|
1225
|
+
(select count(*)::int from agent_board.fleet_human_revocations
|
|
1226
|
+
where issuer='https://atomic-runtime.test' and subject='human-runtime'
|
|
1227
|
+
and owner_user_id is null),
|
|
1228
|
+
1, 'stable federation revocation survives owner UUID deletion'
|
|
1229
|
+
);
|
|
1230
|
+
select throws_ok(
|
|
1231
|
+
$$select * from agent_board.onboard_federated_fleet_agent(
|
|
1232
|
+
'https://atomic-runtime.test', 'message-board', 'human-runtime',
|
|
1233
|
+
'{"iss":"https://atomic-runtime.test","aud":"message-board","sub":"human-runtime","iat":802}'::jsonb,
|
|
1234
|
+
'atomic-revoked-future',
|
|
1235
|
+
'8lbFi0KooZCbgv7LYQzJ455CsFFnoeOK9qkcsEwUBZg', 'raw_ed25519_base64url',
|
|
1236
|
+
'sha256:SiF8ib634OSMsAhUlMQk44VFekSV1EcRHzkdhv-R8vc', true, null, 'agent',
|
|
1237
|
+
'{board:send}', '{}', (select invite_code from _matrix_invites where case_name='human-revoked'),
|
|
1238
|
+
(select board_id from _atomic_cfg), (select machine_id from _atomic_cfg),
|
|
1239
|
+
'codex', 'human-revoked', 'message-board', 'sha256:human-revoked',
|
|
1240
|
+
'worker', 'phase_worker', 'atomic-revoked-future')$$,
|
|
1241
|
+
'42501', null, 'deleted-owner identity remains durably barred from fresh-key onboarding'
|
|
1242
|
+
);
|
|
1243
|
+
select is(
|
|
1244
|
+
(select count(*)::int from agent_board.agent_signing_keys
|
|
1245
|
+
where fingerprint='sha256:SiF8ib634OSMsAhUlMQk44VFekSV1EcRHzkdhv-R8vc'),
|
|
1246
|
+
0, 'deleted-owner rejection creates no fresh signing key'
|
|
1247
|
+
);
|
|
1248
|
+
|
|
1249
|
+
select * from finish();
|
|
1250
|
+
rollback;
|