# How we run the month-end close

Each month our Machine finance agent works the close checklist, ties Stripe revenue to the Google Sheets ledger, flags odd numbers and missing docs, and posts open items to Slack. A person closes the books.

Canonical page: https://themachine.myapps.ai/use-cases/month-end-close

Closing the month is the same routine every time, and it still eats several
days. There's a checklist with a few dozen lines. Revenue has to match the
ledger. Missing receipts and contracts need chasing. Then someone eyeballs the
totals against recent months before anything gets signed. Not one of those
steps is difficult. Together they crawl, and most of the effort goes into
proving that the boring 90% is fine so the team can get to the 10% that
isn't.

So an agent on Machine now takes the first pass each month. It matches our
Stripe revenue to the ledger, goes down the rest of the checklist looking for
missing paperwork, points out numbers that look unusual next to previous
months, and posts what's still open in our finance channel on Slack. Journal
entries are off limits, and so is marking the period closed. That call stays
with a person.

- **Team:** Machine
- **Runs on:** A schedule that fires once a month
- **Connected systems:** Stripe · Google Sheets · Slack
- **Mode:** Gathers and flags · a person closes the books

## The problem

The list of tasks isn't what slows the close down. The drag is checking the
same kinds of things over and over. Does booked revenue match what Stripe
really took in? Does each line have the backup document it should? Has any
number shifted far enough from recent months that someone will ask why? Any
one of those takes minutes. All of them, done carefully, in a week already
full of other close work, is where the time disappears.

A formula in the spreadsheet will catch a perfect match, but a near miss slips
past it. It also has no idea what "looks off" means unless a person brings
that judgment, fresh, every month. So the whole checklist gets done by hand,
at full cost, month after month, and it's only as thorough as the calendar
allows.

## What we built

Once the period has ended, a monthly **cron** wakes a close agent on Machine.
Every run gets its own fresh cloud computer, or sandbox, that can read Stripe
revenue plus the checklist and ledger tabs of a Google Sheet. The agent ties
Stripe revenue to what the ledger booked, goes through the remaining checklist
items for missing backup, compares this month with the trailing months to spot
anything unusual, and posts a close-status summary to Slack listing every open
item. Its job is to gather and flag. It never books a journal line and never
signs off the close.

## How it works

### Fire once a month, after the period ends

A **cron** trigger is a timer, and this one goes off monthly, after the
previous period has wrapped up. Each time, Machine starts a new **session**: a
clean sandbox used only for that run. The checklist and the ledger sheet hold
the history, so the agent doesn't need to remember anything from last month.

### Write down what 'done right' means

The agent's **skills** and **memory** are its playbook, and it reads them
before looking at a single number. They spell out when a line counts as
matched, how much slack a timing lag is allowed, which document each checklist
item needs, and how large a jump against the trailing months earns a flag. The
same yardstick applies every month.

### Connect the close, read and flag only

Every tool is reached through a **connector**, a narrow link whose keys stay
on our servers, so the model never sees a raw token. That lets the agent:

- **Look at Stripe.** Revenue, refunds and payouts for the period just closed.
- **Look at the ledger tab.** What got booked for that period, to compare
against Stripe.
- **Look at and mark the checklist tab.** It sees where every close item
stands and adds its own notes and flags there. The ledger's booked entries
are never touched.
- **Message Slack.** One close-status summary with every open item.

### Set the limits

Matching and flagging is the whole job. Closing is not. The agent will not
write a journal entry, change an amount already in the ledger, or tick the
period off as closed. That decision, and anything that follows from it, is a
person's. Credentials are stored encrypted in the **Secrets Manager** and only
handed to the agents you grant them to.

### Post what's still open

Once that's all wired up, each month brings a fully worked checklist and a
single Slack message. It lists what still doesn't reconcile, which items lack
paperwork, and which numbers moved far enough from the trend to deserve a
look. Each entry carries enough detail that nobody has to pull the figures
again to act on it. Finance reads the list, then closes the books themselves.

> **The pattern**
> A **cron** once a month starts a clean session that can read Stripe and can
> read and flag the checklist and ledger in Google Sheets. Matching tolerances
> and anomaly rules sit in the agent's **skills** and **memory**. It gathers
> and flags every open item, and a person closes the books.

## Guardrails

Letting software near the company close is mostly about trust, so access is
narrow and runs in one direction:

- **Isolation.** Each run has a sandbox to itself and can only reach the
  systems it was given. The checklist flags and the Slack message are the only
  things it sends back out.
- **Scoped secrets.** The Stripe and Sheets keys are stored encrypted in the
  **Secrets Manager** and only handed to the agents you grant them to, when the
  sandbox starts.
- **No journal entries, no closing the books.** It can't add a journal line,
  change a booked ledger amount, or mark any checklist item or the period as
  closed. The agent flags. A person closes.
- **Everything is code.** Checklist rules, tolerances and the permissions for
  each system are versioned files in the repo, changed only through a reviewed
  **change request**, never a dashboard toggle.

## The outcome

- **Every month:** The full checklist, worked against this month's numbers
- **Flag only:** The agent books no journal entries and closes no periods
- **One post:** Unmatched lines, missing docs and odd numbers, all in one list

The days we used to spend confirming the easy 90% now go to the short list the
agent actually raised. The first pass happens on schedule whether or not
anyone has found time for it, and when finance sits down to close, the open
items are already waiting in Slack.
