Back to Blog

Modelling un-interruptible activities

Felix HodsonLinkedIn
November 13, 2025
PlanningSchedulingP6Constraints
CalendarsWithout fixWith fixAprMayJunJulAugSepOctNovDecWorking TimeC1C2C3Shadow CalendarC4C5ShadowC6C7Allows starting too shortly before the holidayA3aA3bOk if started long before the holidayA1A2Ok if started after the holidayMilestone allowed long before holidayA4A5M4M5Milestone allowed after holiday

Context

While working on a project recently, there was a requirement to enforce a fairly simple rule around summer holiday (vacation..!) periods. The rule: you can't leave the deck of a motorway overpass "jacked up" when the work site closed for the summer (yes, this is a project in Europe, not the US!)

This is actually a tricky one to express in P6, or indeed generally any similar data model. You can easily stop activities from being active (use a calendar) but this won't prevent your activity starting before, and finishing after, the holiday.

Simple, but also a bit ugly

It's not hard to know if you're breaking the rule, and it's not hard to know what start-dates will result in the rule being broken. But - it is really not trivial to tell P6 this information (or actually, pretty much any scheduling software I can think of).

We are shipping a custom optimiser for the project, so we can build that rule right in without playing any magic tricks with the data model. There are tricks to be played - kinda simple, but also really messy and not that generalisable.

A worked example

Where we started

So you have summer holidays, lets say August is off. The "jacked deck" activities cannot "straddle" August - they must finish before it, or start after it. They also must respect the rest of the network logic.

The way we received the baseline schedule had a very manual way of doing it - just chuck an activity called "Summer holiday" in there, with a "float before the holidays" placeholder to put things in the right place, and linked into the network.

Sounds fine, but doesn't work when you change anything - make something earlier in the network longer, and your holiday moves. You have to manually adjust the "float activity" to keep it right. If the change is bigger than the float, you have to change the logic - move the activity to after the holiday.

Pretty manual, pretty slow, and really not something you want if you're exploring scenarios. Definitely won't allow any Monte Carlo or other kind of simulation - any change to any part of the schedule means checking this, and making manual edits.

(You can make it a little more robust with start-afters and stuff, but its at best "locally ok")

Initial version of the plan, with the summer holiday and the pre-holiday float included

Initial version of the plan, with the summer holiday and the pre-holiday float included

With Design taking 15 days longer, we need to change the network so that deck 4 is after the holiday

With Design taking 15 days longer, we need to change the network so that deck 4 is after the holiday

A (sort of) solution

The activity can be continuous on its calendar (this has no work-days during the holiday), but it will happily start before the holiday and finish after the holiday. Really what you want to do is control the start of the activity, so that it can't start "in the shadow" of the holidays. No starting if you're less than the activity duration away from the holiday.

CalendarsWithout fixWith fixAprMayJunJulAugSepOctNovDecWorking TimeC1C2C3Shadow CalendarC4C5ShadowC6C7Allows starting too shortly before the holidayA3aA3bOk if started long before the holidayA1A2Ok if started after the holidayMilestone allowed long before holidayA4A5M4M5Milestone allowed after holiday

Scheduling constraints for un-interruptible activities around a summer holiday period

Controlling the start can be achieved with a calendar - make a calendar that has the holiday, plus the "shadow" (add the activity duration ahead of the holiday). You can't put the whole activity on this calendar, or you'll not be able to do work in the "shadow" - this just removes a chunk of your working time.

If you chop the activity into 2 elements - its start date and its duration - then you can model it with the calendar. Create a start milestone on the shadow calendar, and the activity stays on the working calendar.

Insert the milestone ahead of the activity in the network and CPM will do what you want - never let the activity start in the "shadow", but it can progress if it was already started.

Updated network with the milestones added and assigned to the shadow calendar

Updated network with the milestones added and assigned to the "shadow" calendar

Design shortened to 5 days, and deck 4 is pulled in front of the holiday

Design shortened to 5 days, and deck 4 is pulled in front of the holiday

Design lengthened to 40 days, and deck 3 pushed out past the holidays

Design lengthened to 40 days, and deck 3 pushed out past the holidays

Now for the downside to this - you need a calendar for every "shadow" length; this could be a lot of calendars, depending on the number of activities that need the rule. You also need a milestone per activity, so can also be a lot of milestones.

There's one more downside that's a bit more subtle - this doesn't allow all changes to work. If you change the duration of a "Jacking deck" activity, then its shadow on the calendar will be the wrong length. You need to pair up duration and calendar changes.

This will make Monte Carlo tricky if you have risks attached to those activities. There might be an escape hatch by having a 100% correlated risk that impacts the shadow calendars as well. When we do MC at PlanLab we use the custom solver inside the simulator, so I've not wriggled all the way down that rabbit hole.

Other potential solutions

Anyone with a great creative way to solve this, would love to hear it! Ping me an email at felix@planlab.ai, or DM me on LinkedIn.