About The Project: Radius
Inspiration
The question we wanted to answer was simple: Can AI agents truly ship to production without a human acting as the merge button?
While building this project, we were motivated by the growing tension between AI adoption and developer trust:
- Adoption is high, trust is low. 90% of developers use AI, yet only 30% report little to no trust in its output (DORA 2025).
- Skepticism is widespread. 46% of developers actively distrust AI accuracy, compared to just 33% who trust it (Stack Overflow 2025).
- The tools themselves prevent autonomy. GitHub's own coding agent cannot mark a PR as ready, approve, or merge it, requiring a human to do so. Additionally, GitLab Duo's foundational flows stop at the merge request with no way to natively complete the delivery.
These constraints showed us that the issue isn't that agents can't write code, it's that there's no enforceable way to let them finish the job. With Radius, we set out to solve this by making autonomy a budget, not a prompt.
What We Learned
- Governance is more important than generation. Writing code is only half of the battle. The hard part is defining a verifiable, deterministic boundary that an agent can never cross.
- Determinism builds trust. By having a single source of truth (
autonomy.yaml) enforced by a dependency-light policy engine, both the agents and the pipeline are held to the exact same rules. - Rollback must be a first-class citizen. A safe autonomous system doesn't just aim to ship, it must prove that it can unship just as fast. Automatic rollback is a requirement, not an afterthought.
- Platform constraints are design constraints. Rather than assuming perfect permissions, we had to work around limitations such as
ai_workflowsscoped tokens, ambient flows not receiving CI variables, and the requirement to register custom flows through the UI. - Evidence is the language of trust. A human shouldn't have to read logs to understand a deployment. A machine-readable evidence pack (
evidence/canary.jsonandevidence/REPORT.md) is what allows for safe, hands-off autonomy.
How We Built It
Radius is a nine-stage, hands-off delivery loop built specifically for the GitLab Duo Agent Platform. We built it with the philosophy of "one human action, zero human merges".
The Architecture
| Component | Purpose | Implementation |
|---|---|---|
| The Contract | The blast-radius budget for our service. | A versioned autonomy.yaml defining error rates, p95 latency, spend, change size, freeze windows, and escalation rules. |
| The Policy Engine | The deterministic gatekeeper. | policy/check.py evaluates every action against the contract with exit codes (0 = allow, 2 = deny). Fully tested and shared between agents and CI. |
| The Demo Service | A deliberately simple target to test against. | A FastAPI service exposing endpoints such as /health, /quote, and /work, complete with chaos injection for canary testing. |
| The Agents | The autonomous actors. | Two custom GitLab Duo flows: Radius Triage & Plan (creates the change and MR) and Radius Release Captain (enforces policy, merges, and governs the release). |
| The Pipeline | The deterministic execution environment. | A .gitlab-ci.yml with all nine stages (plan → create → verify → secure → package → release → configure → monitor → govern). |
The Loop In Action
- Plan: A human creates a single work item from the "Radius ship" template. The Triage flow reads the contract, plans the smallest bounded change, commits it to a branch, and opens a merge request with a full plan.
- Create & Verify: The MR is created, triggering the Release Captain. It computes the diff, runs the policy gate against the contract, and merges the change via the flow's Git credentials.
- Canary & Measure: The pipeline builds both the previous commit's wheel (the stable revision) and the new wheel (the candidate). It routes canary traffic, injects a controlled fault, and collects metrics over a sample of requests.
- Govern & Rollback: The policy engine decides promotion based off of the measured error rate and latency. Using the following logic, where $e$ is the observed error rate, $e_{max}$ is the budget, and $p_{95}$ is the 95th percentile latency:
$$e = \frac{\text{failed requests}}{\text{total requests}}, \quad \text{promote if } (e \le e_{max}) \land (p_{95} \le p_{95}^{max})$$
If breached, the harness halts the candidate, restarts the stable revision on the live port, and verifies its /health response, and the Release Captain posts an evidence-backed rollback comment. If clean, it promotes the candidate.
This entire process is verifiable, as showcased by our tested runs where a canary with a 53.3% error rate was correctly denied, rolled back to the stable revision, and proven with evidence.
The Challenges We Faced
- Runtime Incompatibilities: The GitLab Duo ambient flow runtime was on Python 3.9, which broke our code due to usages of
datetime.UTC. We had to backport todatetime.timezone.utc, drop our Python version requirement to be compatible, add apython:3.9-slimCI job for parity, and create a JSON fallback (autonomy.json) forautonomy.yamlas PyYAML wasn't available in the flow environment. - Merge Permissions: The flow's API token was strictly scoped to
ai_workflows, preventing any merge via the API. We couldn't use project CI variables in ambient flows either. Our solution was to authenticate via the flow service account's Git credential, allowing us to merge directly tomainas a Developer (as allowed by branch protection), completely bypassing the API scope limitation. - Tight Platform Constraints: We had to work around GitLab's lack of time-based triggers, the inability for bots to start flows in certain contexts, and the requirement for custom flows to be manually registered through the UI. Each constraint was accounted for in our design instead of treating them as blockers.
- Building a True Canary: Creating a realistic canary was tricky. We had to build the previous commit as the stable baseline, inject a controlled fault, measure against it, and most importantly, verify the rollback by checking the live revision and build channel post-rollback. All of this had to happen within a CI runner with no external cloud dependencies.
- Keeping Governance and Execution in Sync: It was paramount that the agents, the CLI (
policy/check.py), and CI all enforced the exact same contract. Having a single contract file, extensive testing, and contract parity checks in our verification script ensured that they could never drift apart.
Final Thoughts
Radius is a reference implementation, not a full deployment platform. It's small by design: a FastAPI service, a policy engine, a canary harness, two flows, and a nine-stage pipeline. Its purpose is to prove that with a budgeted canary, automatic rollback, and a verifiable evidence pack, we can bridge the trust gap that has been holding back true agent autonomy.
We didn't build a smarter agent, we built a safer way for agents to ship. With Radius, the budget, not the human, gets the final say.
Built With
- fastapi
- gitlab
- gitlabci
- pydantic
- pytest
- python
- uvicorn
Log in or sign up for Devpost to join the conversation.