Auto Progress Updates, Done Right
Every schedule has to be statused. Every cycle, somebody sits down with the site records and works through the same questions: what started, what finished, what's left on everything in between. It is repetitive, rule-bound work, and it is exactly the kind of thing a computer should help with — which is why P6 has had an "auto-update" capability for decades.
It is also why one of the first things an experienced planner tells a new one is: never press it.
That advice is not superstition. P6's Update Progress genuinely corrupts schedules, for a reason worth understanding precisely — and Oracle's own answer in Primavera Cloud was not to fix it but to delete it. Between "a button that rewrites your actuals" and "no button at all", the industry never actually got the feature it wanted. This post is about why, and about the three rules that make it safe.
What Update Progress actually does
The idea is reasonable. You advance the data date, and P6 progresses every activity in the window as if it went to plan: anything that should have started gets an actual start, anything that should have finished gets an actual finish, and anything in between gets its remaining duration wound down. Status the exceptions by hand, let the machine do the rest.
The problem is a single design decision: the dates it copies into your actuals are not the schedule's current forecast. They come from a pair of fields called Planned Start and Planned Finish— and those fields have a property most P6 users have never been told about.
Planned Dates are not a plan
While an activity has not started, its Planned Dates quietly track the live scheduled dates — every reschedule moves them. The moment the activity is marked started, they unlink and freeze, permanently. From then on they hold whatever the forecast happened to be just before work began: not the baseline, not the current forecast, a fossil.
Think about what that means for the data. The frozen value depends on when the activity was statused relative to the last reschedule — which makes it a property of your update cadence, not of the project. Take two copies of the identical job, status one weekly and one quarterly, and they end up with permanently different Planned Dates: each a patchwork of forecast vintages, frozen activity by activity at moments nobody chose, describing a "plan" that never existed at any single point in time. Nobody agreed to it, and nothing can reproduce it.
The maddening part is that scheduling already has the right construct for "the plan as agreed at a point in time". It is called a baseline: whole-project, snapshotted at a recorded moment, immutable, and you can keep several. Planned Dates are a per-activity micro-baseline taken at a thousand uncontrolled moments — the same idea, implemented as a cache with no invalidation.
The corruption, step by step
Now put the two halves together, because Update Progress copies those fossils unconditionally — including over actuals you entered by hand.
Cycle one: an activity starts late; you status it honestly from site records. Real actual start, slow progress, the forecast finish pushed out to the 20th. Its Planned Finish froze earlier, at the 15th. Cycle two: a colleague runs Update Progress to move the data date to the 22nd, expecting it to touch only the unstatused work. The rule fires: Planned Finish is before the new data date, so the activity is given an actual finish of the 15th. It is now recorded as complete, on a date on which it demonstrably was not, and the honest status you entered last cycle is gone. Nothing warns you. The schedule recalculates cleanly and the fabrication surfaces months later, when the recorded actuals contradict the site diary — usually in a claim.
The sibling feature, Apply Actuals, does the same thing to activities flagged for auto-compute — and Oracle's documentation states plainly that it overwrites timesheet-reported actuals too. The folk remedies planners pass around (a Global Change forcing Planned Dates equal to current dates before every run; or simply the advice never to press the button) are the community routing around a data model, and the first one silently shifts your duration percent completes as a side effect. Forget it once and the trap is re-armed.
OPC's answer: don't
Oracle Primavera Cloud is Oracle's clean-slate rewrite, so it is telling what they did with this feature: they removed it. There is no Update Progress in OPC, no Apply Actuals, no auto-compute. Advancing the data date is a plain field edit, and the scheduler only re-times the remaining work — unstatused activities slide forward; nothing ever fabricates an actual. Progress Spotlight still exists, but it only highlights the activities in the update window so a human knows what to status. By hand. Every one.
As an engineering call, I respect it — they kept the planned-date fields for familiarity but made them inert, so the P6 trap structurally cannot happen. But it concedes the original problem. Statusing a thousand-activity programme every cycle is still repetitive, rule-bound work, and OPC's position amounts to: the safe version was too hard, so you get the manual version. If you want bulk statusing in OPC you are writing your own scripts against the REST API, and now the safety rules are your problem.
The three rules P6 should have shipped
The frustrating thing is that the safe version is not conceptually hard. Three rules eliminate the trap while keeping everything that made the feature worth having:
- Derive, never cache. Every inferred value comes from the live forecast at the moment of the update — the dates the CPM engine believes right now — never from a stored copy with freeze-on-event semantics. If there is no fossil field, there is no fossil to resurrect.
- Never overwrite what a person entered. Actuals a user recorded are facts, and the machine does not get to edit facts. The gate is per-field, not per-activity: a started activity keeps its real actual start while its remaining duration still advances every cycle.
- Track who wrote what.Values the machine inferred are marked as inferred, so a re-run can freely recompute them — wrong data date, changed scope, run it again and it converges instead of enshrining its own first guess. That is what makes the operation idempotent, and it is the distinction P6's data model cannot express: it protects nothing because it cannot tell a person's entry from its own.
Do all three and the whole update becomes one consistent, repeatable operation: preview it as a diff, apply it as a single named transaction, undo it as a unit.
What this looks like in Planlab
This is how Planlab's agent now does progress updates. You hand it whatever you actually have — a pasted table, the site Excel, or just "A1050 is 60% done and A1060 finished Tuesday" — and the statusing itself runs through one deterministic operation built on those three rules. The agent's job is to establish the status date, parse your records, and show you the result; the rules are not left to its judgement, or yours.
Three modes cover the decisions that actually matter:
- Full — classic statusing. Reported activities take their updates, everything else is assumed not to have progressed, and the data date moves: unreported work reschedules beyond it and the slippage becomes visible. The agent lists the activities that should have been underway but got no update before you commit — that list is a finding, not a footnote.
- Auto — the P6 promise, kept safely. Unreported activities are statused from their live scheduled dates, never from a frozen copy, never over an existing actual.
- Partial — the mode the legacy tools never had. Only the activities you have data for are statused, each stamped with its own per-activity data date, and the project data date does not move. The rest of the schedule — dates, logic, the model you have been building all year — stays exactly as it is. Weekly site data for one area no longer forces a whole-programme update, and a later full update reconciles cleanly because every override is recorded.
And when your data disagrees with the record — a 0% report against an activity with a user-entered actual start — the operation refuses that row and the agent brings you the conflict instead of silently picking a winner. Every update previews as a diff against the live schedule before anything commits, and commits as one named transaction you can undo.
Statusing is the one thing every schedule on every project needs every single cycle. It deserved better than a button nobody dares press and a product that gave up on it. If your update cycle still involves either of those, get in touch — this is exactly the work the agent is for.

