Workflow 1: Time Entry Ingestion and Recalculation
Trigger. Inbound webhook on the time-entry endpoint. Fires on every new or edited entry from the time-tracking system. Payload: engagement_code, hours, role, entry_date, staff_id, notes.
Conditions and branches.
- Look up the Engagement Health opportunity where Engagement Code equals engagement_code. If no match, branch to the exception path: post to #engagement-health with “Unmatched time entry: code [engagement_code], [hours]h on [entry_date]. No engagement found: check the code in both systems.” Stop.
- If the opportunity stage is Period Closed or Absorbed, branch to the late-entry path: add the hours to Hours Logged Lifetime only, flag the record late-entry-received, notify the account owner, and stop. Do not reopen a closed period silently.
- If the entry is an edit rather than a create, subtract the prior value before adding the new one. Without this the counters inflate on every correction.
Actions in order.
- Add hours to Hours Logged This Period.
- Add hours to Hours Logged Lifetime.
- Recalculate Burn Percentage as Hours Logged This Period divided by Sold Hours Per Period, times 100, rounded to one decimal.
- Recalculate Expected Burn Percentage as elapsed days in the period divided by total days in the period, times 100.
- Write Pace Variance as Burn Percentage minus Expected Burn Percentage.
- If Burn Percentage is above 100, write Overage Hours as Hours Logged This Period minus Sold Hours Per Period; otherwise set Overage Hours to zero.
- If the opportunity is in Onboarding, move it to On Track.
- Clear the timesheet-gap tag if present.
- Fire the internal event burn-recalculated, which is the trigger the threshold workflows listen for.
Stop and exit. Exits after firing the event. No waits, no messaging. Keep this workflow mechanical: all judgment lives downstream.
Workflow 2: Threshold Alert Ladder
Trigger. Internal event burn-recalculated.
Conditions and branches. Four mutually exclusive branches, each gated on Last Alert Threshold Fired so a threshold never alerts twice in one period.
- Branch A: 70 percent. Burn Percentage is 70 or above and below 90, and Last Alert Threshold Fired is None.
- Branch B: 90 percent. Burn Percentage is 90 or above and below 100, and Last Alert Threshold Fired is None or 70.
- Branch C: 100 percent. Burn Percentage is 100 or above and below 120, and Last Alert Threshold Fired is not 100 or 120.
- Branch D: 120 percent. Burn Percentage is 120 or above and Last Alert Threshold Fired is not 120. This is the partner-level escalation.
Branch A actions.
- Move opportunity to Watch. Remove engagement-on-track, add engagement-watch.
- Set Last Alert Threshold Fired to 70 and Last Alert Date to today.
- Post to #engagement-health: “Watch: [Client] [Engagement Code] at [Burn Percentage]% of [Sold Hours Per Period]h with [days remaining] days left in the period. Expected burn [Expected Burn Percentage]%. Owner: [Account Owner].”
- Wait 0 minutes. No SMS at this level.
Branch B actions.
- Move opportunity to At Risk. Remove engagement-watch, add engagement-at-risk.
- Set Last Alert Threshold Fired to 90, Last Alert Date to today.
- Post to #engagement-health with the same number block plus the Scope Change Request form link.
- Send SMS to the Account Owner: “[Client] is at [Burn Percentage]% of this month's hours with [days remaining] days to go. Raise a scope change here before it tips over: [form link]”
- Wait 2 business days.
- If the engagement is still At Risk and carries no scope-call-requested tag, send a second SMS to the Account Owner and copy the Delivery Lead: “Still no scope change raised on [Client]: now [Burn Percentage]%. [form link]”
- Wait 3 business days.
- If still no scope change, book the engagement onto the next Internal Margin Review slot and notify the partner group.
Branch C actions.
- Move opportunity to Over Scope. Remove engagement-at-risk, add engagement-over-scope and overage-unbilled.
- Set Last Alert Threshold Fired to 100, Last Alert Date to today, Overage Decision to Not Yet Decided.
- Send SMS to Account Owner and Delivery Lead: “[Client] has passed its sold hours: [Overage Hours]h over. Record the call here: [Overage Decision form link]”
- Post to #engagement-health and notify the partner group by email with the burn history for the last three periods attached.
- Wait 1 business day.
- If Overage Decision is still Not Yet Decided, send the account owner a third SMS and create an internal task due same day.
- Wait 2 business days.
- If Overage Decision is still Not Yet Decided, default the engagement into the Internal Margin Review agenda and escalate to the partner group. The build never lets an undecided overage run quietly.
Branch D actions.
- Set Last Alert Threshold Fired to 120.
- Notify the partner group by SMS and email immediately, no waits: “[Client] [Engagement Code] is at [Burn Percentage]%: [Overage Hours]h beyond scope. Owner [Account Owner], decision status [Overage Decision].”
- Add the engagement to the next partner meeting agenda automatically.
Stop and exit. Every branch exits immediately if the engagement moves to Scope Change Agreed, Absorbed or Period Closed, or if the engagement-over-scope tag is removed. Exit on any Last Alert Threshold Fired value higher than the branch's own, so a fast-burning engagement does not run two ladders in parallel.
Workflow 3: Pace Variance Early Warning
Trigger. Internal event burn-recalculated. This runs independently of the threshold ladder, because an engagement can burn dangerously fast while still being under 70 percent.
Conditions and branches.
- Pace Variance is 15 or greater, Burn Percentage is below 70, at least 5 days remain in the period, and the pace-ahead tag is absent.
- Second condition: Last Alert Date is not within the last 7 days. A single cooldown window prevents a daily drip.
Actions in order.
- Add tag pace-ahead.
- Move the opportunity to Watch if it is currently On Track.
- Set Last Alert Date to today.
- Post to #engagement-health: “Pace ahead: [Client] [Engagement Code] has used [Burn Percentage]% of hours with only [Expected Burn Percentage]% of the period elapsed. At this rate it finishes the month around [projected percentage]%. Owner: [Account Owner].”
- Wait 5 business days.
- Recheck Pace Variance. If it has fallen below 10, remove pace-ahead, return the opportunity to On Track, and post “[Client] pace has normalized.” Exit.
- If Pace Variance is still 15 or greater, send SMS to the Account Owner: “[Client] is still burning ahead of plan. Worth a look at what changed in the last two weeks: [record link]”
Stop and exit. Exits if the threshold ladder fires at 90 or above (the louder alert takes over), if the engagement reaches Period Closed, or if fewer than 5 days remain in the period.
Workflow 4: Scope Change Request to Client Confirmation
Trigger. Submission of the internal Scope Change Request form.
Conditions and branches.
- If the recommended action is Absorb or Trim Deliverables, skip the client-facing sequence entirely: write Overage Decision, notify the partner group, and route to Workflow 5.
- If the recommended action is Bill Client, continue. Check the client has a contact with Scope Approval Authority set. If not, notify the account owner to identify one and hold the workflow until the field is set.
- If the contact carries do-not-sms-client, run the email-only variant.
Actions in order.
- Create an opportunity in Scope Change Requests at Drafted, carrying the engagement reference, the hours requested and the description.
- Have BO draft the client-facing summary from the form answers and attach it to the opportunity as an internal note. Notify the account owner to review and approve the draft. Nothing goes out unreviewed.
- Wait for the account owner to move the opportunity to Sent to Client. This is a manual gate by design.
- On that stage change, email the approval contact. Subject: “Quick check-in on the [workstream] work”. Body: “Hi [First Name]. The [workstream] piece we picked up in the last few weeks has grown beyond what we originally scoped, and I would rather talk to you about it now than surprise you later. Can you give me 30 minutes this week? [Scope Review Call link]”
- Tag the engagement scope-call-requested.
- Wait 2 days.
- If no booking, send SMS (consent and quiet hours permitting): “Hi [First Name], [Owner] here from [Firm]. Chasing a short call about the [workstream] work. Here are my open slots: [link]. Reply STOP to opt out.”
- Wait 3 days.
- If still no booking, notify the account owner to call the client directly and create a task due today. Automation stops trying after two nudges.
- On booking, move the engagement to Scope Conversation Booked, swap the tag to scope-call-booked, and schedule the pre-call brief for 90 minutes before the appointment.
- After the call, when the account owner moves the Scope Change Request to In Negotiation or Approved, send the Client Scope Confirmation form by email: “As discussed. Here is the summary of the additional work and the hours it covers. Confirm below and we will get straight on with it.”
- On form submission, move the request to Approved and fire Workflow 5.
Stop and exit. Exits on booking (for the nudge sequence), on Approved or Declined, if the client replies with an opt-out keyword, or if the engagement reaches Period Closed without resolution.
Workflow 5: Baseline Reset and Billing Handoff
Trigger. Scope Change Request moves to Approved, or the Overage Decision form is submitted.
Conditions and branches.
- Bill Client. Additional hours agreed and confirmed.
- Absorb. Requires a non-empty Overage Decision Reason; the workflow rejects the submission and re-prompts if the field is blank.
- Trim Deliverables. Scope reduced rather than hours added.
- Pause Work. Delivery stops until a commercial decision is made.
Bill Client actions.
- Add the approved hours to Sold Hours Per Period.
- Recalculate Burn Percentage against the new baseline.
- Set Overage Hours to zero, Overage Decision to Bill Client, Last Alert Threshold Fired to None.
- Remove engagement-over-scope, engagement-at-risk, overage-unbilled and pace-ahead. Add engagement-on-track.
- Move the engagement to Scope Change Agreed, then to On Track on the next ingestion event.
- Push the approved line to QuickBooks or Xero as a draft invoice line against the client record. Draft, not sent. A human releases invoices.
- Email the account owner the confirmation record and file the signed confirmation against Scope Document Link.
- Wait 1 day, then email the sponsor: “Thanks [First Name]: all confirmed, the team is carrying on. You will see this reflected on the next invoice.”
Absorb actions.
- Set Overage Decision to Absorb, move the engagement to Absorbed.
- Keep overage-unbilled applied. This tag is how absorbed hours stay visible at renewal.
- Increment Consecutive Over Scope Periods.
- Notify the partner group with the reason text, no client messaging at all.
- If Consecutive Over Scope Periods is now 2 or more, add chronic-over-scope and create a repricing task on the account owner due 14 days before Renewal Date.
Trim Deliverables actions.
- Set Overage Decision to Trim Deliverables.
- Notify the delivery lead with a task to update the delivery plan and the scope document.
- Email the sponsor a short confirmation of what is being deferred: “To keep this month inside the hours we agreed, we are moving [deferred item] to next month. Shout if that order does not work for you.”
- Return the engagement to On Track.
Pause Work actions.
- Set Overage Decision to Pause Work, add tag work-paused.
- Notify the delivery lead and every staff member with time logged on the engagement in the last 14 days.
- Create a partner task to make the commercial call within 2 business days.
- Do not message the client automatically. A pause is a human conversation.
Stop and exit. Exits once the branch completes. Re-entry is possible in a later period, which is exactly the signal Consecutive Over Scope Periods is counting.
Workflow 6: Period Close and Counter Roll
Trigger. Scheduled, daily at 00:30 in the firm's timezone. Operates on every engagement whose Period End Date is yesterday.
Conditions and branches.
- If Billing Period Type is Fixed Fee Project, do not roll counters. A project has one budget for its whole life. Snapshot only.
- If Billing Period Type is Time and Materials Cap, roll the dates but carry Hours Logged This Period forward rather than resetting, because the cap is cumulative.
- If the engagement is in Pause Work, hold the close and notify the partner group instead.
Actions in order.
- Write a history snapshot: period dates, Sold Hours Per Period, Hours Logged This Period, Burn Percentage, Overage Hours, Overage Decision.
- If Burn Percentage closed at 100 or above, increment Consecutive Over Scope Periods. Otherwise set it to zero.
- If Consecutive Over Scope Periods reaches 2, add chronic-over-scope and notify the partner group: “[Client] has now closed [n] consecutive periods over scope. This is a pricing conversation, not a delivery one.”
- Reset Hours Logged This Period to zero (except the T&M branch), Burn Percentage to zero, Overage Hours to zero, Last Alert Threshold Fired to None, Overage Decision to Not Yet Decided.
- Roll Period Start Date and Period End Date forward by one period.
- Remove engagement-watch, engagement-at-risk, engagement-over-scope, pace-ahead. Add engagement-on-track. Leave overage-unbilled and chronic-over-scope in place.
- Move the engagement to On Track.
- Wait 1 day, then email the sponsor the one-question Post-Period Delivery Survey: “One question: did this month's work land the way you expected?” with a three-option answer.
- If the survey answer is the lowest option, notify the account owner immediately and create a task due same day, regardless of how the burn closed.
Stop and exit. Exits per engagement once counters are rolled. Logs a failure to #engagement-health if any engagement cannot be rolled, so a stuck record is visible rather than silently frozen.
Workflow 7: Timesheet Gap Detection
Trigger. Scheduled, weekdays at 09:00.
Conditions and branches.
- Engagement is in any active stage (not Period Closed, Absorbed or Pause Work).
- No time entry received against its Engagement Code in the last 5 business days.
- The timesheet-gap tag is not already applied.
Actions in order.
- Add tag timesheet-gap.
- Post to #engagement-health: “No time logged on [Client] [Engagement Code] for 5 business days. Either the work has stopped or the integration has. Check both.”
- Send SMS to the Delivery Lead: “Nothing logged on [Client] in a week: is that right, or is the timer not running?”
- Wait 2 business days.
- If still no entries, escalate to the Account Owner and the operations lead by email, and create a task to verify the webhook and the project code mapping.
- Wait 3 business days.
- If still no entries, notify the partner group. Five consecutive silent engagements in one week should be read as an integration failure, and the digest flags that pattern explicitly.
Stop and exit. Exits the moment any entry arrives for that Engagement Code: Workflow 1 removes the tag, which cancels this sequence.
Workflow 8: Weekly Partner Digest and Renewal Prep
Trigger. Scheduled, Mondays at 07:30. Second trigger: daily check for engagements 21 days from Renewal Date.
Conditions and branches. The digest always sends, even when there is nothing to report. An empty digest is itself information. The renewal branch fires per engagement.
Digest actions.
- Assemble counts by stage from the Engagement Health pipeline.
- List every engagement carrying engagement-at-risk or engagement-over-scope, with burn, overage hours, owner and decision status.
- List every engagement carrying chronic-over-scope, ordered by Renewal Date ascending.
- List every engagement carrying overage-unbilled, with total absorbed hours for the period.
- List every timesheet-gap.
- Email the partner group. Subject: “Engagement health: week of [date]”.
- Post the same summary to #engagement-health.
Renewal branch actions.
- 21 days before Renewal Date, book the Quarterly Retainer Review internal slot for the account owner and the responsible partner.
- Attach the last four period snapshots, total absorbed hours, and the count of scope changes raised and approved.
- If chronic-over-scope is present, open the brief with the recommended uplift framing and the absorbed-hours total.
- Wait until 7 days before Renewal Date. If the internal review has not happened, SMS the responsible partner.
- On renewal, reset Consecutive Over Scope Periods, clear chronic-over-scope and overage-unbilled, and write the new Sold Hours Per Period and Renewal Date.
Stop and exit. The digest is one-shot weekly. The renewal branch exits on renewal, or if the engagement is marked lost or closed.