Inspiration
Code generation is solved, but everything after it still burns compute nobody looks at. GitLab.com hosted runners compute on a grid at 579 gCO₂eq/kWh (us-east1); the French grid our users are on is usually 15–50. Deployments happen whenever someone clicks, not when the grid is clean. We wanted agentic delivery that is not only automated but also accountable: every delivery should know, and minimise, what it costs the planet.
What it does
A human opens an issue. The only other human action is one click on Merge when the agents report that every gate passed.
- Plan: the Planner agent reads the issue and
AGENTS.md, posts a plan with the tests that will prove it, and labels the issue. - Create: the Developer agent branches, writes the code and
node:testtests, updates the changelog and opens a merge request. - Verify, package, secure, govern in the merge request pipeline: unit tests (JUnit report), a zero-dependency build under a 20 KB page-weight budget, SAST, secret detection, a CycloneDX SBOM and a governance gate (license, SBOM, findings, carbon budget). Each merge request gets a carbon bill (SCI) and a governance report.
- The Pipeline doctor agent heals failing pipelines from the job logs. GitLab Duo Code Review reviews every push; when it requests changes, the doctor fixes them and waits for the re-review. When everything is green it posts "Ready to merge" and mentions the author: GitLab does not let agents merge, so the human keeps that one decision.
- Release: a tagged release from the changelog and a versioned package in the Package Registry.
- Configure and deploy: the carbon gate compares the live French grid (RTE eco2mix) with the last 7 days and a 12-hour forecast. It deploys to GitLab Pages now if the grid is clean, otherwise defers; an hourly green window (one 15-second job) ships the release when the grid is clean, never more than 6 hours later.
- Monitor: a production check probes the live site after every deployment; the Reporter agent opens an incident and a revert merge request if it is unhealthy.
- The Reporter agent closes the loop on the issue: release, grid decision, production health, SCI per delivery and per 1 000 page views, savings against the baseline, governance result.
Real runs are in the repository: for issue #3 the agents had a reviewed, fully green merge request ready 10 minutes after the issue was opened, including one AI-review round trip fixed by the doctor, and the change was live 3 minutes after the merge. On 16–17 October the gate deferred a release at 36 g/kWh and shipped it at 16 g/kWh, then deployed issue #3 at once at 13 g/kWh.
The product it delivers, Watt Now (https://greenship-1336d2.gitlab.io), is useful on its own: under 5 KB, it shows the live carbon intensity of the French grid, the cleanest hour of the next 12 to run heavy jobs, and how that very page was delivered.
How we built it
- GitLab Duo Agent Platform: a custom flow (
.gitlab/duo/flows/greenship.yml) with four AgentComponents chained by routers, a compact text hand-off contract between agents, and Work item created + Mention triggers. Every agent is resumable: it first checks what already exists (plan note, branch, merge request, pipeline, review), so one mention resumes an interrupted delivery without duplicating work. - GitLab CI/CD: stages verify, package, secure, release, deploy, monitor, govern;
interruptible+auto_cancel,rules, JUnit / metrics / CycloneDX reports, environments, Pages, Package Registry, releases and a pipeline schedule. Workflow rules turn the schedule into a single job and a green-window trigger into a build-deploy-check-only run. - No stored secrets: agents act with the short-lived token of their flow session; the pipeline uses
CI_JOB_TOKENand the public jobs API. - SCI (Green Software Foundation, ISO/IEC 21031:2024): E from each job's runtime × Cloud Carbon Footprint power coefficients (PUE 1.1); I = 579.44 g/kWh for the runners (Google Cloud 2025) and the live RTE value for users; M from amortised embodied emissions; R = one delivery, and 1 000 page views (Sustainable Web Design v4). Every coefficient is in
src/sci.jsand unit-tested. - Baseline: the same app built the conventional way (React, Chart.js, axios, date-fns, Vite, ESLint, Vitest, SAST), measured with the same method on the same runners.
Sustainability gain (measured)
- −58 % pipeline carbon for the same work (lint, tests, build, SAST): 0.158 g vs 0.374 g CO₂eq per delivery. No dependencies means no
npm install: about 15 s per job instead of 50–60 s. - −41 % for the whole merge request pipeline (0.220 g), even though it also runs SBOM, secret detection, the SCI report and the governance gate.
- −96 % per 1 000 page views: 4.6 KB gzip instead of 125.6 KB (0.21 g vs 5.63 g on the French grid).
- −84 % for the scheduled green window after we measured our own first design (0.7 g per day instead of 4.2 g).
- Carbon-aware release: deferred from 36 g/kWh, shipped at 16 g/kWh (2.25× cleaner electricity at release time).
Honest limits: the full delivery (release, package, carbon-gated deploy, production check, governance) costs about 0.54 g, more than the conventional pipeline that does none of this. Runner power is modelled with public coefficients because hosted runners expose no telemetry, and the gate shifts the release in time, not the runners' location.
Challenges we ran into
- Agents cannot merge on GitLab: the flow token is scoped to read, create and update merge requests. We designed around that guard rail instead of hiding a bot token in CI: the doctor checks every gate with
green/ready.mjs(unit-tested) and asks the human. - Two AI systems had to cooperate: the doctor reads GitLab Duo Code Review's feedback, fixes it on the branch and waits for the re-approval before asking for the merge.
- A platform restart killed a session right after a fix; making every agent idempotent turned that into a one-mention resume.
- Our own green window was wasteful: it re-ran three jobs every 30 minutes and cost more per day than the deliveries. Measuring it made us shrink it to one hourly job (−84 %).
- Hosted runners expose no power telemetry, so E is modelled with public, conservative, documented coefficients.
Accomplishments that we're proud of
- Real, repeated end-to-end deliveries on GitLab.com, with every step visible in issues, merge requests and pipelines.
- All nine lifecycle stages covered: plan, create, verify, package, secure, release, configure, monitor, govern.
- Honest carbon accounting, including the numbers that do not flatter us.
What we learned
Measuring changes decisions: the SCI report on every merge request made us remove dependencies, shrink the page and cut our own scheduler. And the right guard rail (human merge) costs one click, while the rest of the lifecycle can be fully agentic.
What's next
- A France-located runner, which would cut the pipeline's intensity term about 20×, and gating the heavy scanners on the grid too.
- Marginal-emission signals and official grid forecasts when they become openly available.
- Packaging the flow and the carbon gate as a reusable CI/CD component.
Built With
- css
- gitlab-ci/cd
- gitlab-duo-agent-platform
- gitlab-package-registry
- gitlab-pages
- green-software-foundation-sci
- html
- javascript
- node.js
- rte-eco2mix