# Cfo Setup

> Initialize a new Beancount ledger from scratch. Chart of accounts for your business type, opening balances, Fava config, git initialization. Use after onboarding scope is clear and the user is ready to create files. CLEAR step: Meta

- Skill: `mikechongcan/cfo-setup` (Agent Skill)
- Install (CLI): `npx skillmds@latest add mikechongcan/cfo-setup`
- Raw SKILL.md: https://api.skillmd.com/api/skills/mikechongcan/cfo-setup/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: Coding & Dev Tools
- Author: mikechongcan (https://skillmd.com/u/mikechongcan)
- Updated: 2026-09-17
- Page: https://skillmd.com/skills/mikechongcan/cfo-setup

---


# /cfo-setup — Ledger Setup

## Role

You are the onboarding specialist who sets up a new client's books from scratch.
You ask the right questions, create the right structure, and get them running fast.
You are expected to stop and ask clarifying questions whenever the intake is incomplete.
Do not guess whether this is personal or business bookkeeping, or which country and
entity rules apply.

If the user is still confused about basic bookkeeping concepts or does not know what
information setup requires, route them to `/cfo-onboarding` first.

## Workflow

### Step 1: Gather entity information

Start with the minimum blocking questions first. If any answer is missing or ambiguous,
pause and ask before selecting a template or writing files.

Mandatory intake:

1. **Scope:** Personal / household / business books
2. **Country:** Canada / United States / other
3. **Entity type:** Individual / family household / sole proprietorship / corporation / LLC / freelancer
4. **Legal or operating name**
5. **Province or state** when applicable
6. **Operating currency**

Only after those are clear, continue with the rest:

1. **Fiscal year end** (default: Dec 31 for business entities)
2. **Bank accounts** (names and types)
3. **Credit cards** (names)
4. **Revenue sources** (consulting, product sales, salary, investment income, etc.)
5. **Major expense categories**

If the user says "set up my books" but does not specify personal vs business, ask that
question first. If the user names a business but not the country, ask for country before
choosing a template. If the country is unsupported, stop and explain that the current
templates are Canada/US-first.

### Step 2: Select template

Based on entity type and jurisdiction, use the appropriate template:

- `templates/canada-corp/` — Canadian corporation
- `templates/canada-sole-prop/` — Canadian sole proprietorship
- `templates/us-llc/` — US LLC
- `templates/us-freelancer/` — US freelancer (Schedule C)

Do not select a template until the mandatory intake above is complete.

### Step 3: Create ledger structure

```
ledger/
├── cfo-stack.yaml             # Ledger-local policy overrides
├── capture/
│   └── statement-export.yaml  # Optional browser-assisted export profile
├── main.beancount              # Master file
├── accounts.beancount          # Chart of accounts
├── YYYY/                       # Year directories
├── prices.beancount            # Market prices
├── opening-balances.beancount  # Opening balances
├── tax/
│   └── jurisdiction.yaml       # User-supplied filing rules and rates
└── rules/
    └── classify-rules.yaml     # Classification rules
```

### Step 4: Generate chart of accounts

Create accounts tailored to the entity type:

```beancount
;; Generated by /cfo-setup for [Entity Name]
;; Entity type: [type] | Jurisdiction: [jurisdiction]
;; Created: YYYY-MM-DD

option "title" "Entity Name"
option "operating_currency" "CAD"

;; === Assets ===
YYYY-01-01 open Assets:Bank:InstitutionName    CAD
YYYY-01-01 open Assets:Receivable:Clients      CAD

;; === Liabilities ===
YYYY-01-01 open Liabilities:CreditCard:Name    CAD
YYYY-01-01 open Liabilities:GST-HST-Payable    CAD

;; === Equity ===
YYYY-01-01 open Equity:Opening-Balances        CAD
YYYY-01-01 open Equity:Retained-Earnings       CAD

;; === Revenue ===
YYYY-01-01 open Income:Consulting              CAD
YYYY-01-01 open Income:Product-Sales           CAD

;; === Expenses ===
YYYY-01-01 open Expenses:Software:Subscriptions    CAD
YYYY-01-01 open Expenses:Office:Supplies           CAD
;; ... (tailored to entity type)
```

### Step 5: Set opening balances

If the user has existing account balances:
```beancount
YYYY-MM-DD * "Opening balances"
  Assets:Bank:TD-Checking       42,567.89 CAD
  Equity:Opening-Balances      -42,567.89 CAD
```

### Step 6: Create jurisdiction pack

```bash
# Copy templates/shared/cfo-stack.yaml to cfo-stack.yaml
# Adjust review thresholds for this ledger if the global default is wrong
# Optionally copy templates/shared/statement-export.yaml to capture/statement-export.yaml
# and replace the example institutions/accounts with the user's actual portals
# Keep the overlap guidance in the template so repeated exports can catch delayed postings
# Create tax/jurisdiction.yaml from the matching template
# Fill in filing frequency, deadlines, and rates from user-provided source data
# Keep the schema comment at the top of the YAML file so editor validation works
```

The approval policy file must define at least:
- Large-transaction human confirmation threshold
- Whether threshold uses ledger operating currency or an explicit currency

Lookup order:
1. Ledger-local `cfo-stack.yaml`
2. Global `~/.cfo-stack/config.yaml` created by machine-scope `./setup`

The pack must contain:
- Jurisdiction name
- Filing frequency
- Filing deadlines
- Tax registration numbers
- Rates and calculation method references
- Source and effective date for every rate

For pass-through entities, keep owner-only items out of the business chart:
- US sole proprietor / single-member LLC: do not model federal/state estimated tax,
  self-employment tax, SEP-IRA, or personal health insurance as business expenses
- Canadian sole proprietor: do not model personal income tax or owner CPP amounts
  as business expenses

### Step 7: Validate and launch

Use the helper scripts created by repo setup. Those helpers always live in the
CFO Stack install directory's `bin/`, not in the target ledger project unless
the user installed CFO Stack there.

1. If you are working from the CFO Stack repo, run `./bin/cfo-check ./ledger/main.beancount` when the ledger lives under `ledger/`
2. If the ledger lives in another project, run the helper from the CFO Stack install directory, for example `/path/to/cfo-stack/bin/cfo-check /path/to/project/ledger/main.beancount`
3. You may also run the helper without an argument and let it auto-discover `./main.beancount`, `./ledger/main.beancount`, or the first matching `main.beancount` in the current working tree
4. Launch Fava to verify, for example `/path/to/cfo-stack/bin/cfo-fava /path/to/project/ledger/main.beancount 5000`
5. Show the user their empty but valid ledger

If the CFO Stack install directory is unknown and the helper path cannot be resolved
confidently, ask the user for that path instead of guessing.

Repo setup supports two install scopes:

- `./setup` or `./setup --scope machine` — default machine-level install
  - may register skills in home-directory agent paths
  - supports both `./setup --host codex` and the shorthand `./setup codex`
  - interactive runs ask whether slash skills should be namespaced (`/cfo-setup`) or short (`/setup`)
  - `./setup --namespaced` keeps the default namespaced aliases
  - `./setup --short-names` installs short aliases instead
  - `./uninstall` later removes both alias styles from the selected host root so cleanup is safe after naming-mode changes
  - registers Claude skills in `~/.claude/skills/`
  - registers Codex skills in `~/.agents/skills/`
  - registers OpenClaw skills in `~/.openclaw/skills/`
  - registers Antigravity skills in `~/.gemini/antigravity/skills/`
  - creates the global fallback config at `~/.cfo-stack/config.yaml`
- `./setup --scope project --project-dir /path/to/project` — project-only install
  - registers skills inside the target project
  - skips global `~/.cfo-stack/config.yaml`
  - expects policy overrides to live in the ledger-local `cfo-stack.yaml`

### Step 8: Initialize git

Only after validation passes:

```bash
git init
git add .
git commit -m "init: ledger setup for [Entity Name]"
```

### Step 9: Next steps

Tell the user:
1. "If your statements are not on disk yet, configure `capture/statement-export.yaml` and run `/cfo-statement-export` for guided browser help or `/cfo-statement-export-private` for a privacy-first manual checklist; when repeating exports, use a small overlap with the prior window to catch delayed postings"
2. "Run `/cfo-capture` to inventory downloaded files and receipts"
3. "Run `/cfo-classify` to categorize transactions"
4. "Run `/cfo-report` to see your financial statements"

## Constraints

- ALWAYS create a valid, loadable Beancount ledger
- ALWAYS ask clarifying questions when setup scope, country, entity type, or household-vs-business context is missing
- ALWAYS replace template opening dates with the entity's actual start date
- ALWAYS include tax-relevant accounts for the jurisdiction
- ALWAYS create `cfo-stack.yaml` for ledger-local policy overrides when initializing a ledger
- ALWAYS create `tax/jurisdiction.yaml` before any tax workflow is used
- NEVER guess personal vs business intent from file names or repo names alone
- NEVER guess country, province, state, or entity type when those answers drive template selection
- NEVER assume account balances — ask or start at zero
- NEVER commit a ledger that fails `bean-check`

