Developer Handover Pack
Everything needed to build the automation from scratch: current state, full agent specs, data flow, and the build stack.
Developer Handover Pack
Compliance Deadline Tracking
[YourCompany.com] · Legal Department · Prepared by FullSpec · [Today's Date]
This document is the authoritative technical reference for the Compliance Deadline Tracking automation build. It covers the current-state process map with bottleneck analysis, full agent specifications with IO contracts, an end-to-end data flow trace, and the recommended build stack. The FullSpec team uses this pack to build, wire, and test every automated component. Your team's responsibility is limited to confirming tool access, agreeing escalation thresholds, and reviewing the compliance register structure before build begins.
01Process snapshot
02Agent specifications
The Deadline Monitor Agent is the entry point of the automation. It watches for two trigger conditions: a new row submitted via the compliance intake form, and a daily scheduled scan of the Google Sheets register for rows whose calculated reminder dates fall on or before today. On each trigger it validates data completeness across all required fields, resolves the responsible owner's email address from the contacts lookup tab, calculates the 30-day, 14-day, and 3-day reminder trigger dates from the deadline field, writes the validated record back to the register with status set to Open, creates a Google Calendar event assigned to the responsible owner, and queues the first reminder email via Gmail. This agent replaces the most repetitive intake and preparation work and eliminates the weekly manual register review entirely. Estimated build time: 14 hours. Complexity: Moderate.
// Input
form_submission: {
obligation_name: string, // e.g. 'ASIC Annual Return 2025'
obligation_category: string, // 'Licence' | 'Filing' | 'Contract' | 'Policy'
deadline_date: date, // ISO 8601, e.g. '2025-07-15'
responsible_owner_email: string,
required_action: string,
risk_level: string // 'Low' | 'Medium' | 'High'
}
// Validation checks
// - All required fields present and non-empty
// - deadline_date is a valid future date
// - responsible_owner_email resolves in the contacts lookup tab
// - If validation fails: flag row status as 'Incomplete', send alert to legal manager
// Output
register_row_written: {
row_id: string, // auto-generated, e.g. 'OBL-2025-047'
obligation_name: string,
obligation_category: string,
deadline_date: date,
responsible_owner_email: string,
required_action: string,
risk_level: string,
status: 'Open',
reminder_date_30d: date,
reminder_date_14d: date,
reminder_date_3d: date,
calendar_event_id: string, // Google Calendar event ID
first_reminder_sent_at: datetime,
acknowledgement_token: string // unique UUID for acknowledgement link
}- Google Sheets API access requires a service account with Editor role on the compliance register spreadsheet. Confirm the spreadsheet ID and sheet tab names ('Register', 'Contacts') before build.
- The intake form must be built or connected before this agent can be wired. A Google Form posting to the register sheet is acceptable; a Notion form requires a webhook relay to the orchestration layer.
- Reminder date calculation must account for weekends: if a calculated reminder date falls on a Saturday or Sunday, shift it to the preceding Friday.
- The acknowledgement_token must be a UUID v4 generated at write time and stored in the register row. It is embedded in the Gmail reminder link as a query parameter.
- Google Calendar events must use the responsible owner's Google account. Confirm that all owners are within the same Google Workspace domain, or handle external calendar invites separately.
- If the daily scan finds a reminder_date field matching today but the status is not 'Open' (e.g. already 'Escalated' or 'Complete'), skip that row without re-sending.
- The Gmail sending account must be confirmed before build. Use a shared mailbox (e.g. compliance@[YourCompany.com]) rather than a personal account to avoid dependency on an individual user.
- Dedupe: if a row_id already exists in the register with the same obligation_name and deadline_date, do not create a duplicate. Flag to the legal manager for review.
- Confirm which Google Workspace tier is in use. Calendar API and Gmail send-as require at minimum Google Workspace Business Starter.
The Escalation Agent monitors the acknowledgement status of every open reminder in the compliance register and fires when 48 hours elapse after a reminder email is sent without a corresponding acknowledgement token being marked as received. On trigger, it posts a direct Slack message to the responsible owner and a separate notification to the designated compliance Slack channel, then updates the register row status to Escalated. For items flagged as High risk, it also sends a Gmail notification to the legal manager to prompt manual review. The agent runs on a scheduled check every 4 hours during business hours. Estimated build time: 10 hours. Complexity: Moderate.
// Input
register_row: {
row_id: string,
obligation_name: string,
deadline_date: date,
responsible_owner_email: string,
risk_level: string,
first_reminder_sent_at: datetime,
acknowledgement_received_at: null,
status: 'Open'
}
// Output
slack_dm_sent: {
recipient: responsible_owner_slack_id, // resolved from Contacts tab
message_text: string, // includes obligation_name, deadline_date, acknowledgement_link
sent_at: datetime
}
slack_channel_post: {
channel: '#compliance-alerts',
message_text: string,
sent_at: datetime
}
register_row_updated: {
row_id: string,
status: 'Escalated',
escalated_at: datetime,
escalation_count: integer // increment on each escalation cycle
}
// High-risk branch (risk_level = 'High' only)
gmail_sent_to_legal_manager: {
to: legal_manager_email,
subject: 'High-Risk Compliance Item Overdue: {obligation_name}',
body: string // includes row_id, deadline_date, responsible_owner_email
}- Slack integration requires a Slack app installed in the workspace with chat:write and users:read.email OAuth scopes. Confirm the workspace slug and that the compliance-alerts channel exists before build.
- Responsible owner Slack IDs must be stored in the Contacts tab of the Google Sheets register alongside email addresses. The agent resolves the Slack user ID by matching on email via the Slack users.lookupByEmail API endpoint.
- The escalation_count field prevents indefinite re-escalation. After 3 escalation cycles with no acknowledgement, the agent updates the status to 'Pending Manager Review' and stops sending automated Slack messages.
- The 48-hour window is calculated against first_reminder_sent_at, not against the deadline date. Confirm this logic with the legal manager before build.
- Slack paid tier (Pro or above, currently $8/month per the tooling list) is required for the Slack API app installation. Confirm the current plan.
- Do not send escalation Slack DMs outside 08:00 to 18:00 in the owner's local timezone. Store timezone per owner in the Contacts tab.
- Confirm the legal manager's email address for high-risk escalation routing before build.
The Completion and Reporting Agent handles two distinct trigger paths. The first path fires when a responsible owner clicks the acknowledgement link in a reminder email: the agent receives the token via the acknowledgement endpoint, validates it against the register, updates the row status to Complete, and creates a timestamped evidence log entry in Notion. The second path fires on a Monday morning schedule at 07:30 and compiles a weekly digest email summarising all open, overdue, and recently completed items drawn from the live register, then sends it via Gmail to the legal manager. Estimated build time: 10 hours. Complexity: Moderate.
// Input (Path A: Acknowledgement)
http_request: {
method: 'GET',
query_param: { token: string } // UUID v4 acknowledgement_token
}
register_row_lookup: { // matched on acknowledgement_token
row_id: string,
obligation_name: string,
obligation_category: string,
deadline_date: date,
responsible_owner_email: string,
risk_level: string
}
// Output (Path A)
register_row_updated: {
row_id: string,
status: 'Complete',
acknowledgement_received_at: datetime,
completed_by: responsible_owner_email
}
notion_evidence_page_created: {
database_id: string, // Notion compliance evidence database ID
properties: {
obligation_name: string,
row_id: string,
deadline_date: date,
completed_by: string,
completed_at: datetime,
risk_level: string,
category: string
}
}
// Input (Path B: Weekly Digest)
register_read: {
filter: status IN ('Open', 'Escalated', 'Complete'),
date_range: last_7_days AND next_30_days
}
// Output (Path B)
gmail_digest_sent: {
to: legal_manager_email,
subject: 'Weekly Compliance Digest - {date}',
sections: ['Open items', 'Overdue / Escalated', 'Completed this week'],
sent_at: datetime
}- The acknowledgement endpoint must be a publicly accessible URL hosted by the orchestration layer. It must accept a GET request with a token query parameter and return a simple confirmation HTML page ('Thank you, your acknowledgement has been recorded.').
- Acknowledgement tokens are single-use. Once a token is consumed, the row status is set to Complete and subsequent requests with the same token must return a 200 with a 'Already recorded' message, not an error.
- Notion integration requires a Notion internal integration token with Insert Content and Read Content capabilities scoped to the compliance evidence database. Confirm the Notion workspace tier (current tooling cost $16/month indicates Plus or above). Obtain the database ID before build.
- The weekly digest email must be generated from a templated HTML structure, not a plain-text body. Confirm whether the legal manager's Gmail client renders HTML.
- If the register contains no items matching the digest filter, send the digest anyway with a message confirming zero open or overdue items. Do not skip the send.
- Path A and Path B are independent trigger paths within the same agent. They share the same Google Sheets connection credentials but must not interfere with each other's execution.
- Confirm with the legal manager whether completed items should be archived to a separate 'Archive' sheet tab or simply marked in place. Archiving is recommended for long-term register performance.
03End-to-end data flow
// ============================================================
// TRIGGER: Intake form submitted (Google Form or Notion form)
// ============================================================
form_payload = {
obligation_name: string, // 'ASIC Annual Return 2025'
obligation_category: string, // 'Filing'
deadline_date: date, // '2025-07-15'
responsible_owner_email: string, // 'priya@[YourCompany.com]'
required_action: string,
risk_level: string // 'High'
}
// ============================================================
// AGENT HANDOFF 1: form_payload -> Deadline Monitor Agent
// ============================================================
// Step 1: Validate fields
validation_result = validate(form_payload)
// IF invalid: update register row status = 'Incomplete'
// send alert email to legal_manager_email -> EXIT
// Step 2: Resolve owner contact
owner_record = GoogleSheets.read('Contacts', filter: email = responsible_owner_email)
// owner_record.slack_user_id, owner_record.timezone
// Step 3: Calculate reminder dates
reminder_date_30d = deadline_date - 30 days // adjusted for weekends
reminder_date_14d = deadline_date - 14 days // adjusted for weekends
reminder_date_3d = deadline_date - 3 days // adjusted for weekends
// Step 4: Generate acknowledgement token
acknowledgement_token = uuid_v4()
acknowledgement_link = 'https://ack.[YourCompany.com]/confirm?token=' + acknowledgement_token
// Step 5: Write register row
GoogleSheets.write('Register', {
row_id: 'OBL-2025-047',
obligation_name: form_payload.obligation_name,
obligation_category: form_payload.obligation_category,
deadline_date: form_payload.deadline_date,
responsible_owner_email: form_payload.responsible_owner_email,
required_action: form_payload.required_action,
risk_level: form_payload.risk_level,
status: 'Open',
reminder_date_30d: reminder_date_30d,
reminder_date_14d: reminder_date_14d,
reminder_date_3d: reminder_date_3d,
calendar_event_id: '', // populated in step 6
acknowledgement_token: acknowledgement_token,
first_reminder_sent_at: null, // populated in step 7
acknowledgement_received_at: null,
escalated_at: null,
escalation_count: 0,
completed_by: null
})
// Step 6: Create Google Calendar event
calendar_event_id = GoogleCalendar.createEvent({
title: obligation_name + ' - Compliance Deadline',
date: deadline_date,
attendees: [responsible_owner_email],
description: 'Register row: OBL-2025-047. Action required: ' + required_action
})
GoogleSheets.update('Register', row_id = 'OBL-2025-047', { calendar_event_id })
// Step 7: Send first reminder email (on reminder_date_30d or immediately if < 30 days to deadline)
Gmail.send({
to: responsible_owner_email,
subject: 'Compliance Reminder: ' + obligation_name + ' due ' + deadline_date,
body: template('reminder_email', { obligation_name, deadline_date,
required_action, acknowledgement_link })
})
GoogleSheets.update('Register', row_id = 'OBL-2025-047', {
first_reminder_sent_at: now()
})
// ============================================================
// SCHEDULED: Daily 07:00 scan (Deadline Monitor Agent)
// ============================================================
// For each row WHERE status = 'Open'
// AND (reminder_date_14d = today OR reminder_date_3d = today):
// Repeat Gmail.send() with appropriate urgency copy
// Update first_reminder_sent_at if not already set
// ============================================================
// AGENT HANDOFF 2: register_row -> Escalation Agent
// ============================================================
// Scheduled check every 4 hours (08:00-18:00, Mon-Fri)
escalation_candidates = GoogleSheets.read('Register', filter: {
status: 'Open',
first_reminder_sent_at: < now() - 48h,
acknowledgement_received_at: null
})
// For each candidate:
Slack.postDM({
user_id: owner_record.slack_user_id,
text: 'Action required: ' + obligation_name + ' is due ' + deadline_date
+ '. Please confirm: ' + acknowledgement_link
})
Slack.postChannel({
channel: '#compliance-alerts',
text: obligation_name + ' overdue for acknowledgement. Owner: ' + responsible_owner_email
})
GoogleSheets.update('Register', row_id, {
status: 'Escalated',
escalated_at: now(),
escalation_count: escalation_count + 1
})
// IF risk_level = 'High':
Gmail.send({
to: legal_manager_email,
subject: 'High-Risk Compliance Item Overdue: ' + obligation_name,
body: template('high_risk_escalation', { row_id, obligation_name,
deadline_date, responsible_owner_email })
})
// IF escalation_count >= 3 AND status != 'Complete':
GoogleSheets.update('Register', row_id, { status: 'Pending Manager Review' })
// No further automated Slack DMs sent
// ============================================================
// AGENT HANDOFF 3: acknowledgement_token -> Completion Agent (Path A)
// ============================================================
// HTTP GET /confirm?token={acknowledgement_token}
matched_row = GoogleSheets.read('Register',
filter: { acknowledgement_token: query_param.token }
)
// IF token not found or already used: return 200 'Already recorded'
GoogleSheets.update('Register', matched_row.row_id, {
status: 'Complete',
acknowledgement_received_at: now(),
completed_by: matched_row.responsible_owner_email
})
Notion.createPage({
database_id: NOTION_COMPLIANCE_DB_ID,
properties: {
obligation_name: matched_row.obligation_name,
row_id: matched_row.row_id,
deadline_date: matched_row.deadline_date,
completed_by: matched_row.responsible_owner_email,
completed_at: now(),
risk_level: matched_row.risk_level,
category: matched_row.obligation_category
}
})
// HTTP response to owner: 200 HTML 'Thank you, your acknowledgement has been recorded.'
// ============================================================
// SCHEDULED: Monday 07:30 (Completion Agent Path B) -> Weekly Digest
// ============================================================
digest_data = GoogleSheets.read('Register', filter: {
status: IN ['Open', 'Escalated', 'Pending Manager Review', 'Complete'],
OR: [
{ deadline_date: BETWEEN today AND today + 30d },
{ acknowledgement_received_at: BETWEEN today - 7d AND today }
]
})
Gmail.send({
to: legal_manager_email,
subject: 'Weekly Compliance Digest - ' + format(today, 'DD MMM YYYY'),
body: template('weekly_digest', {
open_items: digest_data.filter(status = 'Open'),
escalated_items: digest_data.filter(status IN ['Escalated', 'Pending Manager Review']),
completed_items: digest_data.filter(status = 'Complete'
AND acknowledgement_received_at >= today - 7d)
})
})
// END OF FLOW04Recommended build stack
More documents for this process
Every document generated for Compliance Deadline Tracking.