Step 0 — Orient from the register, not from memory
This is a fresh session — there is no prior turn to resume. {{vendor_register}}
is the memory.
Open {{vendor_register}} and read every existing row: vendor name, contact,
date received, status of each of the three documents, overall flag, and the
Gmail thread ID recorded in the last column. This is what this run's new
requests get checked against so nothing is processed twice.
Step 1 — Pull new vendor requests
Check {{request_label}} in Gmail for threads not yet reflected in
{{vendor_register}} (match on Gmail thread ID). For each one, identify the
vendor name, the contact email, and every attachment.
Step 2 — Validate against the fixed checklist
Every vendor gets the same three checks, no exceptions:
- W-9 — a completed IRS Form W-9: legal name, TIN or EIN filled in, and a
signature with a date. Missing any field, or unsigned → invalid.
- Banking form — bank name, account number, and routing number all
present, and the form signed. Check completeness only; do not extract or
transcribe the account or routing number anywhere. Missing a field or
unsigned → invalid.
- Signed contract — a signature present, dated, and the vendor's legal
name matching the name on the W-9 and the banking form. A name mismatch,
missing signature, or missing date → invalid.
If any of the three documents is absent entirely, record it as missing
rather than invalid — don't guess at content that isn't there.
Step 3 — Cross-check vendor identity
Compare the legal name across all three documents and the contact email's
domain against the vendor name. A mismatch (different entity name on the
contract than the W-9, or a contact email that doesn't plausibly belong to the
vendor) is its own flag, even if each document is individually complete —
note it as name-mismatch.
Step 4 — Record every vendor, flagged or clean
Append or update one row per vendor in {{vendor_register}}: vendor name,
contact email, date received, W-9 status, banking form status, contract
status, overall flag (clean / missing / invalid / name-mismatch, or a
combination), and the Gmail thread ID. Never leave a request unrecorded for
being incomplete — an incomplete vendor is still a row, flagged.
Step 5 — Draft a follow-up for anything missing or invalid
For every vendor with any flag, create a Gmail draft addressed to the vendor's
contact naming exactly what's missing or needs correction (e.g. "the W-9 is
unsigned," "the contract lists a different legal entity than the W-9"). Save
it as a draft only — never send it.
Step 6 — Post the batch for review
Post to {{review_channel}}: every vendor processed this run, grouped clean
vs. flagged, each with its register row and, for flags, the specific document
and issue. Note that a draft follow-up exists for each flagged vendor, waiting
to be reviewed and sent.
Step 7 — Stop — never approve, never touch payment or banking
Your last action is the Slack post. You never mark a vendor approved, and you
never schedule, configure, or write to any payment method, ACH setup, or
banking profile in any system — not even for a vendor whose three documents
are fully complete and consistent. That decision, and the setup that follows
it, is always a person's.
1---2name: vendor-doc-intake3description: Daily vendor-onboarding intake for {{request_label}}. Validates the W-9, banking form, and signed contract for every new vendor request against a fixed checklist, records every vendor's status in {{vendor_register}}, drafts a follow-up for anything missing or invalid, and posts the batch to {{review_channel}}. Load this before checking a single vendor so every one is held to the same standard and the agent never approves a vendor or touches payment or banking setup.4---56<skill name="vendor-doc-intake">78<overview>9Process every new vendor request landing in `{{request_label}}` without missing10a missing or invalid document, and without ever moving toward approval or11payment. A cron fires every `{{cadence}}` against a fresh session; the session12has no memory of the last run, so it reads `{{vendor_register}}` first, pulls13new request email, checks the W-9, banking form, and signed contract against a14fixed checklist, records the result, and posts the batch to Slack. Recording15and flagging are the agent's job; approving a vendor and setting up payment or16banking are not — those stay with a person, on every vendor, complete17paperwork or not.18</overview>1920<when-to-load>21- The `{{cadence}}` cron fires the intake run.22- A human asks the agent to re-check a specific vendor's document status.23- A human asks why a vendor was flagged or what's still missing.24</when-to-load>2526<workflow>2728## Step 0 — Orient from the register, not from memory2930This is a fresh session — there is no prior turn to resume. `{{vendor_register}}`31is the memory.3233Open `{{vendor_register}}` and read every existing row: vendor name, contact,34date received, status of each of the three documents, overall flag, and the35Gmail thread ID recorded in the last column. This is what this run's new36requests get checked against so nothing is processed twice.3738## Step 1 — Pull new vendor requests3940Check `{{request_label}}` in Gmail for threads not yet reflected in41`{{vendor_register}}` (match on Gmail thread ID). For each one, identify the42vendor name, the contact email, and every attachment.4344## Step 2 — Validate against the fixed checklist4546Every vendor gets the same three checks, no exceptions:4748- **W-9** — a completed IRS Form W-9: legal name, TIN or EIN filled in, and a49 signature with a date. Missing any field, or unsigned → **invalid**.50- **Banking form** — bank name, account number, and routing number all51 present, and the form signed. Check completeness only; do not extract or52 transcribe the account or routing number anywhere. Missing a field or53 unsigned → **invalid**.54- **Signed contract** — a signature present, dated, and the vendor's legal55 name matching the name on the W-9 and the banking form. A name mismatch,56 missing signature, or missing date → **invalid**.5758If any of the three documents is absent entirely, record it as **missing**59rather than invalid — don't guess at content that isn't there.6061## Step 3 — Cross-check vendor identity6263Compare the legal name across all three documents and the contact email's64domain against the vendor name. A mismatch (different entity name on the65contract than the W-9, or a contact email that doesn't plausibly belong to the66vendor) is its own flag, even if each document is individually complete —67note it as **name-mismatch**.6869## Step 4 — Record every vendor, flagged or clean7071Append or update one row per vendor in `{{vendor_register}}`: vendor name,72contact email, date received, W-9 status, banking form status, contract73status, overall flag (`clean` / `missing` / `invalid` / `name-mismatch`, or a74combination), and the Gmail thread ID. Never leave a request unrecorded for75being incomplete — an incomplete vendor is still a row, flagged.7677## Step 5 — Draft a follow-up for anything missing or invalid7879For every vendor with any flag, create a Gmail draft addressed to the vendor's80contact naming exactly what's missing or needs correction (e.g. "the W-9 is81unsigned," "the contract lists a different legal entity than the W-9"). Save82it as a draft only — never send it.8384## Step 6 — Post the batch for review8586Post to `{{review_channel}}`: every vendor processed this run, grouped clean87vs. flagged, each with its register row and, for flags, the specific document88and issue. Note that a draft follow-up exists for each flagged vendor, waiting89to be reviewed and sent.9091## Step 7 — Stop — never approve, never touch payment or banking9293Your last action is the Slack post. You never mark a vendor approved, and you94never schedule, configure, or write to any payment method, ACH setup, or95banking profile in any system — not even for a vendor whose three documents96are fully complete and consistent. That decision, and the setup that follows97it, is always a person's.9899</workflow>100101<guardrails>102- **No approval, ever.** The agent has no connector or instruction that marks103 a vendor approved — not even for a fully clean, matched set of documents.104 That step is always a human's.105- **No payment or banking action, ever.** The agent never sets up, schedules,106 or writes to a payment method, ACH enrollment, or banking profile in any107 system, regardless of document completeness.108- **No sensitive data at rest in the register.** Bank account and routing109 numbers are checked for presence and completeness on the source form but110 never transcribed into `{{vendor_register}}` — only a status.111- **Record, don't discard.** A vendor with a missing or invalid document is112 still recorded in `{{vendor_register}}` with its flag — never silently113 dropped or skipped.114- **No force-validating.** Don't infer a signature, a TIN, or a name match115 that isn't actually on the document. Flag it as missing or invalid instead116 of assuming it's fine.117- **Drafts, never sends.** Every outbound email to a vendor is created as a118 Gmail draft. A human reviews and sends it.119- **Scoped, brokered credentials.** Gmail and Google Sheets access are120 injected into the sandbox at runtime, scoped to this agent's grant.121- **Idempotent per run.** Match new requests against `{{vendor_register}}`'s122 Gmail thread IDs before processing so the same request is never recorded123 twice across runs.124</guardrails>125126</skill>