Inspiration

Back in 2021, early on in my software development journey I discovered and began to use this package called staticman; it was a nodejs open source tool that allowed developers to have dynamic content as part of a fully static website. And I’d use this with my own portfolio and client projects. Sadly a few months into using it I began to experience problems after the project was abandoned and left without maintainers, and I couldn't get anything to work.

What it does

Fast forward to 2026, and the dawn of agents combined with Gitlab’s agentic DevSecOps automation I realized I could reawaken the project. So I wrapped it in something I’m calling MIB, Maintainers in a Box: and these are agents that triage, build, review, scan, deploy, monitor and release the open sources Staticman project. The first step is issue triaging so when an issue is created on staticman repo either through agents or humans our triage workflow and agent picks it up automatically and classifies it, checking for duplicates and if it meets the criteria set, only then it’s marked as ready for the next step. Once the issue has been confirmed by the triage agent and ready to be worked on, the maintainer tags duo developer in the comments. This is the first supervision point; one because workflows can’t tag other workflows and it’s also important for the maintainer to see what duo developers will be working on from the notes generated by our triage agent. Once Duo Developer is done, it submits a draft merge request, and because it’s draft our Duo Chat can’t review it. So as the second supervised human intervention, the maintainer reads the merge request, inspects the diff, sets auto merge and marks the merge request as ready. This triggers Duo Chat to review it and if all is well i.e pipeline passed and it found no issues, its merged and a main branch pipeline is set in motion.
After the main branch pipeline completes successfully, we have our second last human supervised point. That is prod deployment which is a massive responsibility. So at this point MIB hands control over back to the maintainer who manually runs the deployment job deploying the app to Google cloud. We then check our live deployed status page is as expected and the final supervised action of the maintainer is to tag our releaser workflow and merge its MR creating a new release that can be viewed in the releases page. Important to mention that our release workflow has a rollback mechanism built in.

How we built it

MIB wraps Staticman, an abandoned MIT-licensed Node service, in a DevSecOps lifecycle built on GitLab Duo Agent Platform. Custom flows handle triage, security fixes, release notes, monitoring diagnosis and auditing, and the Duo Developer writes the code. Around them sits a GitLab CI pipeline: lint and a coverage ratchet as hard gates, four scanners, a review app per merge request, staging deploys with smoke tests, and a manual production job that deploys a no-traffic candidate, tests it, shifts traffic and rolls back on failure. Duo code review runs with custom rules that flag stale or unverified claims. An AGENTS.md file and a rule that an issue must authorize any change to CI or infrastructure keep the agents inside written limits. It runs on Google Cloud Run with keyless authentication.

Challenges we ran into

Platform limits shaped the design. A flow can't start another flow, so a human assigns the Developer, and I found no flow tool that merges, so a human merges. We also hit real bugs. A failed, rolled-back production promotion still published a release, because allow_failure let the release job start. We found it with a deliberate failure test and fixed it with a proof-of-promotion marker. Duo's review once arrived after auto-merge, and agent sessions sometimes dropped or duplicated. We broke our own authorization rule on early CI changes, and the auditor flagged it.

Accomplishments that we're proud of

The loop works end to end on real changes: an issue became triaged, coded, reviewed, scanned, deployed to staging, promoted and released, with each human gate chosen and written down. The review rules caught real stale claims in our own release notes, and the failure test found a bug that would otherwise have shipped. We also measured a waste after the fact. An hourly pipeline re-ran four jobs on unchanged code, and cutting them took scheduled runs from 263 to about 102 job-seconds (61 percent, over 15 runs). We estimated the carbon as an SCI range and said what we couldn't measure. Every merge request states what is not verified.

What we learned

  • A rolled-back production deploy still published a release (issue #25), because of allow_failure on the deploy job. We found it with a failure test and fixed it with a proof-of-promotion marker.
  • Duo's code review caught stale claims in our own release notes, using custom review rules.
  • Auto-merge once beat Duo's review by 80 seconds.

What's next for Maintainers in a Box

More autonomy where it's safe: a way to start the releaser without a human mention, and a merge step that waits for review.

Built With

Share this project:

Updates

Submission history