1. Project Setup and Notification Profile
Trigger: Project Setup form submission, or an opportunity reaching Fully Executed in the firm's proposal pipeline.
Conditions: none. Every project gets a card and a notification profile, or it appears on the gap list in workflow 9.
Actions in order:
- Create the card in Project Delivery at Kickoff Scheduled. Write project_name, project_code, delivery_lead, account_owner, project_start_date, target_delivery_date, handover_items.
- Write original_delivery_date equal to target_delivery_date and never write to it again. Every slippage measurement in this build depends on that field staying honest.
- Load stage_sla_days per stage from the project type, set stage_entered_date to today, set project_health to Green, revision_round and date_change_count to 0.
- Apply project-active and notify-all as the default, which the client can change.
- Send the kickoff email from the delivery lead with the Project Kickoff booking link: "Hi [first name], [project_name] is live and I am your point of contact. First thing: 60 minutes to agree the plan and what we need from each other - [booking link]. Second thing, and it will save us both time later: tell me how you want to be kept informed. [preferences form link]. Some clients want a note at every milestone, some want one summary a week. Both are fine; what I would rather avoid is you having to email me to find out where things are."
- Wait 3 days. If the preferences form is not submitted, send one reminder and proceed on notify-all.
- On preferences submission: write notify_level, notify_contacts, notify_channel. Swap the notify tag to match. Confirm: "Set. You will hear from me [at every milestone / when the key milestones land / once a week on Fridays], and you will never have to ask where we are."
- Notify the delivery lead with the final profile.
Exit: single pass.
2. Milestone Reached Notification
The core workflow. Everything else in this build supports it.
Trigger: the card changes stage in Project Delivery.
Conditions: project-active present, project-paused absent. Branch on the notify tag: notify-all sends on every stage change; notify-key sends only on Discovery complete, each phase complete, With Client for Review, Approved and Handover; notify-digest sends nothing here and lets workflow 9 carry it; notify-none sends nothing at all. Outside working hours, hold the send until 08:30 the next working day.
Actions in order:
- Write current_milestone as the new stage's client-facing name, next_milestone as the following stage, and next_milestone_due as today plus that stage's stage_sla_days. Reset stage_entered_date to today. Remove stage-overdue.
- Select the per-milestone template. Each stage has its own, and all of them follow the same four-part shape, which is what makes them answer the client's questions before they are asked: what just happened, what happens next and by when, what we need from you, when you will next hear from us.
- Send from the delivery lead to notify_contacts, subject "[project_code] [project_name] - [current_milestone]". Example body, Discovery complete: "Hi [first name], discovery is done. We have what we need on [area one] and [area two], and the one surprise was [item] - it does not change the date. Next: we move into build, which runs to [next_milestone_due]. Nothing needed from you during this phase. You will hear from me when build completes, or sooner if anything changes."
- Example body, With Client for Review: "Hi [first name], the first deliverable is ready: [link]. Two ways to give us feedback - the form takes five minutes and keeps everything in one place [form link], or book 45 minutes and we will walk through it together [booking link]. Either is fine. We need one of them by [client_action_due] to hold the [target_delivery_date] date."
- Write last_client_update_sent as today. Remove update-stale.
- If the new stage requires client input - Discovery, With Client for Review, or any stage flagged as client-dependent on the project type: apply awaiting-client, write client_action_required and client_action_due, and hand to workflow 5.
- Post to the internal delivery channel: "[project_code] moved to [current_milestone]. Lead [delivery_lead]. Next due [next_milestone_due]. Health [project_health]."
- If the new stage is Approved: hand to workflow 8. If Revisions: hand to workflow 6.
Exit: fires once per stage change. A card moved backwards fires too, with the regression template - clients tolerate a step back far better than they tolerate discovering one.
3. Stage SLA Monitor and Health Flag
Trigger: scheduled daily at 07:00 across all cards tagged project-active.
Conditions: days since stage_entered_date, excluding any days the card spent tagged awaiting-client. This exclusion is essential - a project should never be marked amber for a delay the client caused, and the days-lost figure is itself worth reporting.
Actions in order:
- Calculate adjusted days in stage. Compare to stage_sla_days.
- At 100 per cent of SLA: notify the delivery lead only. "[project_code] has been at [current_milestone] for [n] days, which is its full allowance. Move it or log a delay today." No client message. Nothing has gone wrong yet.
- At 120 per cent: apply stage-overdue and project-amber, set project_health to Amber, notify the delivery lead and account_owner jointly, and create a task on the lead due same day: "Move [project_code] or complete the Delay Notice form."
- At 150 per cent, or when target_delivery_date is in the past: apply project-red, set project_health to Red, create a card in Project Escalations at Flagged, and notify the account owner, the practice lead and the partner. Create a task on the partner due within 1 business day: "Review [project_code] - red."
- Still no automatic client message. Every client-facing word about a delay goes through workflow 7 with human approval, because an automated apology for a slip the firm has not yet decided how to fix makes things worse.
- On the card moving stage: remove stage-overdue, and if no other condition holds, reset project_health to Green and remove the amber or red tag. Notify the account owner that the project has recovered.
- Daily, also check last_client_update_sent. If more than 10 days ago and notify-none is not set, apply update-stale and hand to workflow 9's staleness branch.
Exit: runs continuously while the project is active.
4. Kickoff Call Handling
Trigger: a booking on the Project Kickoff calendar.
Conditions: branch on appointment status.
Actions in order:
- Send confirmation with the agenda and the pre-work: "Sixty minutes, and here is the agenda so nobody has to improvise: the outcome we are aiming at, the plan and the dates, what we need from you and when, and how you will hear from us. One thing to bring: who on your side signs off on deliverables."
- Wait until 24 hours before. Send email reminder with the agenda again and any pre-work still outstanding.
- Wait until 2 hours before. Send SMS reminder if notify_channel includes SMS.
- Wait until 1 hour before. Send the delivery lead and account owner a brief: the executed scope, the client's stated outcome from the scoping stage, target_delivery_date, the milestone list, and the communication preferences the client chose.
- Wait until 1 hour after the slot. Branch on status.
- Showed: create a task on the delivery lead due same day: "Move [project_code] to Discovery and populate client_action_required from the kickoff." Moving the card is what sends the client their first milestone notification, so the task is phrased to make that obvious.
- No-show: send one rebooking link, wait 1 day, send a second, notify the account owner. A client who misses their own kickoff is a project-risk signal, not a calendar accident.
- Rescheduled more than twice: notify the account owner and the practice lead, and push target_delivery_date consideration to workflow 7 - a start date that slips has to move the end date or the plan is fiction.
Exit: card reaches Discovery.
5. Awaiting Client Chase
Trigger: awaiting-client applied, by workflow 2 or manually by the delivery lead.
Conditions: project-paused absent. The SLA clock in workflow 3 is frozen for the whole duration of this workflow, and the frozen days are recorded.
Actions in order:
- Write blocked_since_date and blocked_reason. Send the Client Input Request form from the delivery lead: "Hi [first name], one thing holding us up on [project_name]: [client_action_required]. Here is the form, or just reply to this with it: [form link]. I need it by [client_action_due] to keep [target_delivery_date] intact." Naming the consequence is what gets a reply.
- Wait until 1 day before client_action_due. BO sends a short reminder naming only what is still outstanding - never a re-list of items already supplied, which is the fastest way to make a client stop reading.
- Wait until the due date passes by 1 day. BO sends a second chase and, if notify_channel includes SMS, an SMS within quiet hours: "Hi [first name] - [firm] on [project_code]. Still waiting on [item] to carry on. Reply here or [short link]. Reply STOP to opt out."
- Wait 2 days. BO offers the 15-minute Unblock Call: "Hi [first name], rather than chase you again - 15 minutes and we will get [item] sorted together on the call: [booking link]. Sometimes it is faster than finding it."
- Wait 3 days. Notify the delivery lead and account owner: "[project_code] blocked [n] days on [item]. [n] days now excluded from the delivery schedule." Create a task on the account owner to call the client.
- Wait 5 days. Send the schedule-impact notification from the delivery lead, which needs no approval because it states a fact rather than a reason: "Hi [first name], we have been waiting on [item] since [blocked_since_date], which is [n] working days. That time comes out of the schedule, so [target_delivery_date] is no longer realistic unless we get it this week. Not a complaint - I would just rather tell you now than tell you later." Notify the account owner that this went out.
- Wait 10 days from blocked_since_date. Apply project-red, escalate to the partner, and create an escalation card. A project blocked ten working days on client input is a commercial conversation, not a delivery one.
- On the input arriving: remove awaiting-client, clear blocked_reason and client_action_required, record the frozen day count against the project, resume the SLA clock, and notify the delivery lead: "[project_code] unblocked. [n] days lost to client wait, excluded from SLA." Confirm to the client: "Got it, thank you - back on it today."
Exit: input received, or the project is paused or escalated.
6. Review and Revision Loop
Trigger: Review and Approval form submission, a Review Session marked showed, or the card moved to Revisions.
Conditions: branch on the form answer, and on revision_round.
Actions in order:
- Approve as is: remove awaiting-client, move the card to Approved, hand to workflow 8.
- Approve with minor comments: write the comments, move to Approved, create a task on the delivery lead to action the comments during handover, and confirm to the client: "Approved with your two notes - both will be in before handover."
- Request changes: increment revision_round, write the structured feedback to the card, move to Revisions, remove awaiting-client, and send the acknowledgement: "Hi [first name], got your feedback - [n] changes logged: [list]. Back with you by [new next_milestone_due]. If I have misread any of these, tell me now rather than when you see the next version." Reading the changes back is what prevents a second revision round caused by a misunderstanding rather than by the work.
- Create a task on the delivery lead with the revision list attached and a due date.
- Review Session showed branch: create a task on the lead due same day: "Log the changes agreed on today's [project_code] call and move the card." Moving the card sends the acknowledgement automatically.
- If no form submission and no booking by client_action_due: hand back to workflow 5's chase ladder - a deliverable sitting unreviewed is the most common silent project stall there is.
- At revision_round 3: apply revision-loop, notify the account owner and the practice lead, and create a task on the account owner: "Third revision round on [project_code]. Before a fourth, have the conversation: is this a quality problem, a brief problem, or scope that was never agreed? Do not let a fourth round happen by default."
- At revision_round 4: notify the partner. Suppress the automated revision acknowledgement and require the account owner to write to the client personally.
Exit: approval recorded, or the project escalates.
7. Delay and Date Change Notification
The one workflow in this build with a mandatory human gate.
Trigger: Delay Notice form submission. The form is also the only permitted route to changing target_delivery_date; the field is locked against direct editing.
Conditions: branch on whose side the cause sits, as stated on the form, and on date_change_count.
Actions in order:
- Write the new target_delivery_date. Increment date_change_count. Apply date-slipped if the new date is later than original_delivery_date. Recalculate next_milestone_due.
- Draft the client notification from the form's reason and recovery plan, and hold it for approval by account_owner. Nothing sends until they release it. Notify them immediately with a 4-working-hour task: "Delay notification for [project_code] drafted and waiting. Client has not been told yet."
- Firm-side cause, draft text: "Hi [first name], I need to move the [project_name] delivery date from [old date] to [new date]. The reason is [reason] - that is on us, not on anything you did. Here is what we are doing about it: [recovery plan]. What this means for you: [impact]. If that date causes you a problem on your side, call me and we will look at what can be reprioritised."
- Client-side cause, draft text: "Hi [first name], the delivery date moves from [old date] to [new date]. The driver is [reason] - the [n] working days we spent waiting on [item] come straight off the back end of the schedule. Nothing to apologize for on either side, but I would rather you heard it from me now than discovered it in two weeks."
- On release: send the email, write last_client_update_sent, and if notify_channel includes SMS send a heads-up: "Hi [first name] - [delivery lead] has just emailed you about the [project_code] timeline. Worth a read when you get a moment." A delay email that sits unread for three days is a delay the client still does not know about.
- If the account owner does not release within 4 working hours: notify them again and copy the practice lead. The point of the gate is review, not delay.
- Post to the internal delivery channel: "[project_code] date moved [old] to [new]. Cause: [firm or client]. Change count: [n]. Health [project_health]."
- If date_change_count reaches 2: notify the practice lead and partner, and require a recovery plan review before any third change. At 3: the partner takes over client communication on the project entirely.
Exit: notification released and sent.
8. Approval, Handover and Close
Trigger: card moved to Approved.
Conditions: none.
Actions in order:
- Send the approval notification from the delivery lead: "Hi [first name], signed off - thank you. Last step is handover: I will transfer [handover_items summary] and walk your team through it. Book that here: [handover booking link]. Allow [duration]."
- Create the handover task set on the delivery lead from handover_items: files and source assets, credentials and access, documentation, training session, and the named internal owner on the client side.
- On the Handover Session being held: move the card to Handover. Send the handover pack email with everything transferred listed explicitly: "Everything from [project_name], in one place: [list with links]. All of it is yours. Two things worth keeping: [key item] and [key item]."
- Raise the final invoice in the connected accounting system. If no connection exists, create a finance task.
- Move the card to Closed. Remove project-active. Apply the client's post-project tag.
- Wait 2 days. Send the Project Close Feedback form from the account owner, not the delivery lead - a different voice asking makes an honest answer more likely: "Hi [first name], two questions on how [project_name] went, and the second one is the one I actually care about: what should we have done differently? [form link]"
- On feedback submission: write it to the account record and notify the delivery lead and account owner. A score at the top of the range hands to the firm's review or referral workflow. Anything in the bottom half creates a same-day task on the account owner to call.
- Notify the account owner with the project post-mortem figures: total elapsed days against planned, days lost to client wait, number of stages that went overdue, date_change_count, revision_round, and final health flag.
- If the engagement continues as a retainer: hand the account to the reporting cycle and the renewal clock so neither has to be set up from scratch later.
- Wait 30 days. Send one check-in from the account owner: "Hi [first name], a month on from [project_name] - is it doing what you wanted it to do? No agenda, I just want to know whether it stuck."
Exit: after the 30-day check-in.
9. Weekly Client Digest, Staleness Backstop and Internal Health Report
Trigger: scheduled. The client digest runs Fridays at 16:00 local; the staleness branch runs daily at 07:30; the internal report runs Fridays at 08:00.
Conditions: the client digest goes only to projects tagged notify-digest, plus any project tagged notify-key that has had no milestone change this week. Nothing goes to notify-none or project-paused.
Actions in order, client digest:
- Compose per project: current_milestone, what moved this week, next_milestone and next_milestone_due, anything outstanding from the client, and target_delivery_date.
- Send from the delivery lead: "Hi [first name], [project_code] end-of-week: we are at [current_milestone]. This week [what moved]. Next up is [next_milestone] by [next_milestone_due]. [Nothing needed from you / We are still waiting on: [client_action_required]]. Delivery still tracking to [target_delivery_date]."
- Write last_client_update_sent. Remove update-stale.
- Suppress the digest entirely if a milestone notification already went out that day - two messages in one afternoon reads as noise, not diligence.
Actions in order, staleness backstop:
- For any active project where last_client_update_sent is more than 10 days ago: apply update-stale, notify the delivery lead, and send a short holding note from them: "Hi [first name], no milestone to report on [project_code] this week - we are still inside [current_milestone] and it is going fine. Next thing you will hear from me is [next_milestone], due [next_milestone_due]. Nothing needed from you." This message exists purely so a long stage never becomes silence.
- Cap it at one holding note per 10-day window, so a genuinely long build phase produces a note roughly every two weeks rather than a drip.
Actions in order, internal health report:
- Email the partner group and practice leads: every active project with its health flag, stage, days in stage, delivery lead, target date and change count; all red and amber projects with the reason; every project tagged awaiting-client with days blocked; every project tagged revision-loop; every project tagged update-stale; and any executed engagement with no project card at all.
- Append three aggregate figures: median days in stage by stage name, which exposes the real bottleneck across the firm; total days lost to client wait this month; and on-time delivery rate against original_delivery_date.
- Create one task per project on the no-card list, assigned to its account owner.
Exit: single pass per scheduled run.