@creatornader/agent-bridge 0.3.0 → 0.4.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 (75) hide show
  1. package/CHANGELOG.md +174 -5
  2. package/README.md +341 -33
  3. package/ROADMAP.md +78 -16
  4. package/SECURITY.md +68 -1
  5. package/SKILL.md +104 -1
  6. package/dist/archive.d.ts +2 -2
  7. package/dist/archive.js +2 -2
  8. package/dist/{bridge-service-hX1ZQp4W.d.ts → bridge-service-YTjGr91A.d.ts} +1 -1
  9. package/dist/{bridge-store-DPVSCwfs.d.ts → bridge-store-Boaj-ZbO.d.ts} +2 -0
  10. package/dist/bridge.d.ts +17 -7
  11. package/dist/bridge.js +15 -7
  12. package/dist/{chunk-WAI2IYIQ.js → chunk-3YHVUPU2.js} +48 -5
  13. package/dist/chunk-3YHVUPU2.js.map +1 -0
  14. package/dist/{chunk-45BZGB77.js → chunk-6BTJE6D4.js} +168 -7
  15. package/dist/chunk-6BTJE6D4.js.map +1 -0
  16. package/dist/{chunk-5GMB3A77.js → chunk-DQOZJJZ2.js} +22 -10
  17. package/dist/chunk-DQOZJJZ2.js.map +1 -0
  18. package/dist/{chunk-NCO7RLBM.js → chunk-GTK4KOED.js} +108 -8
  19. package/dist/chunk-GTK4KOED.js.map +1 -0
  20. package/dist/{chunk-GADH244D.js → chunk-IHZFI7TH.js} +12 -4
  21. package/dist/chunk-IHZFI7TH.js.map +1 -0
  22. package/dist/{chunk-CEXBMOI5.js → chunk-LAHNQZDN.js} +2 -2
  23. package/dist/{chunk-UAHMP6GC.js → chunk-MCKKVNCE.js} +9 -6
  24. package/dist/chunk-MCKKVNCE.js.map +1 -0
  25. package/dist/{chunk-MBPZXTJA.js → chunk-PDIHDBP3.js} +173 -20
  26. package/dist/chunk-PDIHDBP3.js.map +1 -0
  27. package/dist/{chunk-Q6PPMXJC.js → chunk-SV3SVBYS.js} +377 -21
  28. package/dist/chunk-SV3SVBYS.js.map +1 -0
  29. package/dist/{chunk-SPSMZOCJ.js → chunk-SYGONYMM.js} +4 -4
  30. package/dist/{chunk-A6W4QALF.js → chunk-TC6A7GMF.js} +2 -2
  31. package/dist/cli.js +5856 -413
  32. package/dist/cli.js.map +1 -1
  33. package/dist/client-runtime.d.ts +4 -2
  34. package/dist/client-runtime.js +6 -6
  35. package/dist/contracts/generate.js +1 -1
  36. package/dist/dr.d.ts +9 -2
  37. package/dist/dr.js +6 -4
  38. package/dist/{gateway-CggQ8vTC.d.ts → gateway-BQHpV-MZ.d.ts} +27 -3
  39. package/dist/gateway-main.js +69 -5
  40. package/dist/gateway-main.js.map +1 -1
  41. package/dist/gateway.d.ts +3 -3
  42. package/dist/gateway.js +2 -2
  43. package/dist/index.js +7 -7
  44. package/dist/{postgres-bridge-store-Bfd3hRId.d.ts → postgres-bridge-store-WASumj26.d.ts} +1 -1
  45. package/dist/server.js +7 -7
  46. package/dist/sqlite-edge-store-Bc15DvpX.d.ts +148 -0
  47. package/dist/sqlite.d.ts +19 -80
  48. package/dist/sqlite.js +11 -3
  49. package/docs/architecture-v2.md +278 -13
  50. package/docs/decisions/0001-protocol-layers-and-acknowledgment-semantics.md +2 -2
  51. package/docs/decisions/0003-host-adapters-and-consumer-instance-keys.md +88 -0
  52. package/docs/decisions/0004-client-lifecycle-and-endpoint-migration.md +204 -0
  53. package/docs/deployment.md +205 -0
  54. package/docs/ecosystem.md +35 -3
  55. package/docs/troubleshooting.md +23 -0
  56. package/llms.txt +79 -3
  57. package/openapi/agent-bridge-v2.openapi.json +1023 -0
  58. package/package.json +6 -2
  59. package/schemas/agent-bridge-v2.capabilities.json +24 -0
  60. package/schemas/agent-bridge-v2.mcp.json +6 -0
  61. package/schemas/agent-bridge-v2.schema.json +163 -0
  62. package/sql/migrations/017_gateway_authority_binding.sql +99 -0
  63. package/sql/migrations/018_endpoint_migration_challenges.sql +1028 -0
  64. package/sql/migrations/019_endpoint_migration_same_successor.sql +324 -0
  65. package/dist/chunk-45BZGB77.js.map +0 -1
  66. package/dist/chunk-5GMB3A77.js.map +0 -1
  67. package/dist/chunk-GADH244D.js.map +0 -1
  68. package/dist/chunk-MBPZXTJA.js.map +0 -1
  69. package/dist/chunk-NCO7RLBM.js.map +0 -1
  70. package/dist/chunk-Q6PPMXJC.js.map +0 -1
  71. package/dist/chunk-UAHMP6GC.js.map +0 -1
  72. package/dist/chunk-WAI2IYIQ.js.map +0 -1
  73. /package/dist/{chunk-CEXBMOI5.js.map → chunk-LAHNQZDN.js.map} +0 -0
  74. /package/dist/{chunk-SPSMZOCJ.js.map → chunk-SYGONYMM.js.map} +0 -0
  75. /package/dist/{chunk-A6W4QALF.js.map → chunk-TC6A7GMF.js.map} +0 -0
@@ -56,6 +56,25 @@ var REQUIRED_COLUMNS = /* @__PURE__ */ new Map([
56
56
  ["request_authorities.principal", "text"],
57
57
  ["request_authorities.scopes", "_text"],
58
58
  ["request_authorities.opened_session_user", "name"],
59
+ ["request_authorities.authorized_endpoint_migration_operation", "text"],
60
+ ["gateway_authority.singleton", "bool"],
61
+ ["gateway_authority.authority_id", "uuid"],
62
+ ["endpoint_migration_challenges.challenge_hash", "bpchar"],
63
+ ["endpoint_migration_challenges.authority_id", "uuid"],
64
+ ["endpoint_migration_challenges.workspace_id", "text"],
65
+ ["endpoint_migration_challenges.principal", "text"],
66
+ ["endpoint_migration_challenges.issuer_credential_id", "uuid"],
67
+ ["endpoint_migration_challenges.verifier_credential_id", "uuid"],
68
+ ["endpoint_migration_challenges.issued_at", "timestamptz"],
69
+ ["endpoint_migration_challenges.expires_at", "timestamptz"],
70
+ ["endpoint_migration_challenges.consumed_at", "timestamptz"],
71
+ ["endpoint_migration_challenge_events.sequence", "int8"],
72
+ ["endpoint_migration_challenge_events.event_id", "uuid"],
73
+ ["endpoint_migration_challenge_events.request_id", "uuid"],
74
+ ["endpoint_migration_challenge_events.event_type", "text"],
75
+ ["endpoint_migration_challenge_events.created_at", "timestamptz"],
76
+ ["endpoint_migration_challenge_attestations.name", "text"],
77
+ ["endpoint_migration_challenge_attestations.catalog_definition", "text"],
59
78
  ["row_isolation_attestations.name", "text"],
60
79
  ["row_isolation_attestations.catalog_definition", "text"],
61
80
  ["row_isolation_attestations.attested_at", "timestamptz"],
@@ -196,7 +215,10 @@ var REQUIRED_MIGRATIONS = [
196
215
  { version: 13, name: "row_isolation" },
197
216
  { version: 14, name: "owner_control_plane" },
198
217
  { version: 15, name: "portable_archives" },
199
- { version: 16, name: "native_dr_fence" }
218
+ { version: 16, name: "native_dr_fence" },
219
+ { version: 17, name: "gateway_authority_binding" },
220
+ { version: 18, name: "endpoint_migration_challenges" },
221
+ { version: 19, name: "endpoint_migration_same_successor" }
200
222
  ];
201
223
  function withNativeDrSharedLock(source) {
202
224
  if (!/^begin;\s/i.test(source)) {
@@ -584,11 +606,70 @@ async function runtimeSchemaReady(db, options = {}) {
584
606
  to_regprocedure('agent_bridge.consume_rate_limit(uuid,text,uuid)') IS NOT NULL AS "rateConsume",
585
607
  to_regprocedure('agent_bridge.security_schema_ready()') IS NOT NULL AS "securityReady",
586
608
  to_regclass('agent_bridge.request_authorities') IS NOT NULL AS "requestAuthorities",
609
+ to_regclass('agent_bridge.gateway_authority') IS NOT NULL AS "gatewayAuthority",
610
+ (
611
+ (SELECT attribute.attnotnull
612
+ FROM pg_attribute attribute
613
+ WHERE attribute.attrelid=to_regclass('agent_bridge.gateway_authority')
614
+ AND attribute.attname='singleton' AND attribute.attnum>0 AND NOT attribute.attisdropped)
615
+ AND (SELECT attribute.attnotnull
616
+ FROM pg_attribute attribute
617
+ WHERE attribute.attrelid=to_regclass('agent_bridge.gateway_authority')
618
+ AND attribute.attname='authority_id' AND attribute.attnum>0 AND NOT attribute.attisdropped)
619
+ AND EXISTS (
620
+ SELECT 1 FROM pg_constraint table_constraint
621
+ WHERE table_constraint.conrelid=to_regclass('agent_bridge.gateway_authority')
622
+ AND table_constraint.conname='gateway_authority_singleton'
623
+ AND table_constraint.contype='p'
624
+ AND table_constraint.conkey::smallint[]=ARRAY[(SELECT attribute.attnum FROM pg_attribute attribute
625
+ WHERE attribute.attrelid=to_regclass('agent_bridge.gateway_authority')
626
+ AND attribute.attname='singleton' AND attribute.attnum>0 AND NOT attribute.attisdropped)]
627
+ )
628
+ AND EXISTS (
629
+ SELECT 1 FROM pg_constraint table_constraint
630
+ WHERE table_constraint.conrelid=to_regclass('agent_bridge.gateway_authority')
631
+ AND table_constraint.conname='gateway_authority_singleton_true'
632
+ AND table_constraint.contype='c'
633
+ AND regexp_replace(
634
+ pg_get_expr(table_constraint.conbin,table_constraint.conrelid),'[[:space:]()]','','g'
635
+ )='singleton'
636
+ )
637
+ AND EXISTS (
638
+ SELECT 1 FROM pg_constraint table_constraint
639
+ WHERE table_constraint.conrelid=to_regclass('agent_bridge.gateway_authority')
640
+ AND table_constraint.conname='gateway_authority_id_unique'
641
+ AND table_constraint.contype='u'
642
+ AND table_constraint.conkey::smallint[]=ARRAY[(SELECT attribute.attnum FROM pg_attribute attribute
643
+ WHERE attribute.attrelid=to_regclass('agent_bridge.gateway_authority')
644
+ AND attribute.attname='authority_id' AND attribute.attnum>0 AND NOT attribute.attisdropped)]
645
+ )
646
+ ) AS "gatewayAuthorityShape",
647
+ EXISTS (
648
+ SELECT 1
649
+ FROM pg_trigger trigger
650
+ JOIN pg_proc trigger_function ON trigger_function.oid=trigger.tgfoid
651
+ JOIN pg_namespace trigger_namespace ON trigger_namespace.oid=trigger_function.pronamespace
652
+ WHERE trigger.tgrelid=to_regclass('agent_bridge.gateway_authority')
653
+ AND trigger.tgname='gateway_authority_immutable'
654
+ AND NOT trigger.tgisinternal AND trigger.tgenabled='O'
655
+ AND (trigger.tgtype::integer & 1)=0
656
+ AND (trigger.tgtype::integer & 2)=2
657
+ AND (trigger.tgtype::integer & 56)=56
658
+ AND trigger_function.proname='reject_gateway_authority_mutation'
659
+ AND trigger_namespace.nspname='agent_bridge'
660
+ AND trigger_function.proowner=(SELECT nspowner FROM pg_namespace WHERE nspname='agent_bridge')
661
+ AND NOT trigger_function.prosecdef
662
+ AND coalesce(trigger_function.proconfig @> ARRAY['search_path=""'],false)
663
+ ) AS "gatewayAuthorityImmutable",
587
664
  to_regprocedure('agent_bridge.open_request_authority(uuid,text,uuid)') IS NOT NULL
588
665
  AND to_regprocedure('agent_bridge.resolve_credential_hash(text)') IS NOT NULL AS "authorityOpen",
666
+ to_regprocedure('agent_bridge.open_request_authority_bound(uuid,text,uuid)') IS NOT NULL AS "authorityBoundOpen",
589
667
  to_regprocedure('agent_bridge.close_request_authority()') IS NOT NULL AS "authorityClose",
668
+ to_regprocedure('agent_bridge.gateway_authority_ready()') IS NOT NULL AS "authorityReady",
590
669
  NOT has_table_privilege((SELECT runtime_role FROM names),'agent_bridge.credentials','SELECT') AS "credentialDigestHidden",
591
670
  NOT has_table_privilege((SELECT runtime_role FROM names),'agent_bridge.request_authorities','SELECT') AS "authorityRowsHidden",
671
+ (NOT has_table_privilege((SELECT runtime_role FROM names),'agent_bridge.gateway_authority','SELECT')
672
+ AND NOT has_table_privilege('public','agent_bridge.gateway_authority','SELECT')) AS "gatewayAuthorityRowsHidden",
592
673
  (NOT has_table_privilege((SELECT runtime_role FROM names),'agent_bridge.agents','SELECT')
593
674
  AND NOT has_table_privilege((SELECT runtime_role FROM names),'agent_bridge.workspaces','SELECT')) AS "principalTablesHidden",
594
675
  (
@@ -596,7 +677,8 @@ async function runtimeSchemaReady(db, options = {}) {
596
677
  SELECT 1
597
678
  FROM unnest(ARRAY[
598
679
  'agent_bridge.credentials','agent_bridge.agents',
599
- 'agent_bridge.workspaces','agent_bridge.request_authorities'
680
+ 'agent_bridge.workspaces','agent_bridge.request_authorities',
681
+ 'agent_bridge.gateway_authority'
600
682
  ]) protected_table(value)
601
683
  CROSS JOIN unnest(ARRAY[
602
684
  'SELECT','INSERT','UPDATE','DELETE','TRUNCATE','REFERENCES','TRIGGER'
@@ -609,7 +691,8 @@ async function runtimeSchemaReady(db, options = {}) {
609
691
  SELECT 1
610
692
  FROM unnest(ARRAY[
611
693
  'agent_bridge.credentials','agent_bridge.agents',
612
- 'agent_bridge.workspaces','agent_bridge.request_authorities'
694
+ 'agent_bridge.workspaces','agent_bridge.request_authorities',
695
+ 'agent_bridge.gateway_authority'
613
696
  ]) protected_table(value)
614
697
  CROSS JOIN unnest(ARRAY['SELECT','INSERT','UPDATE','REFERENCES']) requested_privilege(value)
615
698
  WHERE has_any_column_privilege(
@@ -617,10 +700,26 @@ async function runtimeSchemaReady(db, options = {}) {
617
700
  )
618
701
  )
619
702
  ) AS "authorityTablesLocked",
703
+ NOT EXISTS (
704
+ SELECT 1
705
+ FROM unnest(ARRAY[
706
+ 'SELECT','INSERT','UPDATE','DELETE','TRUNCATE','REFERENCES','TRIGGER'
707
+ ]) requested_privilege(value)
708
+ WHERE has_table_privilege('public','agent_bridge.gateway_authority',requested_privilege.value)
709
+ )
710
+ AND NOT EXISTS (
711
+ SELECT 1
712
+ FROM unnest(ARRAY['SELECT','INSERT','UPDATE','REFERENCES']) requested_privilege(value)
713
+ WHERE has_any_column_privilege(
714
+ 'public','agent_bridge.gateway_authority',requested_privilege.value
715
+ )
716
+ ) AS "gatewayAuthorityPublicLocked",
620
717
  (
621
718
  has_function_privilege((SELECT runtime_role FROM names),'agent_bridge.resolve_credential_hash(text)','EXECUTE')
622
719
  AND has_function_privilege((SELECT runtime_role FROM names),'agent_bridge.open_request_authority(uuid,text,uuid)','EXECUTE')
720
+ AND has_function_privilege((SELECT runtime_role FROM names),'agent_bridge.open_request_authority_bound(uuid,text,uuid)','EXECUTE')
623
721
  AND has_function_privilege((SELECT runtime_role FROM names),'agent_bridge.close_request_authority()','EXECUTE')
722
+ AND has_function_privilege((SELECT runtime_role FROM names),'agent_bridge.gateway_authority_ready()','EXECUTE')
624
723
  AND has_function_privilege((SELECT runtime_role FROM names),'agent_bridge.record_scope_denial(uuid,text,uuid)','EXECUTE')
625
724
  AND has_function_privilege((SELECT runtime_role FROM names),'agent_bridge.consume_rate_limit(uuid,text,uuid)','EXECUTE')
626
725
  AND NOT has_function_privilege((SELECT runtime_role FROM names),'agent_bridge.active_request_authority()','EXECUTE')
@@ -629,7 +728,9 @@ async function runtimeSchemaReady(db, options = {}) {
629
728
  AND NOT has_function_privilege((SELECT runtime_role FROM names),'agent_bridge.consume_rate_limit_unbound_011(uuid,text,uuid)','EXECUTE')
630
729
  AND NOT has_function_privilege('public','agent_bridge.resolve_credential_hash(text)','EXECUTE')
631
730
  AND NOT has_function_privilege('public','agent_bridge.open_request_authority(uuid,text,uuid)','EXECUTE')
731
+ AND NOT has_function_privilege('public','agent_bridge.open_request_authority_bound(uuid,text,uuid)','EXECUTE')
632
732
  AND NOT has_function_privilege('public','agent_bridge.close_request_authority()','EXECUTE')
733
+ AND NOT has_function_privilege('public','agent_bridge.gateway_authority_ready()','EXECUTE')
633
734
  AND NOT has_function_privilege('public','agent_bridge.record_scope_denial(uuid,text,uuid)','EXECUTE')
634
735
  AND NOT has_function_privilege('public','agent_bridge.consume_rate_limit(uuid,text,uuid)','EXECUTE')
635
736
  AND NOT has_function_privilege('public','agent_bridge.record_scope_denial_unbound_011(uuid,text,uuid)','EXECUTE')
@@ -639,7 +740,8 @@ async function runtimeSchemaReady(db, options = {}) {
639
740
  JOIN pg_namespace namespace ON namespace.oid=procedure.pronamespace
640
741
  WHERE namespace.nspname='agent_bridge'
641
742
  AND procedure.proname IN (
642
- 'resolve_credential_hash','open_request_authority','active_request_authority',
743
+ 'resolve_credential_hash','open_request_authority','open_request_authority_bound',
744
+ 'gateway_authority_ready','active_request_authority',
643
745
  'assert_active_request_credential','close_request_authority','record_scope_denial',
644
746
  'consume_rate_limit','record_scope_denial_unbound_011','consume_rate_limit_unbound_011'
645
747
  )
@@ -653,8 +755,64 @@ async function runtimeSchemaReady(db, options = {}) {
653
755
  );
654
756
  const row = objects.rows[0];
655
757
  if (!Boolean(
656
- row?.immutable && row.deliveryAudit && row.idempotency && row.claim && row.publisher && row.terminal && row.source && row.thread && row.created && row.presence && row.project && row.targets && row.scopeSets && row.securityEvents && row.ratePolicies && row.rateBuckets && row.replacement && row.rateCleanup && row.credentialSecurity && row.eventAppendOnly && row.scopeAudit && row.rateConsume && row.securityReady && row.requestAuthorities && row.authorityOpen && row.authorityClose && row.credentialDigestHidden && row.authorityRowsHidden && row.principalTablesHidden && row.authorityTablesLocked && row.authorityCatalog
758
+ row?.immutable && row.deliveryAudit && row.idempotency && row.claim && row.publisher && row.terminal && row.source && row.thread && row.created && row.presence && row.project && row.targets && row.scopeSets && row.securityEvents && row.ratePolicies && row.rateBuckets && row.replacement && row.rateCleanup && row.credentialSecurity && row.eventAppendOnly && row.scopeAudit && row.rateConsume && row.securityReady && row.requestAuthorities && row.gatewayAuthority && row.gatewayAuthorityShape && row.gatewayAuthorityImmutable && row.authorityOpen && row.authorityBoundOpen && row.authorityClose && row.authorityReady && row.credentialDigestHidden && row.authorityRowsHidden && row.gatewayAuthorityRowsHidden && row.principalTablesHidden && row.authorityTablesLocked && row.gatewayAuthorityPublicLocked && row.authorityCatalog
657
759
  )) return false;
760
+ const endpointChallenge = await db.query(`
761
+ WITH names AS (
762
+ SELECT ('agent_bridge_runtime_' || substr(md5(current_database()),1,16))::name AS runtime_role
763
+ ) SELECT
764
+ to_regclass('agent_bridge.endpoint_migration_challenges') IS NOT NULL
765
+ AND to_regclass('agent_bridge.endpoint_migration_challenge_events') IS NOT NULL
766
+ AND to_regclass('agent_bridge.endpoint_migration_challenge_attestations') IS NOT NULL AS tables,
767
+ to_regprocedure('agent_bridge.issue_endpoint_migration_challenge(uuid,uuid,text)') IS NOT NULL
768
+ AND to_regprocedure('agent_bridge.consume_endpoint_migration_challenge(uuid,uuid,text)') IS NOT NULL
769
+ AND to_regprocedure('agent_bridge.endpoint_migration_challenge_ready()') IS NOT NULL AS functions,
770
+ NOT EXISTS (
771
+ SELECT 1
772
+ FROM unnest(ARRAY[
773
+ 'agent_bridge.endpoint_migration_challenges',
774
+ 'agent_bridge.endpoint_migration_challenge_events',
775
+ 'agent_bridge.endpoint_migration_challenge_attestations'
776
+ ]) relation_name
777
+ CROSS JOIN unnest(ARRAY['SELECT','INSERT','UPDATE','DELETE','TRUNCATE','REFERENCES','TRIGGER']) privilege
778
+ WHERE has_table_privilege((SELECT runtime_role FROM names),relation_name,privilege)
779
+ OR has_table_privilege('public',relation_name,privilege)
780
+ )
781
+ AND has_function_privilege((SELECT runtime_role FROM names),
782
+ 'agent_bridge.issue_endpoint_migration_challenge(uuid,uuid,text)','EXECUTE')
783
+ AND has_function_privilege((SELECT runtime_role FROM names),
784
+ 'agent_bridge.consume_endpoint_migration_challenge(uuid,uuid,text)','EXECUTE')
785
+ AND NOT has_function_privilege('public',
786
+ 'agent_bridge.issue_endpoint_migration_challenge(uuid,uuid,text)','EXECUTE')
787
+ AND NOT has_function_privilege('public',
788
+ 'agent_bridge.consume_endpoint_migration_challenge(uuid,uuid,text)','EXECUTE')
789
+ AND NOT EXISTS (
790
+ SELECT 1
791
+ FROM pg_catalog.pg_proc procedure
792
+ JOIN pg_catalog.pg_namespace namespace ON namespace.oid=procedure.pronamespace
793
+ WHERE namespace.nspname='agent_bridge'
794
+ AND procedure.proname IN (
795
+ 'guard_endpoint_migration_challenge',
796
+ 'reject_endpoint_migration_challenge_truncate',
797
+ 'reject_endpoint_migration_challenge_event_mutation',
798
+ 'reject_endpoint_migration_challenge_attestation_mutation',
799
+ 'cleanup_endpoint_migration_challenges',
800
+ 'endpoint_migration_challenge_active_credential',
801
+ 'endpoint_migration_challenge_direct_lineage',
802
+ 'endpoint_migration_challenge_catalog_definition',
803
+ 'endpoint_migration_challenge_ready'
804
+ )
805
+ AND has_function_privilege((SELECT runtime_role FROM names),procedure.oid,'EXECUTE')
806
+ ) AS grants,
807
+ EXISTS (
808
+ SELECT 1 FROM pg_catalog.pg_attribute
809
+ WHERE attrelid='agent_bridge.request_authorities'::regclass
810
+ AND attname='authorized_endpoint_migration_operation'
811
+ AND NOT attnotnull
812
+ ) AS marker
813
+ `);
814
+ const endpoint = endpointChallenge.rows[0];
815
+ if (!endpoint?.tables || !endpoint.functions || !endpoint.grants || !endpoint.marker) return false;
658
816
  try {
659
817
  const security = await db.query(
660
818
  "SELECT agent_bridge.security_schema_ready() AS ready"
@@ -665,7 +823,10 @@ async function runtimeSchemaReady(db, options = {}) {
665
823
  const portableArchive = await db.query(
666
824
  "SELECT agent_bridge.portable_archive_ready() AS ready"
667
825
  );
668
- return security.rows[0]?.ready === true && ownerControl.rows[0]?.ready === true && portableArchive.rows[0]?.ready === true && await rowIsolationReady(
826
+ const gatewayAuthority = await db.query(
827
+ "SELECT agent_bridge.gateway_authority_ready() AS ready"
828
+ );
829
+ return security.rows[0]?.ready === true && ownerControl.rows[0]?.ready === true && portableArchive.rows[0]?.ready === true && gatewayAuthority.rows[0]?.ready === true && await rowIsolationReady(
669
830
  db,
670
831
  options.allowPrivilegedCaller === true
671
832
  );
@@ -706,4 +867,4 @@ export {
706
867
  runtimeSchemaReady,
707
868
  runMigrations
708
869
  };
709
- //# sourceMappingURL=chunk-45BZGB77.js.map
870
+ //# sourceMappingURL=chunk-6BTJE6D4.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/migrations.ts"],"sourcesContent":["import { createHash } from \"node:crypto\";\nimport { readdir, readFile } from \"node:fs/promises\";\nimport { join } from \"node:path\";\nimport type { PgQueryable } from \"./postgres-bridge-store.js\";\n\nconst MIGRATION_NAME = /^(\\d+)_([a-z0-9_]+)\\.sql$/;\n// Native DR holds this database-local key with pg_advisory_lock. Migration and\n// Agent Bridge membership mutations take the shared transaction form.\nexport const NATIVE_DR_ADVISORY_LOCK_KEY = 1646705664;\nconst REQUIRED_COLUMNS = new Map([\n [\"workspaces.id\", \"text\"],\n [\"agents.id\", \"uuid\"],\n [\"agents.workspace_id\", \"text\"],\n [\"agents.principal\", \"text\"],\n [\"credentials.id\", \"uuid\"],\n [\"credentials.workspace_id\", \"text\"],\n [\"credentials.agent_id\", \"uuid\"],\n [\"credentials.token_hash\", \"bpchar\"],\n [\"credentials.scopes\", \"_text\"],\n [\"credentials.scope_set_name\", \"text\"],\n [\"credentials.replaces_credential_id\", \"uuid\"],\n [\"credentials.revoked_by\", \"text\"],\n [\"credentials.revocation_reason\", \"text\"],\n [\"credentials.expiry_grace_until\", \"timestamptz\"],\n [\"credential_scope_sets.name\", \"text\"],\n [\"credential_scope_sets.scopes\", \"_text\"],\n [\"credential_scope_sets.created_at\", \"timestamptz\"],\n [\"security_events.sequence\", \"int8\"],\n [\"security_events.event_id\", \"uuid\"],\n [\"security_events.event_type\", \"text\"],\n [\"security_events.outcome\", \"text\"],\n [\"security_events.reason_code\", \"text\"],\n [\"security_events.workspace_id\", \"text\"],\n [\"security_events.principal\", \"text\"],\n [\"security_events.actor_principal\", \"text\"],\n [\"security_events.credential_id\", \"uuid\"],\n [\"security_events.related_credential_id\", \"uuid\"],\n [\"security_events.operation_id\", \"text\"],\n [\"security_events.request_id\", \"uuid\"],\n [\"security_events.policy_id\", \"text\"],\n [\"security_events.retry_after_seconds\", \"int4\"],\n [\"security_events.created_at\", \"timestamptz\"],\n [\"rate_limit_policies.policy_id\", \"text\"],\n [\"rate_limit_policies.operation_id\", \"text\"],\n [\"rate_limit_policies.capacity\", \"int4\"],\n [\"rate_limit_policies.refill_per_second\", \"numeric\"],\n [\"rate_limit_policies.enabled\", \"bool\"],\n [\"rate_limit_buckets.credential_id\", \"uuid\"],\n [\"rate_limit_buckets.policy_id\", \"text\"],\n [\"rate_limit_buckets.tokens\", \"numeric\"],\n [\"rate_limit_buckets.updated_at\", \"timestamptz\"],\n [\"request_authorities.backend_pid\", \"int4\"],\n [\"request_authorities.transaction_id\", \"xid8\"],\n [\"request_authorities.request_id\", \"uuid\"],\n [\"request_authorities.credential_id\", \"uuid\"],\n [\"request_authorities.workspace_id\", \"text\"],\n [\"request_authorities.principal\", \"text\"],\n [\"request_authorities.scopes\", \"_text\"],\n [\"request_authorities.opened_session_user\", \"name\"],\n [\"request_authorities.authorized_endpoint_migration_operation\", \"text\"],\n [\"gateway_authority.singleton\", \"bool\"],\n [\"gateway_authority.authority_id\", \"uuid\"],\n [\"endpoint_migration_challenges.challenge_hash\", \"bpchar\"],\n [\"endpoint_migration_challenges.authority_id\", \"uuid\"],\n [\"endpoint_migration_challenges.workspace_id\", \"text\"],\n [\"endpoint_migration_challenges.principal\", \"text\"],\n [\"endpoint_migration_challenges.issuer_credential_id\", \"uuid\"],\n [\"endpoint_migration_challenges.verifier_credential_id\", \"uuid\"],\n [\"endpoint_migration_challenges.issued_at\", \"timestamptz\"],\n [\"endpoint_migration_challenges.expires_at\", \"timestamptz\"],\n [\"endpoint_migration_challenges.consumed_at\", \"timestamptz\"],\n [\"endpoint_migration_challenge_events.sequence\", \"int8\"],\n [\"endpoint_migration_challenge_events.event_id\", \"uuid\"],\n [\"endpoint_migration_challenge_events.request_id\", \"uuid\"],\n [\"endpoint_migration_challenge_events.event_type\", \"text\"],\n [\"endpoint_migration_challenge_events.created_at\", \"timestamptz\"],\n [\"endpoint_migration_challenge_attestations.name\", \"text\"],\n [\"endpoint_migration_challenge_attestations.catalog_definition\", \"text\"],\n [\"row_isolation_attestations.name\", \"text\"],\n [\"row_isolation_attestations.catalog_definition\", \"text\"],\n [\"row_isolation_attestations.attested_at\", \"timestamptz\"],\n [\"control_requests.request_id\", \"uuid\"],\n [\"control_requests.operation\", \"text\"],\n [\"control_requests.fingerprint\", \"bpchar\"],\n [\"control_requests.actor\", \"name\"],\n [\"control_requests.result\", \"jsonb\"],\n [\"control_requests.created_at\", \"timestamptz\"],\n [\"control_events.sequence\", \"int8\"],\n [\"control_events.event_id\", \"uuid\"],\n [\"control_events.request_id\", \"uuid\"],\n [\"control_events.operation\", \"text\"],\n [\"control_events.outcome\", \"text\"],\n [\"control_events.actor\", \"name\"],\n [\"control_events.workspace_id\", \"text\"],\n [\"control_events.principal\", \"text\"],\n [\"control_events.credential_id\", \"uuid\"],\n [\"control_events.related_credential_id\", \"uuid\"],\n [\"control_events.reason_code\", \"text\"],\n [\"control_events.created_at\", \"timestamptz\"],\n [\"owner_control_attestations.name\", \"text\"],\n [\"owner_control_attestations.catalog_definition\", \"text\"],\n [\"owner_control_attestations.attested_at\", \"timestamptz\"],\n [\"control_membership_events.sequence\", \"int8\"],\n [\"control_membership_events.request_id\", \"uuid\"],\n [\"control_membership_events.action\", \"text\"],\n [\"control_membership_events.member_role\", \"name\"],\n [\"control_membership_events.control_role\", \"text\"],\n [\"control_membership_events.actor\", \"name\"],\n [\"control_membership_events.created_at\", \"timestamptz\"],\n [\"archive_membership_events.sequence\", \"int8\"],\n [\"archive_membership_events.request_id\", \"uuid\"],\n [\"archive_membership_events.action\", \"text\"],\n [\"archive_membership_events.member_role\", \"name\"],\n [\"archive_membership_events.actor\", \"name\"],\n [\"archive_membership_events.created_at\", \"timestamptz\"],\n [\"archive_operations.sequence\", \"int8\"],\n [\"archive_operations.request_id\", \"uuid\"],\n [\"archive_operations.phase\", \"text\"],\n [\"archive_operations.operation\", \"text\"],\n [\"archive_operations.workspace\", \"text\"],\n [\"archive_operations.client_verified_digest\", \"bpchar\"],\n [\"archive_operations.message_count\", \"int8\"],\n [\"archive_operations.receipt_count\", \"int8\"],\n [\"archive_operations.message_inserted_count\", \"int8\"],\n [\"archive_operations.receipt_inserted_count\", \"int8\"],\n [\"archive_operations.server_content_binding\", \"bpchar\"],\n [\"archive_operations.outcome\", \"text\"],\n [\"archive_operations.failure_code\", \"text\"],\n [\"archive_operations.published_at\", \"timestamptz\"],\n [\"archive_operations.apply\", \"bool\"],\n [\"archive_operations.actor\", \"name\"],\n [\"archive_operations.created_at\", \"timestamptz\"],\n [\"archive_operation_batches.sequence\", \"int8\"],\n [\"archive_operation_batches.request_id\", \"uuid\"],\n [\"archive_operation_batches.record_kind\", \"text\"],\n [\"archive_operation_batches.batch_ordinal\", \"int8\"],\n [\"archive_operation_batches.record_count\", \"int8\"],\n [\"archive_operation_batches.batch_fingerprint\", \"bpchar\"],\n [\"archive_operation_batches.chain_binding\", \"bpchar\"],\n [\"archive_operation_batches.actor\", \"name\"],\n [\"archive_operation_batches.created_at\", \"timestamptz\"],\n [\"archive_import_records.sequence\", \"int8\"],\n [\"archive_import_records.request_id\", \"uuid\"],\n [\"archive_import_records.record_kind\", \"text\"],\n [\"archive_import_records.record_key\", \"text\"],\n [\"archive_import_records.batch_ordinal\", \"int8\"],\n [\"archive_import_records.semantic_fingerprint\", \"bpchar\"],\n [\"archive_import_records.inserted\", \"bool\"],\n [\"archive_import_records.actor\", \"name\"],\n [\"archive_import_records.created_at\", \"timestamptz\"],\n [\"archive_transaction_authorizations.backend_pid\", \"int4\"],\n [\"archive_transaction_authorizations.transaction_id\", \"text\"],\n [\"archive_transaction_authorizations.request_id\", \"uuid\"],\n [\"archive_transaction_authorizations.operation\", \"text\"],\n [\"archive_transaction_authorizations.workspace\", \"text\"],\n [\"archive_transaction_authorizations.client_verified_digest\", \"bpchar\"],\n [\"archive_transaction_authorizations.actor\", \"name\"],\n [\"archive_transaction_authorizations.messages_consumed\", \"bool\"],\n [\"archive_transaction_authorizations.receipts_consumed\", \"bool\"],\n [\"archive_transaction_authorizations.created_at\", \"timestamptz\"],\n [\"portable_archive_attestations.name\", \"text\"],\n [\"portable_archive_attestations.catalog_definition\", \"text\"],\n [\"portable_archive_attestations.attested_at\", \"timestamptz\"],\n [\"messages.sequence\", \"int8\"],\n [\"messages.id\", \"uuid\"],\n [\"messages.workspace\", \"text\"],\n [\"messages.project\", \"text\"],\n [\"messages.source\", \"text\"],\n [\"messages.targets\", \"jsonb\"],\n [\"messages.delivery_mode\", \"text\"],\n [\"messages.delivery_max_attempts\", \"int4\"],\n [\"messages.delivery_retry_base_delay_ms\", \"int4\"],\n [\"messages.delivery_retry_max_delay_ms\", \"int4\"],\n [\"messages.delivery_retry_jitter_ratio\", \"float8\"],\n [\"messages.delivery_not_before\", \"timestamptz\"],\n [\"receipts.workspace\", \"text\"],\n [\"receipts.message_id\", \"uuid\"],\n [\"receipts.principal\", \"text\"],\n [\"deliveries.id\", \"uuid\"],\n [\"deliveries.message_id\", \"uuid\"],\n [\"deliveries.workspace\", \"text\"],\n [\"deliveries.publisher\", \"text\"],\n [\"deliveries.recipient\", \"text\"],\n [\"deliveries.state\", \"text\"],\n [\"deliveries.lease_token\", \"uuid\"],\n [\"deliveries.created_at\", \"timestamptz\"],\n [\"deliveries.priority_rank\", \"int2\"],\n [\"deliveries.cycle_attempt\", \"int4\"],\n [\"deliveries.requeue_count\", \"int4\"],\n [\"deliveries.last_actor\", \"text\"],\n [\"deliveries.last_action\", \"text\"],\n [\"delivery_events.delivery_id\", \"uuid\"],\n [\"delivery_events.publisher\", \"text\"],\n [\"delivery_events.to_state\", \"text\"],\n [\"delivery_events.cycle_attempt\", \"int4\"],\n [\"delivery_events.requeue_count\", \"int4\"],\n [\"delivery_events.actor\", \"text\"],\n [\"delivery_events.action\", \"text\"],\n [\"agent_instances.workspace\", \"text\"],\n [\"agent_instances.instance\", \"text\"],\n [\"agent_instances.capabilities\", \"jsonb\"],\n]);\n\nexport interface AppliedMigration {\n version: number;\n name: string;\n checksum: string;\n}\n\nexport interface MigrationPlanEntry extends AppliedMigration {\n source: string;\n}\n\nexport const REQUIRED_MIGRATIONS = [\n { version: 1, name: \"schema_state\" },\n { version: 2, name: \"workspaces_agents_credentials\" },\n { version: 3, name: \"messages_receipts_deliveries\" },\n { version: 4, name: \"message_query_indexes\" },\n { version: 5, name: \"delivery_events_presence\" },\n { version: 6, name: \"legacy_shared_context_import\" },\n { version: 7, name: \"runtime_role\" },\n { version: 8, name: \"message_projects\" },\n { version: 9, name: \"mailbox_query_indexes\" },\n { version: 10, name: \"publisher_delivery_policy\" },\n { version: 11, name: \"credential_security\" },\n { version: 12, name: \"request_authority\" },\n { version: 13, name: \"row_isolation\" },\n { version: 14, name: \"owner_control_plane\" },\n { version: 15, name: \"portable_archives\" },\n { version: 16, name: \"native_dr_fence\" },\n { version: 17, name: \"gateway_authority_binding\" },\n { version: 18, name: \"endpoint_migration_challenges\" },\n { version: 19, name: \"endpoint_migration_same_successor\" },\n] as const;\n\nfunction withNativeDrSharedLock(source: string): string {\n if (!/^begin;\\s/i.test(source)) {\n throw new Error(\"migration must begin with an explicit transaction\");\n }\n return source.replace(\n /^begin;\\s/i,\n `begin;\\n\\nselect pg_advisory_xact_lock_shared(${NATIVE_DR_ADVISORY_LOCK_KEY});\\n\\n`,\n );\n}\n\nfunction checksum(source: string): string {\n return createHash(\"sha256\").update(source, \"utf8\").digest(\"hex\");\n}\n\nasync function recordedMigrations(db: PgQueryable): Promise<AppliedMigration[]> {\n const exists = await db.query<{ table_name: string | null }>(\n \"SELECT to_regclass('agent_bridge.schema_migrations')::text AS table_name\",\n );\n if (!exists.rows[0]?.table_name) return [];\n const result = await db.query<{ version: number; name: string; checksum: string }>(\n \"SELECT version, name, checksum FROM agent_bridge.schema_migrations ORDER BY version\",\n );\n return result.rows.map((row) => ({\n version: Number(row.version),\n name: row.name,\n checksum: row.checksum,\n }));\n}\n\nexport async function loadMigrationPlan(directory: string): Promise<MigrationPlanEntry[]> {\n const files = (await readdir(directory))\n .filter((file) => MIGRATION_NAME.test(file))\n .sort((left, right) => left.localeCompare(right));\n const expected = await Promise.all(files.map(async (file) => {\n const match = file.match(MIGRATION_NAME)!;\n const source = await readFile(join(directory, file), \"utf8\");\n return { version: Number(match[1]), name: match[2], source, checksum: checksum(source) };\n }));\n\n if (\n expected.length !== REQUIRED_MIGRATIONS.length ||\n !expected.every(\n (migration, index) =>\n migration.version === REQUIRED_MIGRATIONS[index]?.version &&\n migration.name === REQUIRED_MIGRATIONS[index]?.name,\n )\n ) {\n throw new Error(\"migration directory does not match the required migration sequence\");\n }\n return expected;\n}\n\nexport async function migrationsReady(\n db: PgQueryable,\n expected: ReadonlyArray<Pick<MigrationPlanEntry, \"version\" | \"name\" | \"checksum\">>,\n): Promise<boolean> {\n const applied = await recordedMigrations(db);\n return expected.every(\n (required, index) =>\n applied[index]?.version === required.version &&\n applied[index]?.name === required.name &&\n applied[index]?.checksum === required.checksum,\n ) && applied.length === expected.length;\n}\n\nexport async function rowIsolationReady(db: PgQueryable, allowPrivilegedCaller: boolean): Promise<boolean> {\n const result = await db.query<{\n rolesReady: boolean;\n callerReady: boolean;\n callerBypasses: boolean;\n ownershipReady: boolean;\n policiesReady: boolean;\n functionsReady: boolean;\n constraintsReady: boolean;\n triggersReady: boolean;\n grantsReady: boolean;\n catalogReady: boolean;\n }>(`WITH names AS (\n SELECT\n ('agent_bridge_runtime_' || substr(md5(current_database()),1,16))::name AS runtime_role,\n ('agent_bridge_data_owner_' || substr(md5(current_database()),1,16))::name AS data_owner,\n ('agent_bridge_context_reader_' || substr(md5(current_database()),1,16))::name AS context_reader,\n ('agent_bridge_event_writer_' || substr(md5(current_database()),1,16))::name AS event_writer\n ), required_roles(role_name) AS (\n SELECT runtime_role FROM names UNION ALL SELECT data_owner FROM names\n UNION ALL SELECT context_reader FROM names UNION ALL SELECT event_writer FROM names\n ), domain_tables(table_name) AS (\n VALUES ('messages'),('receipts'),('deliveries'),('delivery_events'),('agent_instances')\n ), caller_role AS (\n SELECT * FROM pg_roles WHERE rolname=current_user\n ), expected_policies(table_name,policy_name,command_name,role_name,needs_workspace,needs_principal) AS (\n SELECT 'messages','messages_owner_all','*',data_owner::text,false,false FROM names UNION ALL\n SELECT 'messages','messages_runtime_select','r',runtime_role::text,true,true FROM names UNION ALL\n SELECT 'messages','messages_runtime_insert','a',runtime_role::text,true,true FROM names UNION ALL\n SELECT 'receipts','receipts_owner_all','*',data_owner::text,false,false FROM names UNION ALL\n SELECT 'receipts','receipts_runtime_select','r',runtime_role::text,true,true FROM names UNION ALL\n SELECT 'receipts','receipts_runtime_insert','a',runtime_role::text,true,true FROM names UNION ALL\n SELECT 'deliveries','deliveries_owner_all','*',data_owner::text,false,false FROM names UNION ALL\n SELECT 'deliveries','deliveries_runtime_select','r',runtime_role::text,true,true FROM names UNION ALL\n SELECT 'deliveries','deliveries_runtime_insert','a',runtime_role::text,true,true FROM names UNION ALL\n SELECT 'deliveries','deliveries_runtime_update','w',runtime_role::text,true,true FROM names UNION ALL\n SELECT 'delivery_events','delivery_events_owner_all','*',data_owner::text,false,false FROM names UNION ALL\n SELECT 'delivery_events','delivery_events_runtime_select','r',runtime_role::text,true,true FROM names UNION ALL\n SELECT 'delivery_events','delivery_events_writer_insert','a',event_writer::text,false,false FROM names UNION ALL\n SELECT 'agent_instances','agent_instances_owner_all','*',data_owner::text,false,false FROM names UNION ALL\n SELECT 'agent_instances','agent_instances_runtime_select','r',runtime_role::text,true,false FROM names UNION ALL\n SELECT 'agent_instances','agent_instances_runtime_insert','a',runtime_role::text,true,true FROM names UNION ALL\n SELECT 'agent_instances','agent_instances_runtime_update','w',runtime_role::text,true,true FROM names UNION ALL\n SELECT 'agent_instances','agent_instances_runtime_delete','d',runtime_role::text,true,true FROM names\n ), actual_policies AS (\n SELECT relation.relname AS table_name,policy.polname AS policy_name,\n policy.polcmd AS command_name,policy.polpermissive,\n ARRAY(SELECT role.rolname::text FROM unnest(policy.polroles) member(oid)\n JOIN pg_roles role ON role.oid=member.oid ORDER BY role.rolname) AS role_names,\n coalesce(pg_get_expr(policy.polqual,policy.polrelid),'') || ' ' ||\n coalesce(pg_get_expr(policy.polwithcheck,policy.polrelid),'') AS expressions\n FROM pg_policy policy\n JOIN pg_class relation ON relation.oid=policy.polrelid\n JOIN pg_namespace namespace ON namespace.oid=relation.relnamespace\n WHERE namespace.nspname='agent_bridge'\n AND relation.relname IN (SELECT table_name FROM domain_tables)\n )\n SELECT\n (SELECT count(*)=4 AND bool_and(\n role.rolname=(required.role_name::text)\n AND NOT role.rolcanlogin AND NOT role.rolsuper AND NOT role.rolcreatedb\n AND NOT role.rolcreaterole AND NOT role.rolreplication AND NOT role.rolbypassrls\n )\n FROM required_roles required JOIN pg_roles role ON role.rolname=required.role_name::text) AS \"rolesReady\",\n ((SELECT rolsuper OR rolbypassrls FROM caller_role) OR (\n (SELECT rolcanlogin AND rolinherit AND NOT rolsuper AND NOT rolcreatedb\n AND NOT rolcreaterole AND NOT rolreplication AND NOT rolbypassrls\n FROM caller_role)\n AND pg_has_role(current_user,(SELECT runtime_role FROM names),'MEMBER')\n AND NOT EXISTS (\n SELECT 1 FROM pg_roles unexpected\n WHERE unexpected.oid<>(SELECT oid FROM caller_role)\n AND unexpected.rolname<>(SELECT runtime_role::text FROM names)\n AND pg_has_role(current_user,unexpected.oid,'MEMBER')\n )\n )) AS \"callerReady\",\n EXISTS (\n SELECT 1 FROM pg_roles elevated\n WHERE (elevated.rolsuper OR elevated.rolbypassrls)\n AND pg_has_role(current_user,elevated.oid,'MEMBER')\n ) AS \"callerBypasses\",\n (SELECT count(*)=5 AND bool_and(\n relation.relrowsecurity AND relation.relforcerowsecurity\n AND owner.rolname=(SELECT data_owner::text FROM names)\n )\n FROM domain_tables required\n JOIN pg_namespace namespace ON namespace.nspname='agent_bridge'\n JOIN pg_class relation ON relation.relnamespace=namespace.oid AND relation.relname=required.table_name\n JOIN pg_roles owner ON owner.oid=relation.relowner)\n AND EXISTS (\n SELECT 1 FROM pg_class attestation\n JOIN pg_namespace namespace ON namespace.oid=attestation.relnamespace\n WHERE namespace.nspname='agent_bridge'\n AND attestation.relname='row_isolation_attestations'\n AND attestation.relowner=namespace.nspowner\n ) AS \"ownershipReady\",\n ((SELECT count(*) FROM actual_policies)=18 AND NOT EXISTS (\n SELECT 1 FROM expected_policies expected\n LEFT JOIN actual_policies actual\n ON actual.table_name=expected.table_name AND actual.policy_name=expected.policy_name\n WHERE actual.policy_name IS NULL OR actual.command_name<>expected.command_name\n OR NOT actual.polpermissive OR actual.role_names<>ARRAY[expected.role_name]\n OR (expected.needs_workspace AND position('current_request_workspace' in actual.expressions)=0)\n OR (expected.needs_principal AND position('current_request_principal' in actual.expressions)=0)\n OR (NOT expected.needs_workspace AND NOT expected.needs_principal\n AND position('true' in actual.expressions)=0)\n )) AS \"policiesReady\",\n (SELECT count(*)=4 AND bool_and(\n procedure.proconfig @> ARRAY['search_path=\"\"']::text[]\n AND CASE procedure.proname\n WHEN 'record_delivery_event' THEN owner.rolname=(SELECT event_writer::text FROM names)\n AND procedure.prosecdef AND procedure.provolatile='v'\n WHEN 'row_isolation_catalog_definition' THEN\n owner.oid=(SELECT relation.relowner FROM pg_class relation\n JOIN pg_namespace namespace ON namespace.oid=relation.relnamespace\n WHERE namespace.nspname='agent_bridge'\n AND relation.relname='row_isolation_attestations')\n AND NOT procedure.prosecdef AND procedure.provolatile='s'\n ELSE owner.rolname=(SELECT context_reader::text FROM names)\n AND procedure.prosecdef AND procedure.provolatile='s'\n END\n )\n FROM pg_proc procedure\n JOIN pg_namespace namespace ON namespace.oid=procedure.pronamespace\n JOIN pg_roles owner ON owner.oid=procedure.proowner\n WHERE namespace.nspname='agent_bridge'\n AND procedure.proname IN (\n 'current_request_workspace','current_request_principal',\n 'record_delivery_event','row_isolation_catalog_definition'\n ))\n AND NOT EXISTS (\n SELECT 1 FROM pg_proc private_function\n JOIN pg_namespace private_namespace ON private_namespace.oid=private_function.pronamespace\n WHERE private_namespace.nspname='agent_bridge'\n AND has_function_privilege('public',private_function.oid,'EXECUTE')\n )\n AND has_function_privilege((SELECT runtime_role FROM names),'agent_bridge.current_request_workspace()','EXECUTE')\n AND has_function_privilege((SELECT runtime_role FROM names),'agent_bridge.current_request_principal()','EXECUTE')\n AND has_function_privilege((SELECT runtime_role FROM names),'agent_bridge.row_isolation_catalog_definition()','EXECUTE')\n AND NOT has_function_privilege((SELECT runtime_role FROM names),'agent_bridge.record_delivery_event()','EXECUTE')\n AND NOT has_function_privilege((SELECT runtime_role FROM names),'agent_bridge.reject_delivery_identity_mutation()','EXECUTE')\n AND NOT has_function_privilege((SELECT runtime_role FROM names),'agent_bridge.enforce_delivery_actor_role()','EXECUTE')\n AND NOT has_function_privilege((SELECT runtime_role FROM names),'agent_bridge.reject_delivery_event_mutation()','EXECUTE')\n AS \"functionsReady\",\n ((SELECT count(*)=5 AND bool_and(constraint_record.convalidated)\n FROM (VALUES\n ('agent_bridge.messages'::regclass,'messages_workspace_id_source_unique'),\n ('agent_bridge.deliveries'::regclass,'deliveries_publisher_message_fk'),\n ('agent_bridge.deliveries'::regclass,'deliveries_event_identity_unique'),\n ('agent_bridge.delivery_events'::regclass,'delivery_events_delivery_publisher_fk'),\n ('agent_bridge.row_isolation_attestations'::regclass,'row_isolation_attestation_name')\n ) required(relation_id,constraint_name)\n JOIN pg_constraint constraint_record\n ON constraint_record.conrelid=required.relation_id\n AND constraint_record.conname=required.constraint_name)\n AND (SELECT count(*)=2 AND bool_and(attribute.attnotnull)\n FROM pg_attribute attribute\n WHERE (attribute.attrelid,attribute.attname) IN (\n ('agent_bridge.deliveries'::regclass,'publisher'),\n ('agent_bridge.delivery_events'::regclass,'publisher')\n ) AND attribute.attnum>0 AND NOT attribute.attisdropped)\n ) AS \"constraintsReady\",\n (SELECT count(*)=4 AND bool_and(trigger.tgenabled='O')\n FROM (VALUES\n ('agent_bridge.deliveries'::regclass,'deliveries_record_event'),\n ('agent_bridge.deliveries'::regclass,'deliveries_identity_immutable'),\n ('agent_bridge.deliveries'::regclass,'deliveries_actor_role'),\n ('agent_bridge.delivery_events'::regclass,'delivery_events_append_only')\n ) required(relation_id,trigger_name)\n JOIN pg_trigger trigger ON trigger.tgrelid=required.relation_id\n AND trigger.tgname=required.trigger_name AND NOT trigger.tgisinternal) AS \"triggersReady\",\n (has_schema_privilege((SELECT runtime_role FROM names),'agent_bridge','USAGE')\n AND NOT has_schema_privilege((SELECT runtime_role FROM names),'agent_bridge','CREATE')\n AND has_schema_privilege((SELECT data_owner FROM names),'agent_bridge','USAGE')\n AND NOT has_schema_privilege((SELECT data_owner FROM names),'agent_bridge','CREATE')\n AND has_schema_privilege((SELECT context_reader FROM names),'agent_bridge','USAGE')\n AND NOT has_schema_privilege((SELECT context_reader FROM names),'agent_bridge','CREATE')\n AND has_schema_privilege((SELECT event_writer FROM names),'agent_bridge','USAGE')\n AND NOT has_schema_privilege((SELECT event_writer FROM names),'agent_bridge','CREATE')\n AND has_table_privilege((SELECT runtime_role FROM names),'agent_bridge.messages','SELECT')\n AND has_table_privilege((SELECT runtime_role FROM names),'agent_bridge.messages','INSERT')\n AND NOT has_table_privilege((SELECT runtime_role FROM names),'agent_bridge.messages','UPDATE,DELETE,TRUNCATE,REFERENCES,TRIGGER')\n AND has_table_privilege((SELECT runtime_role FROM names),'agent_bridge.receipts','SELECT')\n AND has_table_privilege((SELECT runtime_role FROM names),'agent_bridge.receipts','INSERT')\n AND NOT has_table_privilege((SELECT runtime_role FROM names),'agent_bridge.receipts','UPDATE,DELETE,TRUNCATE,REFERENCES,TRIGGER')\n AND has_table_privilege((SELECT runtime_role FROM names),'agent_bridge.deliveries','SELECT')\n AND has_table_privilege((SELECT runtime_role FROM names),'agent_bridge.deliveries','INSERT')\n AND has_table_privilege((SELECT runtime_role FROM names),'agent_bridge.deliveries','UPDATE')\n AND NOT has_table_privilege((SELECT runtime_role FROM names),'agent_bridge.deliveries','DELETE,TRUNCATE,REFERENCES,TRIGGER')\n AND has_table_privilege((SELECT runtime_role FROM names),'agent_bridge.delivery_events','SELECT')\n AND NOT has_table_privilege((SELECT runtime_role FROM names),'agent_bridge.delivery_events','INSERT,UPDATE,DELETE,TRUNCATE,REFERENCES,TRIGGER')\n AND has_table_privilege((SELECT runtime_role FROM names),'agent_bridge.agent_instances','SELECT')\n AND has_table_privilege((SELECT runtime_role FROM names),'agent_bridge.agent_instances','INSERT')\n AND has_table_privilege((SELECT runtime_role FROM names),'agent_bridge.agent_instances','UPDATE')\n AND has_table_privilege((SELECT runtime_role FROM names),'agent_bridge.agent_instances','DELETE')\n AND NOT has_table_privilege((SELECT runtime_role FROM names),'agent_bridge.agent_instances','TRUNCATE,REFERENCES,TRIGGER')\n AND has_sequence_privilege((SELECT runtime_role FROM names),'agent_bridge.messages_sequence_seq','USAGE')\n AND NOT has_sequence_privilege((SELECT runtime_role FROM names),'agent_bridge.messages_sequence_seq','SELECT,UPDATE')\n AND NOT has_sequence_privilege((SELECT runtime_role FROM names),'agent_bridge.delivery_events_sequence_seq','USAGE,SELECT,UPDATE')\n AND has_table_privilege((SELECT context_reader FROM names),'agent_bridge.request_authorities','SELECT')\n AND NOT has_table_privilege((SELECT context_reader FROM names),'agent_bridge.request_authorities','INSERT,UPDATE,DELETE,TRUNCATE,REFERENCES,TRIGGER')\n AND has_table_privilege((SELECT event_writer FROM names),'agent_bridge.delivery_events','INSERT')\n AND NOT has_table_privilege((SELECT event_writer FROM names),'agent_bridge.delivery_events','SELECT,UPDATE,DELETE,TRUNCATE,REFERENCES,TRIGGER')\n AND NOT EXISTS (\n SELECT 1 FROM pg_class relation\n JOIN pg_namespace namespace ON namespace.oid=relation.relnamespace\n WHERE namespace.nspname='agent_bridge' AND relation.relkind IN ('r','p','v','m','f')\n AND (\n (relation.relname<>'request_authorities' AND has_table_privilege(\n (SELECT context_reader FROM names),relation.oid,\n 'SELECT,INSERT,UPDATE,DELETE,TRUNCATE,REFERENCES,TRIGGER'\n ))\n OR (relation.relname<>'delivery_events' AND has_table_privilege(\n (SELECT event_writer FROM names),relation.oid,\n 'SELECT,INSERT,UPDATE,DELETE,TRUNCATE,REFERENCES,TRIGGER'\n ))\n )\n )\n AND has_sequence_privilege((SELECT event_writer FROM names),'agent_bridge.delivery_events_sequence_seq','USAGE')\n AND NOT has_sequence_privilege((SELECT event_writer FROM names),'agent_bridge.delivery_events_sequence_seq','SELECT,UPDATE')\n AND NOT EXISTS (\n SELECT 1 FROM pg_class sequence\n JOIN pg_namespace namespace ON namespace.oid=sequence.relnamespace\n WHERE namespace.nspname='agent_bridge' AND sequence.relkind='S'\n AND (\n has_sequence_privilege((SELECT context_reader FROM names),sequence.oid,'USAGE,SELECT,UPDATE')\n OR (sequence.relname<>'delivery_events_sequence_seq' AND has_sequence_privilege(\n (SELECT event_writer FROM names),sequence.oid,'USAGE,SELECT,UPDATE'\n ))\n )\n )\n AND NOT has_sequence_privilege('public','agent_bridge.messages_sequence_seq','USAGE,SELECT,UPDATE')\n AND NOT has_sequence_privilege('public','agent_bridge.delivery_events_sequence_seq','USAGE,SELECT,UPDATE')\n AND has_table_privilege((SELECT runtime_role FROM names),'agent_bridge.row_isolation_attestations','SELECT')\n AND NOT has_table_privilege((SELECT runtime_role FROM names),'agent_bridge.row_isolation_attestations','INSERT,UPDATE,DELETE,TRUNCATE,REFERENCES,TRIGGER')\n AND NOT EXISTS (\n SELECT 1\n FROM unnest(ARRAY[\n 'agent_bridge.credentials','agent_bridge.agents',\n 'agent_bridge.workspaces','agent_bridge.request_authorities'\n ]) protected_table(value)\n CROSS JOIN unnest(ARRAY[\n 'SELECT','INSERT','UPDATE','DELETE','TRUNCATE','REFERENCES','TRIGGER'\n ]) requested_privilege(value)\n WHERE has_table_privilege(\n (SELECT runtime_role FROM names),protected_table.value,requested_privilege.value\n )\n )\n AND NOT EXISTS (\n SELECT 1\n FROM unnest(ARRAY[\n 'agent_bridge.credentials','agent_bridge.agents',\n 'agent_bridge.workspaces','agent_bridge.request_authorities'\n ]) protected_table(value)\n CROSS JOIN unnest(ARRAY['SELECT','INSERT','UPDATE','REFERENCES']) requested_privilege(value)\n WHERE has_any_column_privilege(\n (SELECT runtime_role FROM names),protected_table.value,requested_privilege.value\n )\n )\n AND NOT has_table_privilege('public','agent_bridge.row_isolation_attestations','SELECT,INSERT,UPDATE,DELETE,TRUNCATE,REFERENCES,TRIGGER')\n AND NOT pg_has_role((SELECT runtime_role FROM names),(SELECT data_owner FROM names),'MEMBER')\n AND NOT pg_has_role((SELECT runtime_role FROM names),(SELECT context_reader FROM names),'MEMBER')\n AND NOT pg_has_role((SELECT runtime_role FROM names),(SELECT event_writer FROM names),'MEMBER')\n AND NOT EXISTS (\n SELECT 1 FROM pg_proc private_function\n JOIN pg_namespace namespace ON namespace.oid=private_function.pronamespace\n WHERE namespace.nspname='agent_bridge'\n AND (\n (NOT (private_function.proname IN ('current_request_workspace','current_request_principal')\n AND private_function.pronargs=0)\n AND has_function_privilege((SELECT context_reader FROM names),private_function.oid,'EXECUTE'))\n OR (NOT (private_function.proname='record_delivery_event' AND private_function.pronargs=0)\n AND has_function_privilege((SELECT event_writer FROM names),private_function.oid,'EXECUTE'))\n )\n )\n ) AS \"grantsReady\",\n (SELECT count(*)=1 AND bool_and(\n attestation.catalog_definition=agent_bridge.row_isolation_catalog_definition()\n )\n FROM agent_bridge.row_isolation_attestations attestation\n WHERE attestation.name='domain-v1') AS \"catalogReady\"\n `);\n const row = result.rows[0];\n const callerReady = row?.callerReady && (allowPrivilegedCaller || !row.callerBypasses);\n return Boolean(\n row?.rolesReady && callerReady && row.ownershipReady && row.policiesReady &&\n row.functionsReady && row.constraintsReady && row.triggersReady && row.grantsReady && row.catalogReady\n );\n}\n\nexport async function runtimeSchemaReady(\n db: PgQueryable,\n options: { allowPrivilegedCaller?: boolean } = {},\n): Promise<boolean> {\n const columns = await db.query<{ table_name: string; column_name: string; udt_name: string }>(\n `SELECT relation.relname AS table_name, attribute.attname AS column_name,\n type.typname AS udt_name\n FROM pg_catalog.pg_attribute attribute\n JOIN pg_catalog.pg_class relation ON relation.oid=attribute.attrelid\n JOIN pg_catalog.pg_namespace namespace ON namespace.oid=relation.relnamespace\n JOIN pg_catalog.pg_type type ON type.oid=attribute.atttypid\n WHERE namespace.nspname='agent_bridge'\n AND attribute.attnum>0 AND NOT attribute.attisdropped`,\n );\n const actual = new Map(\n columns.rows.map((row) => [`${row.table_name}.${row.column_name}`, row.udt_name]),\n );\n if ([...REQUIRED_COLUMNS].some(([name, type]) => actual.get(name) !== type)) return false;\n\n const objects = await db.query<{ immutable: boolean; deliveryAudit: boolean; idempotency: boolean; claim: boolean; publisher: boolean; terminal: boolean; source: boolean; thread: boolean; created: boolean; presence: boolean; project: boolean; targets: boolean; scopeSets: boolean; securityEvents: boolean; ratePolicies: boolean; rateBuckets: boolean; replacement: boolean; rateCleanup: boolean; credentialSecurity: boolean; eventAppendOnly: boolean; scopeAudit: boolean; rateConsume: boolean; securityReady: boolean; requestAuthorities: boolean; gatewayAuthority: boolean; gatewayAuthorityShape: boolean; gatewayAuthorityImmutable: boolean; authorityOpen: boolean; authorityBoundOpen: boolean; authorityClose: boolean; authorityReady: boolean; credentialDigestHidden: boolean; authorityRowsHidden: boolean; gatewayAuthorityRowsHidden: boolean; principalTablesHidden: boolean; authorityTablesLocked: boolean; gatewayAuthorityPublicLocked: boolean; authorityCatalog: boolean }>(\n `WITH names AS (\n SELECT ('agent_bridge_runtime_' || substr(md5(current_database()),1,16))::name AS runtime_role\n ) SELECT\n EXISTS (\n SELECT 1 FROM pg_trigger\n WHERE tgrelid='agent_bridge.messages'::regclass\n AND tgname='messages_immutable' AND NOT tgisinternal\n ) AS immutable,\n EXISTS (\n SELECT 1 FROM pg_trigger\n WHERE tgrelid='agent_bridge.deliveries'::regclass\n AND tgname='deliveries_record_event' AND NOT tgisinternal\n ) AS \"deliveryAudit\",\n to_regclass('agent_bridge.messages_idempotency') IS NOT NULL AS idempotency,\n to_regclass('agent_bridge.deliveries_claim') IS NOT NULL AS claim,\n to_regclass('agent_bridge.deliveries_publisher_lookup') IS NOT NULL AS publisher,\n to_regclass('agent_bridge.deliveries_terminal_lookup') IS NOT NULL AS terminal,\n to_regclass('agent_bridge.messages_source') IS NOT NULL AS source,\n to_regclass('agent_bridge.messages_thread') IS NOT NULL AS thread,\n to_regclass('agent_bridge.messages_created') IS NOT NULL AS created,\n to_regclass('agent_bridge.messages_project') IS NOT NULL AS project,\n to_regclass('agent_bridge.messages_targets_gin') IS NOT NULL AS targets,\n to_regclass('agent_bridge.agent_instances_active') IS NOT NULL AS presence,\n to_regclass('agent_bridge.credential_scope_sets') IS NOT NULL AS \"scopeSets\",\n to_regclass('agent_bridge.security_events') IS NOT NULL AS \"securityEvents\",\n to_regclass('agent_bridge.rate_limit_policies') IS NOT NULL AS \"ratePolicies\",\n to_regclass('agent_bridge.rate_limit_buckets') IS NOT NULL AS \"rateBuckets\",\n to_regclass('agent_bridge.credentials_replacement_lineage') IS NOT NULL AS replacement,\n to_regclass('agent_bridge.rate_limit_buckets_cleanup') IS NOT NULL AS \"rateCleanup\",\n EXISTS (\n SELECT 1 FROM pg_trigger\n WHERE tgrelid=to_regclass('agent_bridge.credentials')\n AND tgname='credentials_validate_security' AND NOT tgisinternal\n ) AS \"credentialSecurity\",\n EXISTS (\n SELECT 1 FROM pg_trigger\n WHERE tgrelid=to_regclass('agent_bridge.security_events')\n AND tgname='security_events_append_only' AND NOT tgisinternal\n ) AS \"eventAppendOnly\",\n to_regprocedure('agent_bridge.record_scope_denial(uuid,text,uuid)') IS NOT NULL AS \"scopeAudit\",\n to_regprocedure('agent_bridge.consume_rate_limit(uuid,text,uuid)') IS NOT NULL AS \"rateConsume\",\n to_regprocedure('agent_bridge.security_schema_ready()') IS NOT NULL AS \"securityReady\",\n to_regclass('agent_bridge.request_authorities') IS NOT NULL AS \"requestAuthorities\",\n to_regclass('agent_bridge.gateway_authority') IS NOT NULL AS \"gatewayAuthority\",\n (\n (SELECT attribute.attnotnull\n FROM pg_attribute attribute\n WHERE attribute.attrelid=to_regclass('agent_bridge.gateway_authority')\n AND attribute.attname='singleton' AND attribute.attnum>0 AND NOT attribute.attisdropped)\n AND (SELECT attribute.attnotnull\n FROM pg_attribute attribute\n WHERE attribute.attrelid=to_regclass('agent_bridge.gateway_authority')\n AND attribute.attname='authority_id' AND attribute.attnum>0 AND NOT attribute.attisdropped)\n AND EXISTS (\n SELECT 1 FROM pg_constraint table_constraint\n WHERE table_constraint.conrelid=to_regclass('agent_bridge.gateway_authority')\n AND table_constraint.conname='gateway_authority_singleton'\n AND table_constraint.contype='p'\n AND table_constraint.conkey::smallint[]=ARRAY[(SELECT attribute.attnum FROM pg_attribute attribute\n WHERE attribute.attrelid=to_regclass('agent_bridge.gateway_authority')\n AND attribute.attname='singleton' AND attribute.attnum>0 AND NOT attribute.attisdropped)]\n )\n AND EXISTS (\n SELECT 1 FROM pg_constraint table_constraint\n WHERE table_constraint.conrelid=to_regclass('agent_bridge.gateway_authority')\n AND table_constraint.conname='gateway_authority_singleton_true'\n AND table_constraint.contype='c'\n AND regexp_replace(\n pg_get_expr(table_constraint.conbin,table_constraint.conrelid),'[[:space:]()]','','g'\n )='singleton'\n )\n AND EXISTS (\n SELECT 1 FROM pg_constraint table_constraint\n WHERE table_constraint.conrelid=to_regclass('agent_bridge.gateway_authority')\n AND table_constraint.conname='gateway_authority_id_unique'\n AND table_constraint.contype='u'\n AND table_constraint.conkey::smallint[]=ARRAY[(SELECT attribute.attnum FROM pg_attribute attribute\n WHERE attribute.attrelid=to_regclass('agent_bridge.gateway_authority')\n AND attribute.attname='authority_id' AND attribute.attnum>0 AND NOT attribute.attisdropped)]\n )\n ) AS \"gatewayAuthorityShape\",\n EXISTS (\n SELECT 1\n FROM pg_trigger trigger\n JOIN pg_proc trigger_function ON trigger_function.oid=trigger.tgfoid\n JOIN pg_namespace trigger_namespace ON trigger_namespace.oid=trigger_function.pronamespace\n WHERE trigger.tgrelid=to_regclass('agent_bridge.gateway_authority')\n AND trigger.tgname='gateway_authority_immutable'\n AND NOT trigger.tgisinternal AND trigger.tgenabled='O'\n AND (trigger.tgtype::integer & 1)=0\n AND (trigger.tgtype::integer & 2)=2\n AND (trigger.tgtype::integer & 56)=56\n AND trigger_function.proname='reject_gateway_authority_mutation'\n AND trigger_namespace.nspname='agent_bridge'\n AND trigger_function.proowner=(SELECT nspowner FROM pg_namespace WHERE nspname='agent_bridge')\n AND NOT trigger_function.prosecdef\n AND coalesce(trigger_function.proconfig @> ARRAY['search_path=\"\"'],false)\n ) AS \"gatewayAuthorityImmutable\",\n to_regprocedure('agent_bridge.open_request_authority(uuid,text,uuid)') IS NOT NULL\n AND to_regprocedure('agent_bridge.resolve_credential_hash(text)') IS NOT NULL AS \"authorityOpen\",\n to_regprocedure('agent_bridge.open_request_authority_bound(uuid,text,uuid)') IS NOT NULL AS \"authorityBoundOpen\",\n to_regprocedure('agent_bridge.close_request_authority()') IS NOT NULL AS \"authorityClose\",\n to_regprocedure('agent_bridge.gateway_authority_ready()') IS NOT NULL AS \"authorityReady\",\n NOT has_table_privilege((SELECT runtime_role FROM names),'agent_bridge.credentials','SELECT') AS \"credentialDigestHidden\",\n NOT has_table_privilege((SELECT runtime_role FROM names),'agent_bridge.request_authorities','SELECT') AS \"authorityRowsHidden\",\n (NOT has_table_privilege((SELECT runtime_role FROM names),'agent_bridge.gateway_authority','SELECT')\n AND NOT has_table_privilege('public','agent_bridge.gateway_authority','SELECT')) AS \"gatewayAuthorityRowsHidden\",\n (NOT has_table_privilege((SELECT runtime_role FROM names),'agent_bridge.agents','SELECT')\n AND NOT has_table_privilege((SELECT runtime_role FROM names),'agent_bridge.workspaces','SELECT')) AS \"principalTablesHidden\",\n (\n NOT EXISTS (\n SELECT 1\n FROM unnest(ARRAY[\n 'agent_bridge.credentials','agent_bridge.agents',\n 'agent_bridge.workspaces','agent_bridge.request_authorities',\n 'agent_bridge.gateway_authority'\n ]) protected_table(value)\n CROSS JOIN unnest(ARRAY[\n 'SELECT','INSERT','UPDATE','DELETE','TRUNCATE','REFERENCES','TRIGGER'\n ]) requested_privilege(value)\n WHERE has_table_privilege(\n (SELECT runtime_role FROM names),protected_table.value,requested_privilege.value\n )\n )\n AND NOT EXISTS (\n SELECT 1\n FROM unnest(ARRAY[\n 'agent_bridge.credentials','agent_bridge.agents',\n 'agent_bridge.workspaces','agent_bridge.request_authorities',\n 'agent_bridge.gateway_authority'\n ]) protected_table(value)\n CROSS JOIN unnest(ARRAY['SELECT','INSERT','UPDATE','REFERENCES']) requested_privilege(value)\n WHERE has_any_column_privilege(\n (SELECT runtime_role FROM names),protected_table.value,requested_privilege.value\n )\n )\n ) AS \"authorityTablesLocked\",\n NOT EXISTS (\n SELECT 1\n FROM unnest(ARRAY[\n 'SELECT','INSERT','UPDATE','DELETE','TRUNCATE','REFERENCES','TRIGGER'\n ]) requested_privilege(value)\n WHERE has_table_privilege('public','agent_bridge.gateway_authority',requested_privilege.value)\n )\n AND NOT EXISTS (\n SELECT 1\n FROM unnest(ARRAY['SELECT','INSERT','UPDATE','REFERENCES']) requested_privilege(value)\n WHERE has_any_column_privilege(\n 'public','agent_bridge.gateway_authority',requested_privilege.value\n )\n ) AS \"gatewayAuthorityPublicLocked\",\n (\n has_function_privilege((SELECT runtime_role FROM names),'agent_bridge.resolve_credential_hash(text)','EXECUTE')\n AND has_function_privilege((SELECT runtime_role FROM names),'agent_bridge.open_request_authority(uuid,text,uuid)','EXECUTE')\n AND has_function_privilege((SELECT runtime_role FROM names),'agent_bridge.open_request_authority_bound(uuid,text,uuid)','EXECUTE')\n AND has_function_privilege((SELECT runtime_role FROM names),'agent_bridge.close_request_authority()','EXECUTE')\n AND has_function_privilege((SELECT runtime_role FROM names),'agent_bridge.gateway_authority_ready()','EXECUTE')\n AND has_function_privilege((SELECT runtime_role FROM names),'agent_bridge.record_scope_denial(uuid,text,uuid)','EXECUTE')\n AND has_function_privilege((SELECT runtime_role FROM names),'agent_bridge.consume_rate_limit(uuid,text,uuid)','EXECUTE')\n AND NOT has_function_privilege((SELECT runtime_role FROM names),'agent_bridge.active_request_authority()','EXECUTE')\n AND NOT has_function_privilege((SELECT runtime_role FROM names),'agent_bridge.assert_active_request_credential(uuid)','EXECUTE')\n AND NOT has_function_privilege((SELECT runtime_role FROM names),'agent_bridge.record_scope_denial_unbound_011(uuid,text,uuid)','EXECUTE')\n AND NOT has_function_privilege((SELECT runtime_role FROM names),'agent_bridge.consume_rate_limit_unbound_011(uuid,text,uuid)','EXECUTE')\n AND NOT has_function_privilege('public','agent_bridge.resolve_credential_hash(text)','EXECUTE')\n AND NOT has_function_privilege('public','agent_bridge.open_request_authority(uuid,text,uuid)','EXECUTE')\n AND NOT has_function_privilege('public','agent_bridge.open_request_authority_bound(uuid,text,uuid)','EXECUTE')\n AND NOT has_function_privilege('public','agent_bridge.close_request_authority()','EXECUTE')\n AND NOT has_function_privilege('public','agent_bridge.gateway_authority_ready()','EXECUTE')\n AND NOT has_function_privilege('public','agent_bridge.record_scope_denial(uuid,text,uuid)','EXECUTE')\n AND NOT has_function_privilege('public','agent_bridge.consume_rate_limit(uuid,text,uuid)','EXECUTE')\n AND NOT has_function_privilege('public','agent_bridge.record_scope_denial_unbound_011(uuid,text,uuid)','EXECUTE')\n AND NOT has_function_privilege('public','agent_bridge.consume_rate_limit_unbound_011(uuid,text,uuid)','EXECUTE')\n AND NOT EXISTS (\n SELECT 1 FROM pg_proc procedure\n JOIN pg_namespace namespace ON namespace.oid=procedure.pronamespace\n WHERE namespace.nspname='agent_bridge'\n AND procedure.proname IN (\n 'resolve_credential_hash','open_request_authority','open_request_authority_bound',\n 'gateway_authority_ready','active_request_authority',\n 'assert_active_request_credential','close_request_authority','record_scope_denial',\n 'consume_rate_limit','record_scope_denial_unbound_011','consume_rate_limit_unbound_011'\n )\n AND (\n NOT procedure.prosecdef\n OR procedure.proowner <> (SELECT nspowner FROM pg_namespace WHERE nspname='agent_bridge')\n OR NOT coalesce(procedure.proconfig @> ARRAY['search_path=\"\"'],false)\n )\n )\n ) AS \"authorityCatalog\"`,\n );\n const row = objects.rows[0];\n if (!Boolean(\n row?.immutable && row.deliveryAudit && row.idempotency && row.claim && row.publisher &&\n row.terminal && row.source && row.thread && row.created && row.presence && row.project &&\n row.targets && row.scopeSets && row.securityEvents && row.ratePolicies && row.rateBuckets &&\n row.replacement && row.rateCleanup && row.credentialSecurity && row.eventAppendOnly &&\n row.scopeAudit && row.rateConsume && row.securityReady && row.requestAuthorities &&\n row.gatewayAuthority && row.gatewayAuthorityShape && row.gatewayAuthorityImmutable && row.authorityOpen &&\n row.authorityBoundOpen && row.authorityClose && row.authorityReady &&\n row.credentialDigestHidden && row.authorityRowsHidden && row.gatewayAuthorityRowsHidden &&\n row.principalTablesHidden && row.authorityTablesLocked && row.gatewayAuthorityPublicLocked &&\n row.authorityCatalog\n )) return false;\n const endpointChallenge = await db.query<{\n tables: boolean;\n functions: boolean;\n grants: boolean;\n marker: boolean;\n }>(`\n WITH names AS (\n SELECT ('agent_bridge_runtime_' || substr(md5(current_database()),1,16))::name AS runtime_role\n ) SELECT\n to_regclass('agent_bridge.endpoint_migration_challenges') IS NOT NULL\n AND to_regclass('agent_bridge.endpoint_migration_challenge_events') IS NOT NULL\n AND to_regclass('agent_bridge.endpoint_migration_challenge_attestations') IS NOT NULL AS tables,\n to_regprocedure('agent_bridge.issue_endpoint_migration_challenge(uuid,uuid,text)') IS NOT NULL\n AND to_regprocedure('agent_bridge.consume_endpoint_migration_challenge(uuid,uuid,text)') IS NOT NULL\n AND to_regprocedure('agent_bridge.endpoint_migration_challenge_ready()') IS NOT NULL AS functions,\n NOT EXISTS (\n SELECT 1\n FROM unnest(ARRAY[\n 'agent_bridge.endpoint_migration_challenges',\n 'agent_bridge.endpoint_migration_challenge_events',\n 'agent_bridge.endpoint_migration_challenge_attestations'\n ]) relation_name\n CROSS JOIN unnest(ARRAY['SELECT','INSERT','UPDATE','DELETE','TRUNCATE','REFERENCES','TRIGGER']) privilege\n WHERE has_table_privilege((SELECT runtime_role FROM names),relation_name,privilege)\n OR has_table_privilege('public',relation_name,privilege)\n )\n AND has_function_privilege((SELECT runtime_role FROM names),\n 'agent_bridge.issue_endpoint_migration_challenge(uuid,uuid,text)','EXECUTE')\n AND has_function_privilege((SELECT runtime_role FROM names),\n 'agent_bridge.consume_endpoint_migration_challenge(uuid,uuid,text)','EXECUTE')\n AND NOT has_function_privilege('public',\n 'agent_bridge.issue_endpoint_migration_challenge(uuid,uuid,text)','EXECUTE')\n AND NOT has_function_privilege('public',\n 'agent_bridge.consume_endpoint_migration_challenge(uuid,uuid,text)','EXECUTE')\n AND NOT EXISTS (\n SELECT 1\n FROM pg_catalog.pg_proc procedure\n JOIN pg_catalog.pg_namespace namespace ON namespace.oid=procedure.pronamespace\n WHERE namespace.nspname='agent_bridge'\n AND procedure.proname IN (\n 'guard_endpoint_migration_challenge',\n 'reject_endpoint_migration_challenge_truncate',\n 'reject_endpoint_migration_challenge_event_mutation',\n 'reject_endpoint_migration_challenge_attestation_mutation',\n 'cleanup_endpoint_migration_challenges',\n 'endpoint_migration_challenge_active_credential',\n 'endpoint_migration_challenge_direct_lineage',\n 'endpoint_migration_challenge_catalog_definition',\n 'endpoint_migration_challenge_ready'\n )\n AND has_function_privilege((SELECT runtime_role FROM names),procedure.oid,'EXECUTE')\n ) AS grants,\n EXISTS (\n SELECT 1 FROM pg_catalog.pg_attribute\n WHERE attrelid='agent_bridge.request_authorities'::regclass\n AND attname='authorized_endpoint_migration_operation'\n AND NOT attnotnull\n ) AS marker\n `);\n const endpoint = endpointChallenge.rows[0];\n if (!endpoint?.tables || !endpoint.functions || !endpoint.grants || !endpoint.marker) return false;\n try {\n const security = await db.query<{ ready: boolean }>(\n \"SELECT agent_bridge.security_schema_ready() AS ready\",\n );\n const ownerControl = await db.query<{ ready: boolean }>(\n \"SELECT agent_bridge.owner_control_plane_ready() AS ready\",\n );\n const portableArchive = await db.query<{ ready: boolean }>(\n \"SELECT agent_bridge.portable_archive_ready() AS ready\",\n );\n const gatewayAuthority = await db.query<{ ready: boolean }>(\n \"SELECT agent_bridge.gateway_authority_ready() AS ready\",\n );\n return security.rows[0]?.ready === true && ownerControl.rows[0]?.ready === true &&\n portableArchive.rows[0]?.ready === true && gatewayAuthority.rows[0]?.ready === true &&\n await rowIsolationReady(\n db,\n options.allowPrivilegedCaller === true,\n );\n } catch {\n return false;\n }\n}\n\nexport async function runMigrations(\n db: PgQueryable,\n directory: string,\n): Promise<AppliedMigration[]> {\n const expected = await loadMigrationPlan(directory);\n\n for (const migration of expected) {\n const applied = await recordedMigrations(db);\n const recorded = applied.find((entry) => entry.version === migration.version);\n if (recorded) {\n if (recorded.name !== migration.name || recorded.checksum !== migration.checksum) {\n throw new Error(`migration ${migration.version}_${migration.name} conflicts with schema state`);\n }\n continue;\n }\n await db.query(withNativeDrSharedLock(\n migration.source.split(\"__AGENT_BRIDGE_MIGRATION_CHECKSUM__\").join(migration.checksum),\n ));\n const verified = (await recordedMigrations(db)).find(\n (entry) => entry.version === migration.version,\n );\n if (verified?.name !== migration.name || verified.checksum !== migration.checksum) {\n throw new Error(`migration ${migration.version}_${migration.name} was not recorded correctly`);\n }\n }\n\n return recordedMigrations(db);\n}\n"],"mappings":"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","names":["row"]}
@@ -2,8 +2,9 @@
2
2
  import {
3
3
  preparePrivateSqliteLocation,
4
4
  securePrivatePath,
5
+ securePrivateSqliteSidecar,
5
6
  verifyPrivatePathAccess
6
- } from "./chunk-NCO7RLBM.js";
7
+ } from "./chunk-GTK4KOED.js";
7
8
  import {
8
9
  assertIdempotentReplay
9
10
  } from "./chunk-VOQIDTCJ.js";
@@ -33,7 +34,9 @@ var LOCAL_SQLITE_SCHEMA_CONTRACTS = Object.freeze([
33
34
  ]);
34
35
  var EDGE_SQLITE_SCHEMA_CONTRACTS = Object.freeze([
35
36
  Object.freeze({ id: "current-created-schema", sha256: "27f22b2f4024585c87e8d6f76f8999a8df92bb1f585d46594a7a1e852fd53c4c" }),
36
- Object.freeze({ id: "current-upgraded-project-column", sha256: "171ae11f520b4963f517d3102de64cb8a5f45c080078ff02e20aeb17891b585c" })
37
+ Object.freeze({ id: "current-upgraded-project-column", sha256: "171ae11f520b4963f517d3102de64cb8a5f45c080078ff02e20aeb17891b585c" }),
38
+ Object.freeze({ id: "current-upgraded-project-column-migration-gate", sha256: "790b4bfed373ff776ba6700065154f7a3cbbecd94f37ea09a654768ac2a8455c" }),
39
+ Object.freeze({ id: "current-upgraded-migration-gate", sha256: "64634eae28f344f02324e6c002e4cc35ea9a99fe878de843df018482bdde38ef" })
37
40
  ]);
38
41
  var localContractHashes = new Set(LOCAL_SQLITE_SCHEMA_CONTRACTS.map((contract) => contract.sha256));
39
42
  var edgeContractHashes = new Set(EDGE_SQLITE_SCHEMA_CONTRACTS.map((contract) => contract.sha256));
@@ -144,12 +147,14 @@ var localObjects = /* @__PURE__ */ new Map([
144
147
  var edgeColumns = {
145
148
  agent_bridge_metadata: ["singleton", "database_kind", "schema_name", "schema_version"],
146
149
  edge_scopes: ["scope_key", "endpoint_hash", "workspace", "agent", "pull_cursor", "last_sync_at", "last_error", "last_outbound_sync_at", "last_inbound_sync_at", "last_attempt_at", "cache_contract"],
150
+ edge_migration_gates: ["scope_key", "state", "operation_id", "lease_token", "lease_expires_at", "updated_at"],
147
151
  edge_outbox: ["position", "scope_key", "message_id", "idempotency_key", "payload_hash", "draft_json", "state", "attempts", "available_at", "lease_token", "lease_expires_at", "last_error", "blocked_at", "created_at"],
148
152
  edge_inbox: ["scope_key", "message_id", "remote_sequence", "sequence_key", "workspace", "project", "source", "type", "thread_id", "created_at", "expires_at", "message_json"]
149
153
  };
150
154
  var edgeObjects = /* @__PURE__ */ new Map([
151
155
  ["agent_bridge_metadata", ["table", "agent_bridge_metadata"]],
152
156
  ["edge_scopes", ["table", "edge_scopes"]],
157
+ ["edge_migration_gates", ["table", "edge_migration_gates"]],
153
158
  ["edge_outbox", ["table", "edge_outbox"]],
154
159
  ["edge_inbox", ["table", "edge_inbox"]],
155
160
  ["edge_inbox_created", ["index", "edge_inbox"]],
@@ -158,6 +163,8 @@ var edgeObjects = /* @__PURE__ */ new Map([
158
163
  ["edge_inbox_source", ["index", "edge_inbox"]],
159
164
  ["edge_inbox_thread", ["index", "edge_inbox"]],
160
165
  ["edge_outbox_due", ["index", "edge_outbox"]],
166
+ ["edge_migration_gates_state", ["index", "edge_migration_gates"]],
167
+ ["edge_outbox_migration_gate_insert", ["trigger", "edge_outbox"]],
161
168
  ["agent_bridge_metadata_no_delete", ["trigger", "agent_bridge_metadata"]],
162
169
  ["agent_bridge_metadata_no_update", ["trigger", "agent_bridge_metadata"]]
163
170
  ]);
@@ -356,6 +363,7 @@ function isBusy(error) {
356
363
  const sqlite = error;
357
364
  return sqlite.errcode === 5 || /database is (?:locked|busy)/i.test(error.message);
358
365
  }
366
+ var SQLITE_INITIALIZATION_BUSY_TIMEOUT_MS = 15e3;
359
367
  async function retrySqliteBusy(operation, timeoutMs) {
360
368
  const deadline = Date.now() + Math.max(1, Math.trunc(timeoutMs));
361
369
  let delayMs = 5;
@@ -472,14 +480,14 @@ var SQLiteBridgeStore = class {
472
480
  this.path = path;
473
481
  this.busyTimeoutMs = busyTimeoutMs;
474
482
  this.initialized = false;
475
- const selected = preparePrivateSqliteLocation(path);
483
+ const selected = preparePrivateSqliteLocation(path, false, "defer");
476
484
  this.databasePath = selected;
477
485
  this.preexistingFiles = new Set(selected === ":memory:" ? [] : [selected, `${selected}-wal`, `${selected}-shm`].filter(existsSync));
478
486
  const before = selected === ":memory:" || !existsSync(selected) ? void 0 : lstatSync(selected);
479
487
  this.db = openDatabase(selected);
480
488
  try {
481
489
  this.db.exec(`PRAGMA busy_timeout = ${Math.max(1, Math.trunc(this.busyTimeoutMs))}`);
482
- this.restrictFiles();
490
+ this.restrictFiles(false);
483
491
  if (before) {
484
492
  const after = lstatSync(selected);
485
493
  if (after.dev !== before.dev || after.ino !== before.ino) throw new Error("SQLite database path identity changed while opening");
@@ -489,12 +497,14 @@ var SQLiteBridgeStore = class {
489
497
  throw error;
490
498
  }
491
499
  }
492
- restrictFiles() {
500
+ restrictFiles(includeSidecars = true) {
493
501
  if (this.databasePath === ":memory:") return;
494
- for (const path of [this.databasePath, `${this.databasePath}-wal`, `${this.databasePath}-shm`]) {
502
+ const paths = includeSidecars ? [this.databasePath, `${this.databasePath}-wal`, `${this.databasePath}-shm`] : [this.databasePath];
503
+ for (const path of paths) {
495
504
  if (!existsSync(path)) continue;
496
505
  if (path === this.databasePath && this.preexistingFiles.has(path)) verifyPrivatePathAccess(path, "file");
497
- else securePrivatePath(path, "file");
506
+ else if (path === this.databasePath) securePrivatePath(path, "file");
507
+ else securePrivateSqliteSidecar(path);
498
508
  }
499
509
  }
500
510
  async initialize() {
@@ -515,8 +525,9 @@ var SQLiteBridgeStore = class {
515
525
  const encoded = (parts[0] ?? 0) * 1e6 + (parts[1] ?? 0) * 1e3 + (parts[2] ?? 0);
516
526
  if (encoded < 3051003) throw new Error("SQLite 3.51.3 or newer is required");
517
527
  assertLocalUpgradeCandidate(this.db);
518
- await retrySqliteBusy(() => this.db.exec(schema), this.busyTimeoutMs);
519
- await retrySqliteBusy(() => this.db.exec("BEGIN IMMEDIATE"), this.busyTimeoutMs);
528
+ const initializationTimeoutMs = Math.max(this.busyTimeoutMs, SQLITE_INITIALIZATION_BUSY_TIMEOUT_MS);
529
+ await retrySqliteBusy(() => this.db.exec(schema), initializationTimeoutMs);
530
+ await retrySqliteBusy(() => this.db.exec("BEGIN IMMEDIATE"), initializationTimeoutMs);
520
531
  try {
521
532
  const columns = this.db.prepare("PRAGMA table_info(bridge_messages)").all();
522
533
  if (!columns.some((column) => column.name === "project")) {
@@ -989,6 +1000,7 @@ var SQLiteBridgeStore = class {
989
1000
  };
990
1001
 
991
1002
  export {
1003
+ SQLITE_INITIALIZATION_BUSY_TIMEOUT_MS,
992
1004
  retrySqliteBusy,
993
1005
  LOCAL_SQLITE_APPLICATION_ID,
994
1006
  EDGE_SQLITE_APPLICATION_ID,
@@ -1010,4 +1022,4 @@ export {
1010
1022
  verifySqliteHealth,
1011
1023
  SQLiteBridgeStore
1012
1024
  };
1013
- //# sourceMappingURL=chunk-5GMB3A77.js.map
1025
+ //# sourceMappingURL=chunk-DQOZJJZ2.js.map