Skip to content

date: 2026-06-18 tags: [ci, merge-order, regression, branch-protection] status: active graduated_to:

Two independently-green PRs can combine to break main — neither re-ran against the merge

SymptomGetTaskContextToolTest was green on its own PR (#573) and stayed green when the CarbonImmutable date migration (#571/#572) was green on its PR — but once both merged, get_task_context rendered Due: 2026-07-01 00:00:00 on main and the test failed.

Root cause — the two PRs were each tested against a main that did not contain the other. The date migration turned TaskDue::date from a string into a CarbonImmutable; the handoff tool read $task->due->date directly. Whichever PR merged second was never re-tested against the first, so the broken combination shipped to main with two green CI histories. GitHub does not re-run a PR's CI when its base branch advances unless branch protection requires the branch to be up to date.

Fixapp/Mcp/Tools/GetTaskContextTool.php:45 now renders $task->due?->date->toDateString() (commit abef9a4). The deeper fix is process, not code.

Guard — enable branch-protection "Require branches to be up to date before merging" so the second PR must rebase onto the first and re-run CI against the real combination; or rebase a PR onto latest main before merging when another PR touching the same surface has landed. The nightly full-suite run on main is the backstop that detects it after the fact, not before.