Context
Design pass on #4902 (see its comment history) found the relay/broker pipeline (orb_relay_pending, src/orb/relay.ts) — not the fleet-analytics ingest pipeline #4902's title names — is the correct infrastructure to extend: it has real per-installation auth (orb_enrollments.secret_hash) and self-host containers already poll it, unlike the fleet-analytics ingest pipe (shared bearer token, self-reported unverified instance_id).
Scope decision from that same pass: v1 config-push is for Orb's own operational state (enrollment lifecycle, opt-in capability announcements, deprecation notices) — explicitly NOT for auto-applying anything that would override an operator's own .loopover.yml/DB settings.
Requirements
Boundaries
Enqueue side only — does not include the self-host consumption/dispatch side (separate issue) or what a received push actually does (separate, later issue once this and the consumption side exist).
maintainer-only — new privileged write surface that can push messages into a self-hosted operator's instance; the trust-boundary scoping above needs to hold exactly, not be reinterpreted mid-implementation.
Context
Design pass on #4902 (see its comment history) found the relay/broker pipeline (
orb_relay_pending,src/orb/relay.ts) — not the fleet-analytics ingest pipeline #4902's title names — is the correct infrastructure to extend: it has real per-installation auth (orb_enrollments.secret_hash) and self-host containers already poll it, unlike the fleet-analytics ingest pipe (shared bearer token, self-reported unverifiedinstance_id).Scope decision from that same pass: v1 config-push is for Orb's own operational state (enrollment lifecycle, opt-in capability announcements, deprecation notices) — explicitly NOT for auto-applying anything that would override an operator's own
.loopover.yml/DB settings.Requirements
kind TEXT NOT NULL DEFAULT 'github_webhook'toorb_relay_pending(doesn't exist today — only free-textevent_name).enqueueConfigPush-style function + a new internal write endpoint, gated the same way the kill-switch endpoint is (requireAppRole(..., ["operator"])), inserting oneorb_relay_pendingrow per targetedinstallation_idwithkind = 'config_push'and a typedraw_body(e.g.{ pushId, message, capability?, deprecatesAt? }).installation_ids, not a percentage/canary selector — no rollout-percentage primitive exists anywhere in this codebase to build on; don't invent one speculatively.orb_enrollments.installation_idhas no uniqueness constraint (seerelay.ts's existing#1783tie-break comment); building real per-container addressing now is scope creep ahead of demonstrated need.Boundaries
Enqueue side only — does not include the self-host consumption/dispatch side (separate issue) or what a received push actually does (separate, later issue once this and the consumption side exist).
maintainer-only — new privileged write surface that can push messages into a self-hosted operator's instance; the trust-boundary scoping above needs to hold exactly, not be reinterpreted mid-implementation.