@creatornader/agent-bridge 0.4.0 → 0.5.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 (76) hide show
  1. package/CHANGELOG.md +73 -1
  2. package/README.md +73 -7
  3. package/ROADMAP.md +29 -0
  4. package/SECURITY.md +23 -0
  5. package/SKILL.md +5 -1
  6. package/dist/archive.d.ts +2 -2
  7. package/dist/{bridge-service-YTjGr91A.d.ts → bridge-service-CNBKdYXh.d.ts} +2 -1
  8. package/dist/{bridge-store-Boaj-ZbO.d.ts → bridge-store-ByJ6CaJk.d.ts} +1 -0
  9. package/dist/bridge.d.ts +15 -8
  10. package/dist/bridge.js +10 -8
  11. package/dist/{chunk-PDIHDBP3.js → chunk-7VJI2MXI.js} +116 -26
  12. package/dist/chunk-7VJI2MXI.js.map +1 -0
  13. package/dist/{chunk-4VB44KJU.js → chunk-AWE3DFZV.js} +3 -2
  14. package/dist/chunk-AWE3DFZV.js.map +1 -0
  15. package/dist/{chunk-IHZFI7TH.js → chunk-E4OWHGUE.js} +5 -2
  16. package/dist/chunk-E4OWHGUE.js.map +1 -0
  17. package/dist/{chunk-SYGONYMM.js → chunk-HUHG7XTB.js} +6 -5
  18. package/dist/chunk-HUHG7XTB.js.map +1 -0
  19. package/dist/{chunk-DQOZJJZ2.js → chunk-IVG4XWWS.js} +5 -5
  20. package/dist/{chunk-DQOZJJZ2.js.map → chunk-IVG4XWWS.js.map} +1 -1
  21. package/dist/{chunk-3YHVUPU2.js → chunk-P635FAN4.js} +4 -4
  22. package/dist/chunk-P635FAN4.js.map +1 -0
  23. package/dist/{chunk-6BTJE6D4.js → chunk-QNXHDOJ5.js} +56 -23
  24. package/dist/chunk-QNXHDOJ5.js.map +1 -0
  25. package/dist/{chunk-MCKKVNCE.js → chunk-QPC6JHA3.js} +5 -5
  26. package/dist/{chunk-SV3SVBYS.js → chunk-SN7PIVDF.js} +2 -2
  27. package/dist/{chunk-2DFNOLMO.js → chunk-XDNT6ZNZ.js} +9 -6
  28. package/dist/chunk-XDNT6ZNZ.js.map +1 -0
  29. package/dist/{chunk-LAHNQZDN.js → chunk-Z6JP6MYD.js} +2 -2
  30. package/dist/cli.js +9 -9
  31. package/dist/cli.js.map +1 -1
  32. package/dist/client-runtime.d.ts +3 -3
  33. package/dist/client-runtime.js +6 -6
  34. package/dist/contracts/generate.js +1 -1
  35. package/dist/dr.js +3 -3
  36. package/dist/{gateway-BQHpV-MZ.d.ts → gateway-CW-61lvs.d.ts} +2 -2
  37. package/dist/gateway-main.js +5 -5
  38. package/dist/gateway.d.ts +3 -3
  39. package/dist/gateway.js +3 -3
  40. package/dist/index.js +7 -7
  41. package/dist/{postgres-bridge-store-WASumj26.d.ts → postgres-bridge-store-C9KG9Z69.d.ts} +1 -1
  42. package/dist/postgres-production-preflight.d.ts +32 -0
  43. package/dist/postgres-production-preflight.js +249 -0
  44. package/dist/postgres-production-preflight.js.map +1 -0
  45. package/dist/server.js +7 -7
  46. package/dist/{sqlite-edge-store-Bc15DvpX.d.ts → sqlite-edge-store-CdMIOrho.d.ts} +1 -1
  47. package/dist/sqlite.d.ts +3 -3
  48. package/dist/sqlite.js +2 -2
  49. package/docs/architecture-v2.md +36 -5
  50. package/docs/deployment.md +144 -0
  51. package/llms.txt +2 -1
  52. package/openapi/agent-bridge-v2.openapi.json +5 -1
  53. package/package.json +5 -1
  54. package/schemas/agent-bridge-v2.capabilities.json +2 -1
  55. package/schemas/agent-bridge-v2.mcp.json +5 -1
  56. package/schemas/agent-bridge-v2.schema.json +4 -0
  57. package/sql/migrations/007_runtime_role.sql +8 -4
  58. package/sql/migrations/013_row_isolation.sql +71 -8
  59. package/sql/migrations/014_owner_control_plane.sql +124 -31
  60. package/sql/migrations/015_portable_archives.sql +143 -41
  61. package/sql/migrations/016_native_dr_fence.sql +102 -35
  62. package/sql/migrations/018_endpoint_migration_challenges.sql +36 -10
  63. package/sql/migrations/019_endpoint_migration_same_successor.sql +34 -10
  64. package/sql/migrations/020_managed_authority_compat.sql +698 -0
  65. package/sql/migrations/021_native_backup_reader.sql +421 -0
  66. package/sql/setup.sql +1 -3
  67. package/dist/chunk-2DFNOLMO.js.map +0 -1
  68. package/dist/chunk-3YHVUPU2.js.map +0 -1
  69. package/dist/chunk-4VB44KJU.js.map +0 -1
  70. package/dist/chunk-6BTJE6D4.js.map +0 -1
  71. package/dist/chunk-IHZFI7TH.js.map +0 -1
  72. package/dist/chunk-PDIHDBP3.js.map +0 -1
  73. package/dist/chunk-SYGONYMM.js.map +0 -1
  74. /package/dist/{chunk-MCKKVNCE.js.map → chunk-QPC6JHA3.js.map} +0 -0
  75. /package/dist/{chunk-SV3SVBYS.js.map → chunk-SN7PIVDF.js.map} +0 -0
  76. /package/dist/{chunk-LAHNQZDN.js.map → chunk-Z6JP6MYD.js.map} +0 -0
@@ -0,0 +1,421 @@
1
+ begin;
2
+
3
+ select pg_advisory_xact_lock(1646705660);
4
+
5
+ do $preflight$
6
+ begin
7
+ if not agent_bridge.security_schema_ready() then
8
+ raise exception 'native backup reader security readiness validation failed';
9
+ elsif not agent_bridge.owner_control_plane_ready() then
10
+ raise exception 'native backup reader owner readiness validation failed';
11
+ elsif not agent_bridge.gateway_authority_ready() then
12
+ raise exception 'native backup reader gateway readiness validation failed';
13
+ elsif not agent_bridge.endpoint_migration_challenge_ready() then
14
+ raise exception 'native backup reader endpoint readiness validation failed';
15
+ elsif not agent_bridge.portable_archive_ready() then
16
+ raise exception 'native backup reader archive readiness validation failed';
17
+ elsif not exists(select 1 from agent_bridge.row_isolation_attestations attestation
18
+ where attestation.name='domain-v1'
19
+ and attestation.catalog_definition=agent_bridge.row_isolation_catalog_definition()) then
20
+ raise exception 'native backup reader row-isolation attestation validation failed';
21
+ elsif (select nspowner<>current_user::regrole::oid from pg_catalog.pg_namespace
22
+ where nspname='agent_bridge') then
23
+ raise exception 'native backup reader migration authority must own the Agent Bridge schema';
24
+ end if;
25
+ end
26
+ $preflight$;
27
+
28
+ do $role$
29
+ declare
30
+ backup_role text := 'agent_bridge_backup_reader_'||substr(md5(current_database()),1,16);
31
+ begin
32
+ if exists(select 1 from pg_catalog.pg_roles where rolname=backup_role) then
33
+ raise exception 'reserved Agent Bridge native backup role already exists';
34
+ end if;
35
+ execute format(
36
+ 'create role %I nologin inherit nosuperuser nocreatedb nocreaterole noreplication nobypassrls',
37
+ backup_role
38
+ );
39
+ if current_setting('server_version_num')::integer>=160000 and not exists(
40
+ select 1 from pg_catalog.pg_auth_members membership
41
+ join pg_catalog.pg_roles granted on granted.oid=membership.roleid
42
+ join pg_catalog.pg_roles member on member.oid=membership.member
43
+ where granted.rolname=backup_role and member.rolname=current_user
44
+ and membership.admin_option
45
+ ) then
46
+ execute format(
47
+ 'grant %I to %I with admin true,inherit true,set true',backup_role,current_user
48
+ );
49
+ elsif current_setting('server_version_num')::integer>=160000 and not exists(
50
+ select 1 from pg_catalog.pg_auth_members membership
51
+ join pg_catalog.pg_roles granted on granted.oid=membership.roleid
52
+ join pg_catalog.pg_roles member on member.oid=membership.member
53
+ where granted.rolname=backup_role and member.rolname=current_user
54
+ and coalesce((to_jsonb(membership)->>'inherit_option')::boolean,true)
55
+ and coalesce((to_jsonb(membership)->>'set_option')::boolean,true)
56
+ ) then
57
+ execute format(
58
+ 'grant %I to %I with admin false,inherit true,set true',backup_role,current_user
59
+ );
60
+ else
61
+ if current_setting('server_version_num')::integer<160000 then
62
+ execute format('grant %I to %I with admin option',backup_role,current_user);
63
+ end if;
64
+ end if;
65
+ end
66
+ $role$;
67
+
68
+ create table agent_bridge.native_backup_attestations (
69
+ name text primary key,
70
+ catalog_definition text not null,
71
+ attested_at timestamptz not null default now(),
72
+ constraint native_backup_attestation_name check(name='native-backup-v1')
73
+ );
74
+
75
+ create function agent_bridge.reject_native_backup_attestation_mutation()
76
+ returns trigger language plpgsql set search_path = '' as $$
77
+ begin
78
+ raise exception 'native backup attestations are append-only';
79
+ end
80
+ $$;
81
+
82
+ create trigger native_backup_attestations_append_only
83
+ before update or delete on agent_bridge.native_backup_attestations
84
+ for each row execute function agent_bridge.reject_native_backup_attestation_mutation();
85
+
86
+ create trigger native_backup_attestations_no_truncate
87
+ before truncate on agent_bridge.native_backup_attestations
88
+ for each statement execute function agent_bridge.reject_native_backup_attestation_mutation();
89
+
90
+ do $grants$
91
+ declare
92
+ backup_role text := 'agent_bridge_backup_reader_'||substr(md5(current_database()),1,16);
93
+ begin
94
+ execute format('revoke all on schema agent_bridge from %I',backup_role);
95
+ execute format('revoke all on all tables in schema agent_bridge from %I',backup_role);
96
+ execute format('revoke all on all sequences in schema agent_bridge from %I',backup_role);
97
+ execute format('revoke execute on all functions in schema agent_bridge from %I',backup_role);
98
+ execute format('grant usage on schema agent_bridge to %I',backup_role);
99
+ execute format('grant select on all tables in schema agent_bridge to %I',backup_role);
100
+ execute format('grant select on all sequences in schema agent_bridge to %I',backup_role);
101
+ end
102
+ $grants$;
103
+
104
+ create function agent_bridge.native_backup_catalog_definition()
105
+ returns text language sql stable set search_path = '' as $$
106
+ with names as (select
107
+ ('agent_bridge_backup_reader_'||substr(md5(current_database()),1,16))::name backup_role,
108
+ (select nspowner from pg_catalog.pg_namespace where nspname='agent_bridge') schema_owner
109
+ ), catalog_objects(kind,identity,definition) as (
110
+ select 'role',role.rolname,
111
+ role.rolcanlogin::text||':'||role.rolinherit::text||':'||role.rolsuper::text||':'||
112
+ role.rolcreatedb::text||':'||role.rolcreaterole::text||':'||
113
+ role.rolreplication::text||':'||role.rolbypassrls::text||':'||role.rolconnlimit::text
114
+ from pg_catalog.pg_roles role where role.rolname=(select backup_role from names)
115
+ union all
116
+ select 'membership',granted.rolname||'->'||member.rolname,
117
+ bool_or(membership.admin_option)::text||':'||
118
+ bool_or(coalesce((to_jsonb(membership)->>'inherit_option')::boolean,true))::text||':'||
119
+ bool_or(coalesce((to_jsonb(membership)->>'set_option')::boolean,true))::text
120
+ from pg_catalog.pg_auth_members membership
121
+ join pg_catalog.pg_roles granted on granted.oid=membership.roleid
122
+ join pg_catalog.pg_roles member on member.oid=membership.member
123
+ where membership.roleid=(select oid from pg_catalog.pg_roles
124
+ where rolname=(select backup_role from names))
125
+ or membership.member=(select oid from pg_catalog.pg_roles
126
+ where rolname=(select backup_role from names))
127
+ group by granted.rolname,member.rolname
128
+ union all
129
+ select 'schema_acl','agent_bridge',
130
+ pg_catalog.pg_get_userbyid(privilege.grantor)||':'||
131
+ privilege.privilege_type||':'||privilege.is_grantable::text
132
+ from pg_catalog.pg_namespace namespace
133
+ cross join lateral pg_catalog.aclexplode(coalesce(namespace.nspacl,
134
+ pg_catalog.acldefault('n',namespace.nspowner))) privilege
135
+ where namespace.nspname='agent_bridge'
136
+ and privilege.grantee=(select oid from pg_catalog.pg_roles
137
+ where rolname=(select backup_role from names))
138
+ union all
139
+ select 'relation',relation.oid::regclass::text,
140
+ relation.relkind::text||':'||pg_catalog.pg_get_userbyid(relation.relowner)||':'||
141
+ coalesce(string_agg(privilege.privilege_type||':'||privilege.is_grantable::text,','
142
+ order by privilege.privilege_type),'missing')
143
+ from pg_catalog.pg_class relation
144
+ join pg_catalog.pg_namespace namespace on namespace.oid=relation.relnamespace
145
+ left join lateral pg_catalog.aclexplode(coalesce(relation.relacl,
146
+ pg_catalog.acldefault(case when relation.relkind='S' then 'S'::"char" else 'r'::"char" end,
147
+ relation.relowner))) privilege on privilege.grantee=(select oid from pg_catalog.pg_roles
148
+ where rolname=(select backup_role from names))
149
+ where namespace.nspname='agent_bridge' and relation.relkind in ('r','p','v','m','f','S')
150
+ group by relation.oid,relation.relkind,relation.relowner
151
+ union all
152
+ select 'function',procedure.oid::regprocedure::text,
153
+ pg_catalog.pg_get_userbyid(procedure.proowner)||':'||procedure.prosecdef::text||':'||
154
+ procedure.provolatile::text||':'||coalesce(array_to_string(procedure.proconfig,','),'')||':'||
155
+ pg_catalog.pg_get_functiondef(procedure.oid)
156
+ from pg_catalog.pg_proc procedure
157
+ join pg_catalog.pg_namespace namespace on namespace.oid=procedure.pronamespace
158
+ where namespace.nspname='agent_bridge' and procedure.proname in (
159
+ 'reject_native_backup_attestation_mutation','native_backup_catalog_definition',
160
+ 'native_backup_ready'
161
+ )
162
+ union all
163
+ select 'trigger',trigger.tgrelid::regclass::text||'.'||trigger.tgname,
164
+ trigger.tgenabled::text||':'||pg_catalog.pg_get_triggerdef(trigger.oid,true)
165
+ from pg_catalog.pg_trigger trigger
166
+ where trigger.tgrelid='agent_bridge.native_backup_attestations'::regclass
167
+ and not trigger.tgisinternal
168
+ )
169
+ select string_agg(kind||E'\x1f'||identity||E'\x1f'||definition,E'\x1e'
170
+ order by kind,identity,definition) from catalog_objects
171
+ $$;
172
+
173
+ create function agent_bridge.native_backup_ready()
174
+ returns boolean language sql stable security definer set search_path = '' as $$
175
+ with names as (select
176
+ ('agent_bridge_backup_reader_'||substr(md5(current_database()),1,16))::name backup_role,
177
+ ('agent_bridge_runtime_'||substr(md5(current_database()),1,16))::name runtime_role,
178
+ (select nspowner from pg_catalog.pg_namespace where nspname='agent_bridge') schema_owner
179
+ ), semantic_membership as (
180
+ select count(distinct member.oid)=1
181
+ and bool_and(member.oid=(select schema_owner from names))
182
+ and bool_or(membership.admin_option)
183
+ and bool_or(coalesce((to_jsonb(membership)->>'inherit_option')::boolean,true))
184
+ and bool_or(coalesce((to_jsonb(membership)->>'set_option')::boolean,true)) ready
185
+ from pg_catalog.pg_auth_members membership
186
+ join pg_catalog.pg_roles granted on granted.oid=membership.roleid
187
+ join pg_catalog.pg_roles member on member.oid=membership.member
188
+ where granted.rolname=(select backup_role from names)
189
+ ), raw_membership as (
190
+ select count(*)::integer row_count,
191
+ count(*) filter(where membership.grantor=10 and membership.admin_option
192
+ and not coalesce((to_jsonb(membership)->>'inherit_option')::boolean,true)
193
+ and not coalesce((to_jsonb(membership)->>'set_option')::boolean,true)) bootstrap_admin,
194
+ count(*) filter(where membership.grantor=member.oid and not membership.admin_option
195
+ and coalesce((to_jsonb(membership)->>'inherit_option')::boolean,true)
196
+ and coalesce((to_jsonb(membership)->>'set_option')::boolean,true)) self_inherit,
197
+ count(*) filter(where membership.admin_option
198
+ and coalesce((to_jsonb(membership)->>'inherit_option')::boolean,true)
199
+ and coalesce((to_jsonb(membership)->>'set_option')::boolean,true)
200
+ and membership.grantor in (10,member.oid)) combined
201
+ from pg_catalog.pg_auth_members membership
202
+ join pg_catalog.pg_roles granted on granted.oid=membership.roleid
203
+ join pg_catalog.pg_roles member on member.oid=membership.member
204
+ where granted.rolname=(select backup_role from names)
205
+ and member.oid=(select schema_owner from names)
206
+ )
207
+ select
208
+ exists(select 1 from pg_catalog.pg_roles role,names where role.rolname=names.backup_role
209
+ and not role.rolcanlogin and role.rolinherit and not role.rolsuper
210
+ and not role.rolcreatedb and not role.rolcreaterole and not role.rolreplication
211
+ and not role.rolbypassrls and role.rolconnlimit=-1)
212
+ and exists(select 1 from pg_catalog.pg_roles role,names
213
+ where (role.oid=names.schema_owner and (role.rolsuper or role.rolbypassrls))
214
+ or (role.rolname=session_user and role.rolsuper))
215
+ and (select ready from semantic_membership)
216
+ and (select case when current_setting('server_version_num')::integer<160000
217
+ then row_count=1 and combined=1
218
+ else (row_count=1 and combined=1)
219
+ or (row_count=2 and bootstrap_admin=1 and self_inherit=1)
220
+ end from raw_membership)
221
+ and not exists(
222
+ select 1 from pg_catalog.pg_auth_members membership
223
+ join pg_catalog.pg_roles member on member.oid=membership.member
224
+ cross join names
225
+ where membership.roleid=(select oid from pg_catalog.pg_roles
226
+ where rolname=names.backup_role) and (
227
+ member.oid<>names.schema_owner or not (
228
+ (membership.grantor=10 and membership.admin_option
229
+ and coalesce((to_jsonb(membership)->>'inherit_option')::boolean,true)
230
+ =coalesce((to_jsonb(membership)->>'set_option')::boolean,true))
231
+ or (membership.grantor=member.oid
232
+ and coalesce((to_jsonb(membership)->>'inherit_option')::boolean,true)
233
+ and coalesce((to_jsonb(membership)->>'set_option')::boolean,true))
234
+ )
235
+ )
236
+ )
237
+ and not exists(
238
+ select 1 from pg_catalog.pg_auth_members membership
239
+ cross join names
240
+ where membership.member=(select oid from pg_catalog.pg_roles
241
+ where rolname=names.backup_role)
242
+ )
243
+ and has_schema_privilege((select backup_role from names),'agent_bridge','USAGE')
244
+ and not has_schema_privilege((select backup_role from names),'agent_bridge','CREATE')
245
+ and not exists(
246
+ select 1 from pg_catalog.pg_namespace namespace,names
247
+ cross join lateral pg_catalog.aclexplode(coalesce(namespace.nspacl,
248
+ pg_catalog.acldefault('n',namespace.nspowner))) privilege
249
+ where namespace.nspname='agent_bridge'
250
+ and privilege.grantee=(select oid from pg_catalog.pg_roles where rolname=names.backup_role)
251
+ and (privilege.privilege_type<>'USAGE' or privilege.is_grantable)
252
+ )
253
+ and not exists(
254
+ select 1 from pg_catalog.pg_class relation
255
+ join pg_catalog.pg_namespace namespace on namespace.oid=relation.relnamespace,names
256
+ where namespace.nspname='agent_bridge' and relation.relkind in ('r','p','v','m','f','S')
257
+ and not case when relation.relkind='S'
258
+ then has_sequence_privilege(names.backup_role,relation.oid,'SELECT')
259
+ and not has_sequence_privilege(names.backup_role,relation.oid,'USAGE,UPDATE')
260
+ else has_table_privilege(names.backup_role,relation.oid,'SELECT')
261
+ and not has_table_privilege(names.backup_role,relation.oid,
262
+ 'INSERT,UPDATE,DELETE,TRUNCATE,REFERENCES,TRIGGER')
263
+ end
264
+ )
265
+ and not exists(
266
+ select 1 from pg_catalog.pg_class relation
267
+ join pg_catalog.pg_namespace namespace on namespace.oid=relation.relnamespace,names
268
+ cross join lateral pg_catalog.aclexplode(coalesce(relation.relacl,
269
+ pg_catalog.acldefault(case when relation.relkind='S' then 'S'::"char" else 'r'::"char" end,
270
+ relation.relowner))) privilege
271
+ where namespace.nspname='agent_bridge' and relation.relkind in ('r','p','v','m','f','S')
272
+ and privilege.grantee=(select oid from pg_catalog.pg_roles where rolname=names.backup_role)
273
+ and (privilege.privilege_type<>'SELECT' or privilege.is_grantable)
274
+ )
275
+ and not exists(
276
+ select 1 from pg_catalog.pg_attribute attribute
277
+ join pg_catalog.pg_class relation on relation.oid=attribute.attrelid
278
+ join pg_catalog.pg_namespace namespace on namespace.oid=relation.relnamespace,names
279
+ cross join lateral pg_catalog.aclexplode(attribute.attacl) privilege
280
+ where namespace.nspname='agent_bridge' and attribute.attnum>0 and not attribute.attisdropped
281
+ and privilege.grantee=(select oid from pg_catalog.pg_roles where rolname=names.backup_role)
282
+ )
283
+ and not exists(
284
+ select 1 from pg_catalog.pg_proc procedure
285
+ join pg_catalog.pg_namespace namespace on namespace.oid=procedure.pronamespace,names
286
+ where namespace.nspname='agent_bridge'
287
+ and has_function_privilege(names.backup_role,procedure.oid,'EXECUTE')
288
+ )
289
+ and (select count(*)=3 and bool_and(
290
+ procedure.proowner=(select schema_owner from names)
291
+ and procedure.proconfig @> array['search_path=""']::text[]
292
+ and case procedure.proname when 'native_backup_ready' then procedure.prosecdef
293
+ else not procedure.prosecdef end
294
+ and case procedure.proname when 'reject_native_backup_attestation_mutation'
295
+ then procedure.provolatile='v' else procedure.provolatile='s' end
296
+ ) from pg_catalog.pg_proc procedure
297
+ join pg_catalog.pg_namespace namespace on namespace.oid=procedure.pronamespace
298
+ where namespace.nspname='agent_bridge' and procedure.proname in (
299
+ 'reject_native_backup_attestation_mutation','native_backup_catalog_definition',
300
+ 'native_backup_ready'))
301
+ and has_function_privilege((select runtime_role from names),
302
+ 'agent_bridge.native_backup_ready()','EXECUTE')
303
+ and not has_function_privilege('public','agent_bridge.native_backup_ready()','EXECUTE')
304
+ and not has_function_privilege((select backup_role from names),
305
+ 'agent_bridge.native_backup_ready()','EXECUTE')
306
+ and not exists(select 1 from pg_catalog.pg_proc procedure,names
307
+ where procedure.oid in (
308
+ 'agent_bridge.reject_native_backup_attestation_mutation()'::regprocedure,
309
+ 'agent_bridge.native_backup_catalog_definition()'::regprocedure
310
+ ) and (has_function_privilege(names.runtime_role,procedure.oid,'EXECUTE')
311
+ or has_function_privilege('public',procedure.oid,'EXECUTE')
312
+ or has_function_privilege(names.backup_role,procedure.oid,'EXECUTE')))
313
+ and (select count(*)=2 and bool_and(trigger.tgenabled='O')
314
+ from pg_catalog.pg_trigger trigger
315
+ where trigger.tgrelid='agent_bridge.native_backup_attestations'::regclass
316
+ and trigger.tgname in ('native_backup_attestations_append_only',
317
+ 'native_backup_attestations_no_truncate') and not trigger.tgisinternal)
318
+ and (select count(*)=1 and bool_and(
319
+ attestation.catalog_definition=agent_bridge.native_backup_catalog_definition())
320
+ from agent_bridge.native_backup_attestations attestation
321
+ where attestation.name='native-backup-v1')
322
+ $$;
323
+
324
+ revoke all on function agent_bridge.reject_native_backup_attestation_mutation() from public;
325
+ revoke all on function agent_bridge.native_backup_catalog_definition() from public;
326
+ revoke all on function agent_bridge.native_backup_ready() from public;
327
+
328
+ do $function_grants$
329
+ declare
330
+ runtime_role text := 'agent_bridge_runtime_'||substr(md5(current_database()),1,16);
331
+ backup_role text := 'agent_bridge_backup_reader_'||substr(md5(current_database()),1,16);
332
+ begin
333
+ execute format('revoke execute on function agent_bridge.reject_native_backup_attestation_mutation() from %I,%I',runtime_role,backup_role);
334
+ execute format('revoke execute on function agent_bridge.native_backup_catalog_definition() from %I,%I',runtime_role,backup_role);
335
+ execute format('revoke execute on function agent_bridge.native_backup_ready() from %I',backup_role);
336
+ execute format('grant execute on function agent_bridge.native_backup_ready() to %I',runtime_role);
337
+ end
338
+ $function_grants$;
339
+
340
+ do $readiness_versions$
341
+ declare
342
+ owner_definition text;
343
+ archive_definition text;
344
+ endpoint_definition text;
345
+ begin
346
+ select pg_catalog.pg_get_functiondef(
347
+ 'agent_bridge.owner_control_plane_ready()'::regprocedure
348
+ ) into owner_definition;
349
+ if owner_definition not like '%owner-control-v7%' then
350
+ raise exception 'owner readiness contract is not the migration 020 definition';
351
+ end if;
352
+ execute replace(owner_definition,'owner-control-v7','owner-control-v8');
353
+
354
+ select pg_catalog.pg_get_functiondef(
355
+ 'agent_bridge.portable_archive_ready()'::regprocedure
356
+ ) into archive_definition;
357
+ if archive_definition not like '%portable-archive-v4%' then
358
+ raise exception 'archive readiness contract is not the migration 020 definition';
359
+ end if;
360
+ execute replace(archive_definition,'portable-archive-v4','portable-archive-v5');
361
+
362
+ select pg_catalog.pg_get_functiondef(
363
+ 'agent_bridge.endpoint_migration_challenge_ready()'::regprocedure
364
+ ) into endpoint_definition;
365
+ if endpoint_definition not like '%endpoint-migration-v2%' then
366
+ raise exception 'endpoint readiness contract is not the migration 019 definition';
367
+ end if;
368
+ execute replace(endpoint_definition,'endpoint-migration-v2','endpoint-migration-v3');
369
+ end
370
+ $readiness_versions$;
371
+
372
+ alter table agent_bridge.endpoint_migration_challenge_attestations
373
+ drop constraint endpoint_migration_challenge_attestation_name;
374
+ alter table agent_bridge.endpoint_migration_challenge_attestations
375
+ add constraint endpoint_migration_challenge_attestation_name
376
+ check(name in ('endpoint-migration-v1','endpoint-migration-v2','endpoint-migration-v3'));
377
+
378
+ select set_config(
379
+ 'role','agent_bridge_control_owner_'||substr(md5(current_database()),1,16),false
380
+ );
381
+ insert into agent_bridge.owner_control_attestations(name,catalog_definition)
382
+ values('owner-control-v8',agent_bridge.owner_control_attestation_definition());
383
+ reset role;
384
+
385
+ insert into agent_bridge.portable_archive_attestations(name,catalog_definition)
386
+ values('portable-archive-v5',agent_bridge.portable_archive_attestation_definition());
387
+
388
+ insert into agent_bridge.endpoint_migration_challenge_attestations(name,catalog_definition)
389
+ values('endpoint-migration-v3',agent_bridge.endpoint_migration_challenge_catalog_definition());
390
+
391
+ insert into agent_bridge.native_backup_attestations(name,catalog_definition)
392
+ values('native-backup-v1',agent_bridge.native_backup_catalog_definition());
393
+
394
+ do $final_readiness$
395
+ begin
396
+ if not agent_bridge.security_schema_ready() then
397
+ raise exception 'native backup reader final security readiness validation failed';
398
+ elsif not agent_bridge.owner_control_plane_ready() then
399
+ raise exception 'native backup reader final owner readiness validation failed';
400
+ elsif not agent_bridge.gateway_authority_ready() then
401
+ raise exception 'native backup reader final gateway readiness validation failed';
402
+ elsif not agent_bridge.endpoint_migration_challenge_ready() then
403
+ raise exception 'native backup reader final endpoint readiness validation failed';
404
+ elsif not agent_bridge.portable_archive_ready() then
405
+ raise exception 'native backup reader final archive readiness validation failed';
406
+ elsif not exists(select 1 from agent_bridge.row_isolation_attestations attestation
407
+ where attestation.name='domain-v1'
408
+ and attestation.catalog_definition=agent_bridge.row_isolation_catalog_definition()) then
409
+ raise exception 'native backup reader final row-isolation attestation validation failed';
410
+ elsif not agent_bridge.native_backup_ready() then
411
+ raise exception 'native backup reader final readiness validation failed';
412
+ end if;
413
+ exception when others then
414
+ raise exception 'native backup reader final validation failed: %',sqlerrm;
415
+ end
416
+ $final_readiness$;
417
+
418
+ insert into agent_bridge.schema_migrations(version,name,checksum)
419
+ values(21,'native_backup_reader','__AGENT_BRIDGE_MIGRATION_CHECKSUM__');
420
+
421
+ commit;
package/sql/setup.sql CHANGED
@@ -63,6 +63,4 @@ end;
63
63
  $$;
64
64
 
65
65
  comment on column shared_context.atrib_receipt_id is
66
- 'Optional signed atrib record receipt_id (record_hash "." creator_key, base64url) ' ||
67
- 'emitted by an atrib-signing wrapper at insert time. ' ||
68
- 'Consumers use this as the informed_by anchor for cross-process causal edges.';
66
+ 'Optional signed atrib record receipt_id (record_hash "." creator_key, base64url) emitted by an atrib-signing wrapper at insert time. Consumers use this as the informed_by anchor for cross-process causal edges.';
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/postgres-bridge-store.ts"],"sourcesContent":["import { randomUUID } from \"node:crypto\";\nimport {\n DeliveryStateConflictError,\n decodeCursor,\n decodeScopedCursor,\n encodeCursor,\n encodeScopedCursor,\n cursorScope,\n scopedCursorScope,\n validateDeliveryCursorPosition,\n validateEventCursorPosition,\n type AgentPresence,\n type BridgeDelivery,\n type BridgeDeliveryEvent,\n type BridgeMessage,\n type BridgePrincipal,\n type DeliveryPolicy,\n} from \"./bridge-domain.js\";\nimport type {\n BridgeStore,\n BridgeDiagnostics,\n ClaimOptions,\n InsertMessageResult,\n MessagePage,\n MessageQuery,\n DeliveryQuery,\n} from \"./bridge-store.js\";\nimport { assertIdempotentReplay } from \"./idempotency.js\";\n\nexport interface PgQueryable {\n query<T extends Record<string, unknown> = Record<string, unknown>>(\n sql: string,\n values?: unknown[],\n ): Promise<{ rows: T[]; rowCount: number | null }>;\n connect?(): Promise<PgTransactionClient>;\n release?(): void;\n /** True when the queryable is already owned by an explicit request transaction. */\n inTransaction?: boolean;\n}\nexport interface PgTransactionClient {\n query<T extends Record<string, unknown> = Record<string, unknown>>(\n sql: string,\n values?: unknown[],\n ): Promise<{ rows: T[]; rowCount: number | null }>;\n release(error?: Error | boolean): void;\n}\n\ntype Row = Record<string, any>;\n\nfunction json(value: unknown): string | null {\n return value === undefined ? null : JSON.stringify(value);\n}\n\nfunction parse(value: unknown): any {\n return typeof value === \"string\" ? JSON.parse(value) : value;\n}\n\nfunction asTimestamp(value: unknown): string | undefined {\n if (value === undefined || value === null) return undefined;\n if (value instanceof Date) return value.toISOString();\n return String(value);\n}\n\nfunction asMessage(row: Row): BridgeMessage {\n const deliveryPolicy: DeliveryPolicy = row.delivery_mode === \"mailbox\"\n ? { mode: \"mailbox\" }\n : {\n mode: \"leased\",\n maxAttempts: Number(row.delivery_max_attempts),\n retryBaseDelayMs: Number(row.delivery_retry_base_delay_ms),\n retryMaxDelayMs: Number(row.delivery_retry_max_delay_ms),\n retryJitterRatio: Number(row.delivery_retry_jitter_ratio),\n ...(row.delivery_not_before ? { notBefore: asTimestamp(row.delivery_not_before) } : {}),\n };\n return {\n id: String(row.id),\n workspace: String(row.workspace),\n project: row.project ?? undefined,\n source: String(row.source),\n sequence: String(row.sequence),\n type: String(row.type),\n content: String(row.content),\n contentType: String(row.content_type),\n data: parse(row.data),\n targets: parse(row.targets) ?? [],\n threadId: row.thread_id ?? undefined,\n replyToId: row.reply_to_id ?? undefined,\n correlationId: row.correlation_id ?? undefined,\n causationId: row.causation_id ?? undefined,\n priority: row.priority,\n expiresAt: asTimestamp(row.expires_at),\n idempotencyKey: row.idempotency_key ?? undefined,\n atribReceiptId: row.atrib_receipt_id ?? undefined,\n informedBy: parse(row.informed_by),\n metadata: parse(row.metadata),\n deliveryPolicy,\n createdAt: asTimestamp(row.created_at) ?? \"\",\n };\n}\n\nfunction asDelivery(row: Row): BridgeDelivery {\n return {\n id: String(row.id),\n messageId: String(row.message_id),\n workspace: String(row.workspace),\n recipient: String(row.recipient),\n state: row.state,\n attempt: Number(row.attempt),\n cycleAttempt: Number(row.cycle_attempt ?? row.attempt),\n requeueCount: Number(row.requeue_count ?? 0),\n createdAt: asTimestamp(row.created_at) ?? \"\",\n priorityRank: Number(row.priority_rank),\n availableAt: asTimestamp(row.available_at) ?? \"\",\n leaseToken: row.lease_token ?? undefined,\n leaseOwner: row.lease_owner ?? undefined,\n leaseExpiresAt: asTimestamp(row.lease_expires_at),\n lastError: row.last_error ?? undefined,\n lastActor: row.last_actor ?? undefined,\n lastAction: row.last_action,\n };\n}\n\nfunction asPresence(row: Row): AgentPresence {\n return {\n workspace: String(row.workspace), agent: String(row.agent), instance: String(row.instance),\n runtimeType: row.runtime_type ?? undefined, capabilities: parse(row.capabilities) ?? [],\n leaseExpiresAt: asTimestamp(row.lease_expires_at) ?? \"\", lastSeenAt: asTimestamp(row.last_seen_at) ?? \"\",\n };\n}\n\nfunction asDeliveryEvent(row: Row): BridgeDeliveryEvent {\n return {\n sequence: String(row.sequence), deliveryId: String(row.delivery_id),\n messageId: String(row.message_id), workspace: String(row.workspace),\n recipient: String(row.recipient),\n fromState: row.from_state == null ? undefined : row.from_state as BridgeDeliveryEvent[\"fromState\"],\n toState: row.to_state as BridgeDeliveryEvent[\"toState\"], attempt: Number(row.attempt),\n cycleAttempt: Number(row.cycle_attempt), requeueCount: Number(row.requeue_count),\n leaseOwner: row.lease_owner ?? undefined, error: row.error ?? undefined,\n actor: String(row.actor), action: row.action,\n createdAt: asTimestamp(row.created_at) ?? \"\",\n };\n}\n\nasync function transaction<T>(db: PgQueryable, work: (client: PgQueryable) => Promise<T>): Promise<T> {\n if (db.inTransaction) return work(db);\n const borrowed = !db.release && Boolean(db.connect);\n const client = borrowed ? await db.connect!() : db;\n try {\n await client.query(\"BEGIN\");\n const result = await work(client);\n await client.query(\"COMMIT\");\n return result;\n } catch (error) {\n await client.query(\"ROLLBACK\").catch(() => undefined);\n throw error;\n } finally {\n if (borrowed && \"release\" in client && typeof client.release === \"function\") client.release();\n }\n}\n\nexport class PostgresBridgeStore implements BridgeStore {\n constructor(private readonly db: PgQueryable) {}\n\n async initialize(): Promise<void> {\n // Deployments apply ordered migrations before starting the service.\n }\n\n async insertMessage(\n input: Omit<BridgeMessage, \"sequence\" | \"createdAt\">,\n ): Promise<InsertMessageResult> {\n const values = [\n input.id,\n input.workspace,\n input.project ?? null,\n input.source,\n input.type,\n input.content,\n input.contentType,\n json(input.data),\n json(input.targets),\n input.threadId ?? null,\n input.replyToId ?? null,\n input.correlationId ?? null,\n input.causationId ?? null,\n input.priority,\n input.expiresAt ?? null,\n input.idempotencyKey ?? null,\n input.atribReceiptId ?? null,\n json(input.informedBy),\n json(input.metadata),\n input.deliveryPolicy.mode,\n input.deliveryPolicy.mode === \"leased\" ? input.deliveryPolicy.maxAttempts : null,\n input.deliveryPolicy.mode === \"leased\" ? input.deliveryPolicy.retryBaseDelayMs : null,\n input.deliveryPolicy.mode === \"leased\" ? input.deliveryPolicy.retryMaxDelayMs : null,\n input.deliveryPolicy.mode === \"leased\" ? input.deliveryPolicy.retryJitterRatio : null,\n input.deliveryPolicy.mode === \"leased\" ? input.deliveryPolicy.notBefore ?? null : null,\n ];\n\n const result = await this.db.query<Row>(\n `WITH inserted AS (\n INSERT INTO agent_bridge.messages (\n id, workspace, project, source, type, content, content_type, data, targets,\n thread_id, reply_to_id, correlation_id, causation_id, priority,\n expires_at, idempotency_key, atrib_receipt_id, informed_by, metadata,\n delivery_mode, delivery_max_attempts, delivery_retry_base_delay_ms,\n delivery_retry_max_delay_ms, delivery_retry_jitter_ratio, delivery_not_before\n )\n VALUES (\n $1, $2, $3, $4, $5, $6, $7, $8::jsonb, $9::jsonb,\n $10, $11, $12, $13, $14, $15, $16, $17, $18::jsonb, $19::jsonb,\n $20, $21, $22, $23, $24, $25\n )\n ON CONFLICT (workspace, source, idempotency_key)\n WHERE idempotency_key IS NOT NULL\n DO NOTHING\n RETURNING *, true AS created\n ), selected AS (\n SELECT * FROM inserted\n UNION ALL\n SELECT existing.*, false AS created\n FROM agent_bridge.messages existing\n WHERE $16::text IS NOT NULL\n AND existing.workspace = $2\n AND existing.source = $4\n AND existing.idempotency_key = $16\n AND NOT EXISTS (SELECT 1 FROM inserted)\n LIMIT 1\n ), delivery_rows AS (\n INSERT INTO agent_bridge.deliveries (\n id, message_id, workspace, publisher, recipient, state, available_at,\n created_at, priority_rank, last_actor, last_action\n )\n SELECT gen_random_uuid(), inserted.id, inserted.workspace, inserted.source, target, 'pending',\n greatest(now(), coalesce(inserted.delivery_not_before, now())),\n inserted.created_at,\n case inserted.priority when 'urgent' then 0 when 'high' then 1 else 2 end,\n inserted.source, 'created'\n FROM inserted\n CROSS JOIN LATERAL jsonb_array_elements_text(inserted.targets) AS target\n WHERE inserted.delivery_mode = 'leased'\n ON CONFLICT (message_id, recipient) DO NOTHING\n )\n SELECT * FROM selected`,\n values,\n );\n\n let row = result.rows[0];\n if (!row && input.idempotencyKey) {\n const existing = await this.db.query<Row>(\n `SELECT *, false AS created\n FROM agent_bridge.messages\n WHERE workspace=$1 AND source=$2 AND idempotency_key=$3`,\n [input.workspace, input.source, input.idempotencyKey],\n );\n row = existing.rows[0];\n }\n if (!row) throw new Error(\"message insert did not return a row\");\n const message = asMessage(row);\n if (row.created !== true) assertIdempotentReplay(message, input);\n return { message, created: row.created === true };\n }\n\n async listMessages(\n principal: BridgePrincipal,\n query: MessageQuery = {},\n ): Promise<MessagePage> {\n const scope = cursorScope(principal, query);\n const cursor = decodeCursor(query.cursor, scope) ?? \"0\";\n const limit = Math.min(Math.max(Math.trunc(query.limit ?? 50), 1), 200);\n const boundary = query.latest ? undefined : await this.db.query<{ sequence: string | null }>(\n \"SELECT max(sequence)::text AS sequence FROM agent_bridge.messages WHERE workspace=$1\",\n [principal.workspace],\n );\n const highWater = boundary?.rows[0]?.sequence;\n const values: unknown[] = query.latest\n ? [principal.workspace, principal.agent]\n : [principal.workspace, cursor, principal.agent];\n const mailbox = query.mailbox ?? \"inbox\";\n const agentParam = query.latest ? 2 : 3;\n const visibility = mailbox === \"sent\" ? `source=$${agentParam}`\n : mailbox === \"all\" ? `(source=$${agentParam} OR targets='[]'::jsonb OR targets ? $${agentParam})`\n : `(targets='[]'::jsonb OR targets ? $${agentParam})`;\n let sql = `SELECT * FROM agent_bridge.messages WHERE workspace=$1 ${query.latest ? \"\" : \"AND sequence>$2::bigint \"}AND ${visibility}`;\n\n if (highWater) {\n values.push(highWater);\n sql += ` AND sequence <= $${values.length}::bigint`;\n }\n\n if (!query.includeExpired) {\n sql += \" AND (expires_at IS NULL OR expires_at > now())\";\n }\n if (query.types?.length) {\n values.push(query.types);\n sql += ` AND type = ANY($${values.length})`;\n }\n if (query.source) {\n values.push(query.source);\n sql += ` AND source = $${values.length}`;\n }\n if (query.project) {\n values.push(query.project);\n sql += ` AND project = $${values.length}`;\n }\n if (query.since) {\n values.push(query.since);\n sql += ` AND created_at >= $${values.length}::timestamptz`;\n }\n if (query.receiptState && query.receiptState !== \"any\") {\n sql += ` AND ${query.receiptState === \"unread\" ? \"NOT \" : \"\"}EXISTS (\n SELECT 1 FROM agent_bridge.receipts receipt\n WHERE receipt.workspace=agent_bridge.messages.workspace\n AND receipt.message_id=agent_bridge.messages.id\n AND receipt.principal=$${agentParam}\n )`;\n }\n if (query.threadId) {\n values.push(query.threadId);\n sql += ` AND thread_id = $${values.length}`;\n }\n\n values.push(limit);\n const result = await this.db.query<Row>(\n `${sql} ORDER BY sequence ${query.latest ? \"DESC\" : \"ASC\"} LIMIT $${values.length}`,\n values,\n );\n const messages = result.rows.map(asMessage);\n const last = messages[messages.length - 1];\n if (query.latest) return { messages, cursor: messages[0] ? encodeCursor(messages[0].sequence, scope) : query.cursor };\n if (messages.length === limit) return { messages, cursor: encodeCursor(last!.sequence, scope) };\n return { messages, cursor: highWater ? encodeCursor(highWater, scope) : query.cursor };\n }\n\n async recordReceipt(\n principal: BridgePrincipal,\n ids: string[],\n readAt = new Date(),\n ): Promise<number> {\n const result = await this.db.query(\n `INSERT INTO agent_bridge.receipts (workspace, message_id, principal, read_at)\n SELECT message.workspace, message.id, $3, $4\n FROM agent_bridge.messages message\n WHERE message.workspace = $1 AND message.id = ANY($2::uuid[])\n AND (message.targets='[]'::jsonb OR message.targets ? $3)\n ON CONFLICT DO NOTHING`,\n [principal.workspace, ids, principal.agent, readAt],\n );\n return result.rowCount ?? 0;\n }\n\n async claimDelivery(\n principal: BridgePrincipal,\n options: ClaimOptions,\n ): Promise<BridgeDelivery | null> {\n return transaction(this.db, async (db) => {\n await db.query(\n `UPDATE agent_bridge.deliveries delivery\n SET state='dead', last_error='message expired', lease_token=NULL,\n lease_owner=NULL, lease_expires_at=NULL,\n last_actor='agent-bridge', last_action='message_expired'\n FROM agent_bridge.messages message\n WHERE delivery.workspace=$1 AND delivery.recipient=$2\n AND delivery.state IN ('pending','retrying','claimed')\n AND message.workspace=delivery.workspace AND message.id=delivery.message_id\n AND message.expires_at IS NOT NULL AND message.expires_at<=now()`,\n [principal.workspace, principal.agent],\n );\n await db.query(\n `UPDATE agent_bridge.deliveries delivery\n SET state='dead', last_error='maximum attempts reached', lease_token=NULL,\n lease_owner=NULL, lease_expires_at=NULL,\n last_actor='agent-bridge', last_action='attempts_exhausted'\n FROM agent_bridge.messages message\n WHERE delivery.workspace=$1 AND delivery.recipient=$2\n AND message.workspace=delivery.workspace AND message.id=delivery.message_id\n AND delivery.cycle_attempt>=message.delivery_max_attempts\n AND (delivery.state IN ('pending','retrying')\n OR (delivery.state='claimed' AND delivery.lease_expires_at<=now()))`,\n [principal.workspace, principal.agent],\n );\n await db.query(\n `UPDATE agent_bridge.deliveries delivery\n SET state='retrying', available_at=now(), lease_token=NULL,\n lease_owner=NULL, lease_expires_at=NULL,\n last_error='lease expired', last_actor='agent-bridge', last_action='lease_expired'\n FROM agent_bridge.messages message\n WHERE delivery.workspace=$1 AND delivery.recipient=$2\n AND message.workspace=delivery.workspace AND message.id=delivery.message_id\n AND delivery.state='claimed' AND delivery.lease_expires_at<=now()\n AND delivery.cycle_attempt<message.delivery_max_attempts`,\n [principal.workspace, principal.agent],\n );\n const candidate = await db.query<Row>(\n `SELECT delivery.id\n FROM agent_bridge.deliveries delivery\n JOIN agent_bridge.messages message\n ON message.workspace=delivery.workspace AND message.id=delivery.message_id\n WHERE delivery.workspace=$1 AND delivery.recipient=$2\n AND delivery.state IN ('pending','retrying')\n AND delivery.available_at<=now()\n AND delivery.cycle_attempt<message.delivery_max_attempts\n AND (message.expires_at IS NULL OR message.expires_at>now())\n ORDER BY delivery.priority_rank, delivery.available_at, delivery.created_at, delivery.id\n FOR UPDATE OF delivery SKIP LOCKED\n LIMIT 1`,\n [principal.workspace, principal.agent],\n );\n if (!candidate.rows[0]) return null;\n const token = randomUUID();\n const owner = principal.instance ?? principal.agent;\n const claimed = await db.query<Row>(\n `UPDATE agent_bridge.deliveries\n SET state='claimed', attempt=attempt+1, cycle_attempt=cycle_attempt+1,\n lease_token=$1, lease_owner=$2,\n lease_expires_at=now()+($3*interval '1 millisecond'),\n last_error=NULL, last_actor=$4, last_action='claim'\n WHERE id=$5\n RETURNING *`,\n [token, owner, options.leaseMs, principal.agent, candidate.rows[0].id],\n );\n return asDelivery(claimed.rows[0]!);\n });\n }\n\n async renewDelivery(\n principal: BridgePrincipal,\n id: string,\n token: string,\n leaseMs: number,\n ): Promise<BridgeDelivery | null> {\n const result = await this.db.query<Row>(\n `UPDATE agent_bridge.deliveries\n SET lease_expires_at=now() + ($1 * interval '1 millisecond')\n WHERE workspace=$2 AND recipient=$3 AND lease_owner=$4 AND id=$5 AND lease_token=$6\n AND state='claimed' AND lease_expires_at>now()\n RETURNING *`,\n [leaseMs, principal.workspace, principal.agent, principal.instance ?? principal.agent, id, token],\n );\n return result.rows[0] ? asDelivery(result.rows[0]) : null;\n }\n\n async settleDelivery(\n principal: BridgePrincipal,\n id: string,\n token: string,\n state: \"acked\" | \"retrying\" | \"dead\",\n error?: string,\n _retryPolicy?: import(\"./bridge-domain.js\").RetryPolicy,\n ): Promise<BridgeDelivery | null> {\n const result = await this.db.query<Row>(\n `UPDATE agent_bridge.deliveries delivery\n SET state=CASE\n WHEN $1='retrying' AND cycle_attempt>=message.delivery_max_attempts THEN 'dead'\n ELSE $1\n END,\n available_at=CASE\n WHEN $1='retrying' AND cycle_attempt<message.delivery_max_attempts THEN\n now() + (\n LEAST(message.delivery_retry_max_delay_ms::double precision,\n message.delivery_retry_base_delay_ms::double precision * power(2, GREATEST(cycle_attempt - 1, 0)))\n * (1 + ((random() * 2) - 1) * message.delivery_retry_jitter_ratio)\n * interval '1 millisecond'\n )\n ELSE available_at\n END,\n last_error=$2, lease_token=NULL, lease_owner=NULL, lease_expires_at=NULL,\n last_actor=$4,\n last_action=CASE\n WHEN $1='acked' THEN 'ack'\n WHEN $1='dead' THEN 'nack_dead'\n WHEN cycle_attempt>=message.delivery_max_attempts THEN 'attempts_exhausted'\n ELSE 'nack_retry'\n END\n FROM agent_bridge.messages message\n WHERE delivery.workspace=$3 AND delivery.recipient=$4 AND delivery.lease_owner=$5\n AND message.workspace=delivery.workspace AND message.id=delivery.message_id\n AND delivery.id=$6 AND delivery.lease_token=$7 AND delivery.state='claimed' AND delivery.lease_expires_at>now()\n RETURNING delivery.*`,\n [\n state,\n error?.slice(0, 1024) ?? null,\n principal.workspace,\n principal.agent,\n principal.instance ?? principal.agent,\n id,\n token,\n ],\n );\n return result.rows[0] ? asDelivery(result.rows[0]) : null;\n }\n\n async listDeliveries(principal: BridgePrincipal, query: DeliveryQuery = {}) {\n const filters = {\n role: query.role ?? \"all\",\n states: [...(query.states ?? [])].sort(),\n messageId: query.messageId ?? null,\n recipient: query.recipient ?? null,\n };\n const scope = scopedCursorScope(\"deliveries\", principal, filters);\n const boundary = validateDeliveryCursorPosition(decodeScopedCursor(query.cursor, scope));\n const createdAt = boundary?.createdAt;\n const id = boundary?.id;\n const limit = query.limit ?? 50;\n const values: unknown[] = [principal.workspace, principal.agent];\n const clauses = [\"delivery.workspace=$1\"];\n const role = query.role ?? \"all\";\n clauses.push(role === \"recipient\" ? \"delivery.recipient=$2\" : role === \"publisher\" ? \"message.source=$2\" : \"(delivery.recipient=$2 OR message.source=$2)\");\n if (createdAt && id) {\n values.push(createdAt, id);\n clauses.push(`(delivery.created_at,delivery.id)>($${values.length - 1}::timestamptz,$${values.length}::uuid)`);\n }\n if (query.messageId) { values.push(query.messageId); clauses.push(`delivery.message_id=$${values.length}`); }\n if (query.recipient) { values.push(query.recipient); clauses.push(`delivery.recipient=$${values.length}`); }\n if (query.states?.length) { values.push(query.states); clauses.push(`delivery.state=ANY($${values.length}::text[])`); }\n values.push(limit);\n const result = await this.db.query<Row>(\n `SELECT delivery.* FROM agent_bridge.deliveries delivery\n JOIN agent_bridge.messages message ON message.workspace=delivery.workspace AND message.id=delivery.message_id\n WHERE ${clauses.join(\" AND \")}\n ORDER BY delivery.created_at,delivery.id LIMIT $${values.length}`,\n values,\n );\n const deliveries = result.rows.map(asDelivery);\n const last = deliveries[deliveries.length - 1];\n return { deliveries, cursor: deliveries.length === limit && last ? encodeScopedCursor(scope, { createdAt: last.createdAt, id: last.id }) : undefined };\n }\n\n async listDeliveryEvents(principal: BridgePrincipal, id: string, query: { cursor?: string; limit?: number } = {}) {\n const limit = Math.min(Math.max(query.limit ?? 50, 1), 200);\n const scope = scopedCursorScope(\"delivery-events\", principal, { deliveryId: id });\n const position = validateEventCursorPosition(decodeScopedCursor(query.cursor, scope));\n const result = await this.db.query<Row>(\n `SELECT event.* FROM agent_bridge.delivery_events event\n JOIN agent_bridge.messages message ON message.workspace=event.workspace AND message.id=event.message_id\n WHERE event.workspace=$1 AND event.delivery_id=$2 AND event.sequence>$3::bigint\n AND (event.recipient=$4 OR message.source=$4)\n ORDER BY event.sequence LIMIT $5`,\n [principal.workspace, id, position ?? \"0\", principal.agent, limit],\n );\n const events = result.rows.map(asDeliveryEvent);\n const last = events[events.length - 1];\n return { events, cursor: events.length === limit && last ? encodeScopedCursor(scope, last.sequence) : undefined };\n }\n\n async cancelDelivery(principal: BridgePrincipal, id: string) {\n return transaction(this.db, async (db) => {\n const visible = await db.query<Row>(\n `SELECT delivery.* FROM agent_bridge.deliveries delivery\n JOIN agent_bridge.messages message ON message.workspace=delivery.workspace AND message.id=delivery.message_id\n WHERE delivery.id=$1 AND delivery.workspace=$2 AND message.source=$3 FOR UPDATE OF delivery`,\n [id, principal.workspace, principal.agent],\n );\n const current = visible.rows[0];\n if (!current) return null;\n if (current.state === \"cancelled\") return asDelivery(current);\n if (![\"pending\", \"retrying\", \"claimed\"].includes(current.state)) {\n throw new DeliveryStateConflictError(`cannot cancel a ${current.state} delivery`);\n }\n const result = await db.query<Row>(\n `UPDATE agent_bridge.deliveries SET state='cancelled', lease_token=NULL,\n lease_owner=NULL, lease_expires_at=NULL, last_error=NULL,\n last_actor=$1, last_action='cancel' WHERE id=$2 RETURNING *`,\n [principal.agent, id],\n );\n return asDelivery(result.rows[0]!);\n });\n }\n\n async requeueDelivery(principal: BridgePrincipal, id: string) {\n return transaction(this.db, async (db) => {\n const visible = await db.query<Row>(\n `SELECT delivery.*,message.expires_at,message.delivery_not_before\n FROM agent_bridge.deliveries delivery\n JOIN agent_bridge.messages message ON message.workspace=delivery.workspace AND message.id=delivery.message_id\n WHERE delivery.id=$1 AND delivery.workspace=$2 AND message.source=$3 FOR UPDATE OF delivery`,\n [id, principal.workspace, principal.agent],\n );\n const current = visible.rows[0];\n if (!current) return null;\n if (![\"dead\", \"cancelled\"].includes(current.state)) {\n throw new DeliveryStateConflictError(`cannot requeue a ${current.state} delivery`);\n }\n if (current.expires_at && new Date(current.expires_at).getTime() <= Date.now()) {\n throw new DeliveryStateConflictError(\"cannot requeue an expired message\");\n }\n const result = await db.query<Row>(\n `UPDATE agent_bridge.deliveries SET state='pending',\n available_at=greatest(now(),coalesce($1::timestamptz,now())),\n cycle_attempt=0,requeue_count=requeue_count+1,\n lease_token=NULL,lease_owner=NULL,lease_expires_at=NULL,last_error=NULL,\n last_actor=$2,last_action='requeue' WHERE id=$3 RETURNING *`,\n [current.delivery_not_before, principal.agent, id],\n );\n return asDelivery(result.rows[0]!);\n });\n }\n\n async diagnostics(principal: BridgePrincipal): Promise<BridgeDiagnostics> {\n const result = await this.db.query<Row>(\n `SELECT\n count(*) FILTER (WHERE state='pending')::integer AS pending,\n count(*) FILTER (WHERE state='claimed')::integer AS claimed,\n count(*) FILTER (WHERE state='retrying')::integer AS retrying,\n count(*) FILTER (WHERE state='dead')::integer AS dead,\n count(*) FILTER (WHERE state='cancelled')::integer AS cancelled,\n min(available_at) FILTER (WHERE state IN ('pending','retrying')) AS oldest_available,\n count(*) FILTER (WHERE state IN ('pending','retrying') AND available_at<=now())::integer AS due,\n count(*) FILTER (WHERE state IN ('pending','retrying') AND available_at>now())::integer AS scheduled,\n count(*) FILTER (WHERE state='claimed' AND lease_expires_at<=now())::integer AS expired_leases,\n min(available_at) FILTER (WHERE state IN ('pending','retrying') AND available_at<=now()) AS oldest_due,\n coalesce(greatest(0,extract(epoch FROM (now()-min(available_at) FILTER (WHERE state IN ('pending','retrying') AND available_at<=now())))*1000),0)::bigint AS queue_lag_ms\n FROM agent_bridge.deliveries WHERE workspace=$1 AND recipient=$2`,\n [principal.workspace, principal.agent],\n );\n const queue = result.rows[0] ?? {};\n return {\n schemaVersion: \"postgres-v2\",\n deliverySupported: true,\n pending: Number(queue.pending ?? 0),\n claimed: Number(queue.claimed ?? 0),\n retrying: Number(queue.retrying ?? 0),\n dead: Number(queue.dead ?? 0),\n cancelled: Number(queue.cancelled ?? 0),\n oldestAvailableAt: asTimestamp(queue.oldest_available),\n due: Number(queue.due ?? 0),\n scheduled: Number(queue.scheduled ?? 0),\n expiredLeases: Number(queue.expired_leases ?? 0),\n oldestDueAt: asTimestamp(queue.oldest_due),\n queueLagMs: Number(queue.queue_lag_ms ?? 0),\n };\n }\n\n async heartbeat(principal: BridgePrincipal, leaseMs: number, runtimeType?: string, capabilities: string[] = []): Promise<AgentPresence> {\n await this.db.query(\n \"DELETE FROM agent_bridge.agent_instances WHERE workspace=$1 AND lease_expires_at<=now()\",\n [principal.workspace],\n );\n const result = await this.db.query<Row>(\n `WITH locked AS (\n SELECT pg_advisory_xact_lock(hashtextextended($1, 0))\n )\n INSERT INTO agent_bridge.agent_instances (workspace,agent,instance,runtime_type,capabilities,lease_expires_at,last_seen_at)\n SELECT $1,$2,$3,$4,$5::jsonb,now() + ($6 * interval '1 millisecond'),now()\n FROM locked\n WHERE EXISTS (\n SELECT 1 FROM agent_bridge.agent_instances\n WHERE workspace=$1 AND agent=$2 AND instance=$3\n ) OR ((\n SELECT count(*) < 128 FROM agent_bridge.agent_instances\n WHERE workspace=$1 AND agent=$2\n ) AND (\n SELECT count(*) < 4096 FROM agent_bridge.agent_instances\n WHERE workspace=$1\n )\n )\n ON CONFLICT (workspace,agent,instance) DO UPDATE SET runtime_type=excluded.runtime_type,capabilities=excluded.capabilities,lease_expires_at=excluded.lease_expires_at,last_seen_at=excluded.last_seen_at\n RETURNING *`,\n [principal.workspace, principal.agent, principal.instance, runtimeType ?? null, JSON.stringify(capabilities), leaseMs],\n );\n if (!result.rows[0]) {\n throw Object.assign(new Error(\"active instance limit reached\"), {\n status: 429,\n code: \"presence_limit\",\n });\n }\n return asPresence(result.rows[0]!);\n }\n\n async listPresence(principal: BridgePrincipal): Promise<AgentPresence[]> {\n await this.db.query(\n \"DELETE FROM agent_bridge.agent_instances WHERE workspace=$1 AND lease_expires_at<=now()\",\n [principal.workspace],\n );\n const result = await this.db.query<Row>(\n \"SELECT * FROM agent_bridge.agent_instances WHERE workspace=$1 ORDER BY agent,instance\",\n [principal.workspace],\n );\n return result.rows.map(asPresence);\n }\n\n}\n"],"mappings":"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","names":[]}