Part 2 of 7 · Compliance tracker series ~4 min read

How a compliance task gets set up

The tracker only tracks what’s in the list. So the first job is making sure the list actually reflects the recurring checks your business has to do. There are three ways a task gets in: somebody types a row in the Drive sheet, somebody loads a ready-made starter pack of common controls, or somebody forwards a policy document to a dedicated address. The first one is obvious. The other two exist because in real life nobody wants to type forty rows by hand on day one.

Key takeaways

  • Three intake lanes feed one task list: the Drive sheet, a starter-pack lane, and an inbox-forwarding lane.
  • The starter pack drops a ready-made set of common controls for your industry into the sheet for review.
  • Forwarded policies are read by Textract; Bedrock Haiku 4.5 suggests a task name, control area, and repeat rule.
  • Every proposed task goes to the owner’s Slack for one-tap approval before it lands in the list.
  • The Drive sheet stays the canonical store. The other lanes are conveniences that write into it.

Three lanes into one task list

Three intake lanes funnel into one task list A diagram with three vertical lane columns at the top and a single unified row at the bottom. Lane one, Drive sheet: somebody types a row directly into the Google Sheet that holds the task list; the drive-sync Lambda mirrors the sheet to S3 every 15 minutes, and the tracker reads from there. Lane two, Starter pack: somebody picks a ready-made set of common controls for their industry; the tracker drops those rows into the Drive sheet pre-filled with sensible repeat rules and proof types, ready to edit. Lane three, Inbox forwarding: somebody forwards a policy or checklist to a dedicated address, controls-at-your-company; SES writes the raw MIME to S3; a parser Lambda runs Textract on the document, then calls Bedrock Haiku 4.5 to suggest a task name, control area, repeat rule, and proof type; the proposed task gets posted to the owner's Slack with Approve and Edit buttons; on approve, the row is added to the Drive sheet via the Sheets API. All three lanes converge on the same Drive sheet, which the drive-sync Lambda keeps mirrored to S3 for the tracker to read. A note at the bottom: the Drive sheet stays the source of truth — the other lanes are conveniences that propose rows for it. Lane 1 · manual Drive sheet • Somebody types a row directly • drive-sync mirrors to S3 every 15 min • Tracker reads from S3 • Source of truth stays in Drive Lane 2 · ready-made Starter pack • Pick a pack for your industry • Common controls, repeat rules set • Rows dropped into the sheet to edit • Fastest way to start from zero Lane 3 · SES + Textract Inbox forwarding • Forward a policy to controls-address • SES writes MIME to S3 • Textract reads it; Haiku 4.5 suggests task • Slack one-tap approve → sheet Drive task list (source of truth) name · control area · owner · repeats · proof to keep · last done · link drive-sync mirrors it to S3 every 15 min — tracker reads from S3 to scheduler, daily tick The Drive sheet stays the source of truth — the other lanes are conveniences that propose rows for it.
Fig 2. Three lanes converge on one Drive sheet. The sheet is the source of truth; the starter pack and the inbox lane are conveniences that propose rows for human approval. The drive-sync Lambda mirrors the sheet to S3 so the tracker can read it without hitting Drive on every tick.

Lane 1: the Drive sheet itself

The simplest lane. Open the task list in Drive, add a row, save. The columns are short: name, control area, owner email, how often it repeats, what proof to keep, and the date it was last done. A small Lambda — drive-sync — runs every fifteen minutes, exports the sheet as plain CSV via the Drive API, and writes it to s3://ct-tasklist-source/tasks.csv if the sheet has changed since the last sync. The tracker reads from S3, not Drive directly. That keeps Drive API calls predictable and gives you S3 versioning for free, so a bad bulk-edit can be rolled back in one click.

This lane covers the cases where you know exactly what a control is, how often it repeats, and you can spend thirty seconds typing it in. It’s also where every later edit happens — changing an owner, adjusting a repeat rule, retiring a task.

Lane 2: the starter pack (the fastest way to start)

Typing forty rows by hand is the thing that stops a compliance tracker before it begins. So the second lane ships a set of ready-made packs — a short, sensible list of the controls a business in your industry usually has to run. A cafe gets food-safety checks, cleaning sign-offs, and fire-equipment inspections. A small software shop gets access reviews, backup tests, and an annual security-policy sign-off. A clinic gets sterilization logs, waste-disposal checks, and staff-training renewals.

Pick a pack and the tracker drops its rows straight into the Drive sheet, each pre-filled with a sensible repeat rule (monthly, quarterly, yearly), a proof type (note, photo, signed form), and a placeholder owner. Nothing is set in stone — the pack is a starting point you edit down to what actually applies. Delete the rows that don’t fit, change the owners, adjust a couple of repeat rules, and you have a working list in minutes instead of an afternoon. The packs live as plain templates in the rules folder, so you can tweak them or add your own without touching code.

Lane 3: inbox forwarding

Some controls are buried in a policy document somebody already wrote. The data-retention policy says reviews happen quarterly. The health-and-safety manual lists a monthly walk-through. The IT handbook calls for an annual access review. Re-typing those into the task list is a fight you don’t need to have when the document already says it.

Set up a dedicated inbound address — something like controls@your-company.com — via Amazon SES. Forward a policy or checklist PDF to it and the tracker takes it from there. SES writes the raw MIME to s3://ct-raw-mime/. The S3 PUT triggers a parser Lambda. The Lambda walks the MIME tree to the attachment, runs Amazon Textract on it (Textract reads PDF, PNG, JPEG, and TIFF natively; for a Word document the parser falls back to python-docx), and gets back the text. A Bedrock Haiku 4.5 call then reads the text and suggests a task: name, control area, a repeat rule, and a proof type, with a confidence score per field and a short note on where in the document it found each one. The prompt is short: “Suggest a recurring compliance task for the list. Return JSON only. Do not invent a frequency the text doesn’t state.” The output goes to a Slack message with approve, edit, and discard buttons. On approve, the row is written to the Drive sheet. Every proposed task goes to a human first, because a control the model misread is worse than one that was never added — the misread one will quietly tell you everything is on track.

Why the task list stays the source of truth

Three lanes in, but only one place where the tracker actually looks. That’s a deliberate constraint. If two lanes both wrote directly to the tracker’s state, every “why did this reminder go out?” question would mean checking three places. Funneling everything through the Drive sheet means there is exactly one row per task, and any owner can read or edit any of it without learning a new tool. The convenience lanes are first-class for getting tasks in, but they always pass through the sheet on the way.

Next post: how the scheduler actually reads the list, computes the next due date from each repeat rule, and picks one of four moves.

All posts