DEV Community

Cover image for How I contribute to GitLab with a coding agent (and approve every push)
Hamza Hasanain
Hamza Hasanain

Posted on Originally published at gitlab.com AI-assisted

How I contribute to GitLab with a coding agent (and approve every push)

I came back to GitLab contributions after about 9 months away, and I had forgotten most of the process. So I wrote it down once, as rules and workflows a coding agent can follow. The agent does the busy work, and I approve every push and every comment.

In one hackathon week, this setup helped me open 20 MRs in 7 GitLab projects. 15 of them are merged now. The setup is public: gitlab-agent-kit.

Table of contents

What is in the kit

  • AGENTS.md: the rules every agent follows. The main one is that nothing goes out without my OK.
  • 8 workflows: onboarding, catchup, scout, analyze, claim, start, ship and followup.
  • 8 roles the workflows hand work to, like issue-analyst, implementer and verifier.
  • tools/gl.py: a GitLab API helper, so the agent does not write raw API calls.
  • Guards: a wording lint, git hooks, and a hook that asks before every push and every GitLab write.
  • A playbook per project, with its commit format, its checks, and lessons from past reviews.

The loop is simple: find a free issue, analyze it, claim it, implement it, ship the MR, and follow up on reviews. The rules live in AGENTS.md, so it works with Claude Code, Codex, Cursor and Antigravity CLI (agy).

Setup

git clone https://gitlab.com/HamzaHassanain/gitlab-agent-kit.git
cd gitlab-agent-kit
tools/init.sh <your-gitlab-username>
Enter fullscreen mode Exit fullscreen mode

Put a personal access token in .env, then run python3 tools/gl.py me to check it. .env and your notes are in .gitignore, so they stay on your machine.

Before the first run, make it yours:

  • Fill the two _edit me_ spots in AGENTS.md: your stack and the projects you want to work on.
  • Rewrite sections 2 and 3 of wording-instructions.md from 10 to 20 of your own GitLab comments. This file decides how every comment and MR description sounds.
  • Add projects to projects.json if you need more.

If you are new to GitLab, start onboarding at https://contributors.gitlab.com/start. The kit has an onboarding workflow for you too. The full guide is in the wiki.

One run with Antigravity CLI

The hackathon MRs went through Claude Code. For this post I ran the same flow in agy on glab, the GitLab CLI.

Scout

I asked for simple glab issues. It read the comments on each candidate and ranked 4 free issues.

scout ranking 4 free glab issues

Analyze

It started one issue-analyst per issue, in parallel. Each one writes a plan and a go or no-go. Then question-resolver answers the open questions from the code and history, so the claim does not ask things we can find ourselves.

four issue-analyst subagents running in parallel

Claim

The claim is one line: Hello! I'd like to work on this. The verifier checked it first, and the agent waited for my OK before posting.

agy refusing to claim before the verifier and my OK

Start and ship

4 implementer workers wrote the code and ran light checks only. Then mr-writer wrote each description from glab's template, with a real reproduction and real test output.

an MR description with a real reproduction and test output

Ready for review

It checked the pipelines, showed me the exact @gitlab-bot ready comment, and asked before posting it.

agy asking before posting @gitlab-bot ready

The run opened 4 MRs: cli!4141, cli!4142, cli!4143 (merged) and cli!4144.

What the guard blocks

tools/agent_guard.py runs before every shell command agy wants to run. These are its answers for three commands:

$ git -C repos/cli push upstream main
{"decision": "deny", "reason": "Never push to upstream. Push only to origin (the community fork) on a feature branch."}

$ cat .env
{"decision": "deny", "reason": "Reading .env is not allowed. gl.py loads the token itself."}

$ git push -u origin my-feature
{"decision": "force_ask", "reason": "git push needs your explicit OK every time."}
Enter fullscreen mode Exit fullscreen mode

Results

As of October 20, 2026, 15 of the 20 hackathon MRs are merged, 5 are in review, and none were closed. Every one of the 7 projects has a merged MR. 6 more MRs came out of review threads after that week, and 4 of them are merged.

Most review comments were not about the agent at all. Extend the existing test table instead of adding a new one. Add fields to the existing log line instead of a new line. These lessons are now in the playbooks, so the agent reads them next time.

This is not an MR spam machine

The main risk with an agent and a hackathon is a pile of low-effort MRs. So the kit pushes the other way:

  • One issue per MR, small and focused.
  • No taking someone else's issue. The check runs before starting and again before shipping, and mr-create refuses if the issue is not assigned to you.
  • Every MR has one honest line about AI use.

Some rules still depend on the agent following AGENTS.md. An agent with full shell access could go around them. So keep your agent's permission prompts on.

What real use changed

  • Claim comments had plans and questions in them. Now a claim is one line.
  • After the merges, I found 3 comments I never answered. Now gl.py inbox lists everything waiting on me, and the verifier checks every write.
  • A heavy local check ran out of memory on my laptop. Now the agent runs light checks only, and the pipeline does the rest.

Takeaway

The way I see it, the agent is good at busy work and bad at knowing when to stop. So I kept every outward action for myself. Try the kit, and open an issue there if something breaks with your agent.

I wrote this post with AI assistance. I reviewed it, and the numbers come from my real MR list.

Top comments (6)

Collapse
 
amintacccp profile image
tamina •

The part that convinced me is that the guard is a hook, not a prompt suggestion: agent_guard.py answering deny on a push to upstream, and a verifier checking every write, is a very different trust level from "please ask me first" in AGENTS.md. The wording file built from your own past comments is the other detail people will copy — an agent MR that sounds like a template is exactly what makes maintainers suspicious. And the gl.py inbox born from finding 3 unanswered comments after the merges is painfully relatable. 15 of 20 merged with zero closed as unwanted says the restraint is working.

Collapse
 
hamzahassanain0 profile image
Hamza Hasanain •

yes exactly.
prompts are suggestions, but hooks and guard scripts are hard limits.
if the agent can bypass a rule, it will do it at some point.

the wording file was necessary because maintainers spot generic AI text immediately.
and missing review comments was painful, so the inbox check had to be automated.

glad the restraint part made sense :)

Collapse
 
amintacccp profile image
tamina •

That line is the one I'd underline: if the agent can bypass a rule, it will do it at some point. It's not even malice, it's just optimization pressure over enough runs — a suggestion in a prompt gets traded away the moment it conflicts with finishing the task, a hook can't be.

And the wording file point feels underrated. The guard stops the wrong action, but the wording file stops the contribution from reading as a drive-by in the first place — two different kinds of trust, and maintainers notice both. Automating the inbox check after missing review comments makes complete sense too: that follow-through is exactly what a human forgets under load, and exactly what shouldn't be left to memory.

Thread Thread
 
hamzahassanain0 profile image
Hamza Hasanain •

when the agent is focused on finishing the task, a prompt is just a soft hint.
without a hook, it will always pick the path of least resistance.

and I agree on the two kinds of trust.
the guard prevents bad actions,
but the wording file prevents losing goodwill before anyone even reads the diff.

thanks a lot for the thoughtful reply :)

Collapse
 
vishisht_choudhary_a12d08 profile image
Vishisht Choudhary •

The guard returning force_ask on every push while flatly denying cat .env is a really nice split, since it keeps the agent useful without handing it the keys. I also like that review feedback goes back into per-project playbooks; 'extend the existing test table instead of adding a new one' is exactly the kind of house style an agent can't infer from the code alone. Have you found the playbooks drift as maintainers change their minds, or do you prune them after each merged MR?

Collapse
 
maxbuildsdev profile image
Max Kaya •

Worth adding that the "approve every push" part is the hard bit, and your wording-instructions.md trick is what makes it work. The rules only hold if the agent's output sounds like you, otherwise you're reviewing every comment twice — once for correctness, once for voice. Seeding that file from 10-20 of your own past comments is probably the highest-leverage part of the kit.

One gap I'd be curious about: the loop you describe is linear (scout → analyze → claim → start → ship → followup). What happens when the verifier says no-go on an issue you already claimed, or when a claim comment goes out and the issue turns out to be taken? Half the wasted agent time in my experience is in the edges around "claim" rather than the work itself, and those are exactly the paths that a rules file tends to under-specify since they're rare and annoying to describe.

Also: did you find a way to measure whether the agent is actually improving your throughput, or is 20 MRs in a week mostly an anecdote? A per-issue time-to-merge before vs after would be a much stronger claim than MR count.