Inspiration
Fully hands-off automation is exciting but scary for the one step that actually carries risk: pushing to production. "Supervised" is the pragmatic sweet spot teams really want, let the agents do everything up to the edge, then give a human one well-informed decision instead of a blind "deploy?" button. I wanted that single approval to be genuinely informed, so I built a Release Captain that quantifies the risk and pre-writes the rollback.
What it does
Wrapped around a fork of the popular json-server REST API, a GitLab Duo flow runs reviewer → remediator → staging-validator autonomously: it reviews the change and runs the 127-test suite, triages and fixes security findings, deploys to a Cloud Run staging environment, and validates the live API. Then the Release Captain (tools/risk_captain.py) computes a deploy risk score from auditable signals, change size, test outcome, security findings by severity, and blast radius (did it touch deploy/config/auth/data paths?), bands it low/medium/high, and writes a concrete rollback plan. The Duo approval_gate surfaces that report and waits for one human click. On approval, production is promoted, re-validated, and auto-rolled-back if the post-deploy check fails. A govern stage adds an SCI carbon ledger and posts the outcome.
How I used GitLab to automate the post-code lifecycle (required)
GitLab Duo Agent Platform: a custom flow (.gitlab/duo/flows/release-captain.yaml, Flow Registry v1) wires reviewer → remediator → staging_validator → HumanInputComponent approval gate → run_manual_job promoter → reporter. The approval gate is what makes it Supervised. GitLab CI/CD: a nine-stage .gitlab-ci.yml with GitLab-managed security templates, Container Registry, release-cli, two environments (staging auto, production when: manual, the human gate), and dotenv artifacts carrying URLs and evidence between stages. Auditable gate: the human approves against a reproducible risk score and rollback plan, not an agent's assurance.
DevSecOps stages covered (required, all nine)
plan · create · verify · package · secure · release · configure · monitor · govern.
Sustainability, for the Most Environmentally Impactful prize (opt-in)
The govern stage runs a real SCI ledger (tools/sci_ledger.py), GSF spec SCI = ((E × I) + M) / R (ISO/IEC 21031:2024): E from measured job seconds × requested vCPU/RAM (CCF coefficients, Google PUE 1.09), I from per-region grid intensity, M embodied carbon amortised per vCPU-second, R = one deploy. It reports the delta vs a baseline. Carbon-lowering choices quantified per deploy: json-server runs TypeScript with no build step (no compile job), a slim image, npm caching, and Cloud Run min-instances 0 (near-zero idle). A live run measured ~0.28 gCO2e per deploy, ~88% under baseline. Region impact is surfaced (≈97% cleaner in europe-north1 than asia-south1). See docs/SUSTAINABILITY.md.
Google Cloud bonus (optional)
Staging and production both deploy to Cloud Run (ops/deploy_cloud_run.sh); deploy code is in the repo. Live URL: https://release-captain-maus47ftea-uc.a.run.app.
How I built it
The base app is untouched upstream json-server (MIT, 75k★), a genuinely deployable REST API, which keeps the "new work" boundary clean. The added automation is Python stdlib (so it runs in any CI image and is unit-tested): the risk scorer, the SCI ledger, and the monitor helpers each have their own logic and tests. The production deploy is a manual job gated on credentials, so the whole code path runs green before cloud is wired.
Challenges I ran into
Making "Supervised" meaningfully different from a blind manual gate. The answer was the Release Captain: turn the pipeline's own signals into a single risk number and a rollback plan, so the one human decision is actually informed. Tuning the risk weights so a clean small change reads "low → approve" and a risky, failing one reads "high → hold", and testing that, took real care.
Accomplishments I'm proud of
A Supervised loop with a genuinely informed gate, wrapped around a real-world OSS project without touching its code, all nine stages, 127 upstream tests still green plus 10 new tests for the risk engine, and a quantified carbon ledger.
What I learned
Where the human belongs in agentic delivery: not approving every step, but owning the one irreversible decision, and that decision is only as good as the evidence you hand them.
What's next
Progressive/canary promotion driven by the risk band; feeding production incident signals back into the risk score; and a one-line switch to Hands-off for low-risk changes.
Built With
- docker
- gitlab-ci-cd
- gitlab-duo-agent-platform
- google-cloud-run
- json-server
- node.js
- python
- typescript
Log in or sign up for Devpost to join the conversation.