@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,227 @@
|
|
|
1
|
+
insert into public.app_settings(key, value)
|
|
2
|
+
values
|
|
3
|
+
('agent_board_monitoring_stale_claim_hours', to_jsonb(24)),
|
|
4
|
+
('agent_board_monitoring_presence_lag_minutes', to_jsonb(15)),
|
|
5
|
+
('agent_board_monitoring_callback_retry_threshold', to_jsonb(25)),
|
|
6
|
+
('agent_board_monitoring_inbox_pending_threshold', to_jsonb(50)),
|
|
7
|
+
('agent_board_monitoring_table_growth_bytes', to_jsonb(52428800))
|
|
8
|
+
on conflict (key) do nothing;
|
|
9
|
+
|
|
10
|
+
create or replace view agent_board.v_ops_stale_claims
|
|
11
|
+
with (security_invoker = true)
|
|
12
|
+
as
|
|
13
|
+
select
|
|
14
|
+
c.id as claim_id,
|
|
15
|
+
c.task_id,
|
|
16
|
+
c.thread_id,
|
|
17
|
+
c.agent_id,
|
|
18
|
+
a.handle as agent_handle,
|
|
19
|
+
c.resource_kind,
|
|
20
|
+
c.resource_key,
|
|
21
|
+
round(extract(epoch from (now() - c.created_at)) / 3600.0, 2) as stale_hours,
|
|
22
|
+
c.lease_expires_at,
|
|
23
|
+
c.created_at
|
|
24
|
+
from agent_board.claims c
|
|
25
|
+
join agent_board.agents a on a.id = c.agent_id
|
|
26
|
+
where c.status = 'active'
|
|
27
|
+
and c.released_at is null
|
|
28
|
+
and c.lease_expires_at < now();
|
|
29
|
+
|
|
30
|
+
create or replace view agent_board.v_ops_presence_heartbeats
|
|
31
|
+
with (security_invoker = true)
|
|
32
|
+
as
|
|
33
|
+
select
|
|
34
|
+
p.agent_id,
|
|
35
|
+
a.handle as agent_handle,
|
|
36
|
+
p.availability,
|
|
37
|
+
p.last_heartbeat_at,
|
|
38
|
+
p.expires_at,
|
|
39
|
+
round(extract(epoch from (now() - p.last_heartbeat_at)) / 60.0, 2) as heartbeat_lag_minutes,
|
|
40
|
+
(p.expires_at < now()) as is_expired
|
|
41
|
+
from agent_board.presence p
|
|
42
|
+
join agent_board.agents a on a.id = p.agent_id
|
|
43
|
+
where p.expires_at < now();
|
|
44
|
+
|
|
45
|
+
create or replace view agent_board.v_ops_open_escalations
|
|
46
|
+
with (security_invoker = true)
|
|
47
|
+
as
|
|
48
|
+
select
|
|
49
|
+
e.id as escalation_id,
|
|
50
|
+
e.task_id,
|
|
51
|
+
e.thread_id,
|
|
52
|
+
e.severity,
|
|
53
|
+
e.status,
|
|
54
|
+
e.summary,
|
|
55
|
+
e.assigned_agent_id,
|
|
56
|
+
assignee.handle as assigned_agent_handle,
|
|
57
|
+
round(extract(epoch from (now() - e.created_at)) / 3600.0, 2) as age_hours,
|
|
58
|
+
e.created_at
|
|
59
|
+
from agent_board.escalations e
|
|
60
|
+
left join agent_board.agents assignee on assignee.id = e.assigned_agent_id
|
|
61
|
+
where e.status in ('open', 'acknowledged');
|
|
62
|
+
|
|
63
|
+
create or replace view agent_board.v_ops_callback_retry_pressure
|
|
64
|
+
with (security_invoker = true)
|
|
65
|
+
as
|
|
66
|
+
select
|
|
67
|
+
coalesce(vcdh.endpoint_id, '00000000-0000-0000-0000-000000000000'::uuid) as endpoint_id,
|
|
68
|
+
count(*) filter (where vcdh.latest_attempt_outcome = 'retryable_failure')::bigint as retryable_failure_count,
|
|
69
|
+
count(*) filter (where vcdh.latest_outbox_status = 'retryable')::bigint as queued_retry_count,
|
|
70
|
+
max(vcdh.latest_attempt_finished_at) as latest_retry_finished_at,
|
|
71
|
+
max(vcdh.last_failure_at) as endpoint_last_failure_at
|
|
72
|
+
from agent_board.v_callback_delivery_health vcdh
|
|
73
|
+
group by coalesce(vcdh.endpoint_id, '00000000-0000-0000-0000-000000000000'::uuid)
|
|
74
|
+
having count(*) filter (where vcdh.latest_attempt_outcome = 'retryable_failure') > 0
|
|
75
|
+
or count(*) filter (where vcdh.latest_outbox_status = 'retryable') > 0;
|
|
76
|
+
|
|
77
|
+
create or replace view agent_board.v_ops_endpoint_disablement
|
|
78
|
+
with (security_invoker = true)
|
|
79
|
+
as
|
|
80
|
+
select
|
|
81
|
+
ce.id as endpoint_id,
|
|
82
|
+
ce.owner_agent_id,
|
|
83
|
+
owner.handle as owner_agent_handle,
|
|
84
|
+
ce.disabled_reason,
|
|
85
|
+
ce.disabled_at,
|
|
86
|
+
ce.last_failure_at
|
|
87
|
+
from agent_board.callback_endpoints ce
|
|
88
|
+
join agent_board.agents owner on owner.id = ce.owner_agent_id
|
|
89
|
+
where ce.endpoint_status = 'disabled';
|
|
90
|
+
|
|
91
|
+
create or replace view agent_board.v_ops_inbox_backlog
|
|
92
|
+
with (security_invoker = true)
|
|
93
|
+
as
|
|
94
|
+
select
|
|
95
|
+
counts.recipient_agent_id as agent_id,
|
|
96
|
+
a.handle as recipient_handle,
|
|
97
|
+
counts.unread_count,
|
|
98
|
+
counts.pending_action_count,
|
|
99
|
+
counts.total_visible_count,
|
|
100
|
+
counts.latest_inbox_updated_at
|
|
101
|
+
from agent_board.v_agent_inbox_counts counts
|
|
102
|
+
join agent_board.agents a on a.id = counts.recipient_agent_id
|
|
103
|
+
where counts.pending_action_count > 0
|
|
104
|
+
or counts.unread_count > 0;
|
|
105
|
+
|
|
106
|
+
create or replace view agent_board.v_ops_table_growth
|
|
107
|
+
with (security_invoker = true)
|
|
108
|
+
as
|
|
109
|
+
select
|
|
110
|
+
table_name,
|
|
111
|
+
pg_total_relation_size(format('agent_board.%I', table_name)::regclass) as total_bytes
|
|
112
|
+
from (
|
|
113
|
+
values
|
|
114
|
+
('messages'),
|
|
115
|
+
('task_events'),
|
|
116
|
+
('presence'),
|
|
117
|
+
('callback_outbox_events'),
|
|
118
|
+
('callback_delivery_attempts'),
|
|
119
|
+
('inbox_items'),
|
|
120
|
+
('delivery_recipients'),
|
|
121
|
+
('board_memberships')
|
|
122
|
+
) as monitored(table_name);
|
|
123
|
+
|
|
124
|
+
create or replace view agent_board.v_callback_health
|
|
125
|
+
with (security_invoker = true)
|
|
126
|
+
as
|
|
127
|
+
with subscription_counts as (
|
|
128
|
+
select
|
|
129
|
+
cs.endpoint_id,
|
|
130
|
+
count(*) filter (where cs.subscription_status = 'active')::bigint as active_subscription_count,
|
|
131
|
+
count(*) filter (where cs.subscription_status = 'disabled')::bigint as disabled_subscription_count
|
|
132
|
+
from agent_board.callback_subscriptions cs
|
|
133
|
+
group by cs.endpoint_id
|
|
134
|
+
),
|
|
135
|
+
attempt_counts as (
|
|
136
|
+
select
|
|
137
|
+
cda.endpoint_id,
|
|
138
|
+
count(*) filter (where cda.attempt_outcome = 'delivered')::bigint as delivered_count,
|
|
139
|
+
count(*) filter (where cda.attempt_outcome = 'retryable_failure')::bigint as retryable_failure_count,
|
|
140
|
+
count(*) filter (where cda.attempt_outcome = 'terminal_failure')::bigint as terminal_failure_count,
|
|
141
|
+
count(*) filter (where cda.attempt_outcome = 'endpoint_disabled')::bigint as endpoint_disabled_count,
|
|
142
|
+
max(cda.finished_at) as latest_attempt_finished_at
|
|
143
|
+
from agent_board.callback_delivery_attempts cda
|
|
144
|
+
group by cda.endpoint_id
|
|
145
|
+
),
|
|
146
|
+
outbox_counts as (
|
|
147
|
+
select
|
|
148
|
+
coe.endpoint_id,
|
|
149
|
+
count(*) filter (where coe.outbox_status = 'retryable')::bigint as queued_retry_count,
|
|
150
|
+
count(*) filter (where coe.outbox_status = 'disabled')::bigint as disabled_outbox_count,
|
|
151
|
+
min(coe.available_at) filter (where coe.outbox_status = 'retryable') as oldest_retry_available_at
|
|
152
|
+
from agent_board.callback_outbox_events coe
|
|
153
|
+
group by coe.endpoint_id
|
|
154
|
+
),
|
|
155
|
+
latest_outbox as (
|
|
156
|
+
select distinct on (coe.endpoint_id)
|
|
157
|
+
coe.endpoint_id,
|
|
158
|
+
coe.id as latest_outbox_event_id,
|
|
159
|
+
coe.outbox_status as latest_outbox_status,
|
|
160
|
+
coe.delivery_mode as latest_delivery_mode,
|
|
161
|
+
coe.source_kind as latest_source_kind,
|
|
162
|
+
coe.updated_at as latest_outbox_updated_at
|
|
163
|
+
from agent_board.callback_outbox_events coe
|
|
164
|
+
order by coe.endpoint_id, coe.updated_at desc, coe.created_at desc, coe.id desc
|
|
165
|
+
)
|
|
166
|
+
select
|
|
167
|
+
ce.id as endpoint_id,
|
|
168
|
+
ce.owner_agent_id,
|
|
169
|
+
owner.handle as owner_agent_handle,
|
|
170
|
+
ce.endpoint_status,
|
|
171
|
+
ce.signing_key_version,
|
|
172
|
+
ce.disabled_at,
|
|
173
|
+
ce.disabled_reason,
|
|
174
|
+
coalesce(subscription_counts.active_subscription_count, 0::bigint) as active_subscription_count,
|
|
175
|
+
coalesce(subscription_counts.disabled_subscription_count, 0::bigint) as disabled_subscription_count,
|
|
176
|
+
coalesce(attempt_counts.delivered_count, 0::bigint) as delivered_count,
|
|
177
|
+
coalesce(attempt_counts.retryable_failure_count, 0::bigint) as retryable_failure_count,
|
|
178
|
+
coalesce(attempt_counts.terminal_failure_count, 0::bigint) as terminal_failure_count,
|
|
179
|
+
coalesce(attempt_counts.endpoint_disabled_count, 0::bigint) as endpoint_disabled_count,
|
|
180
|
+
coalesce(outbox_counts.queued_retry_count, 0::bigint) as queued_retry_count,
|
|
181
|
+
coalesce(outbox_counts.disabled_outbox_count, 0::bigint) as disabled_outbox_count,
|
|
182
|
+
latest_outbox.latest_outbox_event_id,
|
|
183
|
+
latest_outbox.latest_outbox_status,
|
|
184
|
+
latest_outbox.latest_delivery_mode,
|
|
185
|
+
latest_outbox.latest_source_kind,
|
|
186
|
+
latest_attempt.attempt_number as latest_attempt_number,
|
|
187
|
+
latest_attempt.attempt_outcome as latest_attempt_outcome,
|
|
188
|
+
latest_attempt.http_status as latest_http_status,
|
|
189
|
+
latest_attempt.error_summary as latest_error_summary,
|
|
190
|
+
latest_attempt.next_retry_at as latest_next_retry_at,
|
|
191
|
+
attempt_counts.latest_attempt_finished_at,
|
|
192
|
+
latest_outbox.latest_outbox_updated_at,
|
|
193
|
+
outbox_counts.oldest_retry_available_at,
|
|
194
|
+
ce.last_delivery_at,
|
|
195
|
+
ce.last_failure_at,
|
|
196
|
+
round(extract(epoch from (now() - ce.last_delivery_at)))::bigint as last_delivery_age_seconds,
|
|
197
|
+
round(extract(epoch from (now() - ce.last_failure_at)))::bigint as last_failure_age_seconds,
|
|
198
|
+
round(extract(epoch from (now() - attempt_counts.latest_attempt_finished_at)))::bigint as latest_attempt_age_seconds,
|
|
199
|
+
round(extract(epoch from (now() - outbox_counts.oldest_retry_available_at)))::bigint as oldest_retry_age_seconds
|
|
200
|
+
from agent_board.callback_endpoints ce
|
|
201
|
+
join agent_board.agents owner on owner.id = ce.owner_agent_id
|
|
202
|
+
left join subscription_counts on subscription_counts.endpoint_id = ce.id
|
|
203
|
+
left join attempt_counts on attempt_counts.endpoint_id = ce.id
|
|
204
|
+
left join outbox_counts on outbox_counts.endpoint_id = ce.id
|
|
205
|
+
left join latest_outbox on latest_outbox.endpoint_id = ce.id
|
|
206
|
+
left join lateral (
|
|
207
|
+
select
|
|
208
|
+
cda.attempt_number,
|
|
209
|
+
cda.attempt_outcome,
|
|
210
|
+
cda.http_status,
|
|
211
|
+
cda.error_summary,
|
|
212
|
+
cda.next_retry_at
|
|
213
|
+
from agent_board.callback_delivery_attempts cda
|
|
214
|
+
where cda.outbox_event_id = latest_outbox.latest_outbox_event_id
|
|
215
|
+
order by cda.attempt_number desc
|
|
216
|
+
limit 1
|
|
217
|
+
) latest_attempt on true;
|
|
218
|
+
|
|
219
|
+
grant select on agent_board.v_ops_stale_claims,
|
|
220
|
+
agent_board.v_ops_presence_heartbeats,
|
|
221
|
+
agent_board.v_ops_open_escalations,
|
|
222
|
+
agent_board.v_ops_callback_retry_pressure,
|
|
223
|
+
agent_board.v_ops_endpoint_disablement,
|
|
224
|
+
agent_board.v_ops_inbox_backlog,
|
|
225
|
+
agent_board.v_ops_table_growth,
|
|
226
|
+
agent_board.v_callback_health
|
|
227
|
+
to authenticated, service_role;
|
|
@@ -0,0 +1,150 @@
|
|
|
1
|
+
-- Fix ambiguous column resolution in agent_board RLS-policy EXISTS subqueries
|
|
2
|
+
-- introduced by 20260512000003_agent_board_auth_rls.sql.
|
|
3
|
+
--
|
|
4
|
+
-- Bug class (deny): a subquery's FROM alias introduces a column (`id`) that
|
|
5
|
+
-- shadows the outer table's `id`. PostgreSQL resolves the unqualified column
|
|
6
|
+
-- to the inner alias, collapsing the join predicate to a tautological
|
|
7
|
+
-- comparison that is essentially never true. Effect: legitimate readers
|
|
8
|
+
-- (joined board members, board-delivery recipients) are denied access.
|
|
9
|
+
-- - agent_board_authenticated_select_messages (line 136):
|
|
10
|
+
-- dr.source_message_id = id -> dr.source_message_id = dr.id
|
|
11
|
+
-- - agent_board_authenticated_select_tasks (line 165):
|
|
12
|
+
-- dr.source_task_id = id -> dr.source_task_id = dr.id
|
|
13
|
+
-- - agent_board_authenticated_select_boards (line 354):
|
|
14
|
+
-- bm.board_id = id -> bm.board_id = bm.id
|
|
15
|
+
--
|
|
16
|
+
-- Bug class (leak): a subquery's FROM alias introduces a column whose name
|
|
17
|
+
-- matches the outer table's column (`board_id` on board_memberships and on
|
|
18
|
+
-- delivery_recipients/inbox_items). The unqualified outer reference resolves
|
|
19
|
+
-- to the inner alias instead, collapsing the predicate to bm.board_id =
|
|
20
|
+
-- bm.board_id (always true for any non-null membership row). Effect: an
|
|
21
|
+
-- authenticated agent who is a joined/subscribed member of ANY board can
|
|
22
|
+
-- read delivery_recipients and inbox_items rows scoped to ANY OTHER board.
|
|
23
|
+
-- - agent_board_authenticated_select_delivery_recipients (line 383):
|
|
24
|
+
-- bm.board_id = board_id -> bm.board_id = bm.board_id
|
|
25
|
+
-- - agent_board_authenticated_select_inbox_items (line 404):
|
|
26
|
+
-- bm.board_id = board_id -> bm.board_id = bm.board_id
|
|
27
|
+
--
|
|
28
|
+
-- Fix: drop and recreate the affected policies, qualifying every outer-table
|
|
29
|
+
-- reference (messages.id, tasks.id, boards.id, delivery_recipients.board_id,
|
|
30
|
+
-- inbox_items.board_id). No schema-shape change; this is a behavior fix to
|
|
31
|
+
-- the policy expressions.
|
|
32
|
+
|
|
33
|
+
drop policy if exists agent_board_authenticated_select_messages on agent_board.messages;
|
|
34
|
+
create policy agent_board_authenticated_select_messages
|
|
35
|
+
on agent_board.messages
|
|
36
|
+
as permissive
|
|
37
|
+
for select
|
|
38
|
+
to authenticated
|
|
39
|
+
using (
|
|
40
|
+
author_agent_id = agent_board.current_agent_id()
|
|
41
|
+
or exists (
|
|
42
|
+
select 1
|
|
43
|
+
from agent_board.delivery_recipients dr
|
|
44
|
+
where dr.source_message_id = messages.id
|
|
45
|
+
and (
|
|
46
|
+
dr.recipient_agent_id = agent_board.current_agent_id()
|
|
47
|
+
or (
|
|
48
|
+
dr.board_id is not null
|
|
49
|
+
and exists (
|
|
50
|
+
select 1
|
|
51
|
+
from agent_board.board_memberships bm
|
|
52
|
+
where bm.board_id = dr.board_id
|
|
53
|
+
and bm.agent_id = agent_board.current_agent_id()
|
|
54
|
+
and bm.membership_state in ('joined', 'subscribed')
|
|
55
|
+
)
|
|
56
|
+
)
|
|
57
|
+
)
|
|
58
|
+
)
|
|
59
|
+
);
|
|
60
|
+
|
|
61
|
+
drop policy if exists agent_board_authenticated_select_tasks on agent_board.tasks;
|
|
62
|
+
create policy agent_board_authenticated_select_tasks
|
|
63
|
+
on agent_board.tasks
|
|
64
|
+
as permissive
|
|
65
|
+
for select
|
|
66
|
+
to authenticated
|
|
67
|
+
using (
|
|
68
|
+
created_by_agent_id = agent_board.current_agent_id()
|
|
69
|
+
or assigned_agent_id = agent_board.current_agent_id()
|
|
70
|
+
or exists (
|
|
71
|
+
select 1
|
|
72
|
+
from agent_board.delivery_recipients dr
|
|
73
|
+
where dr.source_task_id = tasks.id
|
|
74
|
+
and (
|
|
75
|
+
dr.recipient_agent_id = agent_board.current_agent_id()
|
|
76
|
+
or (
|
|
77
|
+
dr.board_id is not null
|
|
78
|
+
and exists (
|
|
79
|
+
select 1
|
|
80
|
+
from agent_board.board_memberships bm
|
|
81
|
+
where bm.board_id = dr.board_id
|
|
82
|
+
and bm.agent_id = agent_board.current_agent_id()
|
|
83
|
+
and bm.membership_state in ('joined', 'subscribed')
|
|
84
|
+
)
|
|
85
|
+
)
|
|
86
|
+
)
|
|
87
|
+
)
|
|
88
|
+
);
|
|
89
|
+
|
|
90
|
+
drop policy if exists agent_board_authenticated_select_boards on agent_board.boards;
|
|
91
|
+
create policy agent_board_authenticated_select_boards
|
|
92
|
+
on agent_board.boards
|
|
93
|
+
as permissive
|
|
94
|
+
for select
|
|
95
|
+
to authenticated
|
|
96
|
+
using (
|
|
97
|
+
created_by_agent_id = agent_board.current_agent_id()
|
|
98
|
+
or exists (
|
|
99
|
+
select 1
|
|
100
|
+
from agent_board.board_memberships bm
|
|
101
|
+
where bm.board_id = boards.id
|
|
102
|
+
and bm.agent_id = agent_board.current_agent_id()
|
|
103
|
+
and bm.membership_state in ('joined', 'subscribed')
|
|
104
|
+
)
|
|
105
|
+
);
|
|
106
|
+
|
|
107
|
+
drop policy if exists agent_board_authenticated_select_delivery_recipients on agent_board.delivery_recipients;
|
|
108
|
+
create policy agent_board_authenticated_select_delivery_recipients
|
|
109
|
+
on agent_board.delivery_recipients
|
|
110
|
+
as permissive
|
|
111
|
+
for select
|
|
112
|
+
to authenticated
|
|
113
|
+
using (
|
|
114
|
+
recipient_agent_id = agent_board.current_agent_id()
|
|
115
|
+
or (
|
|
116
|
+
board_id is not null
|
|
117
|
+
and exists (
|
|
118
|
+
select 1
|
|
119
|
+
from agent_board.board_memberships bm
|
|
120
|
+
where bm.board_id = delivery_recipients.board_id
|
|
121
|
+
and bm.agent_id = agent_board.current_agent_id()
|
|
122
|
+
and bm.membership_state in ('joined', 'subscribed')
|
|
123
|
+
)
|
|
124
|
+
)
|
|
125
|
+
);
|
|
126
|
+
|
|
127
|
+
drop policy if exists agent_board_authenticated_select_inbox_items on agent_board.inbox_items;
|
|
128
|
+
create policy agent_board_authenticated_select_inbox_items
|
|
129
|
+
on agent_board.inbox_items
|
|
130
|
+
as permissive
|
|
131
|
+
for select
|
|
132
|
+
to authenticated
|
|
133
|
+
using (
|
|
134
|
+
recipient_agent_id = agent_board.current_agent_id()
|
|
135
|
+
or (
|
|
136
|
+
board_id is not null
|
|
137
|
+
and visible_in_board_feed = true
|
|
138
|
+
and exists (
|
|
139
|
+
select 1
|
|
140
|
+
from agent_board.board_memberships bm
|
|
141
|
+
where bm.board_id = inbox_items.board_id
|
|
142
|
+
and bm.agent_id = agent_board.current_agent_id()
|
|
143
|
+
and bm.membership_state in ('joined', 'subscribed')
|
|
144
|
+
)
|
|
145
|
+
)
|
|
146
|
+
);
|
|
147
|
+
|
|
148
|
+
insert into agent_board.schema_version (version)
|
|
149
|
+
values (4)
|
|
150
|
+
on conflict ((true)) do update set version = excluded.version;
|