1. Reporting Profile Setup
Trigger: Reporting Setup form submission, or a client reaching Fully Executed in the firm's proposal pipeline.
Conditions: none, and that matters - every new engagement gets a reporting profile or appears on the exception list.
Actions in order:
- Write report_tier, report_send_day, report_recipients, report_cc_list, report_format, report_data_sources, the three client_kpi fields, account_owner and report_reviewer.
- Derive and write the cycle dates: data_window_open_day as send day minus 7, draft_due_day as send day minus 3, review_due_day as send day minus 1. Roll any date that lands on a weekend back to the previous working day.
- Set reporting_active true, apply reporting-active, set on_time_streak and missed_cycle_count to 0.
- Create the recurring Internal Reporting Day block on the account owner's calendar on the draft due day, every month.
- Send the client the Client Reporting Preferences form from the account owner: "Hi [first name], before we start reporting I would rather build it around what you actually want than guess. Four questions: [form link]. In particular, tell me which date in the month is most useful - if you have a board pack or an internal review, I will land ours ahead of it."
- Wait 5 days. If the preferences form is not submitted, send one reminder, then proceed on the firm's defaults and notify the owner that the cadence was set without client input.
- On preferences submission: overwrite report_send_day, recipients, format, tier and the KPI fields with the client's answers, recalculate the derived dates, move the calendar block, and confirm to the client: "Set. Your report will reach [recipients] on the [send day] of every month, covering the month before. First one: [date]."
- Notify the account owner with the final profile so there is no ambiguity about what was promised.
Exit: single pass. Re-running on a profile change recalculates everything cleanly.
2. Cycle Open and Data Collection Window
Trigger: scheduled daily at 06:00. Fires for any contact tagged reporting-active where today is data_window_open_day.
Conditions: not tagged reporting-paused, or reporting_paused_until is in the past. A cycle card must not already exist for this period.
Actions in order:
- Create the cycle card in Reporting Cycle at Cycle Open - Data Window. Write report_period_label as the month about to end. Reset report_view_count to 0.
- Apply data-pending. Create one task per source named in report_data_sources, assigned to the owner named for that source, due on draft_due_day minus 1.
- If any source is marked as client-supplied: apply data-pending-client, set client_data_outstanding, and send the Data Request form from the account owner: "Hi [first name], one thing I need from your side for this month's report: [source]. Here is the form, it takes two minutes: [form link]. I need it by [due date] to get the report to you on the [send day] as usual."
- Wait 2 days. If client data is still outstanding, BO sends a chase: "Hi [first name] - still need [source] for the report. Quick form: [form link]. If it is easier to just reply with the number, do that and I will handle it."
- Wait 1 day. If still outstanding, BO sends SMS within quiet hours: "Hi [first name], [firm] here - we are waiting on [source] to finish your monthly report. Reply here or use [short link]. Reply STOP to opt out."
- Wait 1 day. If still outstanding, offer the 15-minute Data Clarification Call and notify the account owner: "[Client] has not supplied [source] after three prompts. Report will be late unless you proceed without it."
- If all sources are in: remove data-pending and data-pending-client, clear client_data_outstanding, move the card to Data Complete, and notify the account owner that they are clear to draft.
- If data is still incomplete on the draft due day: notify the owner and the reviewer, and branch - proceed with a stated gap and a note in the report, or log a Reporting Exception. The choice is a human's, and it is recorded either way.
Exit: card reaches Data Complete, or an exception is logged.
3. Draft Build and Internal Review Gate
Trigger: card reaches Data Complete, or today is draft_due_day.
Conditions: the review gate is mandatory. No report sends without report_reviewer marking review complete, which is what makes quality consistent across account managers rather than dependent on which one you got.
Actions in order:
- Send the account owner the draft pack by internal notification: this cycle's figures, last cycle's report_commentary for continuity, the three client_kpi fields, last_feedback_score and any feedback comment, and the client's view behavior over the last three cycles.
- Create a task on the owner due at 17:00 on draft_due_day: "Write commentary and move [client] [period] to Draft Built."
- Wait until 17:00 on the draft due day. If the card has not moved, apply draft-overdue and notify the owner: "[Client] [period] draft is due today and the client expects the report on the [send day]. Two days of slack left."
- Wait 1 day. If still not moved, notify the practice lead as well.
- On the card moving to Draft Built: remove draft-overdue, write report_commentary, move to Internal Review, and notify report_reviewer: "[Client] [period] report ready for review. Needs sign-off by [review_due_day] to send on time. Three things to check: do the numbers match the commentary, is a flat or bad month described honestly, and does it speak to [client_kpi_1]."
- Create a task on the reviewer due at 12:00 on review_due_day.
- Wait until 12:00 on the review due day. If review is not complete, apply review-overdue, notify the reviewer by email and SMS, and copy the practice lead. A reviewer bottleneck is the most common cause of a late report and it needs to be as visible as a late draft.
- If the reviewer requests changes: move the card back to Draft Built, notify the owner with the requested change, due within 4 working hours.
- On review complete: move the card to Report Sent and hand to workflow 4.
Exit: review complete, or the cycle is logged as an exception.
4. Report Send
Trigger: card moved to Report Sent, or the scheduled 09:00 send on report_send_day for any card that has cleared review.
Conditions: review complete, report_commentary not empty, recipients populated. Any failure halts the send and notifies the owner - a report sent without commentary is a spreadsheet, and sending one teaches the client to ignore the next.
Actions in order:
- Write last_report_sent_date. Apply report-sent and report-unopened.
- Branch on timing: if today is on or before report_send_day, increment on_time_streak. If later, apply report-late, reset on_time_streak to 0, and notify the practice lead with the reason captured from whichever stage overran.
- Branch on quarter-end-cycle: if applied, use the quarterly template with a three-month trend section and include the Quarterly Business Review booking link. Otherwise use the monthly template.
- Send from the account owner's address to report_recipients, copying report_cc_list: "Hi [first name], [report_period_label] report: [hosted link]. The short version before you click: [first two sentences of report_commentary]. The headline on [client_kpi_1] is [figure]. Anything in here you want to talk through, reply and I will call you - and if you would rather have this in a different shape, the one-question form at the bottom is the fastest way to tell me."
- If report_format includes PDF: attach it as well as linking, so the client can circulate it internally without sending round a tracked link.
- If report_tier includes a monthly call: include the Monthly Report Review booking link and move the card to Review Call Booked once a booking exists.
- Notify the account owner that the report is out, with the recipient list, so a wrong recipient is caught in minutes rather than next cycle.
- On the first view webhook: write last_report_viewed_date, set report_view_count to 1, remove report-unopened, apply report-viewed, move the card to Report Viewed, notify the owner.
- On each subsequent view: increment report_view_count. At count 4, notify the owner: "[Client] has opened the [period] report four times. It is being circulated - expect questions."
Exit: hands to workflow 5 if unopened after 3 days, otherwise to workflow 7.
5. Unopened Report Recovery
Trigger: 3 days after last_report_sent_date with report-unopened still applied.
Conditions: not reporting-paused. Capped at two attempts per cycle - this build never badgers a client about reading a report.
Actions in order:
- Send one short plain-text email from the owner: "Hi [first name], the [report_period_label] report is here if it got buried: [hosted link]. One line from it: [key figure sentence]. No need to reply."
- Wait 4 days.
- If still unopened, send a single SMS within quiet hours: "Hi [first name] - [owner] at [firm]. Monthly report is in your inbox from [date] if useful: [short link]. Reply STOP to opt out."
- Stop sending. Do not chase a third time.
- Notify the account owner: "[Client] has not opened the [period] report after two prompts."
- If the count of consecutive unopened cycles reaches 2: apply report-non-reader, remove report-reader if present, and create a task on the owner: "Ask [client] directly what format would actually get read. Options: shorter summary tier, the numbers in the body of an email rather than a link, a 15-minute call instead of a document, or a different recipient entirely. Two cycles unread is a format problem, not an attention problem."
- If the count reaches 3: notify the practice lead and flag the account in the next renewal risk review, because an engagement whose reporting nobody reads is an engagement with no visible value attached to it.
Exit: a view webhook, which applies report-reader and cancels this workflow.
6. Review Call Handling
Trigger: a booking on the Monthly Report Review or Quarterly Business Review calendar.
Conditions: branch on which calendar, and on appointment status afterwards.
Actions in order:
- Move the card to Review Call Booked. Send confirmation with the agenda: "Thirty minutes on the [period] report. I will keep it to three things: what moved, what it means for [client_kpi_1], and what we are doing next month. If there is a fourth thing you want on the list, reply and tell me now so I can prepare properly."
- Wait until 24 hours before. Send email reminder with the report link attached again, so the client can arrive having read it.
- Wait until 2 hours before. Send SMS reminder within quiet hours.
- Wait until 1 hour before. Send the account owner the pre-call brief: the report, the commentary, view count, last_feedback_score, any question the client raised on this cycle's report, and - for a quarterly review - the three-month trend and the retainer renewal date if one is within 120 days.
- Quarterly branch: also notify report_reviewer or the relationship partner, who should attend quarterly reviews even if they skip monthly ones.
- Wait until 1 hour after the slot. Branch on status.
- Showed: create a task on the owner due same day: "Send [client] the follow-up note with the three actions agreed." Send the client a short recap template for the owner to complete. Move the card to Cycle Closed.
- No-show: send one rebooking link, wait 2 days, send a second. If no rebooking, close the cycle and note the no-show on the account - two consecutive no-shows on a review call is a disengagement signal worth a partner conversation.
- Canceled with no rebooking in 7 days: notify the owner and the practice lead.
Exit: appointment status resolved and the cycle closed.
7. Feedback Capture and Cycle Close
Trigger: 3 days after the first view, or 7 days after send if never viewed.
Conditions: only one feedback prompt per cycle, ever. A second request for feedback on the same report is a cost, not a courtesy.
Actions in order:
- Send one short email from the owner: "Hi [first name], one question on the [period] report and then I will leave you alone: was it useful? [1 to 5 links]. If the answer is anything under a 4, the comment box is where you tell me what to change - I would rather rebuild it than keep sending something that is not landing."
- On submission: write last_feedback_score and the comment to the account record.
- If the score is 4 or 5: notify the owner, and if a comment was left, create a task to action it next cycle.
- If the score is 3: notify the owner with a task due in 2 days: "Call [client] about the report format - they scored it a 3."
- If the score is 1 or 2: notify the owner and the practice lead immediately. Create a same-day task on the owner to call, and suppress the next cycle's automated send in favor of a rebuilt report the owner sends by hand after the conversation.
- Wait 2 days. Move the card to Cycle Closed, carrying sent date, view count, feedback score, on-time flag and whether a review call was held.
- If three consecutive cycles score 4 or 5 and the client reads every report: notify the owner that this is the right moment to ask for a referral or a review, and hand to the firm's reputation workflow if one exists.
Exit: card closed.
8. Missed Cycle Escalation and Exception Handling
Trigger: scheduled daily at 08:00. Fires on any open cycle card where today is past report_send_day and the card has not reached Report Sent. Also triggered manually by a Reporting Exception submission.
Conditions: branch on whose fault the delay is, read from client_data_outstanding and the stage the card is stuck in.
Actions in order:
- Apply report-late. Reset on_time_streak to 0.
- Firm-side branch - stuck at Draft Built or Internal Review: notify the owner, the reviewer and the practice lead jointly. Send the client a holding message from the owner, which is not optional: "Hi [first name], your [period] report will be with you on [new date] rather than today - my fault, not yours. If you need any figure before then, ask and I will send it straight over." A late report the client is told about is a minor irritation; a late report they notice themselves is a trust event.
- Client-side branch - client_data_outstanding set: notify the owner and send the client: "Hi [first name], we are still waiting on [source] to finish the [period] report. Happy to send it without that section if you would rather have it now - just say which you prefer." Do not apologize for a delay the firm did not cause, and do not let it be invisible either.
- Wait 2 days. If still not sent, escalate to the practice lead with the stage and the owner named.
- Wait 3 days. If still not sent, notify the managing partner and require the Reporting Exception form.
- On exception submission: move the cycle card to Cycle Missed, increment missed_cycle_count, create a card in Reporting Exceptions at Logged with the reason and the owner, and create a task for the practice lead to review the fix before the next cycle opens.
- If missed_cycle_count reaches 2 for any one client: notify the managing partner and flag the account for renewal risk review. Two missed reports is how churn starts.
- If a single account owner accumulates 3 late cycles across their book in a quarter: notify the practice lead. This is a capacity signal about a person, not a quality signal about a client, and it should be read that way.
Exit: cycle sent, or exception resolved.
9. Quarter Flag, Pause Handling and Reporting Health Digest
Trigger: scheduled. The quarter flag runs on the first of each month at 05:00; the pause check runs daily at 05:00; the digest runs on the first working day of each month at 07:00.
Conditions: none.
Actions in order, quarter flag:
- If the current month is the third month of the firm's financial quarter, apply quarter-end-cycle to every contact tagged reporting-active, which switches workflow 4 to the quarterly template and adds the Quarterly Business Review offer.
- Remove the tag on the first of the following month.
- Notify each account owner of which of their clients are on a quarterly cycle this month, so they can allow extra drafting time.
Actions in order, pause handling:
- On a client request to pause, apply reporting-paused and set reporting_paused_until. Confirm to the client: "Paused until [date]. I will pick it back up then without you having to ask."
- Daily, check every paused contact. When reporting_paused_until is today, remove reporting-paused, notify the owner, and let the next cycle open normally. A pause with no end date is how reporting stops permanently.
Actions in order, health digest:
- Email the partner group and practice leads: on-time send rate across the book this month and trailing three months; every late cycle with the stage it stalled at and the owner; every missed cycle with its reason; average last_feedback_score and all scores of 3 or below; clients tagged report-non-reader; and a list of active clients with reporting_active false - the clients receiving no reporting at all, which is the most expensive list in the digest.
- Create one task per client on that last list, assigned to the account owner: "No reporting profile for [client]. Complete the Reporting Setup form or log why not."
Exit: single pass per scheduled run.