11 min read · 2,559 words
Project plans are built from the wrong material. The team collects user stories, estimates each one, stacks them into sprints, and calls it a schedule. User stories are units of value — they describe what the customer gets. They do not describe units of work. The actual work — the components, the integrations, the infrastructure, the dependencies — is invisible in the plan.
That invisibility is why estimates are routinely wrong. It is why dependencies are discovered mid-sprint rather than before work begins. It is why the critical path is debated in planning sessions instead of read directly from the work.
When the work is invisible, every plan is speculation.
Project Design, the fourth discipline of Harmonic Design, fixes this by deriving the project plan from the architecture. When a system is decomposed using Volatility-Based Decomposition, the architecture does not just produce a component model — it produces a work breakdown structure. The components are the work packages. The architectural dependencies are the schedule dependencies. The component roles determine estimation characteristics. The plan is not built from the architecture. It is the architecture, expressed in a different form.
The Core Triad: Who Plans the Project
Before any estimation begins, three perspectives must be present. Project Design calls them the core triad.
| Role | Owns | Agile Equivalent |
|---|---|---|
| Architect | System decomposition — components, dependencies, critical path, technical risk | Tech Lead |
| Project Manager | Resource allocation — availability, cost, organizational constraints, political feasibility | Scrum Master / Delivery Lead |
| Product Manager | Requirements prioritization — customer proxy, conflict resolution, stakeholder management | Product Owner |
The three roles operate together during what Project Design calls the fuzzy front end — the period between project inception and the commitment to a specific plan. This typically consumes fifteen to twenty-five percent of total project duration. During this period, only the core triad is staffed. Full team engagement begins after management commits to a plan.
This is not overhead. It is the mechanism by which the remaining seventy-five percent of the project is executed efficiently. Projects that skip the front end spend more total time and money than those that invest in it — because planning failures during execution cost more than planning itself.
Removing any one perspective from the triad produces predictable blind spots. Without the Architect, the plan lacks structural grounding — estimates are intuitive rather than derived. Without the Project Manager, the structurally correct plan cannot be executed against real organizational constraints. Without the Product Manager, the team builds what was designed rather than what is needed.
The core triad is not a committee. Each role has a distinct ownership boundary. The Architect recommends. The Project Manager translates. The Product Manager prioritizes. The roles must all be present, but they are not interchangeable — and the plan degrades predictably when any one of them is missing.
Activities, Dependencies, Estimates
Every project plan contains three elements: what you are building (activities), what must exist before you can build it (dependencies), and how long it will take (estimates). Project Design derives all three from the architecture rather than constructing them from requirements.
| Element | Conventional Source | Architecture-Derived Source |
|---|---|---|
| Activities | User stories, epics, feature tickets | One work package per VBD component, with defined responsibilities and a clear definition of done |
| Dependencies | Discovered during development or inferred in planning sessions | Encoded in the component model — if Manager A calls Engine B, then Engine B must be interface-stable before Manager A integrates |
| Estimates | Attached to user stories, derived from intuition and experience | Attached to work packages with defined scope — estimable from component role and responsibility, not from intuition alone |
None of these elements require a separate planning process. They emerge from decomposition. When the architecture is right, the plan is already there.
Work Packages from Component Roles
Each VBD component role generates a distinct type of work package with predictable characteristics — predictable because the role defines what the component does and what it depends on.
| Role | Work Package Type | Can Start | Completion Signal |
|---|---|---|---|
| Utility | Shared infrastructure | Day one — no application dependencies | Unit tests pass; multiple consumers verified |
| Engine | Core logic | Day one — no external dependencies | Unit tests pass; no infrastructure required |
| Resource Accessor | Boundary work | After domain model stabilizes | Translation tested; external integration verified against contract |
| Manager | Integration milestone | After dependent Engines and Accessors are ready | End-to-end slice works; integration tests pass across all seams |
An Engine encapsulates business logic with no workflow awareness and no external dependencies. Its work package begins immediately, runs in parallel with everything else, and is done when unit tests pass. No integration required.
A Resource Accessor isolates interaction with an external system. Its work package depends on the domain model being defined — and on the external system being accessible or stubbed — but nothing else. It is complete when the translation logic is tested and the external integration is verified.
A Manager coordinates workflow without executing business logic. Its work package is an integration milestone — it cannot be fully exercised until its Engines and Resource Accessors are ready. Manager completion is the moment when a vertical slice of the system works end to end.
A Utility provides shared capability. It has no application dependencies, should be completed early, and is typically small. Multiple components may depend on it — which is precisely why it goes first.
What a Well-Managed Project Gets Wrong
Many teams produce something like this. They are not running ad-hoc projects. They have ceremonies, a groomed backlog, refined user stories with acceptance criteria, and two-week sprints with proper velocity tracking.
The structure is defensible. This is what careful, experienced delivery looks like.
flowchart TB
classDef story fill:#e8f0fe,color:#1a73e8,stroke:#4285f4,stroke-width:1px
classDef warn fill:#fff3e0,color:#e65100,stroke:#fb8c00,stroke-width:1px
classDef blocked fill:#fce8e6,color:#c62828,stroke:#d93025,stroke-width:2px
subgraph S1["Sprint 1"]
PO["Place Order — 8 pts"]:::story
CO["Cancel Order — 5 pts"]:::story
OH["Order History — 3 pts"]:::story
end
subgraph S2["Sprint 2"]
PI["Payment Integration — 13 pts"]:::story
EN["Email Notifications — 5 pts"]:::story
IC["Inventory Check — 5 pts"]:::story
end
subgraph S3["Sprint 3"]
FC["Fraud Checking — ? pts"]:::warn
RP["Refund Processing — 8 pts"]:::story
BL["Sprint 2 dep — BLOCKED"]:::blocked
end
The stories are coherent from a product perspective. “Place Order” is a genuine unit of value. “Payment Integration” is a genuine concern. “Fraud Checking” is a real requirement.
But nothing in this structure reveals what the actual implementation involves. “Place Order” touches pricing logic, validation rules, inventory checks, payment coordination, and notification dispatch. These are distinct concerns, some of which can run in parallel and some of which cannot. The story hides that structure entirely.
When Sprint 3 hits a dependency on Sprint 2 work that was not finished — and it will — the plan does not explain why. The dependency was there from the beginning. It was embedded in the code before anyone saw it in the plan.
The sprint model is not broken. The stories are not wrong. But the abstraction was built on the wrong axis.
Story-based planning asks: what value does this deliver? Project Design asks: what forces this to change, and what does it depend on? These are different questions, and they produce different plans.
The Same Project, Architecture-Derived
Under Project Design, the same system is planned differently. The component model produces the project network. Each edge is an activity — labeled with the work package name and duration. Each node is an event: the moment when all incoming activities are complete and the next ones can begin. Dashed edges are zero-duration dependency links that consolidate multiple predecessors into a single integration milestone.
flowchart LR
classDef event fill:#f8f9fa,stroke:#9aa0a6,stroke-width:1.5px,color:#3c4043
classDef crit fill:#fce8e6,stroke:#d93025,stroke-width:2px,color:#c62828
classDef milestone fill:#0b57d0,stroke:#0842a0,stroke-width:2px,color:#ffffff
classDef done fill:#188038,stroke:#146c2e,stroke-width:2px,color:#ffffff
N0(["Start"]):::event
N1(["PricingEngine
Done"]):::crit
N2(["PaymentAccessor
Done"]):::crit
N3(["ValidationEngine
Done"]):::event
N4(["OrderAccessor
Done"]):::event
N5(["NotifAccessor
Done"]):::event
N6(["OrderManager
Integration Ready"]):::milestone
N7(["Project
Complete"]):::done
N0 ==>|"E2: PricingEngine · 1.0d
float: 0"| N1
N0 -->|"E1: ValidationEngine · 1.0d
float: 2.0d"| N3
N0 -->|"RA2: OrderAccessor · 1.0d
float: 2.0d"| N4
N0 -->|"RA1: NotifAccessor · 0.5d
float: 2.5d"| N5
N1 ==>|"RA3: PaymentGateway · 2.0d
float: 0"| N2
N2 ==>|"dep"| N6
N3 -.->|"dep"| N6
N4 -.->|"dep"| N6
N5 -.->|"dep"| N6
N6 ==>|"OM: OrderManager · 2.0d
float: 0"| N7
The thick arrows trace the critical path: PricingEngine (1.0d) → PaymentGatewayAccessor (2.0d) → OrderManager Integration Ready → OrderManager (2.0d) — 5.0 days total, zero float. No activity on this path can slip without extending the project. Red nodes mark the events that sit on the critical path.
Everything else has float. ValidationEngine and OrderAccessor each have 2.0 days. NotificationAccessor has 2.5 days. The float tells you where your best engineers go and where scheduling flexibility exists — and it fell out of the network automatically, without a planning session.
The critical path is not something you compute in a planning session. It is already in the architecture. If Manager A depends on Engine B, which depends on Accessor C, then the critical path runs through C → B → A. You can read it off the component diagram. If the diagram does not exist, the critical path is hidden — and you will discover it as a blocked sprint.
Change in Practice
A compliance requirement arrives during development: high-value orders must be checked against a fraud rules engine before placement is confirmed.
This is a single, well-scoped requirement. Watch what happens when it lands on each plan.
In the Feature-List Plan
The team adds a new story: “Fraud Check on High-Value Orders.” It goes into the next sprint. During implementation, the developer realizes that fraud check results need to flow through the order placement path — which means touching the service that handles payment coordination, which is already mid-development on another story. Two tickets that looked independent turn out to share an integration point that nobody modeled because the integration points were not in the plan.
The sprint takes a dependency hit. Estimates are revised. The critical path shifts — but nobody knows which direction because the plan does not model the path.
In the Architecture-Derived Plan
The fraud check maps directly to the architecture. A new Engine is needed: FraudRulesEngine. It has no dependencies on other Engines. A new Resource Accessor is needed: FraudRulesAccessor, which depends on FraudRulesEngine being stable. The PlaceOrderManager adds a dependency on FraudRulesEngine.
Three new work packages. Two can start immediately. One extends the critical path by the duration of FraudRulesEngine + FraudRulesAccessor. The plan updates itself: does the new chain exceed the existing critical path length? If yes, the delivery date moves — explicitly, by a computable amount. If no, it does not move at all.
| Aspect | Feature-List Plan | Architecture-Derived Plan |
|---|---|---|
| Where does the requirement land? | A new story in the next sprint | New components with defined roles and explicit dependencies |
| What does it depend on? | Discovered during implementation | Visible immediately — FraudRulesAccessor depends on FraudRulesEngine |
| Does it affect the critical path? | Unknown until something blocks | Computable: does the new chain exceed the existing longest path? |
| Can it be parallelised? | Assumed, based on team availability | Known — FraudRulesEngine has no deps, starts immediately |
| What is the delivery impact? | Estimated with wide uncertainty | Computed from the extended dependency chain |
Architecture-derived planning does not make scope changes cheaper. It makes their consequences visible before the team discovers them at the keyboard. A new component on the critical path is a delivery-date event. A new component off the critical path is not. The plan can say which is which, because the plan knows the structure.
Estimation Difficulty Is a Structural Signal
Here is the insight that connects Project Design to Boundary-Driven Testing: estimation difficulty and testing difficulty have the same cause.
A component that is hard to estimate is usually hard to estimate because its scope is unclear, its responsibilities span multiple volatility axes, or its dependencies are not well-defined. A component that is hard to test is hard to test for exactly the same reasons. A component that does too much is both hard to estimate and hard to test — because “how long will this take?” and “what exactly does this do?” are the same question.
| Signal | What It Describes | Response |
|---|---|---|
| Estimate range is very wide (e.g., 1–5 days) | Component is doing work that belongs in multiple roles — scope is not coherent | Decompose further. The uncertainty is the boundary telling you it is in the wrong place. |
| Work package cannot start until three other things finish | Component has too many upstream dependencies — possibly a Manager doing Engine work | Examine what the Manager is computing. Logic that belongs in an Engine creates false dependencies. |
| Dependencies feel circular or tangled | Circular dependencies in the architecture — two components need each other | The cycle is a structural problem, not a planning problem. Resolve the cycle; the planning resolves itself. |
| Every change to one story requires re-estimating another | Stories map to cross-cutting architectural concerns — scope is not isolated to one component | Realign work packages to component boundaries, not feature boundaries. |
When a work package cannot be estimated confidently, stop and ask why. The answer is almost always structural. Fix the architecture. The estimates will follow.
Practitioner Observations
The Float Consumption Problem. The primary reason well-managed projects slip is not that critical activities slip — it is that non-critical activities consume their float and quietly become critical, creating a new critical path that was not planned for and is not staffed with the best resources. Float is not a buffer to spend. It is the risk signal that determines where attention belongs at every point in execution. When a near-critical chain — one with small but non-zero float — starts consuming that float faster than planned, the response is reassignment before the transition happens, not after. Monitoring float degradation on near-critical chains is the primary proactive risk management discipline in Project Design.
The Re-Estimation Smell. When a change to one work package requires re-estimating several others, the components are not as independent as the architecture implies. Real independence means that adding a new Engine to the dependency graph of a Manager increases the critical path by exactly the Engine’s duration — and nothing else changes. If it changes more than that, look for hidden coupling: a shared model that multiple Engines depend on, a Utility that encodes more than cross-cutting concerns, or a Manager that is doing work that should be in an Engine.
The Manager Milestone Diagnostic. Manager completion is a natural integration checkpoint — it is the moment when a vertical slice works end to end. If a Manager integration test is failing and it is not clear why, the diagnostic starts with the Engines and Accessors, not the Manager. The Manager coordinates; it does not compute. A Manager integration failure almost always means a contract mismatch at an Engine or Accessor boundary. The Manager is a milestone, not a location where bugs live.
The next time a project plan is being built, resist the instinct to start with stories. Start with the component model. Name every Engine, every Resource Accessor, every Manager. Draw the dependencies between them. Read the critical path off the diagram. Then ask which work packages can begin on day one.
The plan is already in the architecture. You are not building it — you are reading it.
A project plan that cannot be derived from the architecture is not a plan. It is a guess, organized by sprint.