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.

Real upstream project

marshmallow’s own code, tests and release tags.

!1 merged on main Fix handling data_key in ValidationErrors raised in schema validators

  1. release/3.25fails beforepasses afterProven, adaptedv3.25.2
  2. release/3.23fails beforepasses afterProven, adaptedv3.23.4
  3. release/3.21fails beforepasses afterProven, adaptedv3.21.4
  • 3 branches
  • 3 proven

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

Open a row to see each step.

release/3.25Bug reproducedFixed in v3.25.21223/1223Proven, adapted
  1. Probe
    Bug reproduced AssertionError: assert {'fooKey': ['..._schema str']} == {'fooKey': ['...schema dict']} CI re-probe
  2. Pick
    Fix adapted to this branch: src/marshmallow/decorators.py, src/marshmallow/schema.py, src/marshmallow/types.py, tests/test_decorators.py, CHANGELOG.rst
  3. Adapt

    Resolved conflicts: dropped 3.26 changelog/RenderModule/noqa bits, kept SchemaValidator protocol type and used ma_fields.Field annotation; fix logic unchanged.

    Integrity check: unchanged, test unchanged.

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

    Compare on GitLab: the fix, !1 and the port, !2.

  4. Judge

    Final judge: proven-adapted, existing tests 1223/1223

    Attempts and their feedback: not recorded (this proof note predates that record).

  5. CI checks

    !2, pipeline 2986621297

    • 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/3.23Bug reproducedFixed in v3.23.41231/1231Proven, adapted
  1. Probe
    Bug reproduced AssertionError: assert {'fooKey': ['..._schema str']} == {'fooKey': ['...schema dict']} CI re-probe
  2. Pick
    Fix adapted to this branch: src/marshmallow/decorators.py, src/marshmallow/schema.py, src/marshmallow/types.py, tests/test_decorators.py, CHANGELOG.rst
  3. Adapt

    Resolved conflicts: dropped unrelated 3.26 changelog/RenderModule/noqa bits, kept SchemaValidator protocol type, added 3.23.4 changelog entry; fix logic unchanged.

    Integrity check: unchanged, test unchanged.

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

    Compare on GitLab: the fix, !1 and the port, !3.

  4. Judge

    Final judge: proven-adapted, existing tests 1231/1231

    Attempts and their feedback: not recorded (this proof note predates that record).

  5. CI checks

    !3, pipeline 2986621627

    • 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/3.21Bug reproducedFixed in v3.21.41229/1229Proven, adapted
  1. Probe
    Bug reproduced AssertionError: assert {'fooKey': ['..._schema str']} == {'fooKey': ['...schema dict']} CI re-probe
  2. Pick
    Fix adapted to this branch: src/marshmallow/decorators.py, src/marshmallow/schema.py, src/marshmallow/types.py, tests/test_decorators.py, CHANGELOG.rst
  3. Adapt

    Resolved conflicts: kept 3.21's decorators imports (no defaultdict), dropped unrelated 3.26 changelog/RenderModule/noqa bits, kept SchemaValidator protocol type, added 3.21.4 changelog entry.

    Integrity check: unchanged, test unchanged.

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

    Compare on GitLab: the fix, !1 and the port, !4.

  4. Judge

    Final judge: proven-adapted, existing tests 1229/1229

    Attempts and their feedback: not recorded (this proof note predates that record).

  5. CI checks

    !4, pipeline 2986621984

    • 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
  • Proven, adapted: the agent changed code for this branch; the same test proved it
  • Bug reproduced: the test fails without the fix
  • Fixed: the test passes after the backport

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