@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.
Files changed (92) hide show
  1. package/LICENSE +202 -0
  2. package/NOTICE +11 -0
  3. package/README.md +55 -0
  4. package/bin/agent-board-schema.js +97 -0
  5. package/fixtures/already-applied.json +181 -0
  6. package/fixtures/divergent-history.json +173 -0
  7. package/fixtures/production-history.json +173 -0
  8. package/migrations/20260501000001_agent_board_schema_version.sql +12 -0
  9. package/migrations/20260502000000_agent_board_schema.sql +180 -0
  10. package/migrations/20260503000000_agent_board_rpcs.sql +422 -0
  11. package/migrations/20260503000001_agent_board_coordination_rpcs.sql +229 -0
  12. package/migrations/20260504000000_agent_board_read_models.sql +206 -0
  13. package/migrations/20260505000000_agent_board_inbox_schema.sql +341 -0
  14. package/migrations/20260506000000_agent_board_inbox_delivery_rpcs.sql +1200 -0
  15. package/migrations/20260506000001_agent_board_inbox_callback_rpcs.sql +330 -0
  16. package/migrations/20260507000000_agent_board_inbox_reads.sql +334 -0
  17. package/migrations/20260508000000_agent_board_callback_runtime.sql +453 -0
  18. package/migrations/20260508000001_agent_board_inbox_service_role_reads.sql +10 -0
  19. package/migrations/20260510000000_agent_board_dblint_repairs.sql +413 -0
  20. package/migrations/20260511000000_agent_board_auth_schema.sql +146 -0
  21. package/migrations/20260511000001_agent_board_auth_credentials.sql +39 -0
  22. package/migrations/20260512000000_agent_board_auth_provisioning_rpcs.sql +622 -0
  23. package/migrations/20260512000001_agent_board_auth_v1_rpcs.sql +798 -0
  24. package/migrations/20260512000002_agent_board_auth_v2_rpcs.sql +1243 -0
  25. package/migrations/20260512000003_agent_board_auth_rls.sql +484 -0
  26. package/migrations/20260513000000_agent_board_backup_ops.sql +34 -0
  27. package/migrations/20260513000001_agent_board_retention.sql +160 -0
  28. package/migrations/20260513000002_agent_board_monitoring_views.sql +227 -0
  29. package/migrations/20260514000000_agent_board_auth_rls_id_qualification.sql +150 -0
  30. package/migrations/20260515000000_agent_board_boardopt.sql +493 -0
  31. package/migrations/20260516000000_agent_board_callbackcap.sql +113 -0
  32. package/migrations/20260517000000_agent_board_addressing.sql +542 -0
  33. package/migrations/20260628000000_agent_board_signing_store.sql +174 -0
  34. package/migrations/20260628000001_agent_board_signing_proof_rpcs.sql +215 -0
  35. package/migrations/20260628000002_agent_board_signature_rls_reads.sql +300 -0
  36. package/migrations/20260628000003_agent_board_signed_write_gateway.sql +288 -0
  37. package/migrations/20260628000004_agent_board_fleet_registry.sql +411 -0
  38. package/migrations/20260628000005_agent_board_fleet_policy.sql +509 -0
  39. package/migrations/20260628000006_agent_board_fleet_read_models.sql +170 -0
  40. package/migrations/20260629000100_agent_board_fleet_registry_repair.sql +411 -0
  41. package/migrations/20260629000101_agent_board_fleet_policy_refresh.sql +509 -0
  42. package/migrations/20260629000102_agent_board_fleet_read_models_refresh.sql +170 -0
  43. package/migrations/20260630000100_agent_board_harness_kind_open_vocab.sql +15 -0
  44. package/migrations/20260710000000_agent_board_authbound_boundary.sql +155 -0
  45. package/migrations/20260710000100_agent_board_schema_version_rpc.sql +14 -0
  46. package/migrations/20260710000400_agent_board_nonfleet_identity.sql +87 -0
  47. package/migrations/20260710000401_agent_board_workload_providers.sql +39 -0
  48. package/migrations/20260711000000_agent_board_provision_system_fail_closed.sql +242 -0
  49. package/migrations/20260711000100_canary_signed_fleet_enforcement.sql +234 -0
  50. package/migrations/20260712000000_agent_board_bundle_endpoint_compat.sql +97 -0
  51. package/migrations/20260713000000_agent_board_rls_reassert_board_scoping.sql +90 -0
  52. package/package.json +42 -0
  53. package/provenance.json +580 -0
  54. package/schema-manifest.json +458 -0
  55. package/src/check.js +23 -0
  56. package/src/index.js +50 -0
  57. package/src/materialize.js +73 -0
  58. package/src/plan.js +44 -0
  59. package/src/tooling.test.mjs +97 -0
  60. package/tests/agent_board_addressing.test.sql +166 -0
  61. package/tests/agent_board_auth_rls.test.sql +243 -0
  62. package/tests/agent_board_auth_rls_id_qualification.test.sql +225 -0
  63. package/tests/agent_board_auth_rpcs.test.sql +311 -0
  64. package/tests/agent_board_auth_schema.test.sql +411 -0
  65. package/tests/agent_board_authbound_boundary.test.sql +148 -0
  66. package/tests/agent_board_boardopt.test.sql +170 -0
  67. package/tests/agent_board_bundle_endpoint_compat.test.sql +49 -0
  68. package/tests/agent_board_callback_runtime.test.sql +425 -0
  69. package/tests/agent_board_callbackcap.test.sql +222 -0
  70. package/tests/agent_board_canary_signed_fleet_enforcement.test.sql +60 -0
  71. package/tests/agent_board_dblint_rpcs.test.sql +247 -0
  72. package/tests/agent_board_fleet_policy.test.sql +370 -0
  73. package/tests/agent_board_fleet_read_models.test.sql +158 -0
  74. package/tests/agent_board_fleet_registry.test.sql +149 -0
  75. package/tests/agent_board_inbox_reads.test.sql +471 -0
  76. package/tests/agent_board_inbox_rpcs.test.sql +452 -0
  77. package/tests/agent_board_inbox_schema.test.sql +355 -0
  78. package/tests/agent_board_nonfleet_identity.test.sql +26 -0
  79. package/tests/agent_board_rls_reassert_board_scoping.test.sql +39 -0
  80. package/tests/agent_board_schema_version.test.sql +24 -0
  81. package/tests/agent_board_schema_version_rpc.test.sql +40 -0
  82. package/tests/agent_board_signature_rls_reads.test.sql +133 -0
  83. package/tests/agent_board_signed_write_gateway.test.sql +219 -0
  84. package/tests/agent_board_signing_proof_rpcs.test.sql +143 -0
  85. package/tests/agent_board_signing_store.test.sql +183 -0
  86. package/tests/agent_board_smoke.test.sql +12 -0
  87. package/tests/agent_board_v1_invariants.test.sql +298 -0
  88. package/tests/agent_board_v2_invariants.test.sql +753 -0
  89. package/tests/agent_board_workload_providers.test.sql +15 -0
  90. package/tests/fixtures/adopter-base.sql +19 -0
  91. package/tests/fixtures/operator-hardening.sql +27 -0
  92. package/tests/fixtures/test-prereqs.sql +84 -0
@@ -0,0 +1,370 @@
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(15);
7
+
8
+ select has_function('agent_board', 'register_fleet_machine', array['uuid', 'uuid', 'text', 'text', 'text', 'jsonb'], 'register_fleet_machine exists');
9
+ select has_function('agent_board', 'set_fleet_receive_policy', array['uuid', 'text', 'text', 'boolean', 'uuid', 'uuid', 'jsonb'], 'set_fleet_receive_policy exists');
10
+ select has_function('agent_board', 'evaluate_fleet_sender_policy', array['uuid', 'uuid', 'uuid', 'uuid', 'text', 'uuid', 'boolean'], 'evaluate_fleet_sender_policy exists');
11
+ select has_function('agent_board', 'revoke_fleet_subject', array['text', 'uuid', 'uuid', 'text', 'jsonb'], 'revoke_fleet_subject exists');
12
+
13
+ create temp table _fleet_policy_fixture (
14
+ sender uuid,
15
+ recipient uuid,
16
+ external_sender uuid,
17
+ revoked_sender uuid,
18
+ revoked_key_sender uuid,
19
+ tailnet_domain uuid,
20
+ regenesis_domain uuid,
21
+ brother_domain uuid,
22
+ external_domain uuid,
23
+ sender_machine uuid,
24
+ external_machine uuid,
25
+ revoked_machine uuid,
26
+ revoked_key_machine uuid,
27
+ receive_policy uuid,
28
+ signed_evidence uuid,
29
+ revoked_key_evidence uuid,
30
+ signing_key uuid,
31
+ revoked_signing_key uuid
32
+ ) on commit drop;
33
+
34
+ grant all on table _fleet_policy_fixture to authenticated, service_role;
35
+
36
+ do $$
37
+ declare
38
+ v_sender uuid := gen_random_uuid();
39
+ v_recipient uuid := gen_random_uuid();
40
+ v_external_sender uuid := gen_random_uuid();
41
+ v_revoked_sender uuid := gen_random_uuid();
42
+ v_revoked_key_sender uuid := gen_random_uuid();
43
+ v_tailnet_domain uuid;
44
+ v_regenesis_domain uuid;
45
+ v_brother_domain uuid;
46
+ v_external_domain uuid;
47
+ v_sender_machine uuid;
48
+ v_external_machine uuid;
49
+ v_revoked_machine uuid;
50
+ v_revoked_key_machine uuid;
51
+ v_policy uuid;
52
+ v_signing_key uuid;
53
+ v_revoked_signing_key uuid;
54
+ v_signed_evidence uuid;
55
+ v_revoked_key_evidence uuid;
56
+ begin
57
+ insert into agent_board.agents(id, agent_type, handle, display_name)
58
+ values
59
+ (v_sender, 'agent', 'fleet-policy-tailnet-sender', 'Fleet Policy Tailnet Sender'),
60
+ (v_recipient, 'agent', 'fleet-policy-recipient', 'Fleet Policy Recipient'),
61
+ (v_external_sender, 'agent', 'fleet-policy-external-sender', 'Fleet Policy External Sender'),
62
+ (v_revoked_sender, 'agent', 'fleet-policy-revoked-sender', 'Fleet Policy Revoked Sender'),
63
+ (v_revoked_key_sender, 'agent', 'fleet-policy-key-sender', 'Fleet Policy Key Sender');
64
+
65
+ insert into agent_board.fleet_trust_domains(slug, display_name, domain_kind, owner_agent_id, lifecycle_state, approved_at, metadata)
66
+ values
67
+ ('fleet-policy-tailnet', 'Tailnet', 'tailnet', v_recipient, 'active', now(), '{"invitationState":"owner_approved"}'::jsonb),
68
+ ('fleet-policy-regenesis', 'ReGenesis', 'regenesis', v_recipient, 'active', now(), '{"invitationState":"invited"}'::jsonb),
69
+ ('fleet-policy-brother-mac', 'Brother Mac', 'development_mac', v_recipient, 'active', now(), '{"invitationState":"invited"}'::jsonb),
70
+ ('fleet-policy-external', 'External', 'external', v_recipient, 'active', now(), '{"invitationState":"untrusted"}'::jsonb);
71
+
72
+ select id into v_tailnet_domain from agent_board.fleet_trust_domains where slug = 'fleet-policy-tailnet';
73
+ select id into v_regenesis_domain from agent_board.fleet_trust_domains where slug = 'fleet-policy-regenesis';
74
+ select id into v_brother_domain from agent_board.fleet_trust_domains where slug = 'fleet-policy-brother-mac';
75
+ select id into v_external_domain from agent_board.fleet_trust_domains where slug = 'fleet-policy-external';
76
+
77
+ select machine_id
78
+ into v_sender_machine
79
+ from agent_board.register_fleet_machine(v_recipient, v_tailnet_domain, 'tailnet-claw', 'sha256:fleet-policy-tailnet-machine', 'portal', '{"redacted":true}'::jsonb);
80
+
81
+ select machine_id
82
+ into v_external_machine
83
+ from agent_board.register_fleet_machine(v_recipient, v_external_domain, 'external-runner', 'sha256:fleet-policy-external-machine', 'portal', '{"redacted":true}'::jsonb);
84
+
85
+ select machine_id
86
+ into v_revoked_machine
87
+ from agent_board.register_fleet_machine(v_recipient, v_tailnet_domain, 'revoked-runner', 'sha256:fleet-policy-revoked-machine', 'portal', '{"redacted":true}'::jsonb);
88
+
89
+ select machine_id
90
+ into v_revoked_key_machine
91
+ from agent_board.register_fleet_machine(v_recipient, v_tailnet_domain, 'key-runner', 'sha256:fleet-policy-key-machine', 'portal', '{"redacted":true}'::jsonb);
92
+
93
+ insert into agent_board.fleet_machine_agents(machine_id, agent_id, agent_role)
94
+ values
95
+ (v_sender_machine, v_sender, 'phase_worker'),
96
+ (v_external_machine, v_external_sender, 'phase_worker'),
97
+ (v_revoked_machine, v_revoked_sender, 'phase_worker'),
98
+ (v_revoked_key_machine, v_revoked_key_sender, 'phase_worker');
99
+
100
+ select receive_policy_id
101
+ into v_policy
102
+ from agent_board.set_fleet_receive_policy(v_recipient, 'deny by default signed', 'deny', true, null, null, '{"senderPolicy":"explicit_allowlist"}'::jsonb);
103
+
104
+ insert into agent_board.fleet_trust_sets(receive_policy_id, subject_kind, trust_domain_id, effect)
105
+ values
106
+ (v_policy, 'trust_domain', v_tailnet_domain, 'allow'),
107
+ (v_policy, 'trust_domain', v_regenesis_domain, 'allow'),
108
+ (v_policy, 'trust_domain', v_brother_domain, 'allow'),
109
+ (v_policy, 'trust_domain', v_external_domain, 'deny');
110
+
111
+ insert into agent_board.agent_signing_keys(agent_id, key_id, key_version, public_key, public_key_format, fingerprint, status, proof_state)
112
+ values
113
+ (v_sender, 'primary', 1, repeat('A', 43), 'raw_ed25519_base64url', 'sha256:' || repeat('A', 43), 'active', 'proven'),
114
+ (v_revoked_key_sender, 'revoked', 1, repeat('B', 43), 'raw_ed25519_base64url', 'sha256:' || repeat('B', 43), 'active', 'proven');
115
+
116
+ select id into v_signing_key from agent_board.agent_signing_keys where agent_id = v_sender;
117
+ select id into v_revoked_signing_key from agent_board.agent_signing_keys where agent_id = v_revoked_key_sender;
118
+
119
+ insert into agent_board.signature_evidence(agent_id, signing_key_id, key_id, key_version, source_kind, external_evidence_ref, operation, payload_digest, verification_status, verified_at)
120
+ values
121
+ (v_sender, v_signing_key, 'primary', 1, 'external', 'fleet-policy:signed', 'send_direct_message', 'sha256:' || repeat('c', 64), 'verified', now()),
122
+ (v_revoked_key_sender, v_revoked_signing_key, 'revoked', 1, 'external', 'fleet-policy:revoked-key', 'send_direct_message', 'sha256:' || repeat('d', 64), 'verified', now());
123
+
124
+ select id into v_signed_evidence from agent_board.signature_evidence where agent_id = v_sender;
125
+ select id into v_revoked_key_evidence from agent_board.signature_evidence where agent_id = v_revoked_key_sender;
126
+
127
+ perform agent_board.revoke_fleet_subject('machine', v_revoked_machine, v_recipient, 'revoked by policy test', '{"redacted":true}'::jsonb);
128
+ perform agent_board.revoke_fleet_subject('signing_key', v_revoked_signing_key, v_recipient, 'revoked key by policy test', '{"redacted":true}'::jsonb);
129
+
130
+ insert into _fleet_policy_fixture values (
131
+ v_sender,
132
+ v_recipient,
133
+ v_external_sender,
134
+ v_revoked_sender,
135
+ v_revoked_key_sender,
136
+ v_tailnet_domain,
137
+ v_regenesis_domain,
138
+ v_brother_domain,
139
+ v_external_domain,
140
+ v_sender_machine,
141
+ v_external_machine,
142
+ v_revoked_machine,
143
+ v_revoked_key_machine,
144
+ v_policy,
145
+ v_signed_evidence,
146
+ v_revoked_key_evidence,
147
+ v_signing_key,
148
+ v_revoked_signing_key
149
+ );
150
+ end
151
+ $$;
152
+
153
+ create temp table _fleet_direct_rpc_fixture (
154
+ actor_user_id uuid
155
+ ) on commit drop;
156
+
157
+ grant all on table _fleet_direct_rpc_fixture to authenticated, service_role;
158
+
159
+ do $$
160
+ declare
161
+ v_user_id uuid;
162
+ v_suffix text := replace(substr(gen_random_uuid()::text, 1, 8), '-', '');
163
+ begin
164
+ v_user_id := public.ensure_github_user(
165
+ 'fleet-direct-rpc-' || v_suffix,
166
+ 'fleet-direct-rpc-' || v_suffix || '@example.test',
167
+ 'fleet-direct-rpc-' || v_suffix,
168
+ 'Fleet Direct RPC ' || v_suffix
169
+ );
170
+
171
+ update agent_board.agents
172
+ set auth_user_id = v_user_id
173
+ where id = (select sender from _fleet_policy_fixture);
174
+
175
+ insert into _fleet_direct_rpc_fixture(actor_user_id)
176
+ values (v_user_id);
177
+ end
178
+ $$;
179
+
180
+ set local role authenticated;
181
+ select set_config('request.jwt.claim.role', 'authenticated', true);
182
+ select set_config('request.jwt.claim.sub', (select actor_user_id::text from _fleet_direct_rpc_fixture), true);
183
+
184
+ do $$
185
+ begin
186
+ begin
187
+ perform *
188
+ from agent_board.register_fleet_machine(
189
+ (select recipient from _fleet_policy_fixture),
190
+ (select external_domain from _fleet_policy_fixture),
191
+ 'impersonated-machine',
192
+ 'sha256:fleet-policy-impersonated-machine',
193
+ 'portal',
194
+ '{"redacted":true}'::jsonb
195
+ );
196
+ raise exception 'authenticated register_fleet_machine impersonation unexpectedly succeeded';
197
+ exception
198
+ when sqlstate '42501' then null;
199
+ end;
200
+
201
+ begin
202
+ perform *
203
+ from agent_board.set_fleet_receive_policy(
204
+ (select recipient from _fleet_policy_fixture),
205
+ 'impersonated receive policy',
206
+ 'allow',
207
+ false,
208
+ null,
209
+ null,
210
+ '{"redacted":true}'::jsonb
211
+ );
212
+ raise exception 'authenticated set_fleet_receive_policy impersonation unexpectedly succeeded';
213
+ exception
214
+ when sqlstate '42501' then null;
215
+ end;
216
+
217
+ begin
218
+ perform *
219
+ from agent_board.revoke_fleet_subject(
220
+ 'machine',
221
+ (select external_machine from _fleet_policy_fixture),
222
+ (select recipient from _fleet_policy_fixture),
223
+ 'impersonated revocation',
224
+ '{"redacted":true}'::jsonb
225
+ );
226
+ raise exception 'authenticated revoke_fleet_subject impersonation unexpectedly succeeded';
227
+ exception
228
+ when sqlstate '42501' then null;
229
+ end;
230
+ end
231
+ $$;
232
+
233
+ select pass('authenticated fleet RPC impersonation checks are denied');
234
+
235
+ reset role;
236
+ select set_config('request.jwt.claim.role', '', true);
237
+ select set_config('request.jwt.claim.sub', '', true);
238
+
239
+ select is(
240
+ (select allowed from agent_board.evaluate_fleet_sender_policy(
241
+ (select sender from _fleet_policy_fixture),
242
+ (select recipient from _fleet_policy_fixture),
243
+ (select sender_machine from _fleet_policy_fixture),
244
+ null,
245
+ 'send_direct_message',
246
+ (select signed_evidence from _fleet_policy_fixture),
247
+ false
248
+ )),
249
+ true,
250
+ 'Tailnet same-domain sender is allowed with signed evidence'
251
+ );
252
+
253
+ select is(
254
+ (select denial_class from agent_board.evaluate_fleet_sender_policy(
255
+ (select external_sender from _fleet_policy_fixture),
256
+ (select recipient from _fleet_policy_fixture),
257
+ (select external_machine from _fleet_policy_fixture),
258
+ null,
259
+ 'send_direct_message',
260
+ null,
261
+ false
262
+ )),
263
+ 'signature_required',
264
+ 'unsigned external sender is denied before trust-set allow'
265
+ );
266
+
267
+ select is(
268
+ (select denial_class from agent_board.evaluate_fleet_sender_policy(
269
+ (select external_sender from _fleet_policy_fixture),
270
+ (select recipient from _fleet_policy_fixture),
271
+ (select external_machine from _fleet_policy_fixture),
272
+ null,
273
+ 'send_direct_message',
274
+ (select signed_evidence from _fleet_policy_fixture),
275
+ false
276
+ )),
277
+ 'signature_required',
278
+ 'signature evidence must belong to the sender'
279
+ );
280
+
281
+ select is(
282
+ (select denial_class from agent_board.evaluate_fleet_sender_policy(
283
+ (select revoked_sender from _fleet_policy_fixture),
284
+ (select recipient from _fleet_policy_fixture),
285
+ (select revoked_machine from _fleet_policy_fixture),
286
+ null,
287
+ 'send_direct_message',
288
+ null,
289
+ false
290
+ )),
291
+ 'machine_revoked',
292
+ 'revoked machine is denied'
293
+ );
294
+
295
+ select is(
296
+ (select denial_class from agent_board.evaluate_fleet_sender_policy(
297
+ (select revoked_key_sender from _fleet_policy_fixture),
298
+ (select recipient from _fleet_policy_fixture),
299
+ (select revoked_key_machine from _fleet_policy_fixture),
300
+ null,
301
+ 'send_direct_message',
302
+ (select revoked_key_evidence from _fleet_policy_fixture),
303
+ false
304
+ )),
305
+ 'key_revoked',
306
+ 'revoked signing key is denied'
307
+ );
308
+
309
+ select is(
310
+ (select denial_class from agent_board.evaluate_fleet_sender_policy(
311
+ (select sender from _fleet_policy_fixture),
312
+ (select recipient from _fleet_policy_fixture),
313
+ gen_random_uuid(),
314
+ null,
315
+ 'send_direct_message',
316
+ (select signed_evidence from _fleet_policy_fixture),
317
+ false
318
+ )),
319
+ 'domain_denied',
320
+ 'unknown machine is denied'
321
+ );
322
+
323
+ select is(
324
+ (select allowed from agent_board.evaluate_fleet_sender_policy(
325
+ (select sender from _fleet_policy_fixture),
326
+ (select recipient from _fleet_policy_fixture),
327
+ (select sender_machine from _fleet_policy_fixture),
328
+ null,
329
+ 'send_direct_message',
330
+ (select signed_evidence from _fleet_policy_fixture),
331
+ true
332
+ )),
333
+ true,
334
+ 'direct-RPC compatibility still requires machine and signature checks'
335
+ );
336
+
337
+ select ok(
338
+ exists (
339
+ select 1
340
+ from agent_board.fleet_trust_sets fts
341
+ where fts.receive_policy_id = (select receive_policy from _fleet_policy_fixture)
342
+ and fts.trust_domain_id = (select regenesis_domain from _fleet_policy_fixture)
343
+ and fts.effect = 'allow'
344
+ ),
345
+ 'ReGenesis cross-domain allow trust set is present'
346
+ );
347
+
348
+ select ok(
349
+ exists (
350
+ select 1
351
+ from agent_board.fleet_trust_sets fts
352
+ where fts.receive_policy_id = (select receive_policy from _fleet_policy_fixture)
353
+ and fts.trust_domain_id = (select brother_domain from _fleet_policy_fixture)
354
+ and fts.effect = 'allow'
355
+ ),
356
+ 'brother-Mac invitation allow trust set is present'
357
+ );
358
+
359
+ select ok(
360
+ not exists (
361
+ select 1
362
+ from agent_board.fleet_revocation_events
363
+ where metadata::text ~* '(private key|service-role|secret|raw signature|provider payload|local env)'
364
+ ),
365
+ 'fleet policy revocation evidence stays metadata-safe'
366
+ );
367
+
368
+ select finish();
369
+
370
+ rollback;
@@ -0,0 +1,158 @@
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(27);
7
+
8
+ select has_view('agent_board', 'v_fleet_machine_status', 'fleet machine status view exists');
9
+ select has_view('agent_board', 'v_fleet_receive_policy_status', 'fleet receive policy status view exists');
10
+ select has_view('agent_board', 'v_fleet_delivery_posture', 'fleet delivery posture view exists');
11
+
12
+ select has_column('agent_board', 'v_fleet_machine_status', 'machine_id', 'machine status exposes machine id');
13
+ select has_column('agent_board', 'v_fleet_machine_status', 'owner_agent_id', 'machine status exposes owner agent');
14
+ select has_column('agent_board', 'v_fleet_machine_status', 'trust_domain_slug', 'machine status exposes trust-domain slug');
15
+ select has_column('agent_board', 'v_fleet_machine_status', 'machine_fingerprint', 'machine status exposes metadata-safe fingerprint');
16
+ select has_column('agent_board', 'v_fleet_machine_status', 'machine_lifecycle_state', 'machine status exposes lifecycle');
17
+ select has_column('agent_board', 'v_fleet_machine_status', 'active_agent_count', 'machine status exposes active agent count');
18
+
19
+ select has_column('agent_board', 'v_fleet_receive_policy_status', 'receive_policy_id', 'policy status exposes policy id');
20
+ select has_column('agent_board', 'v_fleet_receive_policy_status', 'default_action', 'policy status exposes default action');
21
+ select has_column('agent_board', 'v_fleet_receive_policy_status', 'require_signed_sender', 'policy status exposes signed-sender requirement');
22
+ select has_column('agent_board', 'v_fleet_receive_policy_status', 'allow_trust_set_count', 'policy status exposes allow trust-set count');
23
+ select has_column('agent_board', 'v_fleet_receive_policy_status', 'restrictive_trust_set_count', 'policy status exposes restrictive trust-set count');
24
+
25
+ select has_column('agent_board', 'v_fleet_delivery_posture', 'delivery_recipient_id', 'delivery posture exposes delivery recipient id');
26
+ select has_column('agent_board', 'v_fleet_delivery_posture', 'sender_agent_id', 'delivery posture exposes sender agent id');
27
+ select has_column('agent_board', 'v_fleet_delivery_posture', 'receive_policy_id', 'delivery posture exposes receive policy id');
28
+ select has_column('agent_board', 'v_fleet_delivery_posture', 'denial_class', 'delivery posture exposes denial class');
29
+ select has_column('agent_board', 'v_fleet_delivery_posture', 'allowed', 'delivery posture exposes allowed flag');
30
+ select has_column('agent_board', 'v_fleet_delivery_posture', 'actionable', 'delivery posture exposes actionable flag');
31
+ select has_column('agent_board', 'v_fleet_delivery_posture', 'key_fingerprint', 'delivery posture exposes key fingerprint');
32
+ select has_column('agent_board', 'v_fleet_delivery_posture', 'fetch_descriptor', 'delivery posture exposes bounded fetch descriptor');
33
+
34
+ select ok(
35
+ not exists (
36
+ select 1
37
+ from information_schema.columns
38
+ where table_schema = 'agent_board'
39
+ and table_name in ('v_fleet_machine_status', 'v_fleet_receive_policy_status', 'v_fleet_delivery_posture')
40
+ and column_name ~* '(private_key|service_role|secret|token|raw_signature|provider_payload|local_env|body)'
41
+ ),
42
+ 'fleet read models do not project raw secret, provider, local env, signature, token, or body columns'
43
+ );
44
+
45
+ do $$
46
+ declare
47
+ v_sender uuid := gen_random_uuid();
48
+ v_recipient uuid := gen_random_uuid();
49
+ v_thread uuid := gen_random_uuid();
50
+ v_message uuid := gen_random_uuid();
51
+ v_delivery uuid := gen_random_uuid();
52
+ v_inbox uuid := gen_random_uuid();
53
+ v_domain uuid;
54
+ v_machine uuid;
55
+ v_policy uuid;
56
+ begin
57
+ insert into agent_board.agents(id, agent_type, handle, display_name)
58
+ values
59
+ (v_sender, 'agent', 'fleet-read-sender', 'Fleet Read Sender'),
60
+ (v_recipient, 'agent', 'fleet-read-recipient', 'Fleet Read Recipient');
61
+
62
+ insert into agent_board.threads(id, created_by_agent_id, subject)
63
+ values (v_thread, v_sender, 'Fleet read model thread');
64
+
65
+ insert into agent_board.messages(id, thread_id, author_agent_id, message_sequence, body)
66
+ values (v_message, v_thread, v_sender, 1, 'metadata safe message body not projected');
67
+
68
+ insert into agent_board.delivery_recipients(id, delivery_mode, recipient_agent_id, source_kind, source_message_id)
69
+ values (v_delivery, 'direct', v_recipient, 'message', v_message);
70
+
71
+ insert into agent_board.inbox_items(
72
+ id,
73
+ delivery_recipient_id,
74
+ recipient_agent_id,
75
+ delivery_mode,
76
+ source_kind,
77
+ source_message_id,
78
+ subject,
79
+ preview,
80
+ fetch_descriptor
81
+ )
82
+ values (
83
+ v_inbox,
84
+ v_delivery,
85
+ v_recipient,
86
+ 'direct',
87
+ 'message',
88
+ v_message,
89
+ 'Fleet read',
90
+ 'bounded preview',
91
+ jsonb_build_object('view', 'agent_board.v_thread_feed', 'filters', jsonb_build_object('thread_id', v_thread), 'reason', 'fleet read model test')
92
+ );
93
+
94
+ insert into agent_board.fleet_trust_domains(slug, display_name, domain_kind, owner_agent_id, lifecycle_state, approved_at)
95
+ values ('fleet-read-tailnet', 'Fleet Read Tailnet', 'tailnet', v_recipient, 'active', now())
96
+ returning id into v_domain;
97
+
98
+ select machine_id
99
+ into v_machine
100
+ from agent_board.register_fleet_machine(v_recipient, v_domain, 'fleet-read-machine', 'sha256:fleet-read-machine', 'portal', '{"redacted":true}'::jsonb);
101
+
102
+ insert into agent_board.fleet_machine_agents(machine_id, agent_id, agent_role)
103
+ values (v_machine, v_sender, 'phase_worker');
104
+
105
+ select receive_policy_id
106
+ into v_policy
107
+ from agent_board.set_fleet_receive_policy(v_recipient, 'fleet read allow', 'deny', false, null, null, '{"redacted":true}'::jsonb);
108
+
109
+ insert into agent_board.fleet_trust_sets(receive_policy_id, subject_kind, trust_domain_id, effect)
110
+ values (v_policy, 'trust_domain', v_domain, 'allow');
111
+ end
112
+ $$;
113
+
114
+ select ok(
115
+ exists (
116
+ select 1
117
+ from agent_board.v_fleet_machine_status
118
+ where machine_label = 'fleet-read-machine'
119
+ and active_agent_count = 1
120
+ ),
121
+ 'machine status view reports active machine-agent bindings'
122
+ );
123
+
124
+ select ok(
125
+ exists (
126
+ select 1
127
+ from agent_board.v_fleet_receive_policy_status
128
+ where policy_name = 'fleet read allow'
129
+ and allow_trust_set_count = 1
130
+ and restrictive_trust_set_count = 0
131
+ ),
132
+ 'receive policy status counts allow and restrictive trust sets'
133
+ );
134
+
135
+ select ok(
136
+ exists (
137
+ select 1
138
+ from agent_board.v_fleet_delivery_posture
139
+ where allowed = true
140
+ and actionable = true
141
+ and denial_class is null
142
+ and fetch_descriptor ->> 'view' = 'agent_board.v_thread_feed'
143
+ ),
144
+ 'delivery posture view exposes metadata-safe actionable posture'
145
+ );
146
+
147
+ select ok(
148
+ not exists (
149
+ select 1
150
+ from agent_board.v_fleet_delivery_posture
151
+ where coalesce(fetch_descriptor::text, '') ~* '(private key|service-role|secret|raw signature|provider payload|local env)'
152
+ ),
153
+ 'delivery posture fetch descriptors stay metadata-safe'
154
+ );
155
+
156
+ select finish();
157
+
158
+ rollback;
@@ -0,0 +1,149 @@
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(35);
7
+
8
+ select has_table('agent_board', 'fleet_trust_domains', 'fleet_trust_domains table exists');
9
+ select has_table('agent_board', 'fleet_machines', 'fleet_machines table exists');
10
+ select has_table('agent_board', 'fleet_harness_registrations', 'fleet_harness_registrations table exists');
11
+ select has_table('agent_board', 'fleet_repo_scopes', 'fleet_repo_scopes table exists');
12
+ select has_table('agent_board', 'fleet_machine_agents', 'fleet_machine_agents table exists');
13
+ select has_table('agent_board', 'fleet_receive_policies', 'fleet_receive_policies table exists');
14
+ select has_table('agent_board', 'fleet_trust_sets', 'fleet_trust_sets table exists');
15
+ select has_table('agent_board', 'fleet_revocation_events', 'fleet_revocation_events table exists');
16
+
17
+ select has_column('agent_board', 'fleet_trust_domains', 'domain_kind', 'trust domains expose domain kind');
18
+ select has_column('agent_board', 'fleet_trust_domains', 'owner_agent_id', 'trust domains are owner scoped');
19
+ select has_column('agent_board', 'fleet_machines', 'machine_fingerprint', 'machines store metadata-safe fingerprint');
20
+ select has_column('agent_board', 'fleet_machines', 'enrollment_source', 'machines store enrollment source');
21
+ select has_column('agent_board', 'fleet_harness_registrations', 'harness_kind', 'harness registrations store harness kind');
22
+ select has_column('agent_board', 'fleet_repo_scopes', 'repo_fingerprint', 'repo scopes store metadata-safe repo fingerprint');
23
+ select has_column('agent_board', 'fleet_machine_agents', 'signing_key_id', 'machine-agent links can bind signing keys');
24
+ select has_column('agent_board', 'fleet_receive_policies', 'require_signed_sender', 'receive policies can require signed senders');
25
+ select has_column('agent_board', 'fleet_trust_sets', 'effect', 'trust sets expose policy effect');
26
+ select has_column('agent_board', 'fleet_revocation_events', 'subject_kind', 'revocation events expose subject kind');
27
+
28
+ select col_has_check('agent_board', 'fleet_trust_domains', 'domain_kind', 'domain kind is constrained');
29
+ select col_has_check('agent_board', 'fleet_machines', 'lifecycle_state', 'machine lifecycle state is constrained');
30
+ select col_has_check('agent_board', 'fleet_receive_policies', 'default_action', 'receive policy default action is constrained');
31
+ select col_has_check('agent_board', 'fleet_trust_sets', 'effect', 'trust set effect is constrained');
32
+ select col_has_check('agent_board', 'fleet_revocation_events', 'subject_kind', 'revocation subject kind is constrained');
33
+
34
+ select has_index('agent_board', 'fleet_machines', 'idx_agent_board_fleet_machines_fingerprint_unique', 'machine fingerprint is unique');
35
+ select has_index('agent_board', 'fleet_revocation_events', 'idx_agent_board_fleet_revocation_subject_unique', 'revocations are idempotent per subject');
36
+
37
+ select fk_ok('agent_board', 'fleet_machines', 'trust_domain_id', 'agent_board', 'fleet_trust_domains', 'id', 'machines reference trust domains');
38
+ select fk_ok('agent_board', 'fleet_machine_agents', 'agent_id', 'agent_board', 'agents', 'id', 'machine-agent links reference agents');
39
+ select fk_ok('agent_board', 'fleet_machine_agents', 'signing_key_id', 'agent_board', 'agent_signing_keys', 'id', 'machine-agent links reference signing keys');
40
+ select fk_ok('agent_board', 'fleet_receive_policies', 'recipient_agent_id', 'agent_board', 'agents', 'id', 'receive policies reference recipient agents');
41
+
42
+ select ok(
43
+ exists (select 1 from agent_board.schema_version where version = 7),
44
+ 'schema_version advanced to fleet store version 7'
45
+ );
46
+
47
+ select ok(
48
+ not exists (
49
+ select 1
50
+ from information_schema.columns
51
+ where table_schema = 'agent_board'
52
+ and table_name in (
53
+ 'fleet_trust_domains',
54
+ 'fleet_machines',
55
+ 'fleet_harness_registrations',
56
+ 'fleet_repo_scopes',
57
+ 'fleet_machine_agents',
58
+ 'fleet_receive_policies',
59
+ 'fleet_trust_sets',
60
+ 'fleet_revocation_events'
61
+ )
62
+ and column_name ~* '(private_key|service_role|secret|token|raw_signature|provider_payload|local_env|host_inventory)'
63
+ ),
64
+ 'fleet registry tables do not expose secret or raw inventory columns'
65
+ );
66
+
67
+ do $$
68
+ declare
69
+ v_owner uuid := gen_random_uuid();
70
+ v_domain uuid;
71
+ v_machine uuid;
72
+ v_harness uuid;
73
+ v_repo_scope uuid;
74
+ v_policy uuid;
75
+ begin
76
+ insert into agent_board.agents(id, agent_type, handle, display_name)
77
+ values (v_owner, 'agent', 'fleet-registry-owner', 'Fleet Registry Owner');
78
+
79
+ insert into agent_board.fleet_trust_domains(slug, display_name, domain_kind, owner_agent_id, lifecycle_state, approved_at)
80
+ values ('fleet-registry-tailnet', 'Fleet Registry Tailnet', 'tailnet', v_owner, 'active', now())
81
+ returning id into v_domain;
82
+
83
+ insert into agent_board.fleet_machines(trust_domain_id, owner_agent_id, machine_label, machine_fingerprint, lifecycle_state, enrollment_source, enrolled_at)
84
+ values (v_domain, v_owner, 'claw', 'sha256:fleet-registry-machine', 'active', 'portal', now())
85
+ returning id into v_machine;
86
+
87
+ insert into agent_board.fleet_harness_registrations(machine_id, harness_kind, harness_label)
88
+ values (v_machine, 'codex', 'phase-loop command')
89
+ returning id into v_harness;
90
+
91
+ insert into agent_board.fleet_repo_scopes(harness_registration_id, repo_slug, repo_fingerprint, scope_role)
92
+ values (v_harness, 'consiliency-portal', 'sha256:fleet-registry-repo', 'worker')
93
+ returning id into v_repo_scope;
94
+
95
+ insert into agent_board.fleet_machine_agents(machine_id, agent_id, repo_scope_id, agent_role)
96
+ values (v_machine, v_owner, v_repo_scope, 'phase_worker');
97
+
98
+ insert into agent_board.fleet_receive_policies(recipient_agent_id, policy_name, default_action, require_signed_sender)
99
+ values (v_owner, 'registry smoke', 'deny', true)
100
+ returning id into v_policy;
101
+
102
+ insert into agent_board.fleet_trust_sets(receive_policy_id, subject_kind, trust_domain_id, effect)
103
+ values (v_policy, 'trust_domain', v_domain, 'allow');
104
+
105
+ insert into agent_board.fleet_revocation_events(subject_kind, subject_id, machine_id, revoked_by_agent_id, revocation_reason)
106
+ values ('machine', v_machine, v_machine, v_owner, 'registry smoke');
107
+ end
108
+ $$;
109
+
110
+ select pass('fleet registry tables accept metadata-safe linked rows');
111
+
112
+ select lives_ok(
113
+ $$
114
+ insert into agent_board.fleet_harness_registrations(machine_id, harness_kind, harness_label)
115
+ values (
116
+ (select id from agent_board.fleet_machines where machine_fingerprint = 'sha256:fleet-registry-machine'),
117
+ 'pi',
118
+ 'pi command'
119
+ )
120
+ $$,
121
+ 'fleet harness registrations accept valid open harness descriptors'
122
+ );
123
+
124
+ select throws_ok(
125
+ $$
126
+ insert into agent_board.fleet_harness_registrations(machine_id, harness_kind, harness_label)
127
+ values (
128
+ (select id from agent_board.fleet_machines where machine_fingerprint = 'sha256:fleet-registry-machine'),
129
+ 'Claude Code',
130
+ 'malformed command'
131
+ )
132
+ $$,
133
+ '23514',
134
+ NULL,
135
+ 'fleet harness registrations reject malformed harness descriptors'
136
+ );
137
+
138
+ select ok(
139
+ not exists (
140
+ select 1
141
+ from agent_board.fleet_machines
142
+ where metadata::text ~* '(private key|service-role|secret|raw signature|provider payload|local env)'
143
+ ),
144
+ 'fleet registry metadata stays metadata-safe'
145
+ );
146
+
147
+ select finish();
148
+
149
+ rollback;