@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,288 @@
1
+ create or replace function agent_board.reserve_signed_write_replay(
2
+ p_agent_id uuid,
3
+ p_signing_key_id uuid,
4
+ p_operation text,
5
+ p_payload_digest text,
6
+ p_nonce text default null,
7
+ p_idempotency_key text default null,
8
+ p_envelope_timestamp timestamptz default now(),
9
+ p_expires_at timestamptz default now() + interval '10 minutes'
10
+ )
11
+ returns table(replay_status text)
12
+ language plpgsql
13
+ security definer
14
+ set search_path = agent_board, public
15
+ as $$
16
+ begin
17
+ if (p_nonce is null and p_idempotency_key is null) or (p_nonce is not null and p_idempotency_key is not null) then
18
+ raise exception 'signed_write replay requires exactly one nonce or idempotency key' using errcode = '22023';
19
+ end if;
20
+
21
+ insert into agent_board.signature_replay_state(
22
+ agent_id,
23
+ signing_key_id,
24
+ operation,
25
+ payload_digest,
26
+ nonce,
27
+ idempotency_key,
28
+ envelope_timestamp,
29
+ expires_at,
30
+ replay_status
31
+ )
32
+ values (
33
+ p_agent_id,
34
+ p_signing_key_id,
35
+ p_operation,
36
+ p_payload_digest,
37
+ p_nonce,
38
+ p_idempotency_key,
39
+ p_envelope_timestamp,
40
+ p_expires_at,
41
+ 'consumed'
42
+ );
43
+
44
+ return query select 'reserved'::text;
45
+ exception
46
+ when unique_violation then
47
+ if p_idempotency_key is not null and exists (
48
+ select 1
49
+ from agent_board.signature_replay_state srs
50
+ where srs.agent_id = p_agent_id
51
+ and srs.operation = p_operation
52
+ and srs.idempotency_key = p_idempotency_key
53
+ and srs.payload_digest <> p_payload_digest
54
+ ) then
55
+ raise exception 'idempotency_conflict: signed write idempotency key reused with different payload digest' using errcode = '23505';
56
+ end if;
57
+ raise exception 'nonce_replay: signed write replay token already consumed' using errcode = '23505';
58
+ end;
59
+ $$;
60
+
61
+ create or replace function agent_board._signed_write_actor_id(
62
+ p_payload jsonb,
63
+ p_gateway_decision jsonb,
64
+ p_actor_field text
65
+ )
66
+ returns uuid
67
+ language plpgsql
68
+ security definer
69
+ set search_path = agent_board, public
70
+ as $$
71
+ declare
72
+ v_actor uuid;
73
+ begin
74
+ v_actor := nullif(p_gateway_decision ->> 'agent_id', '')::uuid;
75
+ if v_actor is null then
76
+ v_actor := nullif(p_payload ->> p_actor_field, '')::uuid;
77
+ end if;
78
+ if v_actor is null then
79
+ raise exception 'actor_mismatch: signed write actor is required' using errcode = '42501';
80
+ end if;
81
+ return v_actor;
82
+ end;
83
+ $$;
84
+
85
+ create or replace function agent_board._record_signed_write_evidence(
86
+ p_source_kind text,
87
+ p_source_id uuid,
88
+ p_operation text,
89
+ p_payload jsonb,
90
+ p_gateway_decision jsonb
91
+ )
92
+ returns uuid
93
+ language plpgsql
94
+ security definer
95
+ set search_path = agent_board, public
96
+ as $$
97
+ declare
98
+ v_evidence_id uuid;
99
+ v_agent_id uuid := coalesce(nullif(p_gateway_decision ->> 'agent_id', '')::uuid, nullif(p_payload ->> 'p_author_agent_id', '')::uuid, nullif(p_payload ->> 'p_actor_agent_id', '')::uuid);
100
+ v_status text := coalesce(nullif(p_gateway_decision ->> 'verification_status', ''), 'unsigned');
101
+ begin
102
+ if v_status not in ('unsigned', 'observed', 'warn', 'verified', 'failed') then
103
+ v_status := 'failed';
104
+ end if;
105
+
106
+ insert into agent_board.signature_evidence(
107
+ agent_id,
108
+ signing_key_id,
109
+ key_id,
110
+ key_version,
111
+ algorithm,
112
+ source_kind,
113
+ source_message_id,
114
+ source_task_event_id,
115
+ operation,
116
+ payload_digest,
117
+ canonicalization_version,
118
+ signature_digest,
119
+ verification_status,
120
+ failure_class,
121
+ signed_at,
122
+ verified_at,
123
+ nonce,
124
+ idempotency_key,
125
+ external_evidence_ref,
126
+ metadata
127
+ )
128
+ values (
129
+ v_agent_id,
130
+ nullif(p_gateway_decision ->> 'signing_key_id', '')::uuid,
131
+ nullif(p_gateway_decision ->> 'key_id', ''),
132
+ nullif(p_gateway_decision ->> 'key_version', '')::integer,
133
+ coalesce(nullif(p_gateway_decision ->> 'algorithm', ''), 'Ed25519'),
134
+ p_source_kind,
135
+ case when p_source_kind = 'message' then p_source_id else null end,
136
+ case when p_source_kind = 'task_event' then p_source_id else null end,
137
+ p_operation,
138
+ coalesce(nullif(p_gateway_decision ->> 'payload_digest', ''), 'sha256:unsigned'),
139
+ coalesce(nullif(p_gateway_decision ->> 'canonicalization_version', ''), 'agent-provenance-jcs.v1'),
140
+ nullif(p_gateway_decision ->> 'signature_digest', ''),
141
+ v_status,
142
+ nullif(p_gateway_decision ->> 'failure_class', ''),
143
+ nullif(p_gateway_decision ->> 'signed_at', '')::timestamptz,
144
+ nullif(p_gateway_decision ->> 'verified_at', '')::timestamptz,
145
+ nullif(p_gateway_decision ->> 'nonce', ''),
146
+ nullif(p_gateway_decision ->> 'idempotency_key', ''),
147
+ nullif(p_gateway_decision ->> 'external_evidence_ref', ''),
148
+ jsonb_build_object(
149
+ 'gateway', 'signed-write',
150
+ 'enforcementMode', coalesce(p_gateway_decision ->> 'enforcement_mode', 'observe'),
151
+ 'redacted', true,
152
+ 'metadata-safe', true
153
+ )
154
+ )
155
+ returning id into v_evidence_id;
156
+
157
+ update agent_board.signature_replay_state
158
+ set signature_evidence_id = v_evidence_id
159
+ where agent_id = v_agent_id
160
+ and operation = p_operation
161
+ and (
162
+ (nonce is not null and nonce = nullif(p_gateway_decision ->> 'nonce', ''))
163
+ or (idempotency_key is not null and idempotency_key = nullif(p_gateway_decision ->> 'idempotency_key', ''))
164
+ );
165
+
166
+ return v_evidence_id;
167
+ end;
168
+ $$;
169
+
170
+ create or replace function agent_board.signed_send_direct_message(
171
+ p_payload jsonb,
172
+ p_gateway_decision jsonb
173
+ )
174
+ returns table(message_id uuid, delivery_recipient_id uuid, inbox_item_id uuid, callback_outbox_count integer, signature_evidence_id uuid, verification_status text, created_at timestamptz)
175
+ language plpgsql
176
+ security definer
177
+ set search_path = agent_board, public
178
+ as $$
179
+ declare
180
+ v_row record;
181
+ v_evidence_id uuid;
182
+ v_actor uuid;
183
+ begin
184
+ v_actor := agent_board._signed_write_actor_id(p_payload, p_gateway_decision, 'p_author_agent_id');
185
+ select *
186
+ into v_row
187
+ from agent_board.send_direct_message(
188
+ (p_payload ->> 'p_thread_id')::uuid,
189
+ v_actor,
190
+ (p_payload ->> 'p_recipient_agent_id')::uuid,
191
+ p_payload ->> 'p_subject',
192
+ p_payload ->> 'p_body',
193
+ coalesce(p_payload ->> 'p_message_type', 'comment'),
194
+ coalesce(p_payload ->> 'p_priority', 'medium'),
195
+ nullif(p_payload ->> 'p_idempotency_key', ''),
196
+ coalesce(p_payload -> 'p_metadata', '{}'::jsonb) || jsonb_build_object('signed_write', jsonb_build_object('verification_status', coalesce(p_gateway_decision ->> 'verification_status', 'unsigned'), 'redacted', true))
197
+ );
198
+
199
+ v_evidence_id := agent_board._record_signed_write_evidence('message', v_row.message_id, 'send_direct_message', p_payload, p_gateway_decision);
200
+
201
+ return query
202
+ select v_row.message_id, v_row.delivery_recipient_id, v_row.inbox_item_id, v_row.callback_outbox_count, v_evidence_id, coalesce(p_gateway_decision ->> 'verification_status', 'unsigned'), v_row.created_at;
203
+ end;
204
+ $$;
205
+
206
+ create or replace function agent_board.signed_append_task_event(
207
+ p_payload jsonb,
208
+ p_gateway_decision jsonb
209
+ )
210
+ returns table(task_id uuid, thread_id uuid, event_id uuid, event_sequence bigint, signature_evidence_id uuid, verification_status text, updated_at timestamptz)
211
+ language plpgsql
212
+ security definer
213
+ set search_path = agent_board, public
214
+ as $$
215
+ declare
216
+ v_row record;
217
+ v_evidence_id uuid;
218
+ v_actor uuid;
219
+ begin
220
+ v_actor := agent_board._signed_write_actor_id(p_payload, p_gateway_decision, 'p_actor_agent_id');
221
+ select *
222
+ into v_row
223
+ from agent_board.append_task_event(
224
+ (p_payload ->> 'p_task_id')::uuid,
225
+ v_actor,
226
+ p_payload ->> 'p_event_type',
227
+ coalesce(p_payload -> 'p_payload', '{}'::jsonb) || jsonb_build_object('signed_write', jsonb_build_object('verification_status', coalesce(p_gateway_decision ->> 'verification_status', 'unsigned'), 'redacted', true)),
228
+ nullif(p_payload ->> 'p_status', ''),
229
+ nullif(p_payload ->> 'p_assigned_agent_id', '')::uuid,
230
+ nullif(p_payload ->> 'p_completed_at', '')::timestamptz
231
+ );
232
+
233
+ v_evidence_id := agent_board._record_signed_write_evidence('task_event', v_row.event_id, 'append_task_event', p_payload, p_gateway_decision);
234
+
235
+ return query
236
+ select v_row.task_id, v_row.thread_id, v_row.event_id, v_row.event_sequence, v_evidence_id, coalesce(p_gateway_decision ->> 'verification_status', 'unsigned'), v_row.updated_at;
237
+ end;
238
+ $$;
239
+
240
+ create or replace function agent_board.signed_post_board_message(
241
+ p_payload jsonb,
242
+ p_gateway_decision jsonb
243
+ )
244
+ returns table(message_id uuid, board_id uuid, delivered_recipient_count integer, callback_outbox_count integer, signature_evidence_id uuid, verification_status text, created_at timestamptz)
245
+ language plpgsql
246
+ security definer
247
+ set search_path = agent_board, public
248
+ as $$
249
+ declare
250
+ v_row record;
251
+ v_evidence_id uuid;
252
+ v_actor uuid;
253
+ begin
254
+ v_actor := agent_board._signed_write_actor_id(p_payload, p_gateway_decision, 'p_author_agent_id');
255
+ select *
256
+ into v_row
257
+ from agent_board.post_board_message(
258
+ (p_payload ->> 'p_thread_id')::uuid,
259
+ v_actor,
260
+ (p_payload ->> 'p_board_id')::uuid,
261
+ p_payload ->> 'p_subject',
262
+ p_payload ->> 'p_body',
263
+ coalesce(p_payload ->> 'p_message_type', 'comment'),
264
+ coalesce(p_payload ->> 'p_priority', 'medium'),
265
+ nullif(p_payload ->> 'p_idempotency_key', ''),
266
+ coalesce(p_payload -> 'p_metadata', '{}'::jsonb) || jsonb_build_object('signed_write', jsonb_build_object('verification_status', coalesce(p_gateway_decision ->> 'verification_status', 'unsigned'), 'redacted', true))
267
+ );
268
+
269
+ v_evidence_id := agent_board._record_signed_write_evidence('message', v_row.message_id, 'post_board_message', p_payload, p_gateway_decision);
270
+
271
+ return query
272
+ select v_row.message_id, v_row.board_id, v_row.delivered_recipient_count, v_row.callback_outbox_count, v_evidence_id, coalesce(p_gateway_decision ->> 'verification_status', 'unsigned'), v_row.created_at;
273
+ end;
274
+ $$;
275
+
276
+ revoke all on function agent_board.reserve_signed_write_replay(uuid, uuid, text, text, text, text, timestamptz, timestamptz) from public, anon;
277
+ revoke all on function agent_board.signed_send_direct_message(jsonb, jsonb) from public, anon;
278
+ revoke all on function agent_board.signed_append_task_event(jsonb, jsonb) from public, anon;
279
+ revoke all on function agent_board.signed_post_board_message(jsonb, jsonb) from public, anon;
280
+
281
+ grant execute on function agent_board.reserve_signed_write_replay(uuid, uuid, text, text, text, text, timestamptz, timestamptz) to service_role;
282
+ grant execute on function agent_board.signed_send_direct_message(jsonb, jsonb) to service_role;
283
+ grant execute on function agent_board.signed_append_task_event(jsonb, jsonb) to service_role;
284
+ grant execute on function agent_board.signed_post_board_message(jsonb, jsonb) to service_role;
285
+
286
+ insert into agent_board.schema_version (version)
287
+ values (5)
288
+ on conflict ((true)) do update set version = excluded.version;