Path B (Bring Your Own) · autonomy level: Hands-off

Inspiration

Replicata pays people in USDC on Solana to reproduce scientific experiments. Workers lock a bond, re-run a sealed container and get paid only when a majority agrees. In a project that escrows real money, "tests passed" is not enough to ship. We wanted the strongest possible gate: the release candidate must actually replicate an experiment on Solana before production gets it. Then we wanted the whole path from an issue to that gate and on to production to need nobody.

What it does

You open an issue with the Autopilot template. The next time you look, the change is live, released, and the issue has a delivery summary. We ran exactly that on issue #6:

  • Autopilot planned it and opened !6, which merged itself.
  • main passed 15/15 jobs, including the devnet canary, and production deployed.
  • Release Steward tagged v0.2.0 and posted "Delivered" on the issue.

Three custom flows on the GitLab Duo Agent Platform drive it:

  • Replicata Autopilot (planner → implementer → escrow auditor).
    • The planner checks the trust gate: the ~autopilot label, which only project members can apply. It then posts a plan with the files, the acceptance test and a risk tier.
    • The implementer writes the change and its tests, runs lint and the web tests, and opens the merge request.
    • The auditor reviews the diff against the escrow invariants (vault accounting, commit-reveal, authority checks, the x402 replay guard) and can cancel the auto-merge.
  • Pipeline Medic (pipeline failed).
    • On an Autopilot branch, it repairs the branch.
    • On main or a scheduled canary, it opens an incident with the failing job, log excerpt, root cause, blast radius and fix, plus a revert when a commit caused it.
  • Release Steward (pipeline passed on main). It reads the Conventional Commits, tags a semver release with notes (the tag pipeline publishes the GitLab Release) and posts "Delivered" on the issue that started it.

Autonomy follows blast radius.

  • hands_off changes (web app, worker CLI, docs) merge themselves: the merge request pipeline arms auto-merge, pinned to the exact commit under test.
  • supervised changes (the on-chain escrow program, its IDL, the coordinator that settles payments) go through the same agents and gates, but a human merges them, because that code holds people's money.

The nine stages

  • Plan: Autopilot planner, the issue template, risk tiers.
  • Create: Autopilot implementer, and Duo Code Review on every merge request.
  • Verify:
    • Anchor build plus a committed-IDL check, and clippy;
    • Rust tests (Postgres and Docker-in-Docker);
    • a localnet end-to-end run with three real Docker workers;
    • web tests (Vitest and Playwright).
  • Package: the coordinator image goes to the GitLab Container Registry per commit, and the worker CLI is built as an artifact.
  • Secure: SAST, secret detection, dependency scanning and container scanning, all blocking production; the escrow auditor reviews every Autopilot diff.
  • Release:
    • A staging preview, then the devnet canary. The new image runs as a CI service and must take a real experiment through Solana devnet: publish, three workers claim, commit and reveal, finalize, a buyer pays over x402, and the result hash must match.
    • Only that exact image is promoted to production (Render, then Vercel), and /version must prove it.
    • Release Steward tags the release.
  • Configure: staging and production environments, the agent sandbox image and network allow-list (.gitlab/duo/agent-config.yml), masked CI variables.
  • Monitor: a pipeline schedule runs the devnet canary and a health check every 6 hours, and Pipeline Medic turns failures into incidents.
  • Govern: an OSI-only license audit of every Rust crate and npm package, with an artifact; the ~autopilot trust gate; risk tiers; CODEOWNERS; a protected main.

How we built it (what is new since 5 October)

Replicata (MIT, GitHub) existed with GitHub Actions and manual deploys. During the submission period we imported it to GitLab and built:

  • the whole .gitlab-ci.yml;
  • the three flows and the agent config;
  • the devnet canary and the coordinator /version endpoint it relies on;
  • the license audit, CODEOWNERS and the Autopilot issue template;
  • the deploy scripts.

Production is now deployed by the GitLab pipeline: Render pulls from the GitLab registry, and the pipeline deploys Vercel. Details: docs/GITLAB.md.

What the loop found

Moving the suite to GitLab's shared runners exposed two real worker bugs, now fixed with tests:

  • the sandbox could run experiments as root when the worker itself ran as root;
  • it rejected remote Docker engines (DOCKER_HOST=tcp://).

On the first main pipeline, Pipeline Medic diagnosed two failures by itself:

  • a property test that could generate a blank title (#3);
  • a canary job whose TMPDIR did not exist before the runner downloaded artifacts (#2).

Challenges

Making it truly hands-off on GitLab.com meant designing around four limits of flow tokens:

  • Members API: a flow's token cannot read project members, so the trust gate uses a label only members can apply. Flows also run with a composite identity.
  • Push options: they fail for flow pushes, so Autopilot opens merge requests through the API.
  • Merging: flow tokens cannot merge, so the merge request pipeline arms auto-merge, only for hands_off.
  • Tags: flow tokens cannot create tags through the API, so Release Steward pushes an annotated tag with git.

What's next

Run the canary against mainnet-beta with a small budget, and let Medic propose fixes for main incidents as Autopilot merge requests, not only reverts.

Built With

  • anchor
  • claude
  • docker
  • gitlab
  • gitlab-ci
  • gitlab-duo-agent-platform
  • next.js
  • postgresql
  • render
  • rust
  • solana
  • vercel
  • x402
Share this project:

Updates

Submission history