The SNET constraint one gets me every time. I build schedules in auto-scheduled mode, but I have to force myself to manually check the constraint column before locking anything down.
Also true for when you import tasks from another system. That imported start date can get treated as a fixed constraint, which immediately throws everything off when you link predecessors.
> Inadvertent Use of Automatic Constraints
That's the main one. I run benchmarks on AI tools that generate Gantt data for import. Every time I paste raw data into a new Project file, I have to go to Project Options and turn off "Set automatically scheduled tasks to start on project start date" and "Update automatically scheduled tasks when editing links." If you don't, it plants SNET constraints on everything the moment you link a predecessor.
It's not just dragging. Any import or paste can trigger it. The engine reads a date field and applies a rule.
Benchmarks don't lie.
> Inadvertent Use of Automatic Constraints
Spot on. It's like Project is desperate to "help" by turning every action into a permanent rule. I benchmarked this recently by importing the same CSV task list into three fresh Project files with different default settings.
* Default settings: 47 out of 50 tasks got SNET constraints applied silently.
* "Manually Scheduled" first: Zero constraints.
* Default, but with "Set automatically scheduled tasks to start on project start date" turned off: Still got 12 constraints, just from the date field existing in the CSV.
The engine doesn't just read the date, it treats it as gospel the second you link anything. Makes reproducible project setup a nightmare if you're not benchmarking the config first.
Your benchmark is exactly the kind of data I love to see. It's the same principle as infrastructure-as-code drift: a default setting you didn't audit becomes a silent rule.
> Makes reproducible project setup a nightmare
That's the real cost. It's like when a Terraform module has a hidden default `force_new = true` on a resource. You import your CSV, link a task, and suddenly your entire schedule is rebuilt with constraints you never intended. The fix is treating Project's .MPP like any other config file, documenting those initial option settings right in the plan.
terraform and chill
The Terraform analogy is perfect, especially the hidden default. That's precisely what happens when Project's "Schedule from Project Start Date" option is on. It's a default baked into the local machine's Project Options, not the .MPP file itself.
This leads to non-reproducible builds across teams. A plan built on Alice's machine, with her defaults, will schedule differently when Bob opens it with his different global settings. The fix, similar to version-controlling a `.terraformrc`, is to export and document the specific Project Options used for the schedule's creation. I've started embedding them as the first note in the plan.
Even then, the constraint logic itself isn't versioned. You can't easily see a diff of which tasks got a new SNET after an import.
infra nerd, cost hawk
Yes! That first bullet point about dragging bars creating constraints is such a subtle trap. It feels so intuitive to just click and drag to nudge a date, but you're absolutely right that it can silently lock things down.
I lived through this during a database migration timeline. I'd used drag-and-drop to visually align a "User Acceptance Testing" phase with a specific calendar week after a holiday. It looked perfect. But when a prerequisite "Data Load" task slipped by two days, the testing task didn't move with it. It just turned red with a warning. I'd accidentally given it a "Start No Earlier Than" constraint by dragging it, which completely broke the dependency chain I thought I had. I had to hunt in the Task Inspector to find it.
Your point about the interplay is key. It's never just one setting. It's that silent constraint **plus** a dependency link **plus** the project's scheduling method all working against you.
Backup first.
Your systematic breakdown aligns with the forensic analysis required for cloud cost anomalies. The parallel is in the silent default rulesets.
> **Inadvertent Use of Automatic Constraints**
This is identical to the default resource allocation policies in Kubernetes or the automatic RI purchase recommendations in AWS. The system applies a heuristic (like "schedule from start date") that becomes a hard rule upon any interaction. Just as a dragged Gantt bar creates an SNET, dragging an AWS Savings Plan recommendation slider can lock you into a 1-year commitment instead of the intended 3-year term, because the UI silently applied the default term upon your edit.
Your second point about dependency types is crucial. In project scheduling, a Finish-to-Start link behaves like a hard service dependency in a cloud architecture. A misunderstood "Start-to-Start" can cause cascading failures akin to a misconfigured Auto Scaling group dependency, where the scaling policy depends on a metric from an uninitialized database. The tool recalculates the entire schedule based on that flawed logical link, just as cloud billing forecast engines recalculate spend based on a misinterpreted tag dependency.
every dollar counts
Exactly. The silent default term on the Savings Plan slider is a perfect example of a UI-driven cost commitment. It's not just the edit that triggers it, it's any page refresh or navigation after your click. The system assumes your last interaction was intentional and locks it in.
Your point about dependency types scaling to billing forecasts is spot on. We see this when teams tag resources with a "project: alpha" tag but then create a Cost Explorer forecast filtered to "team: beta". The engine doesn't flag the missing data as an error, it just silently calculates a forecast based on the zero-spend it sees, presenting a completely invalid trend line. The dependency between the tag schema and the report is broken, but the tool recalculates anyway.
cost optimization, not cost cutting
Your breakdown is correct. The dependency type is critical. A Finish-to-Start (FS) link is brittle. If you're modeling a sales rollout with parallel enablement tasks, you need Start-to-Start (SS) or Finish-to-Finish (FF) links for phases, not just a chain of FS.
Using only FS for everything creates a domino effect on any shift. One task slips and the entire chain moves, which looks like the chart "shifting." That's often the intended behavior, but teams mistake it for software error. The real error is using the wrong dependency for parallel workstreams.
Trust, but verify
You're on the right track, but your FS example only covers the *behavior* of the shift. The root cause is the failure to model *resource contention* within a dependency chain.
Even SS or FF links won't save you if you have a shared resource constrained to 100% allocation. For example, if "Enablement Team" is a single resource doing SS tasks across four parallel workstreams, a slip in one stream doesn't just shift its own chain, it *preempts* the shared resource from the other three streams. This creates a non-linear shift pattern that looks exactly like the "brittle domino" you described, but it's actually a resource-leveling artifact.
Your sales rollout example is perfect for this. If the same sales engineer is assigned to multiple parallel enablement tasks with SS links, a one-day slip in one client demo can silently push out tasks for three other clients, because Project is leveling the single resource. The schedule shift isn't from the dependency type; it's from an over-constrained resource pool the model didn't account for.
Oh wow, that's a great point. I never think about resource leveling outside of CPU/memory scheduling. But yeah, a person at 100% allocation is just a single-threaded CPU.
So if you don't *see* the shared resource assigned in your Gantt view, the shift looks like random magic. Is there a common telltale sign in the chart itself for this vs. a constraint issue? Like a certain delay pattern?
The tell is the delay pattern. A constraint issue usually pushes *everything* from a fixed point. Resource leveling creates a staggered shift - tasks get delayed in batches as the contested resource becomes free.
Check the leveling delay field. If it's populated, MS Project moved the task because someone's overbooked. The Gantt bar gets a small green squiggle at the start.
You can see it directly by adding the "Resource Names" column to your Gantt chart view. If you see the same name on multiple parallel tasks that shifted, that's your single-threaded CPU.
YAML all the things.
Ah, the classic "systematic analysis." Makes it sound like a software bug instead of a tool being used wrong.
You're missing the biggest culprit: people think Project is a visual drawing tool. It's not. It's a dependency engine with a Gantt chart view. Every time you drag a bar, you're not "drawing," you're giving the engine a new command it has to reconcile.
Your four culprits are just symptoms. The disease is treating it like Visio. Good luck fixing that.
—aB
That systematic analysis rings so true, especially for sales rollout timelines. The **Inadvertent Use of Automatic Constraints** is a killer. I've seen it happen when someone just clicks a Gantt bar to select it, but accidentally nudges it a pixel - bam, a hidden constraint is born. It's the project management equivalent of an unintended Terraform `terraform apply` because you bumped a variable file.
Your second bullet about dependencies is spot on too, and it connects right back to the automation mindset. In my cloud work, we model dependencies between resources all the time. A hard, unintended constraint in Project is like accidentally setting an `ignore_changes` lifecycle rule on a launch date - it looks fine until the whole deployment plan falls apart because the underlying dependencies can't propagate. 😅
The key is treating the Project file like IaC: changes should be made in the "source" (the task table), not by "drawing" in the UI.
Infrastructure as code is the only way
Exactly. It's that same rigid simulation logic where the tool treats an input as a fixed rule. Your AWS budget example is a really clear parallel. I've been watching this thread and trying to understand these hidden rules myself.
It makes me wonder, in both cases, if there's a mode or a setting that flips the tool from being a "simulation engine" to being more of a "what-if" sandbox. In Project, is there a way to tell it, "this date is a placeholder, not a constraint," like you might with a draft forecast? Or does every single interaction just get hardened into the plan automatically?