Inspiration

Most pipelines run every job on every change, and most "AI for DevOps" stops at one step. We wanted a lane where agents carry a change from the issue to production, where plain code does everything that needs no judgement, and where every run says what it cost.

What it does

GreenLane takes a change through all nine stages of GitLab's DevSecOps lifecycle. Here is one real change, issue #2 to production, on 18 October:

  1. Plan. A person opens an issue. One minute later the Lane Scout has read it, placed the work in the service and the page, labelled it, and posted the lane's forecast: 9 of 13 jobs, 174 runner-seconds, 0.285 g CO2e, with a budget of 0.343 g. The forecast comes from the lane's own planner, so the agent never does the arithmetic.
  2. Create, Verify, Secure. The merge request's pipeline is planned from the files it touched and runs only those jobs. To test the repair, the change carried one mistake on purpose: the server listening on every interface. The SAST gate stopped it.
  3. The repair. 60 seconds after the failure the Lane Mechanic committed the fix (the default back to 127.0.0.1, HOST still overrides it) and said why, quoting bandit's finding. It may never silence a scanner, edit a test or touch the pipeline.
  4. Govern. The govern job audits every commit an agent makes against policy/agents.json: one commit, ten lines, only files a person changed, no tests, no ignores, never the default branch. The Mechanic's fix: within every rule. It also checks the change against the Scout's budget: 83 % of it.
  5. Package, Release. The image is built, scanned and given a bill of materials, then staged as its own Cloud Run revision with no production traffic and its own address. A person asked the Lane Steward for a summary (the plan holds, every skipped job explained) and merged: that merge is the approval of the production deployment.
  6. Release, Configure. On the default branch the lane deploys with no stored key, checks the new revision with real requests, and checks the running service against infra/cloud-run.json: no drift.
  7. The report. The Lane Herald posts on the merge request and the closed issue what shipped: the live revision, the configuration check, and the Scout's forecast next to the change's measured 0.296 g.
  8. Monitor. Every two hours a schedule checks the live service and its configuration. When we changed the service by hand to test it, the check failed and the Lane Watch opened an issue with the evidence two minutes later.

The Lane board (https://greenlane-demo-37vmav4mla-lz.a.run.app/lane) is GreenLane's own page: every merge request with its jobs, its nine-stage evidence strip, its agents' work to the second and its carbon. 9 of 9 stages have evidence.

How we built it

  • GitLab Duo Agent Platform: five custom flows in flows/, written through the AI Catalog's API and read back; flow triggers on work items, pipeline events and mentions; per-agent service accounts and tool lists.
  • GitLab CI/CD: a parent pipeline that plans a dynamic child pipeline; merge request pipelines; the container registry; CycloneDX and SAST reports; staging per merge request and production as GitLab environments; a resource group so deploys take turns; a pipeline schedule for monitoring and drift.
  • Policy as code: policy/agents.json, enforced by govern in every pipeline before the release stage.
  • Google Cloud: Cloud Run (europe-north1, min 0 / max 1), Artifact Registry, Workload Identity Federation with GitLab's OIDC token; the service declared in infra/cloud-run.json.
  • MCP: a read-only endpoint in the service, so GitLab Duo Chat can ask the lane what a change will run and cost.
  • Python standard library only for the planner, the accounting, the audit and the board.

The agents at work (all on record)

  • Issue #2 → merge request 15: Scout, Mechanic (security fix in 60 s), audit, staging, Steward, Herald — above.
  • Merge request 8: nobody was mentioned; the Mechanic fixed an undefined name 111 seconds after the failure.
  • Merge request 9: the Steward caught a change that was right by file paths and incomplete by content.
  • Merge request 7: the Mechanic declined when the code and the tests were both defensible, and said why.
  • Issue #3: the Lane Watch caught a configuration drift on the live service.

The numbers

  • On the runs where the change let the lane leave jobs out: 44 % less CO2e than running everything; a docs-only change 75 % less. 982 runner-seconds never spent.
  • Each agent starts on one event only: an estimated 1,643 agent sessions a month avoided against an agent at every step.
  • Serving from europe-north1 and scaling to zero: 61 % less than us-east1, 87 % less than one instance always on.
  • Method and every source: docs/sci.md. Every step of the runs above: docs/first-pipelines.md.

Challenges we ran into

  • Agents can't start agents: triggers fire only on a person's action. So each agent owns one event, and plain code carries the change between them.
  • Merge requests staging at the same moment raced for the service's traffic list; a GitLab resource group made deploys take turns.
  • A flow's token can't read job artifacts, so every figure an agent needs is printed in a job log or a committed table.

Accomplishments that we're proud of

One real change went from issue to production through all nine stages with five agents, and every step is a link anyone can open. The agents are audited by the pipeline itself, and the Lane board shows all of it on one page.

What we learned

Give each agent one event and a short list of things it may never do, let code do the rest, and check the agents with a policy the pipeline enforces.

What's next

The Scout opening the branch for small issues, the Herald writing GitLab release notes, and the lane offered as a CI/CD component other projects can include.

Built With

  • bandit
  • docker
  • duo-agent-platform
  • gitlab
  • gitlab-ci
  • gitlab-duo
  • gitleaks
  • google-cloud-run
  • mcp
  • python
  • trivy
  • workload-identity-federation
Share this project:

Updates

Submission history