# Books

URL: /workflows/processes/books · Id: `process:books`

> Books records every Transaction in one ledger, closes each Period, and files tax at the entity total.

Books records every [Transaction](/business/nouns/transaction) in one ledger, closes each [Period](/business/nouns/period), and files tax at the entity total.

## Outcome
| Part | This Process |
| --- | --- |
| Outcome | Each month’s Period is reconciled, closed and locked, and the Founder has its profit and loss. |
| Reads | [Transaction](/business/nouns/transaction), [Period](/business/nouns/period) |
| Leaves | [Period](/business/nouns/period), [Entry](/business/nouns/entry), [Document](/business/nouns/document) |
| On time | Within 5 days (business hours); the clock stops while an Action waits on `awaitingInput`. Late Actions go to the [Founder](/agents/founding/founder). |
| Runs in | Each Startup |

## Accountable
[Finance Lead](/agents/finance/finance-lead), [Finance Team](/agents/finance).

## Workflows
| Workflow | Runs | Team |
| --- | --- | --- |
| [Monthly close](/workflows/processes/books/monthly-close) | every month | [Finance Team](/agents/finance) |
| [Tax filing](/workflows/processes/books/tax-filing) | every day | [Finance Team](/agents/finance) |

## Who does each step

| Workflow | Step | Role | Calls | Approval |
| --- | --- | --- | --- | --- |
| [Monthly close](/workflows/processes/books/monthly-close) | 1. Reconcile every Stripe Transaction with its Entries. | [Finance Lead](/agents/finance/finance-lead) | [Transaction.reconcile](/business/nouns/transaction/reconcile) | Within a Mandate |
| [Monthly close](/workflows/processes/books/monthly-close) | 2. Recognize revenue on delivered Orders and elapsed Subscription days. | [Finance Lead](/agents/finance/finance-lead) | [Period.recognize](/business/nouns/period/recognize) | None |
| [Monthly close](/workflows/processes/books/monthly-close) | 3. Record payouts and fees. | [Finance Lead](/agents/finance/finance-lead) | [Entry.post](/business/nouns/entry/post) | Asks first; waits 1 business hour |
| [Monthly close](/workflows/processes/books/monthly-close) | 4. Close the Period. | [Finance Lead](/agents/finance/finance-lead) | [Period.close](/business/nouns/period/close) | Within a Mandate |
| [Monthly close](/workflows/processes/books/monthly-close) | 5. Lock the Period once the Founder approves. | [Finance Lead](/agents/finance/finance-lead) | [Period.lock](/business/nouns/period/lock) | Asks first; waits 1 business hour |
| [Monthly close](/workflows/processes/books/monthly-close) | 6. Send the profit and loss to the Founder. | [Finance Lead](/agents/finance/finance-lead) | [Message.create](/business/nouns/message/create) | None |
| [Tax filing](/workflows/processes/books/tax-filing) | 1. Total sales per jurisdiction across every Startup the Company holds, from Stripe Tax. | [Finance Lead](/agents/finance/finance-lead) | [Transaction.list](/business/nouns/transaction/list) | None |
| [Tax filing](/workflows/processes/books/tax-filing) | 2. Register in each jurisdiction whose threshold is crossed. | [Finance Lead](/agents/finance/finance-lead) | [Company.register](/business/nouns/company/register) | Asks first; waits 1 business hour |
| [Tax filing](/workflows/processes/books/tax-filing) | 3. Turn on Stripe Tax collection for new sales there. | [Finance Lead](/agents/finance/finance-lead) | [Setting.update](/business/nouns/setting/update) | None |
| [Tax filing](/workflows/processes/books/tax-filing) | 4. File each return by its deadline and pay the tax due. | [Finance Lead](/agents/finance/finance-lead) | [Company.submit](/business/nouns/company/submit) | Asks first; waits 1 business hour |

## Events
| Direction | When | What happens |
| --- | --- | --- |
| In | Every month | Starts [Monthly close](/workflows/processes/books/monthly-close) |
| In | Every day | Starts [Tax filing](/workflows/processes/books/tax-filing) |
| In | On [`Order.paid`](/business/events/Order.paid) | Wakes this Process, the first time only. A Startup takes its first outside payment. |
| Out | [`Transaction.reconciled`](/business/events/Transaction.reconciled) | Raised by step 1 of [Monthly close](/workflows/processes/books/monthly-close) |
| Out | [`Period.recognized`](/business/events/Period.recognized) | Raised by step 2 of [Monthly close](/workflows/processes/books/monthly-close) |
| Out | [`Entry.posted`](/business/events/Entry.posted) | Raised by step 3 of [Monthly close](/workflows/processes/books/monthly-close) |
| Out | [`Period.closed`](/business/events/Period.closed) | Raised by step 4 of [Monthly close](/workflows/processes/books/monthly-close) |
| Out | [`Period.locked`](/business/events/Period.locked) | Raised by step 5 of [Monthly close](/workflows/processes/books/monthly-close) |
| Out | `Message.created` | Raised by step 6 of [Monthly close](/workflows/processes/books/monthly-close) |
| Out | [`Company.registered`](/business/events/Company.registered) | Raised by step 2 of [Tax filing](/workflows/processes/books/tax-filing) |
| Out | `Setting.updated` | Raised by step 3 of [Tax filing](/workflows/processes/books/tax-filing) |
| Out | [`Company.submitted`](/business/events/Company.submitted) | Raised by step 4 of [Tax filing](/workflows/processes/books/tax-filing) |

## Plays
No Play names this Process.

## Controls
- [Segregation of duties](/systems/trust-and-governance/controls/segregation-of-duties)
- [Reconciliation completeness](/systems/trust-and-governance/controls/reconciliation-completeness)
- [Period sign-off](/systems/trust-and-governance/controls/period-sign-off)

## Settings
| Setting | Type | Default | Say | Set with |
| --- | --- | --- | --- | --- |
| `close.businessDay` | `integer` | `5` | Close the books by the fifth business day | [Setting.update](/business/nouns/setting/update) |
| `close.lockOnApproval` | `boolean` | `true` | Lock each month once I approve it | [Setting.update](/business/nouns/setting/update) |

## Failure
A failed step retries; when retries run out, the Action goes to the [Founder](/agents/founding/founder).

| Step | On failure |
| --- | --- |
| [Monthly close](/workflows/processes/books/monthly-close) 1. Reconcile every Stripe Transaction with its Entries. | Goes to the [Founder](/agents/founding/founder). |
| [Monthly close](/workflows/processes/books/monthly-close) 5. Lock the Period once the Founder approves. | Times out after 5 days. Goes to the [Founder](/agents/founding/founder). |

## Loop
No loop: the path is never randomized, because it serves [Append-only records](/systems/trust-and-governance/controls/append-only-records).

## Code

**Ask**

```text
Turn on books
```

**API**

```bash
curl -X POST https://api.sb/leaseline.app/processes/process_1/enable \
  -H "Authorization: Bearer $STARTUP_BUILDER_API_KEY"
```

**SDK**

```ts
import { $ } from 'startup-builder'

await $.Process.enable({ process: 'process_1' })
```

**CLI**

```bash
npx startup-builder do Process.enable --json '{"process":"process_1"}'
```

**MCP**

```json
{
  "name": "do",
  "arguments": {
    "code": "return await $.Process.enable({ process: 'process_1' })"
  }
}
```

## Enable
On by default for every Product Template. [Process.pause](/business/nouns/process/pause) stops new Actions; Actions in progress finish.

**Ask**

```text
Close the books by the fifth business day
```

**API**

```bash
curl -X PATCH https://api.sb/leaseline.app/settings/setting_1 \
  -H "Authorization: Bearer $STARTUP_BUILDER_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"value":5,"key":"close.businessDay"}'

curl -X PATCH https://api.sb/leaseline.app/settings/setting_2 \
  -H "Authorization: Bearer $STARTUP_BUILDER_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"value":true,"key":"close.lockOnApproval"}'
```

**SDK**

```ts
import { $ } from 'startup-builder'

await $.Setting.update({ id: 'setting_1', value: 5, key: 'close.businessDay' })
await $.Setting.update({ id: 'setting_2', value: true, key: 'close.lockOnApproval' })
```

**CLI**

```bash
npx startup-builder do Setting.update --json '{"id":"setting_1","value":5,"key":"close.businessDay"}'
npx startup-builder do Setting.update --json '{"id":"setting_2","value":true,"key":"close.lockOnApproval"}'
```

**MCP**

```json
{
  "name": "do",
  "arguments": {
    "code": "await $.Setting.update({ id: 'setting_1', value: 5, key: 'close.businessDay' })\nreturn await $.Setting.update({ id: 'setting_2', value: true, key: 'close.lockOnApproval' })"
  }
}
```

## Example
A bookkeeping service records 312 payments and 41 bills in one month. [Monthly close](/workflows/processes/books/monthly-close) reconciles them, locks the Period on the third working day, and sends the profit and loss. [Tax filing](/workflows/processes/books/tax-filing) registers in a new state the week sales there cross the threshold.