@creatornader/agent-bridge 0.5.2 → 0.6.1

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 (78) hide show
  1. package/CHANGELOG.md +57 -1
  2. package/README.md +59 -34
  3. package/ROADMAP.md +74 -17
  4. package/SECURITY.md +6 -5
  5. package/SKILL.md +4 -1
  6. package/dist/archive.d.ts +2 -2
  7. package/dist/{bridge-service-CNBKdYXh.d.ts → bridge-service-DjSYfjKt.d.ts} +4 -2
  8. package/dist/{bridge-store-ByJ6CaJk.d.ts → bridge-store-Bi_LCX8e.d.ts} +5 -1
  9. package/dist/bridge.d.ts +9 -37
  10. package/dist/bridge.js +6 -10
  11. package/dist/chunk-23UDQZMT.js +54 -0
  12. package/dist/chunk-23UDQZMT.js.map +1 -0
  13. package/dist/{chunk-AWE3DFZV.js → chunk-4V2PFJEF.js} +11 -4
  14. package/dist/chunk-4V2PFJEF.js.map +1 -0
  15. package/dist/{chunk-E4OWHGUE.js → chunk-63JKCBC6.js} +10 -8
  16. package/dist/chunk-63JKCBC6.js.map +1 -0
  17. package/dist/chunk-6ZOLE3E3.js +242 -0
  18. package/dist/chunk-6ZOLE3E3.js.map +1 -0
  19. package/dist/chunk-7B3XRRNI.js +27 -0
  20. package/dist/chunk-7B3XRRNI.js.map +1 -0
  21. package/dist/{chunk-7VJI2MXI.js → chunk-IF5OKPBK.js} +32 -14
  22. package/dist/chunk-IF5OKPBK.js.map +1 -0
  23. package/dist/{chunk-QPC6JHA3.js → chunk-IXNQG4SB.js} +12 -16
  24. package/dist/chunk-IXNQG4SB.js.map +1 -0
  25. package/dist/{chunk-HUHG7XTB.js → chunk-JIRNR75D.js} +30 -193
  26. package/dist/chunk-JIRNR75D.js.map +1 -0
  27. package/dist/{chunk-JUTJRAMA.js → chunk-LF37B6KL.js} +6 -4
  28. package/dist/chunk-LF37B6KL.js.map +1 -0
  29. package/dist/{chunk-2EVLG3YA.js → chunk-UKFRCP6X.js} +10 -7
  30. package/dist/chunk-UKFRCP6X.js.map +1 -0
  31. package/dist/{chunk-SN7PIVDF.js → chunk-ZUZ7TCIH.js} +13 -1
  32. package/dist/{chunk-SN7PIVDF.js.map → chunk-ZUZ7TCIH.js.map} +1 -1
  33. package/dist/cli.js +45 -40
  34. package/dist/cli.js.map +1 -1
  35. package/dist/client-config.d.ts +1 -1
  36. package/dist/client-config.js +1 -1
  37. package/dist/client-runtime.d.ts +3 -3
  38. package/dist/client-runtime.js +5 -5
  39. package/dist/contracts/generate.js +3 -3
  40. package/dist/contracts/generate.js.map +1 -1
  41. package/dist/dr.d.ts +8 -0
  42. package/dist/dr.js +1 -1
  43. package/dist/{gateway-CW-61lvs.d.ts → gateway-DWZ3pX48.d.ts} +7 -2
  44. package/dist/gateway-main.js +12 -3
  45. package/dist/gateway-main.js.map +1 -1
  46. package/dist/gateway.d.ts +3 -3
  47. package/dist/gateway.js +3 -3
  48. package/dist/index.js +8 -7
  49. package/dist/index.js.map +1 -1
  50. package/dist/{postgres-bridge-store-C9KG9Z69.d.ts → postgres-bridge-store-ChoOuFEY.d.ts} +1 -1
  51. package/dist/server.d.ts +0 -2
  52. package/dist/server.js +8 -7
  53. package/dist/{sqlite-edge-store-CdMIOrho.d.ts → sqlite-edge-store-BAFUeysk.d.ts} +1 -1
  54. package/dist/sqlite.d.ts +7 -3
  55. package/dist/sqlite.js +1 -1
  56. package/docs/architecture-v2.md +26 -14
  57. package/docs/decisions/0001-protocol-layers-and-acknowledgment-semantics.md +2 -1
  58. package/docs/decisions/0002-canonical-operation-contract-registry.md +11 -1
  59. package/docs/decisions/0005-retire-direct-supabase-runtime.md +52 -0
  60. package/docs/deployment.md +41 -17
  61. package/docs/ecosystem.md +6 -4
  62. package/docs/troubleshooting.md +15 -0
  63. package/llms.txt +4 -4
  64. package/openapi/agent-bridge-v2.openapi.json +11 -6
  65. package/package.json +5 -3
  66. package/schemas/agent-bridge-v2.capabilities.json +11 -5
  67. package/schemas/agent-bridge-v2.mcp.json +13 -12
  68. package/schemas/agent-bridge-v2.schema.json +26 -24
  69. package/scripts/gateway-release-check.mjs +92 -0
  70. package/dist/chunk-2EVLG3YA.js.map +0 -1
  71. package/dist/chunk-7VJI2MXI.js.map +0 -1
  72. package/dist/chunk-AWE3DFZV.js.map +0 -1
  73. package/dist/chunk-E4OWHGUE.js.map +0 -1
  74. package/dist/chunk-HUHG7XTB.js.map +0 -1
  75. package/dist/chunk-JUTJRAMA.js.map +0 -1
  76. package/dist/chunk-QPC6JHA3.js.map +0 -1
  77. package/dist/chunk-Z6JP6MYD.js +0 -584
  78. package/dist/chunk-Z6JP6MYD.js.map +0 -1
package/CHANGELOG.md CHANGED
@@ -4,7 +4,63 @@ All notable changes to agent-bridge are documented in this file.
4
4
 
5
5
  The format follows [Keep a Changelog](https://keepachangelog.com/en/1.1.0/) and the project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
6
6
 
7
- ## [Unreleased]
7
+ ## [0.6.1] - 2026-07-21
8
+
9
+ ### Added
10
+
11
+ - Report the running package version and image Git revision through authenticated
12
+ gateway capabilities.
13
+ - Add a release check that compares the live gateway with the intended version and
14
+ revision before the production proof starts.
15
+
16
+ ### Changed
17
+
18
+ - Describe Agent Bridge first as a way for AI agents to message each other and hand
19
+ off work across tools, sessions, and machines. Keep mailbox and provider terms in
20
+ the technical sections where they explain behavior.
21
+ - Record the source revision in production image builds and labels.
22
+
23
+ ## [0.6.0] - 2026-07-21
24
+
25
+ ### Added
26
+
27
+ - Add `agent-bridge send --queue-only` for an explicit gateway outbox write that
28
+ makes no network request. A later manual or automatic sync publishes the same
29
+ immutable message from its original endpoint, workspace, and principal scope.
30
+
31
+ ### Changed
32
+
33
+ - Describe Agent Bridge as messaging and work delivery across tools, sessions, and
34
+ machines. The npm package remains `@creatornader/agent-bridge`; npm rejects the
35
+ unscoped `agentbridge` name as confusingly similar to another package.
36
+ - Limit runtime providers and generated capability contracts to local SQLite and the
37
+ authenticated gateway.
38
+
39
+ ### Removed
40
+
41
+ - Remove the direct Supabase PostgREST runtime provider and its publishable-key
42
+ authorization model. Historical schema, migration 006 import, and the reconciliation
43
+ command remain available for upgrades.
44
+
45
+ ### Fixed
46
+
47
+ - Make the production proof use the real gateway edge scope during its offline
48
+ phase. The proof now carries the configured workspace, uses an explicit stable
49
+ message ID for replay, and waits for rate-limited replays to deduplicate before
50
+ continuing.
51
+ - Verify a Fly restart through a later successful machine `start` event instead of
52
+ requiring `instance_id` to change. Fly may retain that identifier across a plain
53
+ restart. Limit receipt value scanning to secret-bearing environment variables so
54
+ ordinary GitHub job identifiers cannot cause false leak reports. Permit GitHub to
55
+ reuse the sender host for the fresh-edge verifier while still requiring distinct
56
+ sender and receiver host evidence.
57
+ - Preserve only Agent Bridge roles and relevant default privileges in PostgreSQL native
58
+ DR backups when a managed provider gives the schema owner privileges in unrelated
59
+ schemas.
60
+ - Treat zero-valued Windows file IDs as unavailable during endpoint migration. Distinct
61
+ single-link edge files remain valid, while ambiguous hard-link cases still fail closed.
62
+ - Give PostgreSQL integration tests enough time to create temporary databases and apply
63
+ migrations before Vitest advances to later tests and overlaps their cleanup.
8
64
 
9
65
  ## [0.5.2] - 2026-07-20
10
66
 
package/README.md CHANGED
@@ -4,21 +4,23 @@
4
4
  [![test](https://github.com/creatornader/agent-bridge/actions/workflows/test.yml/badge.svg)](https://github.com/creatornader/agent-bridge/actions/workflows/test.yml)
5
5
  [![license](https://img.shields.io/github/license/creatornader/agent-bridge)](LICENSE)
6
6
 
7
- Agent Bridge is a durable, pull-first mailbox and work-delivery control plane for AI
8
- agents across runtimes, sessions, and machines. It gives coding agents, desktop agents,
9
- always-on workers, and agent frameworks a shared inbox that survives disconnection and
10
- restart. Start locally with SQLite, then use an operator-owned PostgreSQL gateway when
11
- agents need to communicate across machines.
7
+ Agent Bridge lets AI agents message each other and hand off work across tools,
8
+ sessions, and machines. Messages wait while an agent is offline and are still there
9
+ after it restarts.
12
10
 
13
- It supports three operating modes:
11
+ Use it through MCP, a CLI, a Node library, or an authenticated HTTPS gateway. Start
12
+ locally with SQLite. Use PostgreSQL when agents need to communicate across machines.
13
+
14
+ It supports two operating modes:
14
15
 
15
16
  | Mode | Store | Use case |
16
17
  | --- | --- | --- |
17
18
  | Local | SQLite WAL | One machine, no service or account |
18
19
  | Gateway | PostgreSQL plus a local SQLite edge store | Cross-machine messaging, offline sends, claims, retries, and presence |
19
- | Legacy Supabase | Existing `shared_context` table through PostgREST | Compatibility while a v1 deployment migrates |
20
20
 
21
- PostgreSQL remains the authority in gateway mode. SQLite holds local-only messages or gateway edge state. Supabase is one way to host PostgreSQL, not a protocol dependency.
21
+ PostgreSQL is the authority in gateway mode. SQLite holds local-only messages or
22
+ gateway edge state. Supabase can host PostgreSQL, but Agent Bridge does not depend on
23
+ its client APIs. The direct Supabase runtime adapter was removed in 0.6.0.
22
24
 
23
25
  ## Quick start
24
26
 
@@ -63,7 +65,8 @@ a production TLS deployment. Read [the deployment guide](docs/deployment.md) bef
63
65
  exposing a gateway, changing network bindings, upgrading the schema, or relying on the
64
66
  named volume for persistent data.
65
67
 
66
- The repository also maintains a provider-neutral Fly.io reference at
68
+ The repository also maintains a Fly.io reference that does not depend on a specific
69
+ database host. It lives at
67
70
  [`deploy/fly.toml`](deploy/fly.toml). It deliberately omits an app name and release
68
71
  command. Check the local contract before creating or changing any Fly resource:
69
72
 
@@ -101,12 +104,29 @@ The Fly gateway expects two secrets: the restricted runtime database URL and a
101
104
  base64-encoded PostgreSQL CA bundle. It decodes the CA in memory and verifies both the
102
105
  certificate chain and database hostname. It never needs a CA file inside the image.
103
106
 
104
- The manual `gateway production proof` workflow tests an existing gateway after its
105
- deployment gate has passed. GitHub must run it from `main` in the protected
107
+ Build the production image with its source revision, then confirm the running gateway
108
+ before moving clients or starting the full proof:
109
+
110
+ ```bash
111
+ fly deploy --config deploy/fly.toml --app <app> \
112
+ --build-arg AGENT_BRIDGE_BUILD_REVISION="$(git rev-parse HEAD)"
113
+ AGENT_BRIDGE_URL="https://<app>.fly.dev" AGENT_BRIDGE_TOKEN="..." \
114
+ npm run verify:gateway:release -- \
115
+ --version "$(node -p "require('./package.json').version")" \
116
+ --revision "$(git rev-parse HEAD)"
117
+ ```
118
+
119
+ The authenticated check compares the running package and Git revision with the
120
+ intended release. It also requires protocol 2.1, request authority, and row isolation.
121
+ It prints no credential. A missing or different revision stops the rollout.
122
+
123
+ The manual `gateway production proof` workflow tests an existing gateway after this
124
+ deployment gate passes. GitHub must run it from `main` in the protected
106
125
  `agent-bridge-production-proof` environment. Separate sender and receiver jobs prove
107
126
  offline outbox replay, exact idempotency, claim, and acknowledgment. The workflow then
108
- restarts the single Fly machine, requires a new runtime instance ID, and verifies the
109
- message and settled delivery with a fresh receiver instance and a new SQLite edge file.
127
+ restarts the single Fly machine, requires a later successful machine start event, and
128
+ verifies the message and settled delivery with a fresh receiver instance and a new
129
+ SQLite edge file.
110
130
  Its versioned receipts contain only identifiers, times, principal and workspace labels,
111
131
  the gateway origin, checks, and SHA-256 host evidence. They omit credentials, database
112
132
  URLs, message content, and SQLite files.
@@ -133,11 +153,16 @@ The accepted protocol and storage decisions live in [docs/architecture-v2.md](do
133
153
 
134
154
  The canonical v2 operation registry generates [JSON Schema](schemas/agent-bridge-v2.schema.json), [OpenAPI 3.1.2](openapi/agent-bridge-v2.openapi.json), and the [MCP manifest](schemas/agent-bridge-v2.mcp.json). Use `GET /v2/capabilities`, MCP `capabilities`, or CLI `agent-bridge capabilities` to discover the operations for that surface and provider. Capabilities distinguish the current, selected, and supported protocol versions.
135
155
 
156
+ Authenticated gateway capabilities also report `implementationVersion`. Production
157
+ images report `implementationRevision` when the operator supplies the Git revision at
158
+ build time. These fields identify deployed code. They do not change protocol version
159
+ negotiation.
160
+
136
161
  Protocol 2.1 uses a gateway-first rollout. An upgraded gateway continues to serve released 2.0 clients, including headerless requests and their direct or null delivery results. A 2.1 client probes before mutation and proceeds only when complete, consistent response headers select 2.1 and advertise 2.1 support. It rejects mutation against a headerless or 2.0 gateway instead of downgrading. Upgrade the gateway before installing or starting 2.1 clients.
137
162
 
138
163
  Two gateway-only HTTP 2.1 operations establish a short-lived endpoint-migration challenge. Initial preflight uses a direct predecessor and successor. After a cutover journal exists, the same active successor credential can issue at the retained source URL and consume at the target URL. Both calls require active transaction-bound authority and use the canonical credential and operation rate buckets. PostgreSQL stores only a domain-separated SHA-256 commitment. A challenge expires within 60 seconds and does not authorize endpoint cutover. Authenticated HTTP 2.1 capabilities include the credential's `grantedScopes`.
139
164
 
140
- The OpenAPI paths describe protocol 2.1. The embedded `x-agent-bridge-protocol-2.0` and `x-agent-bridge-schemas-2.0` vendor extensions contain frozen compatibility schema metadata for released 2.0 clients. They are not a second OpenAPI description. Gateway credentials enforce the operation scopes declared by the canonical registry. Local mode uses process identity, and legacy mode uses its configured key. Provider-neutral artifacts report this difference instead of claiming one authorization model for every backend.
165
+ The OpenAPI paths describe protocol 2.1. The embedded `x-agent-bridge-protocol-2.0` and `x-agent-bridge-schemas-2.0` vendor extensions contain frozen compatibility schema metadata for released 2.0 clients. They are not a second OpenAPI description. Gateway credentials enforce the operation scopes declared by the canonical registry. Local mode uses process identity. Provider-neutral artifacts report this difference instead of claiming one authorization model for every backend.
141
166
 
142
167
  ## Architecture
143
168
 
@@ -229,7 +254,7 @@ for its relationship to MCP, A2A, agmsg, brokers, and agent runtimes.
229
254
 
230
255
  Use the source install for development. The normal installation path is the published
231
256
  `@creatornader/agent-bridge` package shown in the quick start. The unscoped npm name
232
- belongs to another project.
257
+ belongs to another project, and npm rejects `agentbridge` as confusingly similar.
233
258
 
234
259
  ```bash
235
260
  git clone https://github.com/creatornader/agent-bridge.git
@@ -900,6 +925,10 @@ When a send cannot reach the gateway:
900
925
  3. Long-lived MCP gateway clients retry due messages automatically with bounded exponential backoff. `agent-bridge sync` and the MCP `sync` tool trigger the same bounded replay and cache refresh manually. A permanently blocked message remains visible in diagnostics but does not stop later messages.
901
926
  4. An ambiguous retry is safe because the gateway enforces idempotency and rejects changed content under the same key.
902
927
 
928
+ Pass `--queue-only` to `agent-bridge send` when you want to write to the gateway
929
+ outbox without making a network request. The message stays under the configured
930
+ gateway, workspace, and principal scope. Run `agent-bridge sync` to publish it later.
931
+
903
932
  Normal inbox and pending reads fall back to the local cache when the gateway is unreachable. Cached reads report `source: "cache"`, `stale: true`, and `degraded: true`. When a read requested an unacknowledged filter, cached rows are candidates rather than proof of unread state and report `acknowledgements: "unknown"`. Claims, lease changes, delivery settlement, presence, and read-receipt writes still require the gateway because replaying those operations after a lease or identity change is unsafe.
904
933
 
905
934
  ## CLI
@@ -912,6 +941,7 @@ agent-bridge doctor
912
941
  agent-bridge status
913
942
  agent-bridge pending
914
943
  agent-bridge send --type request --target worker "Run the task"
944
+ agent-bridge send --queue-only --type request --target worker "Queue the task"
915
945
  agent-bridge post --category goal-update --project agent-bridge "Gateway is ready"
916
946
  agent-bridge inbox --limit 20
917
947
  agent-bridge sent --limit 20
@@ -939,7 +969,7 @@ agent-bridge watch
939
969
  dispatches a command. They are safe to use after a command name, including `archive`
940
970
  and `dr` commands.
941
971
 
942
- `--project` adds an optional immutable label to a message. It never selects a workspace or changes the active identity. Omit it on reads to include every project and unlabeled messages in the credential-bound workspace. Pass it to `get`, `inbox`, `history`, `pending`, or `watch` for an exact label match. Gateway callers may use `--workspace` only as an assertion. The CLI rejects a mismatch before sending a request. Local mode permits a per-command workspace override. The global legacy Supabase schema has no tenant workspace, so legacy mode fixes workspace to `*` and rejects other `--workspace` values.
972
+ `--project` adds an optional immutable label to a message. It never selects a workspace or changes the active identity. Omit it on reads to include every project and unlabeled messages in the credential-bound workspace. Pass it to `get`, `inbox`, `history`, `pending`, or `watch` for an exact label match. Gateway callers may use `--workspace` only as an assertion. The CLI rejects a mismatch before sending a request. Local mode permits a per-command workspace override.
943
973
 
944
974
  History defaults to mailbox `inbox`: broadcasts plus messages targeted to the configured principal, exactly as prior releases did. `sent` selects messages whose source is that principal, and `all` is the union. `--receipt-state any|unread|read` is caller-relative and valid only with `inbox`. The deprecated `--unacked-by` option remains an identity assertion. The CLI rejects a mismatch before opening storage or contacting a gateway. Server surfaces reject it before querying message storage. Cursors bind workspace, principal, mailbox, and normalized filters. Version 1 cursors are temporarily accepted, while all new cursors are version 2.
945
975
 
@@ -951,24 +981,22 @@ recipient-visible delivery. The filter also scopes lease-expiry and exhaustion
951
981
  maintenance performed by that claim. Released HTTP 2.0 request shapes remain frozen
952
982
  and reject the field.
953
983
 
954
- The legacy Supabase adapter applies mailbox and receipt rules cooperatively. A holder of the legacy publishable key can bypass the adapter through PostgREST or its receipt RPC. Use the authenticated v2 gateway when the authorization boundary must be enforced.
955
-
956
984
  `agent-bridge pending` is a cheap shell gate for agent startup. It exits 0 when unread candidates or due delivery work are visible, 1 only for an authoritative empty result, and 2 when an empty remote state cannot be confirmed. Its JSON result separates unread context from executable delivery work and labels the state as `available`, `empty`, or `unknown`.
957
985
 
958
- `watch` runs until interrupted unless `--polls` sets an explicit bound. Empty polls use capped backoff and jitter. Gateway and legacy network failures retry when the error is transient. Authentication and validation errors stop the watcher.
986
+ `watch` runs until interrupted unless `--polls` sets an explicit bound. Empty polls use capped backoff and jitter. Gateway network failures retry when the error is transient. Authentication and validation errors stop the watcher.
959
987
  Each exact project filter gets its own local watch checkpoint. Switching between a filtered and unfiltered watch cannot advance the other checkpoint.
960
988
 
961
989
  Unknown flags and missing option values fail before a message can be sent. This prevents a misspelled target flag from becoming a broadcast.
962
990
 
963
991
  ## MCP tools
964
992
 
965
- All providers expose the v1 compatibility tools:
993
+ Both providers expose the v1 compatibility tools:
966
994
 
967
995
  - `post_context`
968
996
  - `get_context`
969
997
  - `ack_context`
970
998
 
971
- Local and gateway providers also expose:
999
+ They also expose:
972
1000
 
973
1001
  - `send`
974
1002
  - `history`
@@ -983,8 +1011,6 @@ Local and gateway providers also expose:
983
1011
  - `heartbeat`
984
1012
  - `presence`
985
1013
 
986
- Legacy Supabase does not advertise delivery or presence tools because its schema cannot enforce those operations.
987
-
988
1014
  The acknowledgment names depend on the interface. MCP `ack_context` and CLI `acknowledge` write read receipts. MCP `acknowledge` and CLI `ack` settle claimed deliveries. A receipt never settles delivery work, and delivery settlement never creates a receipt.
989
1015
 
990
1016
  ## Identity and security
@@ -1018,23 +1044,20 @@ The acknowledgment names depend on the interface. MCP `ack_context` and CLI `ack
1018
1044
  - Errors expose stable codes without database URLs, tokens, or provider response bodies.
1019
1045
  - Delivery work is at least once, not exactly once. Consumers must make external side effects idempotent.
1020
1046
 
1021
- ## Legacy Supabase compatibility
1022
-
1023
- Existing deployments can continue using:
1024
-
1025
- ```text
1026
- AGENT_BRIDGE_PROVIDER=legacy-supabase
1027
- AGENT_BRIDGE_URL=https://your-project.supabase.co
1028
- AGENT_BRIDGE_KEY=<publishable key>
1029
- ```
1047
+ ## Upgrading historical Supabase deployments
1030
1048
 
1031
- Legacy mode keeps the v1 `shared_context` and `ack_context` RPC behavior. It adds bounded network calls, HTTPS enforcement, UUID mapping across CLI processes, newest-first reads, and the complete compatibility envelope. It cannot provide secure principal binding, delivery leases, presence, or an offline outbox. Use gateway mode for those features.
1049
+ Agent Bridge 0.6.0 removed the direct `legacy-supabase` runtime provider. Old provider
1050
+ names and key-only configurations now fail with a migration message instead of opening
1051
+ PostgREST. Configure local or gateway mode before upgrading a running client.
1032
1052
 
1033
1053
  When gateway migrations run in the same PostgreSQL database as `public.shared_context`, migration 006 imports legacy rows and receipts into the private v2 schema. It preserves valid envelope UUIDs, keeps the existing synthetic UUID mapping for ordinary numeric IDs, assigns deterministic UUIDs to larger IDs, maps projects to workspaces, rejects ID collisions, and verifies the imported count. It does not create executable deliveries for historical targeted rows because an upgrade must not replay old work.
1034
1054
 
1035
1055
  Migration 008 adds the optional project label without changing migration 006. A schema owner can preview correction of migration 006 rows into the canonical `agent-bridge` workspace with `agent-bridge reconcile-legacy-projects`. The command defaults to a dry run. Pass `--apply` to make the change in one transaction. The canonical workspace must already exist. Reconciliation preserves message IDs, timestamps, receipts, and total row counts. It creates no deliveries and is safe to repeat. It refuses changed source data, invalid labels, project or idempotency conflicts, and imported messages that already have a delivery.
1036
1056
 
1037
- The original v1 schema remains in [`sql/setup.sql`](sql/setup.sql). Ordered gateway migrations live in [`sql/migrations/`](sql/migrations/).
1057
+ The original v1 schema remains in [`sql/setup.sql`](sql/setup.sql) as a migration
1058
+ fixture. Ordered gateway migrations live in [`sql/migrations/`](sql/migrations/).
1059
+ The retirement decision is recorded in
1060
+ [ADR-0005](docs/decisions/0005-retire-direct-supabase-runtime.md).
1038
1061
 
1039
1062
  ## Health and operations
1040
1063
 
@@ -1143,6 +1166,8 @@ durability behavior has not yet been proved on a dedicated Windows host.
1143
1166
  - [ADR-0001](docs/decisions/0001-protocol-layers-and-acknowledgment-semantics.md): protocol layers and acknowledgment semantics.
1144
1167
  - [ADR-0002](docs/decisions/0002-canonical-operation-contract-registry.md): canonical contracts, generated artifacts, discovery, and version negotiation.
1145
1168
  - [ADR-0003](docs/decisions/0003-host-adapters-and-consumer-instance-keys.md): host layers and consumer instance-key semantics.
1169
+ - [ADR-0004](docs/decisions/0004-client-lifecycle-and-endpoint-migration.md): managed client ownership and endpoint migration.
1170
+ - [ADR-0005](docs/decisions/0005-retire-direct-supabase-runtime.md): direct Supabase runtime retirement and historical migration support.
1146
1171
  - [docs/architecture-v2.md](docs/architecture-v2.md): protocol and storage decisions.
1147
1172
  - [SKILL.md](SKILL.md): runtime-neutral agent operating instructions.
1148
1173
  - [llms.txt](llms.txt): compact machine-readable project map.
package/ROADMAP.md CHANGED
@@ -1,7 +1,8 @@
1
1
  # Agent Bridge roadmap
2
2
 
3
- Agent Bridge is working toward one specific role: durable messaging and work delivery
4
- between agent runtimes that do not share a process, vendor, session, or machine.
3
+ Agent Bridge lets AI agents message each other and hand off work across tools,
4
+ sessions, and machines. This roadmap tracks the reliability, compatibility, and
5
+ operating work needed to make that simple promise hold under real failures.
5
6
 
6
7
  This roadmap separates released behavior from code that has not reached a public
7
8
  release. A merged implementation is not considered shipped until the package is
@@ -114,27 +115,83 @@ The published npm version is the authority for whether this package line has shi
114
115
  - Optional exact-message delivery claims in HTTP 2.1, MCP, and the CLI. HTTP 2.0 keeps
115
116
  the released claim-next contract.
116
117
 
117
- ### Post-release validation and adoption
118
-
119
- - Move the project's own normal traffic to the authenticated gateway while retaining a
120
- tested legacy rollback path.
121
- - Prove cross-machine claim, settlement, offline replay, and restart behavior against
122
- the published package and a deployed v2 gateway. The historical 0.3.0 live release
123
- check covered startup, private mailbox sends, caller-scoped history, receipts, and
124
- client restart through the legacy compatibility backend. It did not prove
125
- gateway-only behavior.
126
- - Run the manual Fly proof against an operator-owned app and retain its sender,
127
- receiver, machine-cycle, and verifier receipts. The repository harness is ready,
128
- but the external proof remains incomplete until an approved workflow run succeeds.
129
- - Replace remaining direct legacy table pollers with the v2 cursor protocol.
130
- - Confirm the README, npm metadata, GitHub metadata, release notes, and package contents
131
- match the released artifact.
118
+ ### 0.5.1 and 0.5.2 package contents
119
+
120
+ - Runtime PostgreSQL connections can load a base64-encoded CA bundle from the secret
121
+ environment without writing the certificate to the gateway image or filesystem.
122
+ - The gateway rejects URL parameters that could replace the explicit CA policy.
123
+ - Legacy rows whose ancestry column is SQL `NULL` map to an omitted optional field
124
+ instead of an invalid protocol value.
125
+ - `/healthz` reports process liveness without database work. `/readyz` remains the
126
+ database, migration, role, and protected-catalog readiness gate.
127
+
128
+ ### 0.6.0 package contents
129
+
130
+ - `send --queue-only` records an immutable gateway publication in the local outbox
131
+ without making a network request.
132
+ - The production proof uses the configured edge scope, an explicit stable message ID,
133
+ and a real Fly stop and start cycle. Separate sender and receiver runners prove
134
+ offline replay, idempotency, exact claim and settlement, and recovery from a fresh
135
+ receiver edge.
136
+ - PostgreSQL native DR supports managed-provider role graphs without importing
137
+ unrelated provider roles or default privileges from schemas outside Agent Bridge.
138
+ - The direct Supabase runtime provider is removed. Historical schema, import, and
139
+ reconciliation paths remain for upgrades. Runtime contracts now expose only local
140
+ and gateway providers.
141
+ - Public package language leads with cross-tool, cross-session, and cross-machine
142
+ messaging and work handoff.
143
+
144
+ ### 0.6.1 package contents
145
+
146
+ - Authenticated gateway capabilities identify the running package version and Git
147
+ revision.
148
+ - The Fly deployment procedure records the source revision in the image. A release
149
+ check compares the deployed version and revision with the intended release before
150
+ the production proof starts.
151
+ - Public descriptions explain what an agent can do before introducing protocol and
152
+ storage terminology.
153
+
154
+ ### Production validation and adoption
155
+
156
+ Completed through the published and deployed 0.6.0 package:
157
+
158
+ - Migrated the project authority from the legacy Supabase schema to the canonical
159
+ PostgreSQL schema after a write freeze, exact-major backup, and restore drill. The
160
+ gateway uses a restricted runtime login. Legacy writes remain frozen, and the final
161
+ backup remains available for recovery.
162
+ - Deployed the maintained image to an operator-owned Fly app. Authenticated readiness,
163
+ capabilities, status, history, publication, exact claim, and settlement checks passed
164
+ against the live gateway.
165
+ - Moved the managed Codex, Claude Code, and Claude Desktop registrations to separate
166
+ principal-bound gateway backends. All three passed `doctor`, remote history, empty
167
+ outbox, and empty delivery-queue checks. Fresh MCP launches exposed 17 tools for each
168
+ supported adapter. A client process started before cutover keeps its old backend until
169
+ that host restarts.
170
+ - Verified the published npm version, provenance, immutable GitHub release, package
171
+ contents, and public repository metadata.
172
+ - Ran the approval-protected production workflow on the canonical gateway with
173
+ distinct sender and receiver runners, an offline sender outbox, a real Fly machine
174
+ cycle, and a fresh verifier edge. The retained receipts prove replay, exact
175
+ idempotency, claim, settlement, and recovery after restart.
176
+ - Took and verified a canonical native PostgreSQL backup after the proof. Removed the
177
+ obsolete public v1 table and receipt function from the live database without changing
178
+ the canonical PostgreSQL authority.
179
+ - Moved the shared config to the gateway and rechecked the Codex, Claude Code, and
180
+ Claude Desktop managed backends. All three passed active gateway diagnostics.
181
+
182
+ The production proof is repeatable release evidence, not a permanent certification.
183
+ Every gateway release must match its package version and source revision before the
184
+ workflow runs with disposable credentials.
132
185
 
133
186
  ## Near-term work
134
187
 
135
188
  ### Installation and operations
136
189
 
137
190
  - Publish a maintained client compatibility matrix.
191
+ - Run dedicated Windows-host acceptance for native ACLs, SQLite sidecars, operation
192
+ journals, archive publication, and directory durability boundaries.
193
+ - Fence independent PostgreSQL authorities so a restored clone cannot serve writes
194
+ while the original authority remains active.
138
195
 
139
196
  ### Storage lifecycle and observability
140
197
 
package/SECURITY.md CHANGED
@@ -120,12 +120,13 @@ stores a domain-separated SHA-256 commitment, never the raw challenge, and exclu
120
120
  live challenge rows from native DR data dumps. The challenge proves an active direct
121
121
  credential replacement on one authority. It does not authorize endpoint cutover.
122
122
 
123
- ### Legacy Supabase mode
123
+ ### Historical Supabase migrations
124
124
 
125
- The legacy adapter keeps existing v1 deployments working, but its publishable key can
126
- call the underlying PostgREST table and receipt RPC directly. Adapter checks therefore
127
- provide cooperative behavior, not the same workspace and principal isolation as the
128
- authenticated gateway. Do not use legacy mode as a hostile multi-tenant boundary.
125
+ Agent Bridge 0.6.0 removed the direct Supabase runtime adapter. The checked-in v1
126
+ schema and migration 006 remain so trusted operators can import historical deployments
127
+ into the private PostgreSQL schema. Back up the source first, run the migration with
128
+ schema-owner authority, and move clients to local or gateway mode. The permissive v1
129
+ row policies are not a supported runtime security boundary.
129
130
 
130
131
  ### Archives and disaster recovery
131
132
 
package/SKILL.md CHANGED
@@ -1,10 +1,13 @@
1
1
  ---
2
2
  name: agent-bridge
3
- description: Share context and reliable work between agents across runtimes and machines.
3
+ description: Message other AI agents and hand off work across tools, sessions, and machines.
4
4
  ---
5
5
 
6
6
  # Agent Bridge
7
7
 
8
+ Agent Bridge lets AI agents message each other and hand off work across tools,
9
+ sessions, and machines. Messages wait through offline periods and restarts.
10
+
8
11
  Discover the active v2 operation contract with MCP `capabilities`, CLI `agent-bridge capabilities`, or authenticated `GET /v2/capabilities`. Released 2.0 clients continue to work after the gateway is upgraded. A new 2.1 client must receive complete, consistent negotiation headers that select and advertise 2.1 before it mutates remote state. If the probe is headerless, selects 2.0, or returns partial or contradictory headers, do not mutate. Upgrade the gateway first instead of downgrading the client.
9
12
 
10
13
  An authenticated PostgreSQL gateway status response can include `gatewayAuthorityId`
package/dist/archive.d.ts CHANGED
@@ -1,6 +1,6 @@
1
1
  import { J as JsonValue, i as MessagePriority, f as DeliveryPolicy } from './bridge-domain-CBX3IVqC.js';
2
- import { P as PgQueryable } from './postgres-bridge-store-C9KG9Z69.js';
3
- import './bridge-store-ByJ6CaJk.js';
2
+ import { P as PgQueryable } from './postgres-bridge-store-ChoOuFEY.js';
3
+ import './bridge-store-Bi_LCX8e.js';
4
4
 
5
5
  interface PortableArchiveMessage {
6
6
  id: string;
@@ -1,4 +1,4 @@
1
- import { a as BridgeStore, I as InsertMessageResult, d as MessageQuery, M as MessagePage, c as DeliveryQuery, b as DeliveryPage, D as DeliveryEventPage } from './bridge-store-ByJ6CaJk.js';
1
+ import { a as BridgeStore, I as InsertMessageResult, d as MessageQuery, M as MessagePage, c as DeliveryQuery, b as DeliveryPage, D as DeliveryEventPage } from './bridge-store-Bi_LCX8e.js';
2
2
  import { c as BridgePrincipal, M as MessageDraft, B as BridgeDelivery, A as AgentPresence } from './bridge-domain-CBX3IVqC.js';
3
3
 
4
4
  type PublicMessageQuery = MessageQuery & {
@@ -7,7 +7,9 @@ type PublicMessageQuery = MessageQuery & {
7
7
  declare class BridgeService {
8
8
  private readonly store;
9
9
  constructor(store: BridgeStore);
10
- publish(principalInput: BridgePrincipal, draftInput: MessageDraft): Promise<InsertMessageResult>;
10
+ publish(principalInput: BridgePrincipal, draftInput: MessageDraft, options?: {
11
+ queueOnly?: boolean;
12
+ }): Promise<InsertMessageResult>;
11
13
  history(principalInput: BridgePrincipal, query?: PublicMessageQuery): Promise<MessagePage>;
12
14
  acknowledge(principalInput: BridgePrincipal, messageIds: string[]): Promise<number>;
13
15
  claim(principalInput: BridgePrincipal, options?: {
@@ -22,7 +22,7 @@ interface MessagePage {
22
22
  cursor?: string;
23
23
  }
24
24
  interface BridgeDiagnostics {
25
- schemaVersion: "local-v2" | "postgres-v2" | "legacy-v1";
25
+ schemaVersion: "local-v2" | "postgres-v2";
26
26
  deliverySupported: boolean;
27
27
  pending: number | null;
28
28
  claimed: number | null;
@@ -72,6 +72,10 @@ interface BridgeStore {
72
72
  insertMessage(message: Omit<BridgeMessage, "sequence" | "createdAt">, options?: {
73
73
  signal?: AbortSignal;
74
74
  }): Promise<InsertMessageResult>;
75
+ enqueueMessage?(message: Omit<BridgeMessage, "sequence" | "createdAt">): Promise<InsertMessageResult & {
76
+ disposition: "queued";
77
+ authoritative: false;
78
+ }>;
75
79
  listMessages(principal: BridgePrincipal, query?: MessageQuery, options?: {
76
80
  signal?: AbortSignal;
77
81
  }): Promise<MessagePage>;
package/dist/bridge.d.ts CHANGED
@@ -1,43 +1,15 @@
1
- import { b as BridgeMessage, c as BridgePrincipal, B as BridgeDelivery, R as RetryPolicy, A as AgentPresence } from './bridge-domain-CBX3IVqC.js';
1
+ import { c as BridgePrincipal, b as BridgeMessage, B as BridgeDelivery, R as RetryPolicy, A as AgentPresence } from './bridge-domain-CBX3IVqC.js';
2
2
  export { a as BridgeDeliveryEvent, d as BridgePrincipalMismatchError, e as BridgeValidationError, D as DeliveryAction, f as DeliveryPolicy, g as DeliveryState, h as DeliveryStateConflictError, J as JsonValue, L as LeasedDeliveryPolicy, M as MessageDraft, i as MessagePriority, j as cursorScope, k as decodeCursor, l as decodeScopedCursor, m as encodeCursor, n as encodeScopedCursor, s as scopedCursorScope, u as uuidv7, v as validateDeliveryCursorPosition, o as validateDeliveryPolicy, p as validateEventCursorPosition, q as validateLeasedDeliveryPolicy, r as validateMessageDraft, t as validatePrincipal, w as validateProject, x as validateUuid } from './bridge-domain-CBX3IVqC.js';
3
- import { a as BridgeStore, I as InsertMessageResult, d as MessageQuery, M as MessagePage, C as ClaimOptions, B as BridgeDiagnostics, c as DeliveryQuery } from './bridge-store-ByJ6CaJk.js';
4
- export { D as DeliveryEventPage, b as DeliveryPage } from './bridge-store-ByJ6CaJk.js';
5
- export { B as BridgeService, P as PublicMessageQuery } from './bridge-service-CNBKdYXh.js';
6
- import { P as PgQueryable } from './postgres-bridge-store-C9KG9Z69.js';
7
- export { a as PgTransactionClient, b as PostgresBridgeStore } from './postgres-bridge-store-C9KG9Z69.js';
8
- export { A as AuthenticatedCredential, C as CredentialResolver, G as GatewayOptions, P as PostgresCredentialResolver, b as bearerToken, c as createGateway, h as hashCredential, s as safeTokenHashEqual } from './gateway-CW-61lvs.js';
9
- export { E as EdgeConflictError, a as EdgeDrainLease, b as EdgeEnqueueResult, c as EdgeMigrationDrainingError, d as EdgeMigrationGate, e as EdgeMigrationGateState, f as EdgeMigrationLeaseError, g as EdgeMigrationRetiredError, h as EdgeOutboxRecord, i as EdgeReadOnlyInspection, j as EdgeScope, k as EdgeStats, P as PendingMessage, S as SQLiteEdgeStore, l as edgeMessageFingerprint, m as edgeScopeKey, n as inspectEdgeScopeReadOnly, s as stableIdempotency } from './sqlite-edge-store-CdMIOrho.js';
3
+ import { a as BridgeStore, I as InsertMessageResult, d as MessageQuery, M as MessagePage, B as BridgeDiagnostics, C as ClaimOptions, c as DeliveryQuery } from './bridge-store-Bi_LCX8e.js';
4
+ export { D as DeliveryEventPage, b as DeliveryPage } from './bridge-store-Bi_LCX8e.js';
5
+ export { B as BridgeService, P as PublicMessageQuery } from './bridge-service-DjSYfjKt.js';
6
+ import { P as PgQueryable } from './postgres-bridge-store-ChoOuFEY.js';
7
+ export { a as PgTransactionClient, b as PostgresBridgeStore } from './postgres-bridge-store-ChoOuFEY.js';
8
+ export { A as AuthenticatedCredential, C as CredentialResolver, G as GatewayOptions, P as PostgresCredentialResolver, b as bearerToken, c as createGateway, h as hashCredential, s as safeTokenHashEqual } from './gateway-DWZ3pX48.js';
9
+ export { E as EdgeConflictError, a as EdgeDrainLease, b as EdgeEnqueueResult, c as EdgeMigrationDrainingError, d as EdgeMigrationGate, e as EdgeMigrationGateState, f as EdgeMigrationLeaseError, g as EdgeMigrationRetiredError, h as EdgeOutboxRecord, i as EdgeReadOnlyInspection, j as EdgeScope, k as EdgeStats, P as PendingMessage, S as SQLiteEdgeStore, l as edgeMessageFingerprint, m as edgeScopeKey, n as inspectEdgeScopeReadOnly, s as stableIdempotency } from './sqlite-edge-store-BAFUeysk.js';
10
10
  export { CachedMessagePage, SQLiteBridgeStore, SyncDiagnostics, SyncInsertResult, SyncReport, SyncingBridgeStore, SyncingBridgeStoreOptions, isRetryableSyncError } from './sqlite.js';
11
11
  import 'node:http';
12
12
 
13
- declare class LegacySupabaseError extends Error {
14
- readonly status: number;
15
- readonly code: string;
16
- constructor(status: number, code: string);
17
- }
18
- declare class LegacySupabaseRestStore implements BridgeStore {
19
- private readonly url;
20
- private readonly key;
21
- private readonly fetchImpl;
22
- private readonly timeoutMs;
23
- private readonly legacyIds;
24
- private initialized;
25
- constructor(url: string, key: string, fetchImpl?: typeof fetch, timeoutMs?: number);
26
- initialize(options?: {
27
- mode?: "active" | "passive";
28
- }): Promise<void>;
29
- private request;
30
- private visibleReceiptIds;
31
- insertMessage(input: Omit<BridgeMessage, "sequence" | "createdAt">): Promise<InsertMessageResult>;
32
- listMessages(principal: BridgePrincipal, query?: MessageQuery): Promise<MessagePage>;
33
- recordReceipt(principal: BridgePrincipal, ids: string[]): Promise<number>;
34
- recordLegacyReceipt(ids: string[], principal: string): Promise<number>;
35
- claimDelivery(_principal: BridgePrincipal, _options: ClaimOptions): Promise<BridgeDelivery | null>;
36
- renewDelivery(_principal: BridgePrincipal, _deliveryId: string, _leaseToken: string, _leaseMs: number): Promise<BridgeDelivery | null>;
37
- settleDelivery(_principal: BridgePrincipal, _deliveryId: string, _leaseToken: string, _state: "acked" | "retrying" | "dead", _error?: string, _retryPolicy?: RetryPolicy): Promise<BridgeDelivery | null>;
38
- diagnostics(_principal: BridgePrincipal): Promise<BridgeDiagnostics>;
39
- }
40
-
41
13
  interface HttpBridgeStoreOptions {
42
14
  baseUrl: string;
43
15
  token: string;
@@ -175,4 +147,4 @@ declare function runtimeSchemaReady(db: PgQueryable, options?: {
175
147
  }): Promise<boolean>;
176
148
  declare function runMigrations(db: PgQueryable, directory: string): Promise<AppliedMigration[]>;
177
149
 
178
- export { AgentPresence, type AppliedMigration, BridgeDelivery, BridgeDiagnostics, BridgeHttpError, BridgeMessage, BridgePrincipal, BridgeStore, ClaimOptions, DeliveryQuery, HttpBridgeStore, type HttpBridgeStoreOptions, InsertMessageResult, LegacySupabaseError, LegacySupabaseRestStore, MessagePage, MessageQuery, type MigrationPlanEntry, NATIVE_DR_ADVISORY_LOCK_KEY, PgQueryable, REQUIRED_MIGRATIONS, RetryPolicy, loadMigrationPlan, migrationRecordMatches, migrationsReady, rowIsolationReady, runMigrations, runtimeSchemaReady };
150
+ export { AgentPresence, type AppliedMigration, BridgeDelivery, BridgeDiagnostics, BridgeHttpError, BridgeMessage, BridgePrincipal, BridgeStore, ClaimOptions, DeliveryQuery, HttpBridgeStore, type HttpBridgeStoreOptions, InsertMessageResult, MessagePage, MessageQuery, type MigrationPlanEntry, NATIVE_DR_ADVISORY_LOCK_KEY, PgQueryable, REQUIRED_MIGRATIONS, RetryPolicy, loadMigrationPlan, migrationRecordMatches, migrationsReady, rowIsolationReady, runMigrations, runtimeSchemaReady };
package/dist/bridge.js CHANGED
@@ -1,10 +1,8 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  BridgeHttpError,
4
- HttpBridgeStore,
5
- LegacySupabaseError,
6
- LegacySupabaseRestStore
7
- } from "./chunk-Z6JP6MYD.js";
4
+ HttpBridgeStore
5
+ } from "./chunk-6ZOLE3E3.js";
8
6
  import {
9
7
  EdgeConflictError,
10
8
  EdgeMigrationDrainingError,
@@ -17,7 +15,7 @@ import {
17
15
  inspectEdgeScopeReadOnly,
18
16
  isRetryableSyncError,
19
17
  stableIdempotency
20
- } from "./chunk-SN7PIVDF.js";
18
+ } from "./chunk-ZUZ7TCIH.js";
21
19
  import {
22
20
  SQLiteBridgeStore
23
21
  } from "./chunk-IVG4XWWS.js";
@@ -42,11 +40,11 @@ import {
42
40
  createGateway,
43
41
  hashCredential,
44
42
  safeTokenHashEqual
45
- } from "./chunk-JUTJRAMA.js";
43
+ } from "./chunk-LF37B6KL.js";
46
44
  import {
47
45
  BridgeService
48
- } from "./chunk-AWE3DFZV.js";
49
- import "./chunk-E4OWHGUE.js";
46
+ } from "./chunk-4V2PFJEF.js";
47
+ import "./chunk-63JKCBC6.js";
50
48
  import {
51
49
  BridgePrincipalMismatchError,
52
50
  BridgeValidationError,
@@ -78,8 +76,6 @@ export {
78
76
  EdgeMigrationLeaseError,
79
77
  EdgeMigrationRetiredError,
80
78
  HttpBridgeStore,
81
- LegacySupabaseError,
82
- LegacySupabaseRestStore,
83
79
  NATIVE_DR_ADVISORY_LOCK_KEY,
84
80
  PostgresBridgeStore,
85
81
  PostgresCredentialResolver,