Almost every scheduling model in common use encodes the same assumption: a dependency has a duration. Task B starts after task A finishes, A takes eleven days, therefore B starts on day twelve. Gantt charts, critical path calculations and most project schemas are built on it.
Property development violates this assumption at the most important points in the plan, and the violation is not an edge case — it is the normal condition.
The problem statement
You cannot pour foundations until permits clear. Permits do not take a number of days. They take however long a planning authority takes, which is unknown, unbounded and outside your control.
Encoding that as a duration produces a schedule that is wrong on the day it is created. Teams then maintain the real plan elsewhere, which is why every development business runs a spreadsheet alongside its platform.
What is needed is a dependency that resolves on an event rather than elapsing over a period:
Dependency {
successor: MilestoneId
trigger: EventCondition // not Duration
estimate: ProbabilisticRange? // planning only, never authoritative
}
EventCondition =
| ApprovalGranted(gateId)
| DocumentReceived(docType, fromParty)
| InspectionPassed(inspectionType)
| ConditionEvidenced(conditionId)
| AllOf(EventCondition[])
The critical design rule is that estimate is advisory and never drives state. Downstream milestones move when the event fires, not when the estimate expires. Once you allow an estimate to transition state, you have reintroduced the durations model with extra steps, and the schedule starts lying again.
Stage gates as entities, not statuses
The second modelling error is representing stage gates as a status enum on the project. Gates carry too much to be a field.
StageGate {
id, assetId, projectId
type: Acquisition | Entitlement | Construction | Leasing | Disposition
conditions: Condition[]
approvals: Approval[] // immutable, append-only
evidence: DocumentRef[]
}
Approval {
approver, role, authorityRef // delegation as data
decidedAt, decision, comment
supersededBy: ApprovalId? // corrections append, never edit
}
Two properties matter and both come from the audit requirement rather than the UI.
Approvals must be immutable and append-only. The question an auditor or lender asks is not what the current state is but what was approved at a specific past moment, and by whom. If approvals can be edited in place you cannot answer that.
Delegation of authority has to be data rather than convention, so the system can determine whether a given approval was valid at the time it was given. A signature from someone who had exceeded their limit two weeks earlier is a finding, and it is only detectable if authority is modelled.
One commitment, three projections
The change that removes the most manual work: stop storing cost, schedule and capital draw as separate records.
They are one commitment observed from three angles. A change order alters the budget, moves the programme and shifts the drawdown simultaneously. Modelling them independently guarantees a permanent reconciliation job.
Commitment {
id, assetId, projectId
counterparty
costImpact: Money
scheduleImpact: Duration | EventShift
drawImpact: DrawSchedule
status, evidence: DocumentRef[]
}
Cost reports, programme views and draw requests all become projections over the commitment stream. A change order is one write, and all three views update. This is not an optimisation — it eliminates a whole class of inconsistency that no amount of process discipline can prevent.
Ownership as a first-class dimension
A single project frequently belongs to a joint venture whose reporting structure does not match your internal one. If ownership is a field on the project, the usual response is to duplicate projects per reporting view, and the duplicates diverge within a quarter.
Model entity and ownership structure explicitly, and make reports parameterised by reporting perspective over one underlying dataset. The same project then serves an internal committee and a JV partner without duplication.
The related warning: reporting dimensions have to exist in the model from the start. Retrofitting a dimension — jurisdiction, capital source, asset class — into a live system is among the most expensive changes in this domain, and it is the one most frequently needed in year two.
Where the AI layer fits
Given this model, the highest-value application is unambiguous and unglamorous: document extraction populating Commitment, Condition and Evidence records from contracts, change orders and inspection reports.
The reason it fits so well is that the model gives extraction a target schema. Unstructured extraction with no destination produces a pile of facts nobody can use. Extraction into Commitment with human verification on each record produces a system that stays current at a cost that makes sense.
Build this before anything more ambitious. Variance detection — spotting that a pattern of small subcontractor slippages predicts a schedule break — needs history in a consistent shape, which you will not have until extraction has been running for a while. Building the intelligence layer over sparse, inconsistent data produces confident nonsense, and the credibility cost is hard to recover.
Frequently Asked Questions
Why do duration-based dependencies fail in property development?
Because the critical dependencies resolve on events — permit approvals, inspections, document receipt — that have no predictable duration. Encoding them as durations produces a schedule that is wrong the day it is drawn.
How should conditional dependencies be modelled?
As a trigger expressed by an event condition rather than a duration, with any time estimate kept strictly advisory. If an estimate can transition state, the durations model has been reintroduced and the schedule will misrepresent reality again.
Why should stage gates be entities rather than status fields?
Because they carry conditions, approvals and evidence that auditors, lenders and partners require, and because approval history must be immutable and reconstructible at a past point in time.
Why model delegation of authority as data?
So the system can determine whether an approval was valid at the moment it was given. An approval from someone who had exceeded their authority is a finding, and it is undetectable if authority exists only as convention.
What does one commitment with three projections solve?
It removes the reconciliation between cost, schedule and capital draw by making them views over the same record. A change order becomes a single write updating all three, eliminating a class of inconsistency that process discipline cannot prevent.
Where should AI be applied first in this model?
Document extraction populating commitment, condition and evidence records, because the model supplies a target schema and human verification keeps accuracy acceptable. Variance detection should come later, once consistent history exists.
Full guide, including field capture, costs and build sequencing: Real Estate Project Management Software: The 2026 Build Guide
TechCirkle: custom software development | agentic workflow development

Top comments (0)