Inspiration

An API upgrade can pass every test and still lose your data. The client compiles, the tests stay green and every request gets HTTP 200. Then the backup quietly saves less than it should.

In the Rigveda, the Ṛbhus are three craftsmen who renew old things instead of throwing them away. Ribhu does the same for API integrations. It carries an existing consumer safely through an upstream upgrade, so the code keeps its life after the API changes.

What it does

Ribhu has three parts, and each one has a single job.

  • ribhu, a Rust CLI, reports facts. ribhu scan compares two versions of an OpenAPI spec and finds the consumer's real call sites. ribhu gate fails CI when a breaking change has a confirmed caller, or when it finds a call it cannot place.
  • GitLab Duo flows act. A lead plans, an engineer migrates and repairs, an independent assessor judges the evidence, and a monitor runs incidents. A security triage flow reviews scanner findings.
  • CI pipelines prove it. They run real Memos servers, a staging check, a production canary, a security gate and a verified release.

A person approves the plan, accepts any security risk and merges. A claim is never evidence. Every verdict cites a pipeline, a job or a report.

The demo: a real open-source upgrade

The consumer is a TypeScript backup service for Memos, an open-source notes app. Memos 0.22.0 removed the endpoint that listed every memo. Its replacement returns one page at a time and leaves comments out. Nobody planted a bug. Every failure comes from the real API change.

On 27 October 2026 we ran the whole story live on production:

  1. We upgraded production Memos to 0.22.0. The next backup failed with HTTP 404, and the monitor flow opened incident #52.
  2. The lead flow ran ribhu scan, named the one broken call and posted a plan on #53.
  3. The engineer flow refused to start until the plan had a real approval. A loose "Approved" comment was not enough.
  4. It opened !84. Staging passed with 37 of 37 memos, but the production canary found only 48 of 55. Seven comments were missing.
  5. The assessor ruled the candidate INSUFFICIENT. Repair 1 fetched the comments, but Ribhu's own gate blocked it as an unplaced call. Repair 2 fixed that, and the canary found 55 of 55.
  6. SAST flagged a server-supplied page token reaching a request. Repair 3 validated it, and the maintainer signed off the remaining risk. GitLab Duo's code review then caught a dot-segment path trick, which was fixed with a test.
  7. The maintainer merged. The promote job shipped the exact image that passed, by digest, and checked a real backup. The monitor flow closed #52 only after a fresh run found 55 of 55.

Ribhu ❤️ GitLab

Ribhu is useful beyond the demo.

  • For GitLab integration developers. Point Ribhu at your client code and two GitLab API versions. CI tells you which calls an upgrade breaks, by file and line. On 18.11 to 19.0, the gate exits 2 and names the calls to review.
  • For self-managed administrators. Scan two GitLab versions before you upgrade. GitLab 17.1 moved 334 request bodies in a single minor release, and Ribhu reports each one.

How we built it

  • The tool is a Rust library and CLI with a GitLab CI/CD component, templates/ribhu-gate.yml.
  • The agents are six GitLab Duo flows. Tag pipelines publish them to the AI Catalog, and you start each one by mentioning its service account.
  • Production runs on Google Cloud: a Memos VM on Compute Engine, the backup as a Cloud Run job and a public status service on Cloud Run.
  • No stored credentials. Deployments use GitLab ID tokens through Workload Identity Federation. No cloud key lives in the repository, a flow or a CI/CD variable.
  • Security comes from GitLab SAST, dependency scanning, container scanning, secret detection and DAST. Our own security gate blocks any new finding until a maintainer approves it by name.
  • The docs site runs on GitLab Pages, with a judge walk-through that links every step to its evidence.

Challenges

  • Flows have no Docker and can reach only gitlab.com. So every behavioural check runs in CI, and the flows read its reports.
  • Approval has to bind to the plan. The engineer counts only a reaction or reply on the plan note. Today it correctly refused a top-level comment.
  • Strict judges are uncomfortable. The assessor accepts only exact criterion wordings, so it would not pass a clean candidate. We kept it strict and tracked the gap in #55.
  • Scanners cannot see every fix. SAST does not model a custom validator, so a person still has to judge the evidence.
  • Baselines drift. New dependency advisories appeared overnight and blocked every merge request until main was scanned again.

What we learned

  • Green tests and HTTP 200 prove very little. Count the data.
  • A canary on production data catches what staging cannot. Our staging notebook had no comments, so only production showed the loss.
  • Agents are most useful when they can fail loudly. A refusal or an INSUFFICIENT verdict with evidence beats a confident wrong answer.
  • Keep the person in the loop for decisions, not for every step.

What's next

  • Teach the assessor to accept a criterion that names a passing job (#55).
  • Bound the comments requests and test a 4xx on one (#54).
  • Publish ribhu so any GitLab project can add the gate in one line.

Built With

  • artifact-registry
  • cloud-run
  • compute-engine
  • ffmpeg
  • gitlab
  • gitlab-ai-catalog
  • gitlab-ci
  • gitlab-duo
  • gitlab-pages
  • google-cloud
  • memos
  • node.js
  • openapi
  • playwright
  • rust
  • secret-manager
  • typescript
  • workload-identity-federation
Share this project:

Updates

Submission history