Inspiration
Agents can now take an issue all the way to production on GitLab. That's the "life after code" part: once an agent has written the code, something has to ship it, watch it, and take it back. When an agent gets it wrong at two in the morning, there is no undo for what the agent did: the merge, the flag it switched on, the release it cut, the revision it deployed.
Today the answer is to keep a human approving every step, which throws away the point of agents. I wanted the opposite: let agents do anything they can undo, and stop them only for what they can't. Autonomy set by reversibility, not by a fixed approval level. Ctrl+Z for autonomous software delivery.
What it does
Label an issue rewind:auto and walk away.
- Checkpoint. Before any Duo agent acts, Rewind snapshots everything agents can touch: code, branches, merge requests, issues, labels, feature flags, CI/CD variables (fingerprints only), tags, releases, and which Cloud Run revision serves each environment.
- Agents build. Duo flows plan, develop and open a merge request. Each step gets its own checkpoint and least-privilege tools, so every change is linked to the agent session that made it.
- Gate. Before merge, on the exact commit that would ship, every change is classified as reversible, compensatable or irreversible. Undoable work ships hands-off. Anything that can't be undone (an email sent, a migration with no downgrade, an agent editing its own guardrails) is blocked on the exact file and line, with how to make it undoable.
- Verify and review. Tests, SAST, dependency, secret and container scanning run on the MR. Failures and findings an agent introduced go back to an agent. Duo code review's requested changes go back to the developer agent. What it can't resolve on a fully undoable change ships by policy: Rewind says why on the merge request and watches production.
- Rewind. If production regresses, Rewind opens an incident and undoes the whole change set in mitigation order: traffic first, then the flag, code, merge request and issue. Then it re-snapshots and checks the project against the checkpoint:
Zero drift means a fresh snapshot of the project after the rewind matches the checkpoint exactly: nothing added, nothing missing. Then Rewind closes its own incident.
People step in only where it matters. Anyone on the team can undo or stop a run with a /rewind comment. Accepting something irreversible takes a named person through Rewind's authenticated API, for one commit only.
In the demo (a real run, nothing simulated): an agent ships a weekend flash sale the business signed off on. Duo's review pushes back, but every part is undoable, so it ships. In production a $4 tea is charged $0.00. Monitoring catches it, and Rewind puts traffic back on the previous revision in 18 seconds. It then restores the flag, code, merge request and issue in 35 seconds: zero drift.
How I built it
- Engine (Python 3.12): one handler per kind of state (repository, branch, tag, release, MR, issue, label, feature flag, CI variable, Cloud Run), each with snapshot, diff, classify and an inverse. Every inverse is idempotent (it checks live state first) and conflict-safe (it acts only if the object still matches the plan), so a rewind never overwrites a human's change.
- Policy as data:
policy.yamlholds the classification, per-step agent privileges, gate rules and the review policy. - Service (FastAPI on Cloud Run): GitLab webhooks drive a durable state machine (queued → planning → developing → gating → testing → reviewing → merging → releasing → rewound/shipped/blocked) with step checkpoints, provenance, incidents, approvals and a credit guard. It also serves the dashboard and an MCP server, so agents can ask whether an action is undoable before they act.
- GitLab Duo Agent Platform: developer, code review, fix-pipeline and security-fix flows started via API with least-privilege
agent_privileges. Agent sessions are linked from a single ledger note on the issue. Custom flows and an agent definition are written for the AI Catalog. - GitLab: CI/CD with all scanners, Feature Flags (Unleash), Environments, Releases, Incident Management, the container registry, and the gate itself as a CI/CD component any project can include, no token needed.
- Google Cloud: Cloud Run for the service and the demo app (staging and production revisions are what Rewind rolls back), Cloud Storage for snapshots and ledgers, Artifact Registry, Secret Manager, and keyless CI deploys with Workload Identity Federation.
- Tests: 175 of them, including round-trip tests for every handler against in-memory fakes with real git-tree semantics. Property tests show that random sequences of agent actions followed by a rewind always return to the checkpoint. A live integration test runs against the real project.
Challenges I ran into
- There is no "un-merge." A restore is a new commit, so verification compares trees, not SHAs. Merged MRs and closed issues are compensated and checked handler by handler.
- Secrets can't be restored honestly. Rewind never stores CI/CD variable values, only a keyed HMAC fingerprint. So changing or deleting one is classified irreversible and gated, instead of pretending to roll it back.
- Review concerns on an undoable change. Unassigning the reviewer doesn't clear "requested changes" in GitLab. Rewind applies the override through GraphQL (
overrideRequestedChanges) for that one commit and records the reviewer's words on the MR. - A restore that reverted a human's later commit in rehearsal. Undo is now scoped to the run's own agent sessions, and a human commit on
mainstops the run instead of being reverted. - Tracking flows reliably.
client_referenceneeds a feature-flagged callback, so Rewind tracks workflow IDs in its own store and polls status via GraphQL. POSTs are never retried after a 5xx or timeout, because a retry could start a second agent. - Real-world flakiness: a runner rate limit (now retried, not rewound) and a release auto-cancelled by a newer push (now never cancelled).
Accomplishments that I'm proud of
- Fully hands-off runs on a real GitLab project and real Cloud Run: from label to production to verified rollback, with nobody clicking anything.
- Production mitigated in seconds: 18s in the filmed run, 13s at best, with zero drift verified against the checkpoint.
- An agent that read the policy. Asked to email receipts, the developer agent queued them in an outbox instead ("a separate, approved dispatcher drains the outbox, so this code stays undoable"), and the change shipped. When an agent did write the direct call, the gate blocked it on the exact line.
- All nine DevSecOps stages with evidence for each, and a gate any GitLab project can adopt with one
include:.
What I learned
- Reversibility is a better autonomy dial than approval levels. Most agent work is undoable, so most of it can ship without a human.
- Trust is asymmetric. Undoing should be cheap to authorize (a comment). Accepting the irreversible should be expensive (a named person, one commit). Agents comment with your identity, so a comment can never count as an approval.
- Keep the rules out of the prompt. Agents told a business rule simply followed it; Rewind exists for the mistakes nobody anticipated. The checks live in the policy and in production monitoring, where agents can't talk their way past them.
- Fail closed. Unknown change kinds and anything without a baseline count as irreversible.
What's next for Rewind
- Publish the gate in the GitLab CI/CD Catalog, and the custom flows and agent in the AI Catalog with triggers.
- More handlers: database migrations with verified downgrades, Kubernetes, Terraform-managed infrastructure.
- Change sets that span several projects, for agents working across services.
- Per-team policies, and an MCP tool so any agent, in any IDE, can check reversibility before it acts.
Built With
- artifact-registry
- docker
- fastapi
- gitlab
- gitlab-ci
- gitlab-duo
- gitlab-duo-agent-platform
- google-cloud
- google-cloud-run
- graphql
- httpx
- jinja
- mcp
- pydantic
- pytest
- python
- rest-api
- secret-manager
- unleash
- uvicorn
- workload-identity-federation
Log in or sign up for Devpost to join the conversation.