Vetrix Docs

"What's deploying" feed

Vetrix exposes an instance-wide deployment-transition feed that powers a root-layout banner showing which deployments are in flight across every repo the viewer can see. The backend primitives — event shape, per-viewer ACL filter, per-socket rate limiter, banner-row renderer, auto-hide trigger — are available today. The WebSocket hub, React banner, Prometheus exporter, and Playwright coverage are tracked as focused follow-ups.

Event shape

type FeedEvent struct {
    DeploymentID  uuid.UUID
    RepoID        uuid.UUID
    RepoSlug      string
    EnvironmentID uuid.UUID
    Environment   string
    State         string     // queued | pending | in_progress | success | failure | error | inactive
    Ref           string
    SHA           string
    ActorID       uuid.UUID
    At            time.Time
}

The WebSocket layer at /ws/deployments (deferred) JSON-encodes this verbatim. Field names match the deployments row payload so receivers can reuse existing decoders.

Per-socket ACL filter

type ViewerAccess struct {
    UserID        uuid.UUID
    Collaborator  map[uuid.UUID]bool
    PublicRepos   map[uuid.UUID]bool
    InstanceAdmin bool
}

CanSee(viewer, evt) bool
  • Instance admin — always true.
  • Viewer is a collaborator on evt.RepoID — true.
  • Repo is in the public-visibility set — true.
  • Otherwise — false. Private-repo events never reach non-collaborator sockets; this is an invariant of the filter.

Per-socket rate limiter

c := NewFeedCoalescer(20, time.Second)  // 20 events / 1 s default
c.Offer(evt, now) bool

Non-terminal events past the cap are dropped; terminal events always pass. IsTerminal(state) lists the four terminal states — success, failure, error, inactive — so the client always sees the final status of every deploy even under throttling.

Banner renderer

  • BuildBannerRows(active, cap) returns the top cap entries sorted by StartedAt descending, plus a +N more count for the overflow.
  • ShouldAutoHide(lastActiveAt, now, 10*time.Second) returns true once the 10-second trailing window has elapsed since the last active deployment reached a terminal state.

Prometheus / OTLP naming (deferred)

Planned naming for the metrics layer:

  • Counter: vetrix_deployment_state_total{repo, env, state} — emit once per state transition (idempotency lives in the emitter).
  • Histogram: vetrix_deployment_duration_seconds — recorded on terminal-state transition with labels repo, env, state.
  • OTLP span: vetrix.deployment with repo, env, state, ref, sha attributes.

Deferred follow-ups

  • WebSocket hub + handler at /ws/deployments — JWT gate, per-socket subscription, engine event-bus subscription.
  • DeployingNowBanner.tsx React component + root-layout mount.
  • Keyboard shortcut g d registered through the existing shortcut registry.
  • Prometheus + OTLP exporter wiring.
  • Playwright two-browser sync end-to-end coverage.

The event shape + ACL filter + coalescer + banner-row + auto-hide helpers shipping today are the stable contract the deferred layers will consume.