ReliefOps: 7 agent flows for everything after the code
Tagline (Devpost "elevator pitch", max 200 chars): Push code. Seven GitLab Duo flows triage, fix, review, release and guard it in production. A human makes one call, and every incident makes the next review stricter.
Links
- Repo: https://gitlab.com/gitlab-ai-hackathon/transcend-october-2026/43214382/full-stack-fastapi-template-master
- Video: https://youtu.be/tA7sg3r720U
Track: Path B (existing MIT project: Full Stack FastAPI Template) · Autonomy: Supervised

Inspiration
In a disaster, a supply app is not "just CRUD". If ReliefOps says a depot has 20 boxes of water and it has none, a responder drives to an empty depot. Writing the code is the easy part. The danger is everything after it: a red pipeline nobody understands, a review that misses a race condition, a migration that only breaks on real data, a production bug noticed hours later.
We wanted agents that own that whole "life after code". They should be grounded in the app's real rules, prove what they claim, and keep humans in charge of the decisions that matter.
What it does
ReliefOps is an emergency-supply app: depots record supplies (food, water,
medicine, equipment) and responders reserve stock. Its core rule is that
stock never goes negative. One atomic
UPDATE ... WHERE quantity >= requested statement enforces this.
On top of the app we built 7 custom GitLab Duo Agent Platform flows. Each one is started by a GitLab trigger and covers one stage of the lifecycle:
| Stage | Flow | Trigger | What it does |
|---|---|---|---|
| Plan | Triage | issue created | Gives severity by aid impact, finds duplicates and the suspect MR, names the owner, writes a failing test that proves a bug, makes security issues confidential at once, asks at most 3 questions. |
| Code | Builder | issue assigned to the bot | Spec-first and test-first: acceptance criteria before code. Asks for approval only in risky areas, uses expand-only migrations, opens a draft MR. |
| Verify | Pipeline Doctor | pipeline failed | Sorts the failure into a category, ranks 2–3 theories and rejects the wrong ones, checks past incidents, writes the smallest fix plus a regression test. It never weakens a test. |
| Review | MR Guardian | MR created / ready / conflict | Uses a deterministic risk score from CI, resolves merge conflicts by intent, checks app rules, judges each scanner finding true or false. Verdict: GO / NEEDS_REVIEW / BLOCK. |
| Collaborate | Feedback Applier | mention in any comment | Takes commands: apply, apply option N, intentional: <reason>, explain, undo. Checks permissions, guards against prompt injection. The same feedback 3 times becomes a proposed rule. |
| Release | Release Manager | main pipeline passed | Reads the CI evidence and writes a release card: version, changelog, p95 latency, migrations, confidence, GO / GO_WITH_CARE / HOLD. No evidence, no GO. |
| Operate | Guardian | production deploy or hourly check failed | Measures impact and finds the root cause, which a challenger agent tries to disprove. Opens an incident issue and a revert MR, then a vaccine MR: a new risk rule, a regression test and a blameless post-mortem. |
A human takes three actions in the whole loop: marking an MR ready, merging it, and running the production deploy. Everything else is done by the agents and by CI.
How we built it
1. One agent pattern, used in every flow

Every flow has exactly 4 agents. The first three are read-only: one
investigates, one proposes a patch or a verdict, and an independent
critic tries to prove it wrong against AGENTS.md. Only the fourth
agent has write tools (commit, MR, issue, note). This is least privilege:
a confused reasoning agent cannot change anything.
The agents pass a JSON STATUS along the chain. Each agent acts only on the status it expects; any other status means "do nothing". This avoids fragile conditional routing and runaway chains.

2. Facts from CI, judgement from AI
Agents don't guess things a script can measure:
backend/scripts/risk_facts.pygives every MR a deterministic risk score (13 unit tests). It looks at what changed, how big the change is, coverage of the changed lines, a 2-hop import blast radius, the bug-fix history of the files, and the author's familiarity with them. The score is the same on every run.- Policy as code:
AGENTS.md,risk-policy.yml,triage-policy.ymlandrelease-policy.yml. To change agent behaviour we change a rule, not a prompt. - Memory lives in labelled GitLab issues (
incident,review-decision,feedback-rule). Later runs search them, so a repeated failure is recognised as "seen before". - Every flow escalates to a human in one format: a
needs-humanissue with the root cause, the evidence, 2–3 options and a recommendation.
3. A release pipeline that proves itself (no AI in the safety path)

- Every push: ruff and mypy, then pytest with coverage of at least 90%,
then GitLab SAST, Secret Detection and Dependency Scanning, then
risk-facts, then a container image pushed to the GitLab Container Registry. - Merge to main (staging):
- the migrations are rehearsed on a throwaway Neon branch, which is a copy of the real production database, and data invariants are checked;
- the exact image is deployed to Render staging;
- a concurrent load test sends 40 responders after 20 units: exactly 20 must succeed, 20 must get a 409, and stock must end at 0;
- CI writes one release-evidence JSON for the Release Manager.
- Production: a human runs the pipeline with the input
deploy = production. CI migrates, deploys, then runs smoke tests and invariants. Any failure rolls Render back automatically. If everything passes, CI tagsv1.0.Nand creates a GitLab Release. - Hourly schedule: health and data invariants on production (negative stock, orphan reservations, migration head).
4. Every incident makes the next review stricter

CI rolls back first, and the Guardian investigates after that. Its vaccine
MR adds a rule to risk-policy.yml and a regression test, so the MR Guardian
blocks the same class of bug from then on.
5. Supervised by design
- Agents commit fixes to feature branches. On
mainthey only open MRs, and a human merges them. - Production needs one deliberate human action. Agents never touch production data; when data needs repair, they open an issue for a human.
- Only the MR author, its reviewers and Maintainers can command the agents. Comment text is treated as data, not as instructions.
- Humans can override a BLOCK with
intentional: <reason>, and the reason is recorded. They can also revert the agents' last commit withundo.
Stack
- GitLab Duo Agent Platform: custom flows, triggers, service accounts,
AGENTS.md. - GitLab CI/CD: pipeline inputs, protected variables, Container Registry, Environments, Releases, schedules, SAST, Secret Detection, Dependency Scanning, CODEOWNERS.
- App: FastAPI, SQLModel, PostgreSQL, React and TypeScript.
- Hosting: Render (staging and production) and Neon Postgres (production, staging and rehearsal branches).
Challenges we ran into
- Bots can't trigger flows. A service account's commit doesn't start another flow. We made this part of the Supervised design instead of fighting it: every hand-off between flows goes through a meaningful human action (mark ready, merge, deploy).
- Long flows are fragile. We studied about 50 projects from earlier GitLab hackathons; flows with 5–13 agents often crashed. That led us to at most 4 agents per flow, 5–8 tools per agent, and STATUS handoffs instead of conditional routers.
- Agents can't run tests inside a flow. So the proof comes from the next real pipeline run, and the agents' claims must match CI.
- Permissions in a shared hackathon group. We had no protected tags, so the production approval became a pipeline input with a dropdown.
- Free infrastructure. We had no card for a cloud account, so we used Render and Neon free tiers. Render has no canary deploys, so rollback means redeploying the previous version.
Accomplishments that we're proud of
- The full release chain runs green on real infrastructure: rehearsal on a production copy, staging deploy, a load test that proves stock never goes negative under concurrency, the production deploy, and a GitLab Release.
- We tested the Pipeline Doctor end to end:
- it fixed a real code bug on the same branch;
- it recognised the same bug again from memory, without being fooled by a misleading commit message;
- it reported a type error while the MR Guardian correctly waited for a green pipeline.
- The risk score is deterministic and unit-tested, so "risk" is something you can reproduce, not an AI mood.
- One consistent design across 7 flows and 28 agents.
What we learned
- Agents are most useful when they interpret evidence and least useful when they produce it. Scores, tests, rollbacks and load tests belong in CI.
- An independent critic agent catches the most dangerous agent mistake: a "fix" that just weakens a test.
- Supervised autonomy works best when the human makes a few big decisions, not many small ones.
Built With
- docker
- fastapi
- gitlab-ci
- gitlab-duo-agent-platform
- neon
- postgresql
- python
- react
- render
- sqlmodel
- typescript
Log in or sign up for Devpost to join the conversation.