# Recurring client deliverables: period ledger and test worksheet Companion guide: https://www.overskill.com/learn/plan-recurring-client-deliverables This is an editable planning exercise, not a scheduler. Plain Harbor Studio, clients, people, times and evidence labels below are fictional. No client work, message delivery, approval, payment or application behavior is established. ## 1. Define the schedule Workspace / client / stable service IDs: Deliverable and the exact meaning of Completed: Named timezone / displayed timezone: Period start included / period end excluded: First and last approved period: Due rule / weekend and holiday handling: Catch-up range after a missed run: Who may approve a skip, new due date or completion: Who handles unfinished prior-period work: Whether two periods may remain open at once: What needs a separate cancellation or correction workflow: Sample: workspace STUDIO-01, service site-review, one website-review pack per client per service month. All instants UTC. Only October and November 2026 are approved. Create records at or after each month's opening, never before it. Catch up every missing opened period in this approved list. An ended period can still acquire its missing work record; retain the original deadline. Do not generate earlier contract history or infer future approved months. The fifth calendar day at 17:00 UTC is due, without weekend/holiday adjustment. At now == due, the item is due but not overdue. Open work becomes overdue when now > due. Completion at due is on time. Client approval/delivery remain separate from the internal Completed state used here. ## 2. Keep the four kinds of record separate | Record | Required fields | Identity / preservation rule | | --- | --- | --- | | Schedule rule | Workspace, client ID, service ID, owner, approved periods, timezone, due rule, version | Preserve the rule version captured at creation; later defaults do not rewrite records | | Schedule exception | Client/service/period, skip decision, event ID, approver, approval time, reason | Approve before period-record creation in this sample; creates no deliverable yet | | Period record | Workspace/client/service/period, rule version, owner, original due, current due, state, creation time | Exactly one per identity; do not key on run ID, due date, current owner or rule version | | Change history | Event ID, period identity, actor, recorded time, action, old/new values, reason or evidence | Same ID + identical details is a no-op; changed details under that ID require review | Every sample identity starts STUDIO-01 and uses site-review. The short names C-01/2026-10 below stand for the full tuple. Stable client IDs are C-01 Cedar Cycles (Maya), C-02 Fern Books (Luis), C-03 Harbor Pottery (Alex). | Period ID | Included start UTC | Excluded end UTC | Original due UTC | | --- | --- | --- | --- | | 2026-10 | 2026-10-01 00:00:00Z | 2026-11-01 00:00:00Z | 2026-10-05 17:00:00Z | | 2026-11 | 2026-11-01 00:00:00Z | 2026-12-01 00:00:00Z | 2026-11-05 17:00:00Z | ## 3. Replay the worked history | Time UTC | Command / event ID | Expected change | | --- | --- | --- | | Oct 1, 09:00 | Generate opened approved periods | Create 3 open October rows, rule v1 | | Oct 5, 16:00 | complete-01 | Complete C-01/2026-10; sample pack-v1 and handoff-01 labels | | Oct 6, 09:00 | complete-02 | Complete C-02/2026-10; sample pack-v1 and handoff-02 labels; 16 hours late | | Oct 28, 12:00 | skip-01 | Approve C-02/2026-11 skip for client-requested pause; store exception only | | Nov 3, 09:00 | Delayed generation | Retain 3 October rows; create 2 open November rows and 1 skipped November row | | Nov 3, 09:01 | Retry generation | Create 0; retain all 6 identities, states and deadlines | | Nov 4, 12:00 | due-01 | C-01/2026-11 current due Nov 5, 17:00 → Nov 9, 17:00; Maya records approved extension | | Nov 6, 09:00 | Review snapshot | 6 period rows = 2 completed + 1 skipped + 3 open; 2 open are overdue | The two completion references are invented labels, not existing files or customer outcomes. In a real record, supply the actual reviewed version and handoff evidence. Do not mark a period complete because another period opened. ## 4. Copy the expected period ledger Snapshot: 2026-11-06 09:00:00Z. All dates below are in 2026, UTC. | Client / period | Owner | Rule | State | Original due | Current due | Completion or exception | Review action | | --- | --- | --- | --- | --- | --- | --- | --- | | C-01 / 2026-10 | Maya | v1 | Completed | Oct 5, 17:00 | Oct 5, 17:00 | Oct 5, 16:00; complete-01 | Retain version/evidence; on time | | C-02 / 2026-10 | Luis | v1 | Completed | Oct 5, 17:00 | Oct 5, 17:00 | Oct 6, 09:00; complete-02 | Retain 16-hour lateness | | C-03 / 2026-10 | Alex | v1 | Open | Oct 5, 17:00 | Oct 5, 17:00 | Waiting for client materials | Review late October work; do not relabel November | | C-01 / 2026-11 | Maya | v1 | Open | Nov 5, 17:00 | Nov 9, 17:00 | due-01 extension | Not currently overdue; keep original due/history | | C-02 / 2026-11 | Luis | v1 | Skipped | Nov 5, 17:00 | Nov 5, 17:00 | skip-01 approved Oct 28 | No active work; not a completion | | C-03 / 2026-11 | Alex | v1 | Open | Nov 5, 17:00 | Nov 5, 17:00 | No completion | 16 hours overdue | There are 5 work records when the skipped row is excluded: 2 completed and 3 open. The open-work view contains C-03/2026-10, C-01/2026-11 and C-03/2026-11. Its overdue subset contains the two C-03 rows. Show both period and current due. For a spreadsheet, use separate columns for each identity component and each timestamp. Filter State = Open before comparing now with Current due. Keep original due as a separate value. Do not turn a skipped row into a blank row. The reference exercise uses whole-second UTC instants; define your actual spreadsheet's date parsing and timezone behavior before comparing results. Your ledger: | Workspace | Client ID | Service ID | Period ID | Owner | Rule version | State | Original due | Current due | Completed at / evidence | Exception / change event | | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Your append-only change history: | Event ID | Period identity | Actor | Recorded at | Action | Old value | New value | Reason / evidence | | --- | --- | --- | --- | --- | --- | --- | --- | | | | | | | | | | ## 5. Check retries and boundary cases Use independent resets where noted; do not silently combine contradictory cases. | Case | Setup / action | Expected | Observed / evidence | | --- | --- | --- | --- | | R01 | Empty ledger at Sep 30, 23:59:59 | No opened periods; 0 rows | Not tested | | R02 | Empty ledger at Oct 1, 00:00:00 | 3 October rows, no November rows | Not tested | | R03 | October rows; generate Oct 31, 23:59:59 | No November rows | Not tested | | R04 | October rows and approved November skip; generate Nov 1, 00:00:00 | 3 new period rows: 2 open, 1 skipped | Not tested | | R05 | Worked Nov 3 delayed run and retry | First creates 3; retry creates 0; total 6 | Not tested | | R06 | Independent empty ledger at Nov 3; same approved skip | Create all 6 opened-period rows; October due stays Oct 5 | Not tested | | R07 | Repeat complete-01, skip-01 or due-01 with identical event details | No state or history change | Not tested | | R08 | Reuse due-01 with a different new due time | Reject conflict; preserve ledger/history | Not tested | | R09 | Rerun generator after extension, even under proposed rule v2 | Existing original/current due and v1 snapshots stay unchanged | Not tested | | R10 | C-03 November at Nov 5, 16:59:59 / 17:00:00 / 17:00:01 | Not overdue / due but not overdue / overdue | Not tested | | R11 | C-01 November at Nov 6, 09:00 | Not overdue under approved Nov 9 deadline | Not tested | | R12 | Try skipping already-created work or editing/completing skipped work | Reject; separate approved correction needed | Not tested | | R13 | Complete an open record without version/handoff evidence | Reject; no completion written | Not tested | | R14 | Two simultaneous actual-app runs for one identity | Exactly one record; requires actual concurrency test | Not tested | | R15 | Close period with an unfinished item | Preserve the old period and open state; new period can coexist | Not tested | Also test client separation, a reload, a failed save and late event receipt in the actual app. The reference exercise replays its commands in time order; it does not establish a general out-of-order event processor. Define a review process for late corrections rather than silently replacing their effective time with arrival time. Test version / timestamp / reviewer: Unperformed or failed check / owner / next action: ## 6. Keep the build bounded Start with this ledger and a manually invoked generation test. Verify saved records, history, permissions and simultaneous-run protection before enabling a recurring trigger. Creating work does not send a client message or prove that a client received it. Add scheduling, alerts, delivery and billing only as separate actions with their own tests and evidence. Portal records and access: https://www.overskill.com/learn/build-a-client-portal Build brief: https://www.overskill.com/learn/write-an-ai-app-brief