DuoBack

Every backport, proven by the bug’s own test

Merge a bug fix once. A GitLab Duo agent carries it to every release branch you name. A script, not the model, accepts each backport only if the fix’s regression test fails before it, passes after it, and nothing that passed before breaks.

Staged demo

History staged by a script so every outcome appears.

!50 merged on main security: reject upload names that escape the root

  1. release/1.2fails beforepasses afterProvenv1.2.4
  2. release/1.1fails beforepasses afterProven, adaptedv1.1.8
  3. release/1.0cannot run hereRefused
  4. release/0.9passes without the fixSkipped
  • 4 branches
  • 2 proven
  • 1 refused
  • 1 skipped

The proofLive from gitlab-ai-hackathon/transcend-october-2026/38599834/showcase

Open a row to see each step or the flow run.

release/1.2Bug reproducedFixed in v1.2.412/12Proven
  1. Probe
    Bug reproduced Failed: DID NOT RAISE ValueError CI re-probe
  2. Pick
    Clean cherry-pick
  3. Judge
  4. CI checks

    !51, pipeline 2993794982

    • bp:repro Bug reproduced before backport (expected) success
    • bp:verify Regression test passes, existing tests still pass success
    • bp:integrity Test unchanged or a valid mechanical port success
    • SAST Static analysis of the backport success
    • Secret detection No secrets in the backport success
  5. Release
release/1.1Bug reproducedFixed in v1.1.811/11Proven, adapted
  1. Probe
    Bug reproduced Failed: DID NOT RAISE ValueError CI re-probe
  2. Pick
    Cherry-pick conflicted in: src/core/paths.py
  3. Adapt

    Kept upload_path_for name and its leading-slash stripping.

    The agent’s full note

    Kept upload_path_for name and its leading-slash stripping; added realpath/commonpath ValueError traversal check from the fix; ported test renamed resolve_upload_path->upload_path_for.

    Integrity check: valid port, with resolve_upload_path → upload_path_for renamed in the test.

    What the agent changed: the fix as merged on main, and its port to this branch

    Compare on GitLab: the fix, !50 and the port, !52.

  4. Judge
  5. CI checks

    !52, pipeline 2993795683

    • bp:repro Bug reproduced before backport (expected) success
    • bp:verify Regression test passes, existing tests still pass success
    • bp:integrity Test unchanged or a valid mechanical port success
    • SAST Static analysis of the backport success
    • Secret detection No secrets in the backport success
  6. Release
release/1.0Test cannot run hereNo backport—Refused

Refused on purpose. No core.paths or path-resolving function exists on 1.0 (logic is inline in UploadStore.__init__); test would need to construct UploadStore instead, changing what it checks.

  1. Probe
    Test cannot run here flow run
  2. Backport
    Not attempted: nothing was cherry-picked or opened.
release/0.9Not affectedNo backport—Skipped

Not affected. bug not present (introducing commit 1ca73c66 not on this branch)

  1. Probe
    Bug not present test passes unpatched flow run
  2. Backport
    Not attempted: nothing was cherry-picked or opened.
  • Proven: the fix applied as is and its test proved it
  • Proven, adapted: the agent changed code for this branch; the same test proved it
  • Refused: the test cannot run here, so no backport was opened
  • Skipped: the bug isn't on this branch
  • Bug reproduced: the test fails without the fix
  • Fixed: the test passes after the backport
  • Not affected: the test passes without the fix
  • Test cannot run here: the regression test cannot load on this branch

Why you can trust it

  1. The agent proposesA Duo agent cherry-picks the fix and adapts code where the branch differs.
  2. bp judge decidesA script with no LLM runs the test before and after, and every test that passed before.
  3. CI re-proves itThe backport MR’s own pipeline runs the same checks again from a clean checkout.

Seven rules hold every time. Open one to see the code that enforces it and the test that checks it.

Check your repoThis page reads results from GitLab. It does not run backports.

Try the real-code test: marshmallow-backports.

To install DuoBack on a project:

  1. Enable the DuoBack flow from the AI Catalog.
  2. Add a Pipeline-events trigger: status success, default branch, source push or merge request.
  3. Include ci/backport.yml from the DuoBack project in your .gitlab-ci.yml.
  4. Merge fixes with Backport-to:, Fixes: and Bp-Test: lines in the commit message.

For judges

  • Plan Proof table on the fix MR
  • Create Backport MR opened by the flow
  • Verify bp:repro, bp:verify, bp:integrity
  • Package Each release uploaded to the package registry
  • Secure SAST and secret detection on every backport
  • Release Patch tag and GitLab Release from CI
  • Configure Flow, trigger and CI template
  • Monitor Coverage issue refreshed on every main pipeline
  • Govern Human approval on adapted backports, CODEOWNERS

How it differs

Honest limits