I just finished reading David Anderson's Kanban book, and I've been reflecting on my own experiences with applying Agile on legacy applications, and dealing with work that didn't fit nicely into predictive time boxes.
The assumption when fixing the timeline is that scope should be variable. But often dropping scope if the work is already started, isn't really an option. Using feature branches to not add work until its ready flies in the face of continuous integration - delaying defect discovery and increasing its cost, adding additional merging work and preventing refactoring. Feature toggles can be prohibitively expensive, unfeasible or too high risk to implement. Sometimes even changing one line of code can be so high risk that it requires a month of effort in regression testing or test repair, or causes a discovery avalanche of unplanned work. You can't always break work down or drop scope.
In order to release the software, the set of work done that's planned for release has to be in a finished release-ready state. David suggests the delivery timeline should be fixed, and decoupled from the work pipeline. Although I think efforts can be made toward that goal, because of the release requirement to have a synchronized 'done' event in the software system, they are by nature, coupled. Since new work can affect existing work, something that was done yesterday, may not be done anymore with even a small change in code. Work items are naturally inter-tangled. Regression testing on legacy applications is usually expensive, and thus commonly batched to cover multiple work items. And although the cost of 'release-readiness' can be greatly reduced through automation and defect prevention mechanisms, most existing projects are still quite a ways from this not being expensive. Is it really practical to expect a legacy application to be release-ready by a fixed date without coupled control over the flow of work itself?
If you limit your WIP, at any given moment, you can finish up all work reasonably soon, because you never start too much. I would think the practical way to deal with the fixed delivery date, start a set of work, and at some point later (possibly immediately), let all WIP drain from the system and reach completion. Batch any expensive 'release readiness' tasks such as regression testing as it makes sense given the current cost, and prepare a release ready product. If it's important to be able to hit a fixed timeline in order to build trust and predictability with users, sit on the release until the release date, and keep going with the next release. Otherwise, you can ship them when you have them done, and let them be variable. Your fixed release schedule could be adequately buffered to accommodate the variability of the size of work items.
But there is something to be said for work iterations. It creates cadence and routine, a time for reflecting, adjustment, a trial time period for experimenting, a pressure to minimize, and a time to finish a team's work - a synchronization point. But big pieces of work that don't fit in a sprint shouldn't be skewed to be something other than what they are. Work that is partially done and incomplete, should be visible as exactly that. And since this is where I think Kanban shines, I think adding a signal component to the process makes a lot of sense.
Represent large work (that can't be broken down) as an epic in which the parts aren't required to be useful, integrated with one another, or finalized. Break the work down into parts that can be added to the system without breaking it, and ideally without breaking shipability. At the least, aim for a committable set of work that won't interfere with other development, and that is as near as possible to what it's final form will be. Strive to order work items such that important discoveries will be made as early as possible. And the signal part... limit the number of these epic items allowed to be in progress. If you need to release, the signal process will prevent you from going too far off the tracks. Worst case, you'll need to finish up the started epics in order to ship. Best case, you can ship with partially done work. You can stay continuously integrated, and can schedule the work parts in sprints relative to the priority of the epic when it first starts.