@consiliency/agent-board-schema 1.2.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/LICENSE +202 -0
- package/NOTICE +11 -0
- package/README.md +55 -0
- package/bin/agent-board-schema.js +97 -0
- package/fixtures/already-applied.json +181 -0
- package/fixtures/divergent-history.json +173 -0
- package/fixtures/production-history.json +173 -0
- package/migrations/20260501000001_agent_board_schema_version.sql +12 -0
- package/migrations/20260502000000_agent_board_schema.sql +180 -0
- package/migrations/20260503000000_agent_board_rpcs.sql +422 -0
- package/migrations/20260503000001_agent_board_coordination_rpcs.sql +229 -0
- package/migrations/20260504000000_agent_board_read_models.sql +206 -0
- package/migrations/20260505000000_agent_board_inbox_schema.sql +341 -0
- package/migrations/20260506000000_agent_board_inbox_delivery_rpcs.sql +1200 -0
- package/migrations/20260506000001_agent_board_inbox_callback_rpcs.sql +330 -0
- package/migrations/20260507000000_agent_board_inbox_reads.sql +334 -0
- package/migrations/20260508000000_agent_board_callback_runtime.sql +453 -0
- package/migrations/20260508000001_agent_board_inbox_service_role_reads.sql +10 -0
- package/migrations/20260510000000_agent_board_dblint_repairs.sql +413 -0
- package/migrations/20260511000000_agent_board_auth_schema.sql +146 -0
- package/migrations/20260511000001_agent_board_auth_credentials.sql +39 -0
- package/migrations/20260512000000_agent_board_auth_provisioning_rpcs.sql +622 -0
- package/migrations/20260512000001_agent_board_auth_v1_rpcs.sql +798 -0
- package/migrations/20260512000002_agent_board_auth_v2_rpcs.sql +1243 -0
- package/migrations/20260512000003_agent_board_auth_rls.sql +484 -0
- package/migrations/20260513000000_agent_board_backup_ops.sql +34 -0
- package/migrations/20260513000001_agent_board_retention.sql +160 -0
- package/migrations/20260513000002_agent_board_monitoring_views.sql +227 -0
- package/migrations/20260514000000_agent_board_auth_rls_id_qualification.sql +150 -0
- package/migrations/20260515000000_agent_board_boardopt.sql +493 -0
- package/migrations/20260516000000_agent_board_callbackcap.sql +113 -0
- package/migrations/20260517000000_agent_board_addressing.sql +542 -0
- package/migrations/20260628000000_agent_board_signing_store.sql +174 -0
- package/migrations/20260628000001_agent_board_signing_proof_rpcs.sql +215 -0
- package/migrations/20260628000002_agent_board_signature_rls_reads.sql +300 -0
- package/migrations/20260628000003_agent_board_signed_write_gateway.sql +288 -0
- package/migrations/20260628000004_agent_board_fleet_registry.sql +411 -0
- package/migrations/20260628000005_agent_board_fleet_policy.sql +509 -0
- package/migrations/20260628000006_agent_board_fleet_read_models.sql +170 -0
- package/migrations/20260629000100_agent_board_fleet_registry_repair.sql +411 -0
- package/migrations/20260629000101_agent_board_fleet_policy_refresh.sql +509 -0
- package/migrations/20260629000102_agent_board_fleet_read_models_refresh.sql +170 -0
- package/migrations/20260630000100_agent_board_harness_kind_open_vocab.sql +15 -0
- package/migrations/20260710000000_agent_board_authbound_boundary.sql +155 -0
- package/migrations/20260710000100_agent_board_schema_version_rpc.sql +14 -0
- package/migrations/20260710000400_agent_board_nonfleet_identity.sql +87 -0
- package/migrations/20260710000401_agent_board_workload_providers.sql +39 -0
- package/migrations/20260711000000_agent_board_provision_system_fail_closed.sql +242 -0
- package/migrations/20260711000100_canary_signed_fleet_enforcement.sql +234 -0
- package/migrations/20260712000000_agent_board_bundle_endpoint_compat.sql +97 -0
- package/migrations/20260713000000_agent_board_rls_reassert_board_scoping.sql +90 -0
- package/package.json +42 -0
- package/provenance.json +580 -0
- package/schema-manifest.json +458 -0
- package/src/check.js +23 -0
- package/src/index.js +50 -0
- package/src/materialize.js +73 -0
- package/src/plan.js +44 -0
- package/src/tooling.test.mjs +97 -0
- package/tests/agent_board_addressing.test.sql +166 -0
- package/tests/agent_board_auth_rls.test.sql +243 -0
- package/tests/agent_board_auth_rls_id_qualification.test.sql +225 -0
- package/tests/agent_board_auth_rpcs.test.sql +311 -0
- package/tests/agent_board_auth_schema.test.sql +411 -0
- package/tests/agent_board_authbound_boundary.test.sql +148 -0
- package/tests/agent_board_boardopt.test.sql +170 -0
- package/tests/agent_board_bundle_endpoint_compat.test.sql +49 -0
- package/tests/agent_board_callback_runtime.test.sql +425 -0
- package/tests/agent_board_callbackcap.test.sql +222 -0
- package/tests/agent_board_canary_signed_fleet_enforcement.test.sql +60 -0
- package/tests/agent_board_dblint_rpcs.test.sql +247 -0
- package/tests/agent_board_fleet_policy.test.sql +370 -0
- package/tests/agent_board_fleet_read_models.test.sql +158 -0
- package/tests/agent_board_fleet_registry.test.sql +149 -0
- package/tests/agent_board_inbox_reads.test.sql +471 -0
- package/tests/agent_board_inbox_rpcs.test.sql +452 -0
- package/tests/agent_board_inbox_schema.test.sql +355 -0
- package/tests/agent_board_nonfleet_identity.test.sql +26 -0
- package/tests/agent_board_rls_reassert_board_scoping.test.sql +39 -0
- package/tests/agent_board_schema_version.test.sql +24 -0
- package/tests/agent_board_schema_version_rpc.test.sql +40 -0
- package/tests/agent_board_signature_rls_reads.test.sql +133 -0
- package/tests/agent_board_signed_write_gateway.test.sql +219 -0
- package/tests/agent_board_signing_proof_rpcs.test.sql +143 -0
- package/tests/agent_board_signing_store.test.sql +183 -0
- package/tests/agent_board_smoke.test.sql +12 -0
- package/tests/agent_board_v1_invariants.test.sql +298 -0
- package/tests/agent_board_v2_invariants.test.sql +753 -0
- package/tests/agent_board_workload_providers.test.sql +15 -0
- package/tests/fixtures/adopter-base.sql +19 -0
- package/tests/fixtures/operator-hardening.sql +27 -0
- package/tests/fixtures/test-prereqs.sql +84 -0
|
@@ -0,0 +1,753 @@
|
|
|
1
|
+
create extension if not exists pgtap with schema extensions;
|
|
2
|
+
set search_path = extensions, public, agent_board;
|
|
3
|
+
|
|
4
|
+
begin;
|
|
5
|
+
|
|
6
|
+
select plan(20);
|
|
7
|
+
|
|
8
|
+
insert into agent_board.agents(id, agent_type, handle, display_name)
|
|
9
|
+
values
|
|
10
|
+
('20000000-0000-0000-0000-000000000101', 'agent', 'v2_sender', 'V2 Sender'),
|
|
11
|
+
('20000000-0000-0000-0000-000000000102', 'agent', 'v2_direct_nonmember', 'V2 Direct Nonmember'),
|
|
12
|
+
('20000000-0000-0000-0000-000000000103', 'agent', 'v2_board_member', 'V2 Board Member'),
|
|
13
|
+
('20000000-0000-0000-0000-000000000104', 'agent', 'v2_board_subscriber', 'V2 Board Subscriber'),
|
|
14
|
+
('20000000-0000-0000-0000-000000000105', 'agent', 'v2_left_member', 'V2 Left Member'),
|
|
15
|
+
('20000000-0000-0000-0000-000000000106', 'agent', 'v2_claim_recipient', 'V2 Claim Recipient')
|
|
16
|
+
on conflict (id) do nothing;
|
|
17
|
+
|
|
18
|
+
insert into agent_board.threads(id, thread_type, created_by_agent_id, subject)
|
|
19
|
+
values (
|
|
20
|
+
'20000000-0000-0000-0000-000000000201',
|
|
21
|
+
'coordination',
|
|
22
|
+
'20000000-0000-0000-0000-000000000101',
|
|
23
|
+
'V2 invariant thread'
|
|
24
|
+
);
|
|
25
|
+
|
|
26
|
+
create temporary table v2_board on commit drop as
|
|
27
|
+
select *
|
|
28
|
+
from agent_board.create_board(
|
|
29
|
+
'20000000-0000-0000-0000-000000000101',
|
|
30
|
+
'v2-invariant-board',
|
|
31
|
+
'V2 Invariant Board',
|
|
32
|
+
'Board for delivery invariants',
|
|
33
|
+
'{}'::jsonb
|
|
34
|
+
);
|
|
35
|
+
|
|
36
|
+
create temporary table v2_board_member_join on commit drop as
|
|
37
|
+
select *
|
|
38
|
+
from agent_board.join_board(
|
|
39
|
+
(select board_id from v2_board),
|
|
40
|
+
'20000000-0000-0000-0000-000000000103',
|
|
41
|
+
'joined',
|
|
42
|
+
'20000000-0000-0000-0000-000000000101',
|
|
43
|
+
'{}'::jsonb
|
|
44
|
+
);
|
|
45
|
+
|
|
46
|
+
create temporary table v2_board_subscriber_join on commit drop as
|
|
47
|
+
select *
|
|
48
|
+
from agent_board.join_board(
|
|
49
|
+
(select board_id from v2_board),
|
|
50
|
+
'20000000-0000-0000-0000-000000000104',
|
|
51
|
+
'subscribed',
|
|
52
|
+
'20000000-0000-0000-0000-000000000101',
|
|
53
|
+
'{}'::jsonb
|
|
54
|
+
);
|
|
55
|
+
|
|
56
|
+
create temporary table v2_left_member_join on commit drop as
|
|
57
|
+
select *
|
|
58
|
+
from agent_board.join_board(
|
|
59
|
+
(select board_id from v2_board),
|
|
60
|
+
'20000000-0000-0000-0000-000000000105',
|
|
61
|
+
'joined',
|
|
62
|
+
'20000000-0000-0000-0000-000000000101',
|
|
63
|
+
'{}'::jsonb
|
|
64
|
+
);
|
|
65
|
+
|
|
66
|
+
create temporary table v2_left_member_leave on commit drop as
|
|
67
|
+
select *
|
|
68
|
+
from agent_board.leave_board(
|
|
69
|
+
(select board_id from v2_board),
|
|
70
|
+
'20000000-0000-0000-0000-000000000105',
|
|
71
|
+
'{}'::jsonb
|
|
72
|
+
);
|
|
73
|
+
|
|
74
|
+
create temporary table v2_direct_endpoint on commit drop as
|
|
75
|
+
select *
|
|
76
|
+
from agent_board.register_callback_endpoint(
|
|
77
|
+
'20000000-0000-0000-0000-000000000102',
|
|
78
|
+
'https://example.test/v2-direct',
|
|
79
|
+
'{}'::jsonb
|
|
80
|
+
);
|
|
81
|
+
|
|
82
|
+
create temporary table v2_direct_endpoint_verified on commit drop as
|
|
83
|
+
select *
|
|
84
|
+
from agent_board.verify_callback_endpoint(
|
|
85
|
+
(select endpoint_id from v2_direct_endpoint),
|
|
86
|
+
'20000000-0000-0000-0000-000000000102',
|
|
87
|
+
'{"controlProofRef":"v2/direct"}'::jsonb
|
|
88
|
+
);
|
|
89
|
+
|
|
90
|
+
create temporary table v2_direct_subscription on commit drop as
|
|
91
|
+
select *
|
|
92
|
+
from agent_board.subscribe_callback_endpoint(
|
|
93
|
+
(select endpoint_id from v2_direct_endpoint),
|
|
94
|
+
'20000000-0000-0000-0000-000000000102',
|
|
95
|
+
'own_inbox',
|
|
96
|
+
'inbox.item.delivered',
|
|
97
|
+
null,
|
|
98
|
+
'{}'::jsonb
|
|
99
|
+
);
|
|
100
|
+
|
|
101
|
+
create temporary table v2_board_member_endpoint on commit drop as
|
|
102
|
+
select *
|
|
103
|
+
from agent_board.register_callback_endpoint(
|
|
104
|
+
'20000000-0000-0000-0000-000000000103',
|
|
105
|
+
'https://example.test/v2-board-member',
|
|
106
|
+
'{}'::jsonb
|
|
107
|
+
);
|
|
108
|
+
|
|
109
|
+
create temporary table v2_board_member_verified on commit drop as
|
|
110
|
+
select *
|
|
111
|
+
from agent_board.verify_callback_endpoint(
|
|
112
|
+
(select endpoint_id from v2_board_member_endpoint),
|
|
113
|
+
'20000000-0000-0000-0000-000000000103',
|
|
114
|
+
'{"controlProofRef":"v2/board-member"}'::jsonb
|
|
115
|
+
);
|
|
116
|
+
|
|
117
|
+
create temporary table v2_board_member_subscription on commit drop as
|
|
118
|
+
select *
|
|
119
|
+
from agent_board.subscribe_callback_endpoint(
|
|
120
|
+
(select endpoint_id from v2_board_member_endpoint),
|
|
121
|
+
'20000000-0000-0000-0000-000000000103',
|
|
122
|
+
'board',
|
|
123
|
+
'board.post.delivered',
|
|
124
|
+
(select board_id from v2_board),
|
|
125
|
+
'{}'::jsonb
|
|
126
|
+
);
|
|
127
|
+
|
|
128
|
+
create temporary table v2_board_subscriber_endpoint on commit drop as
|
|
129
|
+
select *
|
|
130
|
+
from agent_board.register_callback_endpoint(
|
|
131
|
+
'20000000-0000-0000-0000-000000000104',
|
|
132
|
+
'https://example.test/v2-board-subscriber',
|
|
133
|
+
'{}'::jsonb
|
|
134
|
+
);
|
|
135
|
+
|
|
136
|
+
create temporary table v2_board_subscriber_verified on commit drop as
|
|
137
|
+
select *
|
|
138
|
+
from agent_board.verify_callback_endpoint(
|
|
139
|
+
(select endpoint_id from v2_board_subscriber_endpoint),
|
|
140
|
+
'20000000-0000-0000-0000-000000000104',
|
|
141
|
+
'{"controlProofRef":"v2/board-subscriber"}'::jsonb
|
|
142
|
+
);
|
|
143
|
+
|
|
144
|
+
create temporary table v2_board_subscriber_subscription on commit drop as
|
|
145
|
+
select *
|
|
146
|
+
from agent_board.subscribe_callback_endpoint(
|
|
147
|
+
(select endpoint_id from v2_board_subscriber_endpoint),
|
|
148
|
+
'20000000-0000-0000-0000-000000000104',
|
|
149
|
+
'board',
|
|
150
|
+
'board.post.delivered',
|
|
151
|
+
(select board_id from v2_board),
|
|
152
|
+
'{}'::jsonb
|
|
153
|
+
);
|
|
154
|
+
|
|
155
|
+
create temporary table v2_claim_seed_delivery on commit drop as
|
|
156
|
+
select *
|
|
157
|
+
from agent_board.send_direct_message(
|
|
158
|
+
'20000000-0000-0000-0000-000000000201',
|
|
159
|
+
'20000000-0000-0000-0000-000000000101',
|
|
160
|
+
'20000000-0000-0000-0000-000000000106',
|
|
161
|
+
'Claim seed subject',
|
|
162
|
+
'Claim seed body',
|
|
163
|
+
'comment',
|
|
164
|
+
'medium',
|
|
165
|
+
'v2-claim-seed',
|
|
166
|
+
'{}'::jsonb
|
|
167
|
+
);
|
|
168
|
+
|
|
169
|
+
create temporary table v2_claim_endpoint on commit drop as
|
|
170
|
+
select *
|
|
171
|
+
from agent_board.register_callback_endpoint(
|
|
172
|
+
'20000000-0000-0000-0000-000000000106',
|
|
173
|
+
'https://example.test/v2-claim',
|
|
174
|
+
'{}'::jsonb
|
|
175
|
+
);
|
|
176
|
+
|
|
177
|
+
create temporary table v2_claim_endpoint_verified on commit drop as
|
|
178
|
+
select *
|
|
179
|
+
from agent_board.verify_callback_endpoint(
|
|
180
|
+
(select endpoint_id from v2_claim_endpoint),
|
|
181
|
+
'20000000-0000-0000-0000-000000000106',
|
|
182
|
+
'{"controlProofRef":"v2/claim"}'::jsonb
|
|
183
|
+
);
|
|
184
|
+
|
|
185
|
+
create temporary table v2_claim_subscription on commit drop as
|
|
186
|
+
select *
|
|
187
|
+
from agent_board.subscribe_callback_endpoint(
|
|
188
|
+
(select endpoint_id from v2_claim_endpoint),
|
|
189
|
+
'20000000-0000-0000-0000-000000000106',
|
|
190
|
+
'own_inbox',
|
|
191
|
+
'inbox.item.delivered',
|
|
192
|
+
null,
|
|
193
|
+
'{}'::jsonb
|
|
194
|
+
);
|
|
195
|
+
|
|
196
|
+
create temporary table v2_disable_endpoint on commit drop as
|
|
197
|
+
select *
|
|
198
|
+
from agent_board.register_callback_endpoint(
|
|
199
|
+
'20000000-0000-0000-0000-000000000106',
|
|
200
|
+
'https://example.test/v2-disable',
|
|
201
|
+
'{}'::jsonb
|
|
202
|
+
);
|
|
203
|
+
|
|
204
|
+
create temporary table v2_disable_endpoint_verified on commit drop as
|
|
205
|
+
select *
|
|
206
|
+
from agent_board.verify_callback_endpoint(
|
|
207
|
+
(select endpoint_id from v2_disable_endpoint),
|
|
208
|
+
'20000000-0000-0000-0000-000000000106',
|
|
209
|
+
'{"controlProofRef":"v2/disable"}'::jsonb
|
|
210
|
+
);
|
|
211
|
+
|
|
212
|
+
create temporary table v2_disable_subscription on commit drop as
|
|
213
|
+
select *
|
|
214
|
+
from agent_board.subscribe_callback_endpoint(
|
|
215
|
+
(select endpoint_id from v2_disable_endpoint),
|
|
216
|
+
'20000000-0000-0000-0000-000000000106',
|
|
217
|
+
'own_inbox',
|
|
218
|
+
'inbox.item.delivered',
|
|
219
|
+
null,
|
|
220
|
+
'{}'::jsonb
|
|
221
|
+
);
|
|
222
|
+
|
|
223
|
+
create temporary table v2_direct_delivery on commit drop as
|
|
224
|
+
select *
|
|
225
|
+
from agent_board.send_direct_message(
|
|
226
|
+
'20000000-0000-0000-0000-000000000201',
|
|
227
|
+
'20000000-0000-0000-0000-000000000101',
|
|
228
|
+
'20000000-0000-0000-0000-000000000102',
|
|
229
|
+
'Direct subject',
|
|
230
|
+
'Direct body to a non-member',
|
|
231
|
+
'comment',
|
|
232
|
+
'high',
|
|
233
|
+
'v2-direct',
|
|
234
|
+
'{}'::jsonb
|
|
235
|
+
);
|
|
236
|
+
|
|
237
|
+
select is(
|
|
238
|
+
(select count(*)::integer from agent_board.delivery_recipients where source_message_id = (select message_id from v2_direct_delivery)),
|
|
239
|
+
1,
|
|
240
|
+
'send_direct_message delivers to explicit recipients without board membership'
|
|
241
|
+
);
|
|
242
|
+
|
|
243
|
+
select is(
|
|
244
|
+
(select count(*)::integer from agent_board.inbox_items where source_message_id = (select message_id from v2_direct_delivery)),
|
|
245
|
+
1,
|
|
246
|
+
'send_direct_message creates one inbox row for a direct non-member recipient'
|
|
247
|
+
);
|
|
248
|
+
|
|
249
|
+
create temporary table v2_direct_replay on commit drop as
|
|
250
|
+
select *
|
|
251
|
+
from agent_board.send_direct_message(
|
|
252
|
+
'20000000-0000-0000-0000-000000000201',
|
|
253
|
+
'20000000-0000-0000-0000-000000000101',
|
|
254
|
+
'20000000-0000-0000-0000-000000000102',
|
|
255
|
+
'Direct subject',
|
|
256
|
+
'Direct body to a non-member',
|
|
257
|
+
'comment',
|
|
258
|
+
'high',
|
|
259
|
+
'v2-direct',
|
|
260
|
+
'{}'::jsonb
|
|
261
|
+
);
|
|
262
|
+
|
|
263
|
+
select is(
|
|
264
|
+
(select message_id::text from v2_direct_replay),
|
|
265
|
+
(select message_id::text from v2_direct_delivery),
|
|
266
|
+
'direct idempotency reuses the canonical message row'
|
|
267
|
+
);
|
|
268
|
+
|
|
269
|
+
select is(
|
|
270
|
+
(
|
|
271
|
+
select count(*)::integer
|
|
272
|
+
from agent_board.callback_outbox_events
|
|
273
|
+
where source_message_id = (select message_id from v2_direct_delivery)
|
|
274
|
+
and event_category = 'inbox.item.delivered'
|
|
275
|
+
),
|
|
276
|
+
1,
|
|
277
|
+
'direct idempotency does not duplicate callback outbox rows'
|
|
278
|
+
);
|
|
279
|
+
|
|
280
|
+
create temporary table v2_multicast_delivery on commit drop as
|
|
281
|
+
select *
|
|
282
|
+
from agent_board.send_multicast_message(
|
|
283
|
+
'20000000-0000-0000-0000-000000000201',
|
|
284
|
+
'20000000-0000-0000-0000-000000000101',
|
|
285
|
+
array[
|
|
286
|
+
'20000000-0000-0000-0000-000000000102'::uuid,
|
|
287
|
+
'20000000-0000-0000-0000-000000000103'::uuid,
|
|
288
|
+
'20000000-0000-0000-0000-000000000102'::uuid
|
|
289
|
+
],
|
|
290
|
+
'Multicast subject',
|
|
291
|
+
'Multicast body',
|
|
292
|
+
'comment',
|
|
293
|
+
'medium',
|
|
294
|
+
'v2-multicast',
|
|
295
|
+
'{}'::jsonb
|
|
296
|
+
);
|
|
297
|
+
|
|
298
|
+
select is(
|
|
299
|
+
(select delivered_recipient_count from v2_multicast_delivery),
|
|
300
|
+
2,
|
|
301
|
+
'send_multicast_message collapses duplicate explicit recipients'
|
|
302
|
+
);
|
|
303
|
+
|
|
304
|
+
select is(
|
|
305
|
+
(select count(*)::integer from agent_board.delivery_recipients where source_message_id = (select message_id from v2_multicast_delivery)),
|
|
306
|
+
2,
|
|
307
|
+
'multicast delivery writes one recipient row per unique recipient'
|
|
308
|
+
);
|
|
309
|
+
|
|
310
|
+
create temporary table v2_board_delivery on commit drop as
|
|
311
|
+
select *
|
|
312
|
+
from agent_board.post_board_message(
|
|
313
|
+
'20000000-0000-0000-0000-000000000201',
|
|
314
|
+
'20000000-0000-0000-0000-000000000101',
|
|
315
|
+
(select board_id from v2_board),
|
|
316
|
+
'Board subject',
|
|
317
|
+
'Board body',
|
|
318
|
+
'comment',
|
|
319
|
+
'urgent',
|
|
320
|
+
'v2-board',
|
|
321
|
+
'{}'::jsonb
|
|
322
|
+
);
|
|
323
|
+
|
|
324
|
+
select is(
|
|
325
|
+
(select delivered_recipient_count from v2_board_delivery),
|
|
326
|
+
2,
|
|
327
|
+
'post_board_message only reaches active joined or subscribed board members'
|
|
328
|
+
);
|
|
329
|
+
|
|
330
|
+
select is(
|
|
331
|
+
(
|
|
332
|
+
select count(*)::integer
|
|
333
|
+
from agent_board.delivery_recipients
|
|
334
|
+
where source_message_id = (select message_id from v2_board_delivery)
|
|
335
|
+
and recipient_agent_id in (
|
|
336
|
+
'20000000-0000-0000-0000-000000000102'::uuid,
|
|
337
|
+
'20000000-0000-0000-0000-000000000105'::uuid
|
|
338
|
+
)
|
|
339
|
+
),
|
|
340
|
+
0,
|
|
341
|
+
'board delivery excludes non-members and agents who already left the board'
|
|
342
|
+
);
|
|
343
|
+
|
|
344
|
+
select is(
|
|
345
|
+
(
|
|
346
|
+
select count(*)::integer
|
|
347
|
+
from agent_board.callback_outbox_events
|
|
348
|
+
where source_message_id = (select message_id from v2_board_delivery)
|
|
349
|
+
and event_category = 'board.post.delivered'
|
|
350
|
+
),
|
|
351
|
+
2,
|
|
352
|
+
'board post callbacks queue exactly one row per active board subscription'
|
|
353
|
+
);
|
|
354
|
+
|
|
355
|
+
create temporary table v2_tasking_delivery on commit drop as
|
|
356
|
+
select *
|
|
357
|
+
from agent_board.create_tasking_delivery(
|
|
358
|
+
'20000000-0000-0000-0000-000000000201',
|
|
359
|
+
'20000000-0000-0000-0000-000000000101',
|
|
360
|
+
'Tasking invariant title',
|
|
361
|
+
'Tasking invariant details',
|
|
362
|
+
array['20000000-0000-0000-0000-000000000103'::uuid],
|
|
363
|
+
(select board_id from v2_board),
|
|
364
|
+
'high',
|
|
365
|
+
'distributed',
|
|
366
|
+
'v2-task',
|
|
367
|
+
'{}'::jsonb
|
|
368
|
+
);
|
|
369
|
+
|
|
370
|
+
select is(
|
|
371
|
+
(select delivered_recipient_count from v2_tasking_delivery),
|
|
372
|
+
3,
|
|
373
|
+
'tasking counts explicit and board fan-out attempts before duplicate collapse'
|
|
374
|
+
);
|
|
375
|
+
|
|
376
|
+
select is(
|
|
377
|
+
(select count(*)::integer from agent_board.delivery_recipients where source_task_id = (select task_id from v2_tasking_delivery)),
|
|
378
|
+
2,
|
|
379
|
+
'tasking suppresses duplicate durable recipient rows across explicit and board fan-out'
|
|
380
|
+
);
|
|
381
|
+
|
|
382
|
+
select *
|
|
383
|
+
into temporary table v2_disable_direct_callbacks
|
|
384
|
+
from agent_board.disable_callback_endpoint(
|
|
385
|
+
(select endpoint_id from v2_direct_endpoint),
|
|
386
|
+
'20000000-0000-0000-0000-000000000102',
|
|
387
|
+
'claim isolation',
|
|
388
|
+
'{}'::jsonb
|
|
389
|
+
);
|
|
390
|
+
|
|
391
|
+
select *
|
|
392
|
+
into temporary table v2_disable_board_member_callbacks
|
|
393
|
+
from agent_board.disable_callback_endpoint(
|
|
394
|
+
(select endpoint_id from v2_board_member_endpoint),
|
|
395
|
+
'20000000-0000-0000-0000-000000000103',
|
|
396
|
+
'claim isolation',
|
|
397
|
+
'{}'::jsonb
|
|
398
|
+
);
|
|
399
|
+
|
|
400
|
+
select *
|
|
401
|
+
into temporary table v2_disable_board_subscriber_callbacks
|
|
402
|
+
from agent_board.disable_callback_endpoint(
|
|
403
|
+
(select endpoint_id from v2_board_subscriber_endpoint),
|
|
404
|
+
'20000000-0000-0000-0000-000000000104',
|
|
405
|
+
'claim isolation',
|
|
406
|
+
'{}'::jsonb
|
|
407
|
+
);
|
|
408
|
+
|
|
409
|
+
-- claim_callback_outbox_events polls globally. Neutralize any preexisting
|
|
410
|
+
-- ready rows before the claim-specific fixture so reused local databases do
|
|
411
|
+
-- not change the expected batch size; rollback restores the original rows.
|
|
412
|
+
update agent_board.callback_outbox_events
|
|
413
|
+
set outbox_status = 'delivered',
|
|
414
|
+
delivered_at = coalesce(delivered_at, now()),
|
|
415
|
+
updated_at = now()
|
|
416
|
+
where outbox_status in ('pending', 'retryable')
|
|
417
|
+
and available_at <= now();
|
|
418
|
+
|
|
419
|
+
insert into agent_board.callback_outbox_events(
|
|
420
|
+
id,
|
|
421
|
+
endpoint_id,
|
|
422
|
+
subscription_id,
|
|
423
|
+
recipient_agent_id,
|
|
424
|
+
inbox_item_id,
|
|
425
|
+
event_category,
|
|
426
|
+
delivery_mode,
|
|
427
|
+
source_kind,
|
|
428
|
+
source_message_id,
|
|
429
|
+
idempotency_key,
|
|
430
|
+
subject,
|
|
431
|
+
preview,
|
|
432
|
+
priority,
|
|
433
|
+
fetch_descriptor,
|
|
434
|
+
outbox_status,
|
|
435
|
+
available_at
|
|
436
|
+
)
|
|
437
|
+
values
|
|
438
|
+
(
|
|
439
|
+
'20000000-0000-0000-0000-000000000901',
|
|
440
|
+
(select endpoint_id from v2_claim_endpoint),
|
|
441
|
+
(select subscription_id from v2_claim_subscription),
|
|
442
|
+
'20000000-0000-0000-0000-000000000106',
|
|
443
|
+
(select inbox_item_id from v2_claim_seed_delivery),
|
|
444
|
+
'inbox.item.delivered',
|
|
445
|
+
'direct',
|
|
446
|
+
'message',
|
|
447
|
+
(select message_id from v2_claim_seed_delivery),
|
|
448
|
+
'v2-claim-pending',
|
|
449
|
+
'Claim pending',
|
|
450
|
+
'Pending callback',
|
|
451
|
+
'medium',
|
|
452
|
+
jsonb_build_object('surface', 'thread', 'targetId', '20000000-0000-0000-0000-000000000201', 'view', 'agent_board.v_thread_feed', 'filters', jsonb_build_object(), 'reason', 'claim invariant'),
|
|
453
|
+
'pending',
|
|
454
|
+
now() - interval '5 minutes'
|
|
455
|
+
),
|
|
456
|
+
(
|
|
457
|
+
'20000000-0000-0000-0000-000000000902',
|
|
458
|
+
(select endpoint_id from v2_claim_endpoint),
|
|
459
|
+
(select subscription_id from v2_claim_subscription),
|
|
460
|
+
'20000000-0000-0000-0000-000000000106',
|
|
461
|
+
(select inbox_item_id from v2_claim_seed_delivery),
|
|
462
|
+
'inbox.item.delivered',
|
|
463
|
+
'direct',
|
|
464
|
+
'message',
|
|
465
|
+
(select message_id from v2_claim_seed_delivery),
|
|
466
|
+
'v2-claim-retryable',
|
|
467
|
+
'Claim retryable',
|
|
468
|
+
'Retryable callback',
|
|
469
|
+
'medium',
|
|
470
|
+
jsonb_build_object('surface', 'thread', 'targetId', '20000000-0000-0000-0000-000000000201', 'view', 'agent_board.v_thread_feed', 'filters', jsonb_build_object(), 'reason', 'claim invariant'),
|
|
471
|
+
'retryable',
|
|
472
|
+
now() - interval '2 minutes'
|
|
473
|
+
),
|
|
474
|
+
(
|
|
475
|
+
'20000000-0000-0000-0000-000000000903',
|
|
476
|
+
(select endpoint_id from v2_claim_endpoint),
|
|
477
|
+
(select subscription_id from v2_claim_subscription),
|
|
478
|
+
'20000000-0000-0000-0000-000000000106',
|
|
479
|
+
(select inbox_item_id from v2_claim_seed_delivery),
|
|
480
|
+
'inbox.item.delivered',
|
|
481
|
+
'direct',
|
|
482
|
+
'message',
|
|
483
|
+
(select message_id from v2_claim_seed_delivery),
|
|
484
|
+
'v2-claim-delivered',
|
|
485
|
+
'Claim delivered',
|
|
486
|
+
'Delivered callback',
|
|
487
|
+
'medium',
|
|
488
|
+
jsonb_build_object('surface', 'thread', 'targetId', '20000000-0000-0000-0000-000000000201', 'view', 'agent_board.v_thread_feed', 'filters', jsonb_build_object(), 'reason', 'claim invariant'),
|
|
489
|
+
'delivered',
|
|
490
|
+
now() - interval '1 minute'
|
|
491
|
+
),
|
|
492
|
+
(
|
|
493
|
+
'20000000-0000-0000-0000-000000000904',
|
|
494
|
+
(select endpoint_id from v2_claim_endpoint),
|
|
495
|
+
(select subscription_id from v2_claim_subscription),
|
|
496
|
+
'20000000-0000-0000-0000-000000000106',
|
|
497
|
+
(select inbox_item_id from v2_claim_seed_delivery),
|
|
498
|
+
'inbox.item.delivered',
|
|
499
|
+
'direct',
|
|
500
|
+
'message',
|
|
501
|
+
(select message_id from v2_claim_seed_delivery),
|
|
502
|
+
'v2-claim-failed',
|
|
503
|
+
'Claim failed',
|
|
504
|
+
'Failed callback',
|
|
505
|
+
'medium',
|
|
506
|
+
jsonb_build_object('surface', 'thread', 'targetId', '20000000-0000-0000-0000-000000000201', 'view', 'agent_board.v_thread_feed', 'filters', jsonb_build_object(), 'reason', 'claim invariant'),
|
|
507
|
+
'failed',
|
|
508
|
+
now() - interval '1 minute'
|
|
509
|
+
),
|
|
510
|
+
(
|
|
511
|
+
'20000000-0000-0000-0000-000000000905',
|
|
512
|
+
(select endpoint_id from v2_claim_endpoint),
|
|
513
|
+
(select subscription_id from v2_claim_subscription),
|
|
514
|
+
'20000000-0000-0000-0000-000000000106',
|
|
515
|
+
(select inbox_item_id from v2_claim_seed_delivery),
|
|
516
|
+
'inbox.item.delivered',
|
|
517
|
+
'direct',
|
|
518
|
+
'message',
|
|
519
|
+
(select message_id from v2_claim_seed_delivery),
|
|
520
|
+
'v2-claim-disabled',
|
|
521
|
+
'Claim disabled',
|
|
522
|
+
'Disabled callback',
|
|
523
|
+
'medium',
|
|
524
|
+
jsonb_build_object('surface', 'thread', 'targetId', '20000000-0000-0000-0000-000000000201', 'view', 'agent_board.v_thread_feed', 'filters', jsonb_build_object(), 'reason', 'claim invariant'),
|
|
525
|
+
'disabled',
|
|
526
|
+
now() - interval '1 minute'
|
|
527
|
+
);
|
|
528
|
+
|
|
529
|
+
create temporary table v2_claimed_once on commit drop as
|
|
530
|
+
select *
|
|
531
|
+
from agent_board.claim_callback_outbox_events(10);
|
|
532
|
+
|
|
533
|
+
select is(
|
|
534
|
+
(select count(*)::integer from v2_claimed_once),
|
|
535
|
+
2,
|
|
536
|
+
'claim_callback_outbox_events only claims pending and retryable rows that are ready now'
|
|
537
|
+
);
|
|
538
|
+
|
|
539
|
+
select is(
|
|
540
|
+
(
|
|
541
|
+
select count(*)::integer
|
|
542
|
+
from v2_claimed_once
|
|
543
|
+
where outbox_event_id in (
|
|
544
|
+
'20000000-0000-0000-0000-000000000903'::uuid,
|
|
545
|
+
'20000000-0000-0000-0000-000000000904'::uuid,
|
|
546
|
+
'20000000-0000-0000-0000-000000000905'::uuid
|
|
547
|
+
)
|
|
548
|
+
),
|
|
549
|
+
0,
|
|
550
|
+
'claim_callback_outbox_events skips delivered, failed, and disabled stop states'
|
|
551
|
+
);
|
|
552
|
+
|
|
553
|
+
create temporary table v2_claimed_twice on commit drop as
|
|
554
|
+
select *
|
|
555
|
+
from agent_board.claim_callback_outbox_events(10);
|
|
556
|
+
|
|
557
|
+
select is(
|
|
558
|
+
(select count(*)::integer from v2_claimed_twice),
|
|
559
|
+
0,
|
|
560
|
+
'claimed callback rows are not immediately reclaimable while already delivering'
|
|
561
|
+
);
|
|
562
|
+
|
|
563
|
+
insert into agent_board.callback_outbox_events(
|
|
564
|
+
id,
|
|
565
|
+
endpoint_id,
|
|
566
|
+
subscription_id,
|
|
567
|
+
recipient_agent_id,
|
|
568
|
+
inbox_item_id,
|
|
569
|
+
event_category,
|
|
570
|
+
delivery_mode,
|
|
571
|
+
source_kind,
|
|
572
|
+
source_message_id,
|
|
573
|
+
idempotency_key,
|
|
574
|
+
subject,
|
|
575
|
+
preview,
|
|
576
|
+
priority,
|
|
577
|
+
fetch_descriptor,
|
|
578
|
+
outbox_status,
|
|
579
|
+
available_at
|
|
580
|
+
)
|
|
581
|
+
values (
|
|
582
|
+
'20000000-0000-0000-0000-000000000906',
|
|
583
|
+
(select endpoint_id from v2_claim_endpoint),
|
|
584
|
+
(select subscription_id from v2_claim_subscription),
|
|
585
|
+
'20000000-0000-0000-0000-000000000106',
|
|
586
|
+
(select inbox_item_id from v2_claim_seed_delivery),
|
|
587
|
+
'inbox.item.delivered',
|
|
588
|
+
'direct',
|
|
589
|
+
'message',
|
|
590
|
+
(select message_id from v2_claim_seed_delivery),
|
|
591
|
+
'v2-claim-past-retry',
|
|
592
|
+
'Past retry',
|
|
593
|
+
'Past retry callback',
|
|
594
|
+
'medium',
|
|
595
|
+
jsonb_build_object('surface', 'thread', 'targetId', '20000000-0000-0000-0000-000000000201', 'view', 'agent_board.v_thread_feed', 'filters', jsonb_build_object(), 'reason', 'claim invariant'),
|
|
596
|
+
'pending',
|
|
597
|
+
now() - interval '1 minute'
|
|
598
|
+
);
|
|
599
|
+
|
|
600
|
+
select throws_ok(
|
|
601
|
+
$$select *
|
|
602
|
+
from agent_board.record_callback_delivery_retry(
|
|
603
|
+
'20000000-0000-0000-0000-000000000906'::uuid,
|
|
604
|
+
(
|
|
605
|
+
select id
|
|
606
|
+
from agent_board.callback_endpoints
|
|
607
|
+
where endpoint_url = 'https://example.test/v2-claim'
|
|
608
|
+
),
|
|
609
|
+
503,
|
|
610
|
+
'temporary outage',
|
|
611
|
+
now() - interval '1 minute',
|
|
612
|
+
'{}'::jsonb
|
|
613
|
+
)$$,
|
|
614
|
+
'22023',
|
|
615
|
+
'next retry timestamp must be in the future',
|
|
616
|
+
'record_callback_delivery_retry requires a future next_retry_at'
|
|
617
|
+
);
|
|
618
|
+
|
|
619
|
+
insert into agent_board.callback_outbox_events(
|
|
620
|
+
id,
|
|
621
|
+
endpoint_id,
|
|
622
|
+
subscription_id,
|
|
623
|
+
recipient_agent_id,
|
|
624
|
+
inbox_item_id,
|
|
625
|
+
event_category,
|
|
626
|
+
delivery_mode,
|
|
627
|
+
source_kind,
|
|
628
|
+
source_message_id,
|
|
629
|
+
idempotency_key,
|
|
630
|
+
subject,
|
|
631
|
+
preview,
|
|
632
|
+
priority,
|
|
633
|
+
fetch_descriptor,
|
|
634
|
+
outbox_status,
|
|
635
|
+
available_at
|
|
636
|
+
)
|
|
637
|
+
values (
|
|
638
|
+
'20000000-0000-0000-0000-000000000907',
|
|
639
|
+
(select endpoint_id from v2_claim_endpoint),
|
|
640
|
+
(select subscription_id from v2_claim_subscription),
|
|
641
|
+
'20000000-0000-0000-0000-000000000106',
|
|
642
|
+
(select inbox_item_id from v2_claim_seed_delivery),
|
|
643
|
+
'inbox.item.delivered',
|
|
644
|
+
'direct',
|
|
645
|
+
'message',
|
|
646
|
+
(select message_id from v2_claim_seed_delivery),
|
|
647
|
+
'v2-terminal',
|
|
648
|
+
'Terminal failure',
|
|
649
|
+
'Terminal failure callback',
|
|
650
|
+
'medium',
|
|
651
|
+
jsonb_build_object('surface', 'thread', 'targetId', '20000000-0000-0000-0000-000000000201', 'view', 'agent_board.v_thread_feed', 'filters', jsonb_build_object(), 'reason', 'claim invariant'),
|
|
652
|
+
'pending',
|
|
653
|
+
now() - interval '1 minute'
|
|
654
|
+
);
|
|
655
|
+
|
|
656
|
+
select *
|
|
657
|
+
into temporary table v2_terminal_failure_result
|
|
658
|
+
from agent_board.record_callback_delivery_terminal_failure(
|
|
659
|
+
'20000000-0000-0000-0000-000000000907',
|
|
660
|
+
(select endpoint_id from v2_claim_endpoint),
|
|
661
|
+
410,
|
|
662
|
+
'gone',
|
|
663
|
+
'{}'::jsonb
|
|
664
|
+
);
|
|
665
|
+
|
|
666
|
+
select is(
|
|
667
|
+
(select outbox_status from v2_terminal_failure_result),
|
|
668
|
+
'failed',
|
|
669
|
+
'record_callback_delivery_terminal_failure moves rows into the failed stop state'
|
|
670
|
+
);
|
|
671
|
+
|
|
672
|
+
select is(
|
|
673
|
+
(
|
|
674
|
+
select count(*)::integer
|
|
675
|
+
from agent_board.claim_callback_outbox_events(10)
|
|
676
|
+
where outbox_event_id = '20000000-0000-0000-0000-000000000907'::uuid
|
|
677
|
+
),
|
|
678
|
+
0,
|
|
679
|
+
'failed callback rows are not claimable again'
|
|
680
|
+
);
|
|
681
|
+
|
|
682
|
+
insert into agent_board.callback_outbox_events(
|
|
683
|
+
id,
|
|
684
|
+
endpoint_id,
|
|
685
|
+
subscription_id,
|
|
686
|
+
recipient_agent_id,
|
|
687
|
+
inbox_item_id,
|
|
688
|
+
event_category,
|
|
689
|
+
delivery_mode,
|
|
690
|
+
source_kind,
|
|
691
|
+
source_message_id,
|
|
692
|
+
idempotency_key,
|
|
693
|
+
subject,
|
|
694
|
+
preview,
|
|
695
|
+
priority,
|
|
696
|
+
fetch_descriptor,
|
|
697
|
+
outbox_status,
|
|
698
|
+
available_at
|
|
699
|
+
)
|
|
700
|
+
values (
|
|
701
|
+
'20000000-0000-0000-0000-000000000908',
|
|
702
|
+
(select endpoint_id from v2_disable_endpoint),
|
|
703
|
+
(select subscription_id from v2_disable_subscription),
|
|
704
|
+
'20000000-0000-0000-0000-000000000106',
|
|
705
|
+
(select inbox_item_id from v2_claim_seed_delivery),
|
|
706
|
+
'inbox.item.delivered',
|
|
707
|
+
'direct',
|
|
708
|
+
'message',
|
|
709
|
+
(select message_id from v2_claim_seed_delivery),
|
|
710
|
+
'v2-disable',
|
|
711
|
+
'Disable endpoint',
|
|
712
|
+
'Disable endpoint callback',
|
|
713
|
+
'medium',
|
|
714
|
+
jsonb_build_object('surface', 'thread', 'targetId', '20000000-0000-0000-0000-000000000201', 'view', 'agent_board.v_thread_feed', 'filters', jsonb_build_object(), 'reason', 'disable invariant'),
|
|
715
|
+
'pending',
|
|
716
|
+
now() - interval '1 minute'
|
|
717
|
+
);
|
|
718
|
+
|
|
719
|
+
select *
|
|
720
|
+
into temporary table v2_disable_result
|
|
721
|
+
from agent_board.disable_callback_delivery_endpoint(
|
|
722
|
+
(select endpoint_id from v2_disable_endpoint),
|
|
723
|
+
'20000000-0000-0000-0000-000000000908',
|
|
724
|
+
'disablement threshold reached',
|
|
725
|
+
'endpoint disabled',
|
|
726
|
+
'{}'::jsonb
|
|
727
|
+
);
|
|
728
|
+
|
|
729
|
+
select is(
|
|
730
|
+
(select endpoint_status from v2_disable_result),
|
|
731
|
+
'disabled',
|
|
732
|
+
'disable_callback_delivery_endpoint disables the endpoint'
|
|
733
|
+
);
|
|
734
|
+
|
|
735
|
+
select is(
|
|
736
|
+
(select outbox_status from agent_board.callback_outbox_events where id = '20000000-0000-0000-0000-000000000908'::uuid),
|
|
737
|
+
'disabled',
|
|
738
|
+
'disable_callback_delivery_endpoint marks pending outbox rows disabled'
|
|
739
|
+
);
|
|
740
|
+
|
|
741
|
+
select is(
|
|
742
|
+
(
|
|
743
|
+
select count(*)::integer
|
|
744
|
+
from agent_board.claim_callback_outbox_events(10)
|
|
745
|
+
where outbox_event_id = '20000000-0000-0000-0000-000000000908'::uuid
|
|
746
|
+
),
|
|
747
|
+
0,
|
|
748
|
+
'disabled callback rows are not claimable again'
|
|
749
|
+
);
|
|
750
|
+
|
|
751
|
+
select * from finish();
|
|
752
|
+
|
|
753
|
+
rollback;
|