Back to Standard Operating Procedure Management

Developer Handover Pack

Everything needed to build the automation from scratch: current state, full agent specs, data flow, and the build stack.

4 pagesPDF · Technical
FS-DOC-04Technical

Developer Handover Pack

Standard Operating Procedure Management

[YourCompany.com] · Operations Department · Prepared by FullSpec · [Today's Date]

This document is the technical reference for the FullSpec team building the SOP Management automation. It covers the current-state process map with bottleneck flags, full agent specifications with IO contracts, the end-to-end data flow trace, and the recommended build stack. Everything in this document is derived from the confirmed process mapping session and stack audit. Where the template does not specify a value (OAuth scopes, rate-limit thresholds, exact field names), realistic and internally consistent defaults have been applied and are clearly identifiable.

01Process snapshot

Step
Name
Description
1
Identify Changed or New SOP
Operations Manager reviews Google Drive ad hoc, often prompted by a colleague message rather than a systematic alert, to spot updated or newly created SOPs needing distribution. (20 min)
2
Update Version Number and Change Log
Manager manually edits the document header to increment the version number and appends a change summary to the log table inside the document. (15 min)
3
Identify Affected Staff Members
Manager cross-references the SOP scope against a team roster in Google Sheets to determine which roles must acknowledge the update. (15 min)
4
Send Notification to Team
Manager composes and sends a Slack message or email to each affected person with a link to the new document and read-receipt instructions. (25 min)
5
Track Who Has Responded
BOTTLENECK: Manager opens the acknowledgement spreadsheet and manually records each reply as team members respond via Slack, email, or form link. Entries are missed and the record is frequently out of date. (30 min)
6
Send Reminder to Non-Responders
BOTTLENECK: Manager checks the spreadsheet every two to three days and individually messages anyone who has not yet acknowledged. This step repeats until the cycle closes. (40 min)
7
Escalate Persistent Non-Responders
Manager notifies the non-responder's line manager or HR contact and logs the escalation event in Google Sheets. (20 min)
8
Archive Previous Version
Manager moves the superseded document to the Notion archive folder and updates any internal wiki links that referenced the old file. (15 min)
9
Update SOP Register
Manager opens the master SOP register in Google Sheets and updates the row with the new version number, revision date, and acknowledgement status. (15 min)
10
Confirm Full Compliance and Close Cycle
Once all required staff have acknowledged, manager marks the cycle complete in the register and notifies any stakeholders who requested confirmation. (10 min)
Time cost summary: Each SOP update cycle costs approximately 205 minutes (3 hours 25 minutes) of manual Operations Manager time. At roughly 12 updates per month that totals approximately 41 hours per month and approximately 5 hours per week of avoidable manual work. Steps 1, 2, 8, and 9 are replaced by the SOP Version and Register Agent. Steps 3, 4, 5, 6, 7, and 10 are replaced by the Distribution and Acknowledgement Agent. One human review gate is preserved for compliance-critical SOPs before distribution begins.
Developer Handover PackPage 1 of 4
FS-DOC-04Technical

02Agent specifications

SOP Version and Register Agent

This agent monitors the approved SOPs folder in Google Drive for any file creation or modification event. On detection it reads the current version token from the document, increments it following a MAJOR.MINOR schema (e.g. v1.3 becomes v1.4 on a minor edit; a full rewrite bumps to v2.0 when the manager sets a flag in the register), writes the updated version string back to the document header, appends a timestamped row to the change-log sheet, and writes a new or updated row to the master SOP register in Google Sheets capturing the file ID, document title, new version, editor email, revision date, change summary, compliance-critical flag, and affected-roles list. The agent then emits a structured payload that triggers the Distribution and Acknowledgement Agent. Estimated build time: 10 hours. Complexity: Moderate.

Trigger
Google Drive file-change webhook: file created or modified inside the /Approved-SOPs folder (folder ID confirmed at stack audit). Event types: create, update. Polling fallback: every 5 minutes if push notifications are unavailable on the connected account tier.
Tools
Google Drive (read file metadata, read/write document content via Docs API), Google Sheets (append and update rows in SOP Register sheet and Change Log sheet)
Replaces steps
Steps 1, 2, 8, 9 (Identify Changed SOP, Update Version and Change Log, Archive Previous Version, Update SOP Register)
Estimated build
10 hours, Moderate
// Input
drive.file.id          : string   // Google Drive file ID of changed document
drive.file.name        : string   // Document title at time of change
drive.event_type       : enum     // 'create' | 'update'
drive.actor_email      : string   // Google account email of editor
drive.modified_time    : ISO8601  // Timestamp of change

// Internal lookups (agent performs)
sheets.register.row    : object   // Existing register row matched by file.id
  .current_version     : string   // e.g. 'v1.3'
  .compliance_flag     : boolean  // true if SOP is compliance-critical
  .affected_roles      : string[] // list of role identifiers

// Output (emitted to Distribution and Acknowledgement Agent)
sop.file_id            : string   // Drive file ID
sop.title              : string   // Document title
sop.new_version        : string   // Incremented version string e.g. 'v1.4'
sop.editor_email       : string
sop.revision_date      : ISO8601
sop.change_summary     : string   // Extracted from doc change-log table, first new row
sop.compliance_flag    : boolean
sop.affected_roles     : string[] // Role identifiers for downstream lookup
sop.register_row_id    : string   // Sheets row reference for downstream updates
  • Google Drive API access requires the automation platform to be authorised under a Google Workspace service account or via OAuth 2.0 with scope drive.readonly plus drive.file. Confirm the Workspace admin has enabled domain-wide delegation if a service account is used.
  • Google Sheets write access requires scope spreadsheets (read/write). The SOP Register sheet must use the agreed column schema: [file_id, title, version, editor_email, revision_date, change_summary, compliance_flag, affected_roles, register_row_id, cycle_status]. Confirm column positions before build.
  • Version increment logic: read the version cell from the matched register row, parse the MAJOR.MINOR string, increment MINOR by 1. If no existing row is found (new document), set version to v1.0 and insert a new register row. If the file is renamed the agent must match on file_id, not title, to avoid creating a duplicate row.
  • Dedupe behaviour: if the Drive webhook fires twice for the same file within a 60-second window (a known Drive API behaviour), the agent must check the modified_time of the last register row update and skip processing if it is within 90 seconds of the incoming event timestamp.
  • The change_summary field is extracted from the first new row added to the change-log table inside the Google Doc. If the table is empty or missing, the field is populated with 'Change summary not provided' and a Slack alert is sent to the operations channel so the manager can update it manually.
  • Archive step: the agent copies the pre-change version of the file to the /SOP-Archive/{file_id}/{version} path in Drive before writing the new version string back to the live document. This replaces step 8 without using Notion for archiving. Confirm with the process owner whether Notion archive links also need updating or whether Drive-only archiving is acceptable for go-live.
  • Confirm before build: Google Drive folder ID for /Approved-SOPs, SOP Register Google Sheets spreadsheet ID and sheet name, column schema sign-off, and whether service account or OAuth 2.0 is the preferred auth method.
Distribution and Acknowledgement Agent

This agent receives the structured payload from the SOP Version and Register Agent and executes the full distribution, tracking, reminder, escalation, and closure cycle without manual intervention. It queries the role-to-SOP mapping table in Google Sheets to resolve the affected-roles list into individual staff member records (name, Slack user ID, email, line manager Slack user ID). It then sends a personalised Slack direct message to each staff member containing the document title, version, a plain-language change summary, a direct Drive link, and a one-click acknowledgement button powered by a Slack interactive component. For any SOP where sop.compliance_flag is true, the agent simultaneously sends a DocuSign envelope to each required signatory. It writes an initial acknowledgement tracker row for every recipient. A scheduled sub-flow runs every 48 hours, identifies outstanding tracker rows, and sends a Slack reminder. After two reminders without response, an escalation message is posted to the line manager's Slack DM and the escalation is logged. Once all required acknowledgements and DocuSign completions are recorded, a summary message is posted to the designated operations Slack channel. Estimated build time: 18 hours. Complexity: Complex.

Trigger
Structured payload received from SOP Version and Register Agent confirming register row has been written, carrying sop.affected_roles and sop.compliance_flag.
Tools
Google Sheets (role mapping lookup, acknowledgement tracker read/write), Slack (interactive messages, DMs, channel posts via Slack Bot Token), DocuSign (envelope creation and webhook status callback for compliance-critical SOPs)
Replaces steps
Steps 3, 4, 5, 6, 7, 10 (Identify Affected Staff, Send Notification, Track Responses, Send Reminders, Escalate Non-Responders, Confirm Compliance and Close Cycle)
Estimated build
18 hours, Complex
// Input (from SOP Version and Register Agent)
sop.file_id            : string
sop.title              : string
sop.new_version        : string
sop.revision_date      : ISO8601
sop.change_summary     : string
sop.compliance_flag    : boolean
sop.affected_roles     : string[]  // e.g. ['ops-manager','warehouse-lead','qa-officer']
sop.register_row_id    : string

// Internal lookups (agent performs)
sheets.role_mapping[]  : object[]  // one record per staff member
  .role_id             : string
  .staff_name          : string
  .slack_user_id       : string    // e.g. 'U04XXXXXXX'
  .email               : string
  .line_manager_slack  : string    // Slack user ID of line manager

// Output (written to acknowledgement tracker sheet + Slack + DocuSign)
tracker.row[]          : object[]  // one row per required acknowledger
  .file_id             : string
  .version             : string
  .staff_name          : string
  .slack_user_id       : string
  .method              : enum      // 'slack_button' | 'docusign'
  .status              : enum      // 'pending' | 'acknowledged' | 'escalated'
  .acknowledged_at     : ISO8601   // null until confirmed
  .reminder_count      : integer   // 0, 1, or 2
  .escalated_at        : ISO8601   // null until escalated

// On acknowledgement (Slack interactive component callback or DocuSign webhook)
callback.slack_user_id : string    // identifies the responder
callback.action_id     : string    // 'ack_sop' confirms button press
callback.timestamp     : ISO8601
callback.envelope_id   : string    // DocuSign only, null for Slack path

// Completion output (posted to Slack channel when all rows resolved)
summary.sop_title      : string
summary.version        : string
summary.total_required : integer
summary.all_acked_at   : ISO8601
summary.channel_id     : string    // ops Slack channel ID
  • Slack interactive components (Block Kit buttons) require a Slack app installed in the workspace with scopes: chat:write, im:write, channels:read, users:read, users:read.email, and incoming-webhook. The app must have an interactive endpoint URL configured pointing to the automation platform's webhook receiver. Confirm the Slack workspace admin can install custom apps before build starts.
  • The Slack acknowledgement button payload must include the file_id and version in the action value so the callback handler can update the correct tracker row without a separate lookup.
  • DocuSign routing only fires when sop.compliance_flag is true. The envelope is created using the DocuSign eSignature REST API (envelopes:create). The template ID for SOP acknowledgement envelopes must be created in DocuSign and its ID recorded in the credential store before build. A DocuSign Connect webhook must be configured to POST envelope-completed events back to the automation platform.
  • Reminder sub-flow: implement as a scheduled workflow running every 48 hours. The flow queries the tracker sheet for rows where status is 'pending' and acknowledged_at is null. It sends a Slack DM to the matching slack_user_id and increments reminder_count. When reminder_count reaches 2 and the row is still pending, escalation fires: a DM is sent to line_manager_slack_id and status is updated to 'escalated'.
  • DocuSign accounts on the Personal plan do not support Connect webhooks. The DocuSign Standard or Business Pro plan is required. Confirm account tier before build.
  • The role-to-SOP mapping table is the single source of truth for recipient resolution. The table must be present and populated before go-live. If a role_id from the incoming payload has no matching row in the mapping table, the agent must log an error to the error table, send a Slack alert to the ops channel, and halt distribution for that role only (not abort the entire cycle).
  • Confirm before build: Slack app credentials (Bot Token, Signing Secret), Slack channel ID for the ops completion summary, DocuSign account ID and integration key, DocuSign SOP acknowledgement template ID, Google Sheets spreadsheet ID and sheet name for the role mapping table and acknowledgement tracker, and the 48-hour reminder window (process owner may want to adjust this).
Developer Handover PackPage 2 of 4
FS-DOC-04Technical

03End-to-end data flow

Full trigger-to-output data flow trace. Field names match the agent IO contracts above.
// ��══════════════════════════════════════════════════════════════════
// TRIGGER: Google Drive file-change event
// ═══════════════════════════════════════════════════════════════════
GOOGLE_DRIVE.webhook.receive({
  file_id        : 'string',       // Drive file ID
  file_name      : 'string',       // Document title
  event_type     : 'create|update',
  actor_email    : 'string',       // Editor Google account
  modified_time  : 'ISO8601'
})

// Dedupe check: skip if last register update for this file_id < 90 seconds ago
IF (now - sheets.register[file_id].last_updated) < 90s => ABORT (duplicate event)

// ═══════════════════════════════════════════════════════════════════
// AGENT 1: SOP Version and Register Agent
// ════════════════════════════════════════════════════════════════��══

// Step 1: Lookup existing register row by file_id
sheets.SOP_Register.lookup(file_id) => {
  current_version  : 'v1.3',
  compliance_flag  : true|false,
  affected_roles   : ['ops-manager','warehouse-lead'],
  register_row_id  : 'string'
}

// Step 2: Increment version
new_version = incrementMinor(current_version)  // 'v1.3' => 'v1.4'
// Full rewrite flag in register => incrementMajor()  // 'v1.4' => 'v2.0'

// Step 3: Archive pre-change file copy
GOOGLE_DRIVE.copy(file_id, dest='/SOP-Archive/{file_id}/{current_version}')

// Step 4: Write new version string to document header via Docs API
GOOGLE_DOCS.update(file_id, field='version_header', value=new_version)

// Step 5: Extract change_summary from change-log table (first new row)
change_summary = GOOGLE_DOCS.readTable(file_id, table_index=0, last_row=true)
// Fallback if empty: change_summary = 'Change summary not provided'
//   => post alert to Slack ops channel

// Step 6: Append row to Change Log sheet
sheets.Change_Log.append({
  file_id, new_version, actor_email, modified_time, change_summary
})

// Step 7: Update SOP Register row
sheets.SOP_Register.update(register_row_id, {
  version        : new_version,
  revision_date  : modified_time,
  change_summary : change_summary,
  cycle_status   : 'in_progress'
})

// ── Agent 1 handoff to Agent 2 ──────────────────────────────────────
EMIT => Distribution_and_Acknowledgement_Agent({
  sop.file_id        : file_id,
  sop.title          : file_name,
  sop.new_version    : new_version,
  sop.revision_date  : modified_time,
  sop.change_summary : change_summary,
  sop.compliance_flag: compliance_flag,
  sop.affected_roles : affected_roles,
  sop.register_row_id: register_row_id
})

// ═══════════════════════════════════════════════════════════════════
// AGENT 2: Distribution and Acknowledgement Agent
// ═══════════════════════════════════════════════════════════════════

// Step 1: Resolve affected_roles to staff records
FOR EACH role_id IN sop.affected_roles:
  sheets.Role_Mapping.lookup(role_id) => {
    staff_name          : 'string',
    slack_user_id       : 'U04XXXXXXX',
    email               : 'string',
    line_manager_slack  : 'U04YYYYYYY'
  }
// Error path: role_id not found => log error, Slack alert, skip this role only

// Step 2: Initialise tracker rows
FOR EACH staff_member IN resolved_staff:
  sheets.Ack_Tracker.append({
    file_id, version: new_version,
    staff_name, slack_user_id,
    method          : IF compliance_flag THEN 'docusign' ELSE 'slack_button',
    status          : 'pending',
    acknowledged_at : null,
    reminder_count  : 0,
    escalated_at    : null
  })

// Step 3a: Send Slack interactive message to each recipient
SLACK.postDirectMessage(slack_user_id, {
  blocks: [
    text: 'SOP Updated: {sop.title} — {sop.new_version}',
    text: 'Change summary: {sop.change_summary}',
    button: { text: 'I have read this SOP', action_id: 'ack_sop',
              value: '{file_id}|{new_version}' }
  ]
})

// Step 3b: If compliance_flag == true — send DocuSign envelope in parallel
IF sop.compliance_flag:
  DOCUSIGN.envelopes.create({
    template_id      : 'DOCUSIGN_SOP_TEMPLATE_ID',   // stored in credential store
    signer.email     : staff_member.email,
    signer.name      : staff_member.staff_name,
    custom_fields    : { sop_title: sop.title, version: new_version }
  }) => { envelope_id: 'string' }
  sheets.Ack_Tracker.update(row, { envelope_id })

// ── Callback: Slack button press ─────────────────────────────────────
SLACK.interactive.callback({
  action_id      : 'ack_sop',
  value          : '{file_id}|{version}',
  user.id        : slack_user_id,
  action_ts      : 'ISO8601'
}) =>
  sheets.Ack_Tracker.update({ file_id, slack_user_id, version }, {
    status          : 'acknowledged',
    acknowledged_at : action_ts
  })

// ── Callback: DocuSign envelope completed ────────────────────────────
DOCUSIGN.connect.webhook({
  envelope_id    : 'string',
  status         : 'completed',
  completed_at   : 'ISO8601'
}) =>
  sheets.Ack_Tracker.update({ envelope_id }, {
    status          : 'acknowledged',
    acknowledged_at : completed_at
  })

// ── Scheduled sub-flow: every 48 hours ──────────────────────────────
SCHEDULER.every_48h:
  pending_rows = sheets.Ack_Tracker.query(status='pending', acknowledged_at=null)
  FOR EACH row IN pending_rows:
    IF row.reminder_count < 2:
      SLACK.postDirectMessage(row.slack_user_id, reminder_message)
      sheets.Ack_Tracker.update(row, { reminder_count: row.reminder_count + 1 })
    ELSE:
      SLACK.postDirectMessage(row.line_manager_slack, escalation_message)
      sheets.Ack_Tracker.update(row, {
        status       : 'escalated',
        escalated_at : now()
      })

// ── Completion check: runs after every tracker update ────────────────
pending_count = sheets.Ack_Tracker.count({ file_id, status='pending' })
escalated_count = sheets.Ack_Tracker.count({ file_id, status='escalated' })
IF (pending_count + escalated_count) == 0:
  SLACK.postChannelMessage(ops_channel_id, {
    text: 'SOP {sop.title} v{new_version} — full acknowledgement complete.',
    fields: { total_required, completed_at: now() }
  })
  sheets.SOP_Register.update(register_row_id, { cycle_status: 'complete' })
Developer Handover PackPage 3 of 4
FS-DOC-04Technical

04Recommended build stack

Orchestration layer
A workflow automation platform (tool TBC at build kick-off). Recommended pattern: one workflow per agent (Workflow 1: SOP Version and Register Agent; Workflow 2: Distribution and Acknowledgement Agent; Workflow 3: 48-hour reminder scheduler; Workflow 4: Slack interactive callback handler; Workflow 5: DocuSign webhook handler). All five workflows share a single credential store holding Google OAuth tokens, Slack Bot Token and Signing Secret, and DocuSign integration key. No credentials are hardcoded in workflow nodes.
Webhook configuration
Google Drive push notifications (channels.watch) should be registered against the /Approved-SOPs folder ID with a TTL of 7 days and auto-renewed by a scheduled workflow before expiry. The Slack interactive endpoint URL and the DocuSign Connect URL must both be publicly reachable HTTPS endpoints provided by the automation platform. TLS 1.2 minimum. Slack request signature verification (X-Slack-Signature header) must be validated on every inbound Slack payload before processing.
Templating approach
Slack Block Kit JSON templates for the acknowledgement message, reminder message, escalation message, and completion summary are stored as named templates inside the automation platform or as static JSON nodes within each workflow. All user-facing strings are parameterised with {sop.title}, {sop.new_version}, {sop.change_summary}, and {staff_name} so copy changes do not require workflow edits. DocuSign envelope layout is managed inside DocuSign template editor; the automation platform only passes custom field values at envelope creation time.
Error logging
A dedicated error table (Supabase: table name sop_automation_errors) captures every caught exception. Required columns: id (uuid), workflow_name (text), error_code (text), error_message (text), payload_snapshot (jsonb), created_at (timestamptz). On any error write, a Slack alert is posted to the ops channel via a shared error-handler webhook node present in all five workflows. Non-retryable errors (e.g. role_id not found in mapping table) log and halt the affected sub-path only. Retryable errors (e.g. Google API 429 rate-limit response) trigger a 60-second back-off and up to three automatic retries before logging as failed.
Testing approach
All agents are built and verified in a sandbox environment first. Google Drive sandbox folder (/Approved-SOPs-TEST) and a duplicate SOP Register sheet are used for all development testing. Slack messages during testing are directed to a private #sop-automation-test channel. DocuSign sandbox (demo.docusign.net) is used for all envelope tests. A feature flag field (test_mode: true) in the credential store prevents any sandbox run from writing to the live SOP Register or posting to the live ops channel.
Estimated total build time
SOP Version and Register Agent: 10 hours. Distribution and Acknowledgement Agent: 18 hours. End-to-end integration testing, error-handler wiring, and sandbox-to-live cutover: 10 hours (included in the 28-hour total confirmed at scoping). Total: 28 hours across a 3 to 4 week delivery window.
Pre-build checklist: before any workflow is built, the following must be confirmed by the process owner and recorded in the project credential store. (1) Google Drive /Approved-SOPs folder ID and service account or OAuth method. (2) SOP Register and Change Log spreadsheet IDs plus column schema sign-off. (3) Role-to-SOP mapping table populated with all current staff and Slack user IDs. (4) Compliance-critical flag applied to all qualifying SOPs in the register. (5) Slack app installed with all required scopes and interactive endpoint URL registered. (6) Slack ops channel ID confirmed. (7) DocuSign account plan confirmed as Standard or above. (8) DocuSign SOP acknowledgement template created and template ID recorded. (9) Supabase project and error table created with correct schema. Reach the FullSpec team at support@gofullspec.com with any pre-build blockers.
Developer Handover PackPage 4 of 4

More documents for this process

Every document generated for Standard Operating Procedure Management.

Launch Plan
Operations · Owner
View
ROI and Business Case
Finance · Owner
View
Process Runbook / SOP
Operations · Owner
View
Integration and API Spec
Technical · Developer
View
Test and QA Plan
Quality · Developer
View