Epic: event-driven reconcile trigger (ADR 0037) #54

Stängd
öppnade 2026-07-28 19:30:59 +00:00 av supernaut · 2 kommentarer
Ägare

Summary

Give the entitlement reconciler (ADR 0035) a prompt, event-driven trigger so an identity change
(sign-up, trial opt-in, Renovate toggle, new repo, future payment) is applied within seconds instead
of waiting up to 5 minutes for the next timer tick — without a work queue, and without turning
the reconciler into a long-running daemon.

What we're building

  • Trigger core: a sentinel file + systemd .path unit fires the existing oneshot reconciler
    (zero reconciler code change). ExecStartPre deletes the sentinel (at-least-once-after-last-write);
    a 30 s min-interval floor coalesces bursts; the 5-min timer stays as the backstop.
  • Three ingress adapters → one sentinel: web writes it directly (co-located, no network);
    the Forgejo repository webhook and the future payment service go through a small,
    stateless, socket-activated auth shim (no admin creds; per-source bearer tokens; TLS via Caddy;
    internal-only + firewalled; pluggable auth for later mTLS).
  • Observability: a trigger_lag KPI + run-cause metrics, Loki kick logs per source, and a
    Loki-based event-path-silent alert.

Decision record

See ADR 0037 — Reconciler event-driven trigger (decisions/0037-reconciler-event-driven-work-queue.md).

Tasks (phased; the timer backstop stays throughout)

  • Phase 1 — trigger core + web adapter: bitborg-infra#235, bitborg-web#95
  • Phase 2 — auth shim + Forgejo repository webhook: bitborg-infra#236
  • Phase 3 — observability (trigger_lag, Loki alert, dashboard): bitborg-infra#237
  • Phase 4 — payment adapter wiring: deferred until the payment service ships (tracked internally)

Out of scope

  • The full work-queue controller (per-object reconcile, getPersonMemberOf, token bucket, per-key
    backoff, reconciler-as-daemon) — retained only as ADR 0037's documented scale-out path.
  • mTLS on the shim — deferred to the payment adapter (Forgejo webhook can't present a client cert).
## Summary Give the entitlement reconciler (ADR 0035) a **prompt, event-driven trigger** so an identity change (sign-up, trial opt-in, Renovate toggle, new repo, future payment) is applied within seconds instead of waiting up to 5 minutes for the next timer tick — **without** a work queue, and **without** turning the reconciler into a long-running daemon. ## What we're building - **Trigger core:** a sentinel file + systemd `.path` unit fires the **existing oneshot reconciler** (zero reconciler code change). `ExecStartPre` deletes the sentinel (at-least-once-after-last-write); a **30 s min-interval floor** coalesces bursts; the **5-min timer stays** as the backstop. - **Three ingress adapters → one sentinel:** web writes it **directly** (co-located, no network); the **Forgejo `repository` webhook** and the **future payment service** go through a small, stateless, socket-activated **auth shim** (no admin creds; per-source bearer tokens; TLS via Caddy; internal-only + firewalled; pluggable auth for later mTLS). - **Observability:** a `trigger_lag` KPI + run-cause metrics, Loki kick logs per source, and a Loki-based **event-path-silent** alert. ## Decision record See ADR 0037 — Reconciler event-driven trigger (`decisions/0037-reconciler-event-driven-work-queue.md`). ## Tasks (phased; the timer backstop stays throughout) - **Phase 1 — trigger core + web adapter:** bitborg-infra#235, bitborg-web#95 - **Phase 2 — auth shim + Forgejo `repository` webhook:** bitborg-infra#236 - **Phase 3 — observability (trigger_lag, Loki alert, dashboard):** bitborg-infra#237 - **Phase 4 — payment adapter wiring:** deferred until the payment service ships (tracked internally) ## Out of scope - The full work-queue controller (per-object reconcile, `getPersonMemberOf`, token bucket, per-key backoff, reconciler-as-daemon) — retained only as ADR 0037's documented scale-out path. - mTLS on the shim — deferred to the payment adapter (Forgejo webhook can't present a client cert).
supernaut lade till detta till projektet Bitborg Roadmap 2026-07-28 19:33:48 +00:00
Upphovsperson
Ägare

Phases 1–3 shipped and verified end-to-end in production (2026-07-29). Moved to Roadmap → Shipped.

  • Phase 1 — trigger core + web adapter (bitborg-infra#235, bitborg-web#95): live + verified — a sign-up/trial/Renovate change writes the sentinel and the reconciler applies it within seconds.
  • Phase 2 — auth shim + Forgejo repository webhook (bitborg-infra#236): live + verified — creating a repo delivers to the shim → kick → reconcile (measured trigger lag 0 s). Shim: the new bitborg-reconcile-trigger service. Needed three follow-up fixes found in prod verification (a delegated-task become, default-vs-system webhook type + a UI-created system webhook, and Forgejo's ALLOWED_HOST_LIST SSRF guard).
  • Phase 3 — observability (bitborg-infra#237): gitborg_reconcile_trigger_lag_seconds metric, a Loki ReconcileEventPathSilent alert (evaluating), and a dashboard row.

Phase 4 — payment adapter + external ingress remains, deferred until the payment service ships (tracked internally). The 5-minute reconciler timer backstops correctness throughout.

**Phases 1–3 shipped and verified end-to-end in production (2026-07-29).** Moved to Roadmap → Shipped. - **Phase 1 — trigger core + web adapter** (bitborg-infra#235, bitborg-web#95): live + verified — a sign-up/trial/Renovate change writes the sentinel and the reconciler applies it within seconds. - **Phase 2 — auth shim + Forgejo `repository` webhook** (bitborg-infra#236): live + verified — creating a repo delivers to the shim → kick → reconcile (measured trigger lag 0 s). Shim: the new `bitborg-reconcile-trigger` service. Needed three follow-up fixes found in prod verification (a delegated-task `become`, default-vs-system webhook type + a UI-created system webhook, and Forgejo's `ALLOWED_HOST_LIST` SSRF guard). - **Phase 3 — observability** (bitborg-infra#237): `gitborg_reconcile_trigger_lag_seconds` metric, a Loki `ReconcileEventPathSilent` alert (evaluating), and a dashboard row. **Phase 4 — payment adapter + external ingress** remains, deferred until the payment service ships (tracked internally). The 5-minute reconciler timer backstops correctness throughout.
Upphovsperson
Ägare

Closing — Phases 1–3 are shipped and verified in production.

Phase Where State
P1 — trigger core (sentinel + .path + 30 s floor) bitborg-infra#235, bitborg-web#95 Closed
P2 — auth shim + Forgejo repository webhook bitborg-infra#236 Closed
P3 — observability (trigger_lag, Loki alert, board) bitborg-infra#237 Closed

The 5-minute timer remains in place as the backstop throughout, as designed.

Phase 4 (payment adapter wiring) was scoped from the outset as deferred until the payment
service ships, and is tracked separately — it is not blocking this epic. The scale-out path (full
work-queue controller, per-object reconcile, mTLS on the shim) stays documented in ADR 0037 as a
future option rather than open work.

Closing — Phases 1–3 are shipped and verified in production. | Phase | Where | State | | ------------------------------------------------------ | --------------------------------- | ------ | | P1 — trigger core (sentinel + `.path` + 30 s floor) | bitborg-infra#235, bitborg-web#95 | Closed | | P2 — auth shim + Forgejo `repository` webhook | bitborg-infra#236 | Closed | | P3 — observability (`trigger_lag`, Loki alert, board) | bitborg-infra#237 | Closed | The 5-minute timer remains in place as the backstop throughout, as designed. **Phase 4 (payment adapter wiring)** was scoped from the outset as deferred until the payment service ships, and is tracked separately — it is not blocking this epic. The scale-out path (full work-queue controller, per-object reconcile, mTLS on the shim) stays documented in ADR 0037 as a future option rather than open work.
Logga in för att delta i denna konversation.
Ingen milstolpe
Inget projekt
Inga tilldelade
1 deltagare
Notiser
Förfallodatum
Förfallodatumet är ogiltigt eller utanför gränserna. Använd formatet "åååå-mm-dd".

Inget förfallodatum satt.

Beroenden

Inga beroenden satta

Referens
bitborg/bitborg-docs#54
Ingen beskrivning angiven.