Inspiration

AI now writes a large share of our code, but teams still struggle to answer three questions about any change: where did it come from, what was it meant to do, and who is responsible for it in production? GitLab's own 2026 research reports that 85% of respondents say the bottleneck has moved from writing code to reviewing and validating it, and that 43% cannot reliably tell AI-generated code from human-written code. We wanted a pipeline that makes those answers a requirement instead of an afterthought.

What it does

DuoGate makes every change carry provenance and intent, checks it automatically, and records the result.

  • Every commit must carry an Assisted-by: <tool|agent|none> trailer, and every merge request must link its intent issue with Closes #<id>.
  • An accountability-gate CI job checks the commits introduced by the merge request, the intent link, and the Secret Detection report. It fails closed and writes a JSON report.
  • An Accountability Ledger is published on GitLab Pages. It classifies each commit (AI-assisted, human-only, missing, merge, or grandfathered baseline) and computes compliance only over commits that are actually evaluated.
  • A staging healthcheck runs a smoke test after deployment.
  • GitLab Duo custom flows add advisory review: an Accountability Card that compares a branch to its linked issue's acceptance criteria and posts a risk and recommendation, an Intent flow that writes acceptance criteria and out-of-scope guardrails, and an Incident Trace flow that traces an incident back to its intent issue and proposes a revert command.

Autonomy level: Supervised. The agents advise and a human decides.

Lifecycle stages covered

Plan, create, verify, secure, release, monitor, and govern (7 of the 9 stages).

How we built it

  • A small Python/Flask inventory service with 57 pytest tests acts as the target application.
  • GitLab CI/CD with SAST, Secret Detection, the accountability gate, a Pages deployment to a staging environment, and an in-process healthcheck.
  • GitLab Duo Agent Platform custom flows (v1 YAML) triggered by mentioning the flow's service account.
  • Commits carry Assisted-by trailers naming the AI tools used in development. Planning, prompts and code were produced with AI assistants including Google Antigravity.

Challenges

  • CI behaved differently from our laptops. CI environment variables leaked into tests and a gitignored file was missing in fresh checkouts, so we isolated the tests.
  • The first ledger counted the GitLab starter commit and merge commits as violations. We added baseline grandfathering and merge-commit exclusion so the metric is meaningful.
  • Custom flows only had issue and repository-file tools in our setup. They cannot read commit messages or diffs, and the Accountability Card said so honestly instead of guessing. That is why enforcement lives in the CI gate and the flows are advisory.

Accomplishments

A green end-to-end pipeline, a live ledger, a gate that enforces provenance and intent, and a Duo flow that reviewed a real branch and was honest about its limits. Scenario A ran end to end: merge request !1 passed its pipeline, merged, deployed, and closed issue #2.

What we learned

Governance of AI-written code works best as enforced metadata plus honest, advisory agents, not agents pretending to see more than their tools allow.

Limitations

  • AI origin cannot be detected reliably in old commits. The contract applies going forward.
  • The incident issue is opened by a human from a template.
  • The Intent and Incident Trace flows are defined but were not executed for this submission, and the failing-gate and failed-deployment demo scenarios are provided as scripts but were not run.
  • Demo commits carry Assisted-by: gitlab-duo as scripted fixtures, not commits authored by Duo.

What's next

Flows with merge-request diff and commit tools, an automatic incident issue from pipeline events, running the Intent and Incident Trace flows, and signed provenance.

Built With

  • flask
  • gitlab-ci-cd
  • gitlab-duo-agent-platform
  • gitlab-pages
  • pytest
  • python
  • sast
  • secret-detection
Share this project:

Updates

Submission history