# Prompt: First-Pass 280E Classification

Sorts a month of transactions into a 280E-aware chart of accounts, with a reason and a confidence per line, so your CPA reviews a sorted pile instead of a raw export. From lesson 04-04 of Distru's No Bullshit AI Course. Version 1.0, tested 2026-09-17 with a frontier chat model on 40 fake transactions. CC0 1.0.

**This is not tax advice.** IRC §280E denies deductions and credits to businesses trafficking in Schedule I or II substances; cost of goods sold is not a deduction and survives, which is why the split matters ([26 U.S.C. §280E](https://www.law.cornell.edu/uscode/text/26/280E)). What counts as COGS for *your* license type, in *your* state, under *your* method (§471, and for some entities the older §263A reading) is your CPA's call. The model proposes a bucket; a licensed professional decides and signs.

Pairs with `280e-chart-of-accounts.csv`. Replace that sheet with your own before you run this; the model can only use the accounts you give it.

## Before you paste

- Export from your bank, card or bookkeeping tool. Columns: `date, payee, description, amount`. Add `memo` if you have one.
- Strip employee names and anything that identifies a customer or patient. Payee company names are fine.
- Twenty to a hundred rows per run. More than that and the model starts skimming.
- Paste your chart of accounts (the CSV) above the transactions, every time. It does not remember last month.

## The prompt

```
You are a bookkeeper's assistant for a licensed cannabis business. You sort transactions; you do not give tax advice and you never decide what is deductible.

License type: [retail / cultivation / manufacturing / distribution]. State: [state]. Month: [YYYY-MM].

Here is our chart of accounts. Use ONLY these account codes:
[paste 280e-chart-of-accounts.csv]

Here are the transactions:
[paste rows: date, payee, description, amount, memo]

For every transaction, return one row with exactly these columns:
date | payee | amount | account_code | account_name | cogs_bucket | confidence | reason | flag

Rules:
- cogs_bucket is one of: COGS, NON_COGS, SPLIT, UNSURE. Use SPLIT when one payment clearly covers both (rent on a building with a grow room and a sales floor, a manager's salary who both trims and sells). Use UNSURE when you cannot tell from the description.
- confidence is 0.00 to 1.00. Be honest: a vague payee with a round amount is not a 0.95.
- reason is one sentence quoting the words in the transaction that drove the choice. Do not invent a purpose that is not in the description.
- flag is blank, or one of: NEW_PAYEE, ROUND_AMOUNT, DUPLICATE?, PERSONAL?, NEEDS_INVOICE, SPLIT_NEEDS_ALLOCATION.
- Never put a transaction in COGS because it would be nice if it were. Put it where the description says it belongs; the CPA moves it if the method allows.
- If a transaction matches no account, use code 9999 UNSORTED with confidence 0.
- Output the table only, then a three-line summary: count per cogs_bucket, total dollars per cogs_bucket, and the five lowest-confidence rows.
Use only the information I gave you. If something is missing, say MISSING instead of guessing.
```

## What a good result looks like

- Every row has an account code from your sheet and nothing else. If you see a code you did not give it, the run is bad; rerun.
- SPLIT and UNSURE rows exist. If a month comes back 100% confident, the model is flattering you.
- Reasons quote the transaction ("payee 'Metro Power', description 'grow bldg meter'"), not a story.
- Dollar totals per bucket add up to the export total. Check this in a spreadsheet, not by eye, and never trust the model's arithmetic over the sheet's.

## Then

Sort by confidence ascending. Everything under about 0.85, every SPLIT and every UNSURE goes in a short list to your CPA with the reason column attached. Do it monthly. The 280E lesson explains why year-end is too late to have this conversation.

## Known failures (we saw these)

- Puts payroll in COGS wholesale. Trimmers and packagers may be; budtenders and sales reps are the classic non-COGS example at retail. The model does not know who does what; give it job titles or expect SPLIT.
- Calls a security system COGS because "cannabis requires security." Compliance-required does not mean cost of goods. Your CPA decides; the prompt tells the model not to reason this way, and it sometimes does anyway.
- Guesses a payee's business from its name. "Green Fern LLC" could be anything. Watch for NEW_PAYEE flags and fill in memos next month.
