Context
#1970 (opt-in federated fleet intelligence) requires a transport path for moving anonymized signal bundles between self-hosted instances: an operator either (a) exports/imports a signed bundle file manually/via CI, or (b) points their instance at a collector they run or trust, per #1970's own Requirements ("Operators choose to either... export/import a signed, anonymized signature bundle, or (b) point at a collector they run/trust"). This issue is the (b) transport client only — the bundle format (sibling issue, export side) and the trust-gating rule applied on import (#6477 design, consumed by the import-side sibling issue) are both separate, non-blocking pieces of work.
Requirements
- Opt-in only, config-as-code via
.loopover.yml (a collector URL/endpoint field, inherit | off | enabled shape matching this repo's existing per-repo toggle convention — see src/signals/focus-manifest.ts's FocusManifestReviewConfig pattern).
- The client only ever talks to an operator-configured endpoint — never a hardcoded or auto-discovered default collector. No central/managed service is assumed anywhere in this codebase's self-host posture.
- Supports both directions the config can express: push (submit this instance's exported bundle to the configured collector) and pull (fetch peer bundles from the configured collector) — reuse the export bundle's shape produced by the sibling export issue; do not invent a second bundle format.
- Fail-safe and rate-limited: a collector that's unreachable, slow, or returns garbage must never block or slow down the review/gate path — this is a background, best-effort sync, not something the gate waits on.
- Never sends code, diffs, GitHub logins, or repo names — only the anonymized bundle produced by the export path.
Deliverables
Test Coverage Requirements
99%+ Codecov patch coverage on the diff (src/**) — including the off/on branches and both the timeout and malformed-response error paths.
Expected Outcome
An operator can configure a collector endpoint and have their instance push/pull anonymized bundles against it in the background, with zero effect on gate behavior if the collector is unavailable.
Links & Resources
Context
#1970 (opt-in federated fleet intelligence) requires a transport path for moving anonymized signal bundles between self-hosted instances: an operator either (a) exports/imports a signed bundle file manually/via CI, or (b) points their instance at a collector they run or trust, per #1970's own Requirements ("Operators choose to either... export/import a signed, anonymized signature bundle, or (b) point at a collector they run/trust"). This issue is the (b) transport client only — the bundle format (sibling issue, export side) and the trust-gating rule applied on import (#6477 design, consumed by the import-side sibling issue) are both separate, non-blocking pieces of work.
Requirements
.loopover.yml(a collector URL/endpoint field,inherit | off | enabledshape matching this repo's existing per-repo toggle convention — seesrc/signals/focus-manifest.ts'sFocusManifestReviewConfigpattern).Deliverables
.loopover.ymlopt-in toggle..loopover.yml.example/config/examples/loopover.full.ymlupdated with the collector-endpoint field.Test Coverage Requirements
99%+ Codecov patch coverage on the diff (
src/**) — including the off/on branches and both the timeout and malformed-response error paths.Expected Outcome
An operator can configure a collector endpoint and have their instance push/pull anonymized bundles against it in the background, with zero effect on gate behavior if the collector is unavailable.
Links & Resources
src/signals/focus-manifest.ts(existing config-as-code wiring pattern to follow)