Case study
Project Falcon. What we built, what we checked, and what it does not prove.
A finance team inside a private equity portfolio ran this on live client books. Not a demo. Here is what it did. The five rules that came first. What we chose not to build. And the one thing that went wrong.
We call this work Project Falcon. The client is not named.
The same month, over and over.
A finance team in a private equity portfolio closes the same month, over and over. It does this for many companies. They do not share a chart of accounts. Or a calendar. Or a bookkeeper. No one piece of the work is hard. It is hard because it is the same work, again and again, on a deadline. And no one can hold the whole picture at once.
That is a private equity portfolio. It is also a CAS practice with thirty clients. Swap the word “company” for the word “client”. The shape of the problem does not change.
One platform. The whole month.
It runs on QuickBooks Online. It covers the month, not a slice of it. It ran in production, on live client books.
On a timerEleven jobs run this on a schedule. Everything that writes goes through one approval queue. There is no second path.
- The close
- A close cockpit. A flux review. Flags for odd items. A morning briefing.
- The money
- Cash, thirteen weeks out. Loan terms, tracked through two lenses. AR, AP and collections.
- The reporting
- Statements and board reports. Plans and forecasts. The cap table.
- The technical accounting
- ASC 842 leases. ASC 606 revenue. ASC 326 CECL. ASC 205-40 going concern. The tax package and the PBC binder, put together.
Five things had to be true first.
Software that reads your books is a reporting tool. Software that writes to them is a different thing. The difference is not a feature you add. It is a set of rules you build before you build anything useful. These five came first.
In the code, not on a slideEach rule is enforced in the code. Some have a test that fails if the rule is broken.
-
Plain code makes each number.
Every figure that reaches the books is worked out by plain code. Not by the AI. Same input, same answer, every time. The code uses exact decimals. It rounds half up. Before any row goes out, the code checks a sum. The parts must add up to the whole price. The last row plugs the liability to the cent. If the sum does not hold, the code stops with an error.
The AI is not in that path. It can ask the code for a figure. It can explain one. It cannot make one.
The AI never makes a number. Code does.
-
A person makes the judgment call. Code never does.
Some inputs need a person’s judgment. The standalone selling price. The percent of the work done so far. The locked lease rate. The yes-or-no calls under ASC 606 and ASC 842. Each one is a required input. The server checks that it is there.
There is a flag in the code. It says whether the code may judge those calls from the text of a contract. It is off, for the life of the code. A test fails if anyone turns it on.
The code will not read a contract and decide if revenue is booked over time. A person answers that. The code does the math that follows from the answer.
This is where most of the field gets it wrong. Reading a contract and making the call is the part your licence covers. Working out a schedule from a call already made is a different thing. That should have been automated ten years ago.
The flag is named
ENGINE_SELF_EVALUATES_CRITERIA_FROM_TEXT. It is false. A test keeps it false. -
It drafts. Someone else says yes.
No tool the AI can call does anything to the books. A call that would change them makes a proposal, marks it pending, and stops. The power to change a client’s books lives in the back end. It never lives in what the AI writes.
When a proposal is approved, it is approved by someone other than the person who prepared it. That is enforced in code, on all three approval lanes. It is not a setting that gets switched off in a busy week. Before it posts, the system claims a one-time key, so the same post cannot land twice. It checks that the period is open. And if a write times out and no one knows if it landed, there is a set way to check and put it right.
A bad guess from the AI is a bad draft, which someone reads. Not a bad journal entry, which someone finds in March.
-
A yes is tied to one action, not to a chat.
A person confirms an action. That yes is tied to that one action. The system takes a fingerprint of it: the trusted scope, and what it will do. It uses SHA-256 for this. When it is time to post, it takes the fingerprint again. It compares the two, in constant time. If anything about the action changed after the yes, it does not run.
The scope keys, which company and which realm, are stripped out of anything the AI touched. They are put back from a trusted source. The AI never supplies them.
“The user confirmed” is a thing an AI can write. A fingerprint is not.
-
It has to be able to say no.
There are hooks in front of every path that writes. And there is a test suite with one job. It confirms the system says no when it should. If the input is missing or cannot be read, the system returns nothing. Or it says “not available”. Or it gives a typed error. It never returns a made-up zero.
The same rule covers what reaches a person. The tax package and the PBC binder put documents together. They compute no tax. They mark no requirement as met. They carry no confidence score. A handoff that reads like an assurance opinion is worse than no handoff at all.
Most testing asks if software does the thing. This asks if it says no, when saying no is right. That is the harder question. It is the one that matters when the input is a client’s live books.
Most tests ask if it works. These ask if it says no when it should.
Where your clients’ data goes.
Firms ask this second or third. Most vendors answer it with a badge.
The AI runs on the providers’ API tier. Both providers’ terms say customer data is not used to train their models. That is a fact about someone else’s business. So check it again at each renewal. Do not take it on faith.
What is ours, and can be checked in the code:
Left out, on purposeNo training on customer data. No reuse of prompts or answers across firms. No pulling one firm’s data into another’s run. What one client’s books taught it stays with that client.
- The usage log
- It records counts and costs. It never stores what was sent or what came back. Our own database is not a shadow copy of what went to the AI.
- The pipelines
- They send computed figures and structured sections. Not whole books. The step that drafts the board notes sees section data. Not the ledger.
- The logs
- Financial data is cut from the logs. Error logs too.
- The keys
- Each firm on the platform has its own keys. A firm that wants its own deal with a provider can bring one. Then its data rides on its own contract.
Who made the call.
Every approved action carries an evidence pack. What was proposed. On what basis. Who approved it. And when.
Each client’s data is kept apart from the rest. The app checks this on every query. Under that sits a backstop. Row-level security, on all 97 tables. If someone forgets to set the scope, the query returns nothing. Not some other client’s books.
No regulator asked for that. It is there for a plain reason. Show a journal entry the software made to anyone with sense. They will ask: who decided it? If the honest answer is “the software did”, no firm that signs its name to the number can use it.
What we chose not to build.
Two things this platform does not do. We list them because the gaps describe it better than the feature list does.
- It does not learn across clients.
- Nothing seen in one client’s books changes how another’s are treated. That leaves real accuracy on the table. It is not close to worth the other choice.
- Three engines it does not have.
- No tax engine. No inventory engine. No FX engine. Those are specialist fields, with their own ways to fail and their own liability. It links to that work. It does not pretend to do it.
We write down what does not work yet.
The system’s own design document grades each of its layers. Some are marked mature. Some are marked recent: real, tested, and new enough that we say so. It carries an open backlog with named items on it.
That is not modesty. It is the same discipline as everything above. A system that will not give a number it cannot stand behind gets built by people who write down what does not work yet.
If you are deciding whether to let someone build a thing that touches your clients’ books, that is what to check. Not the demo.
What went wrong
One thing went wrong. The odd-item check flagged normal, day-to-day transactions as odd. That was noise a person had to review and wave through. The fix was not glamorous. It needed more training on what normal looks like, and it got it. No guardrail failed. Every false flag was a draft someone read. Not an entry someone found. That is the failure mode this system was built to have.
The order is the part worth repeating. The five rules came first. Nothing useful was built until they held. How long it took is not a benchmark for another build. It is not a promise for your firm.
What to ask a builderNot for the demo. For the document that grades its own layers, and the list of what does not work yet.
A CAS team does the same job.
We built this for a private equity finance team. It ran a close across a portfolio of companies. A CAS team runs a close across a portfolio of clients. That is the same job, with the same shape. The same repeat work. The same deadline. The same problem of no one holding the whole picture. The rules do not change.
The same goes for the case to build, not buy. A platform sold to you was built for someone else’s portfolio.
See what this looks like on your own close.
Start with a close teardown. 45 minutes on your own close: the checklist, the calendar, the client you argue with most. You get one written page about it after. Free, five a month. You owe nothing at the end.
No access, no passwords, nothing installed. You share a screen and we talk.
HoursWeekdays, 09:00 – 17:00 Central
WhereMcKinney, Texas
Build with usWe want experts in other fields →