Scaffolding: Federation sync app creation#298
Conversation
|
I'll add more comments after those are addressed to reduce the noise |
| body = payload.model_dump(mode="json") | ||
| path = payload.asset_type.webhook_path | ||
| for peer in config.peers: | ||
| url = peer_webhook_url(peer, path) |
There was a problem hiding this comment.
Outbound sync ignores peer registry
Medium Severity
push_asset_updated_to_peers always uses static config.peers URLs from federation.toml, while site-hello updates PeerRegistry with each peer’s declared sync_service_url. Outbound webhooks never read the registry, so post-hello URL data is unused.
Additional Locations (1)
Reviewed by Cursor Bugbot for commit d0608d2. Configure here.
| asset_type.value, | ||
| uuid, | ||
| ) | ||
| return |
There was a problem hiding this comment.
Redis race drops peer sync
Medium Severity
For non-delete Redis events, handle_redis_asset_event loads the asset from local fed-* OpenSearch and returns without notifying peers when the document is missing. If the gateway publishes Redis before the federated index write is visible, peer sites never receive that update and the event is not retried.
Reviewed by Cursor Bugbot for commit b0bc3f5. Configure here.
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes using high effort and found 4 potential issues.
There are 9 total unresolved issues (including 5 from previous reviews).
❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.
Reviewed by Cursor Bugbot for commit 155b128. Configure here.
| retries: 3 | ||
| networks: | ||
| - sds-network-local | ||
| - sds-network-local-opensearch |
There was a problem hiding this comment.
Wrong OpenSearch Docker network
High Severity
The sds-federation-local-sync service cannot resolve OPENSEARCH_HOST (sds-gateway-local-opensearch) because it's attached to sds-network-local-opensearch while the gateway's OpenSearch service is on sds-gateway-*-opensearch-net. This network isolation prevents communication, causing indexing, Redis fan-out, and OpenSearch health checks to fail.
Reviewed by Cursor Bugbot for commit 155b128. Configure here.
| refresh="wait_for", | ||
| ) | ||
|
|
||
| self._mark_applied(site_name, asset.uuid, event_at) |
There was a problem hiding this comment.
Stale dedupe lost on restart
Medium Severity
The stale-event check uses an in-memory map (_last_event) that is lost on process restart. This allows older webhooks to overwrite newer OpenSearch documents, even though federation_event_at is persisted in the document.
Reviewed by Cursor Bugbot for commit 155b128. Configure here.
| indexer, | ||
| event_at=event_at, | ||
| ) | ||
| return total |
There was a problem hiding this comment.
Unused bootstrap helper functions
Low Severity
bootstrap_local_site and bootstrap_all_peers are never called; run_bootstrap only registers site-hellos and discards the indexer. These helpers add dead paths that diverge from the live startup behavior.
Reviewed by Cursor Bugbot for commit 155b128. Configure here.
| http = build_gateway_http_client() | ||
| os_host = os.environ.get("OPENSEARCH_HOST", "opensearch") | ||
| os_port = os.environ.get("OPENSEARCH_PORT", "9200") | ||
| os_client = OpenSearch(hosts=[{"host": os_host, "port": int(os_port)}]) |
There was a problem hiding this comment.
OpenSearch client lacks auth
High Severity
The federation OpenSearch client is created with only host and port. Gateway OpenSearch expects basic auth (and TLS in production), so pings, document reads, and webhook indexing will fail even if the container can reach the host.
Reviewed by Cursor Bugbot for commit 155b128. Configure here.


In this PR:
federation/(v1) application with:services:bootstrap.py: for initialization of federated data from home site and peers (including when new peer is added)fed_index.py: for handling (external peer) asset indexing on webhook eventslocal_events.py: for handling redis dispatches to fetch local datapeer registry.py: for registering new peers and holding site information from site hellospeer_sync.py: for packaging and sending asset data to peer sites (through their webhook routes)routes:health.py: (stub for now) for pinging site health (is connection established?)webhooks.py: for receiving payloads FROM peers to index into LOCAL federated asset indices as well as asite-hellohook to confirm federation between peersschemasandmodels: for type checking and providing data structures to federation configs, events, and documents (how asset docs are represented byFederatedDatasetDoc,FederatedCaptureDocmay warrant further consideration re: anticipating schema flexibility)mainapp that subscribes to redis events for picking up signals from gateway (handled in PR Scaffolding: Federation gateway setup #299)Note
Medium Risk
New cross-site data path and webhook surface affect federated search consistency; webhook auth is config allowlists only (no signing/mTLS on payloads yet), and startup bootstrap errors are logged but do not block the app.
Overview
Introduces a new
federation/FastAPI sync service that keeps federated dataset/capture metadata in shared OpenSearchfed-*indices and propagates changes between configured peer sites.On startup it optionally runs bootstrap that currently skips gateway export pulls and only sends
site-helloto peers; a background Redis subscriber onfederation:events:{site}loads the local asset from OpenSearch (after gateway indexing) and POSTs asset-updated webhooks to peers. Inbound/sync/api/v1/webhook/*routes index peer payloads with allowlistedsite_namechecks and register peers viasite-hello./healthreports Redis, OpenSearch, config, and subscriber status.Repo wiring adds Docker/compose, justfile, example
federation.toml, dev mTLS cert scripts, and pre-commit (ruff/pyrefly/deptry) scoped tofederation/, plus a broad pytest suite (mesh, webhooks, Redis pipeline, bootstrap helpers).Reviewed by Cursor Bugbot for commit 155b128. Bugbot is set up for automated code reviews on this repo. Configure here.