Nobody reads the expense policy, and the people who enforce it are checking receipts by hand. Here is the model behind a checker that reads the claim, the prompts to build it, and what it takes to run it.
Your private status link is on its way to your inbox.
An expense policy checker is four parts: the policy expressed as rules rather than prose, a claim structure to evaluate them against, a result that explains itself, and a review path for the ambiguous cases. The mistake is trying to automate the decision. What you want to automate is the reading: a reviewer should see "this dinner is 40 over the limit for this city and has no attendee list" rather than a receipt and a policy PDF. Build it as an explainer, not a judge.
Expense checker
11
Waiting on you
183
Cleared without review
6
Exceptions this month
2
Rules exceptioned repeatedly
Category
Dinner, client
City
London
Amount
98.00
Receipt
Attached
Dinner limit for London is 60
Over by 38
Needs review, not a blocker
Attendee list
Missing
Blocker. Client dinners need who was there.
You own the expense policy, or you approve claims against one. You already know your limits and your categories. What you want is for the obviously fine claims to stop consuming review time, and for the exceptions to arrive already explained.
What happens to a claim, and why most of them never reach a reviewer.
A claimant can test a draft claim against the policy and see exactly what it would flag. Most breaches are people not knowing the limit.
Every applicable rule runs against it and produces a sentence: what it checked, what it found, and the gap.
Anything with no findings is approved and never enters the queue. If everything needs review, the tool is re-approving what was already fine.
A reviewer sees the claim, the failing rules in plain language, the receipt and the claimant's recent history, on one screen.
Approving outside policy requires a reason from a short list. Those reasons become the report that tells you which rule is wrong.
A rule exceptioned every week is a rule that needs rewriting, and now you can prove it.
A policy checker is not an approval bot. It is four parts, and the third one is what decides whether people trust it.
Your policy as data: limits per category, per city, per role, receipt thresholds, required fields, banned categories, and the date ranges each version applies to. One file, edited by the policy owner.
What the checker evaluates: claimant, date, category, amount, currency, merchant, attendees, project or cost centre, receipt attached or not.
Not pass or fail. Per rule: what it checked, what it found, and the gap. A reviewer should be able to read the result and never open the policy document.
Where the ambiguous ones go, with an exception mechanism that records who approved and why. Exceptions are data, and the pattern in them is usually a sign the policy needs changing.
These prompts start from a Helix project, which is what handles sign-in, credentials and hosting. Start with Helix
Paste these into Claude Code, Codex or Cursor in order. Each one leaves you with something that runs, so you can stop after any step.
Rules in one file, claims in another, and nothing hardcoded.
In this Helix project, build me an expense policy checker.
The most important design decision comes first: the policy lives in one
file that I can edit, not scattered through the code. Limits change by
city, by category, by seniority and by season, and a policy encoded across
a codebase stops being maintainable within a month.
So: a rules file with per-category limits, per-city overrides, the receipt
threshold, which fields each category requires, banned categories, and the
date each version takes effect. Load it at runtime so changing a limit is
not a code change.
Then the claims themselves: claimant, date, category, merchant, amount,
currency, project, attendees, and whether a receipt is attached. A form to
submit one, and a list.
I sign in through Helix, so do not build a login page. Read the signed-in
user from the runtime. And do not put any key or connection string in the
code: if this needs to reach another system, tell me and I will create the
connection in my workspace. The output that makes a reviewer faster instead of a second gatekeeper.
Now run the rules, and be careful about what you produce.
Do not give me a pass or fail. For each rule that applies, tell me what it
checked, what it found, and the gap: "dinner limit for London is 60, this
claim is 98, over by 38". Write it in plain language. A reviewer should
never need to open the policy document.
Give each rule a severity, set in the rules file rather than in code. A
missing receipt is a blocker. Two units over a meal limit is a note.
Treating those the same trains people to ignore both.
The claim's overall status is derived from its findings, never entered by
hand. And record which version of the policy each claim was checked
against, so raising a limit next quarter does not retroactively change the
history of claims that were assessed correctly at the time. Only the ambiguous claims, and what the arguments about them add up to.
Build the reviewer's queue and put only the ambiguous claims in it.
Clear claims go straight through and never appear. Each item that does
appear shows the claim, the failing rules with their explanations, the
receipt, and what this person has claimed recently.
Actions: approve, approve as an exception with a required reason, reject
with a reason, or send back for more information.
Then the report I actually want: every exception granted, by rule, by
approver, over time. A rule that gets exceptioned constantly is a rule
that does not match how the company works, and this turns that from an
argument into a number. Worth knowing. The exceptions report is the part nobody asks for and everybody ends up using. It converts policy debates into evidence.
The change that shrinks the queue instead of processing it faster.
Last, let a claimant check a draft claim against the policy before
submitting, with exactly the same explanations a reviewer would see.
Most policy breaches are people not knowing the limit rather than people
pushing their luck. Every claim fixed here is a claim that never enters
the queue at all.
Then two small reports: spend by category and team over time, so I can see
whether the policy is drifting away from what things actually cost, and
the people who hit the same rule repeatedly. Read that second one as a
training need, not an enforcement list. The step that turns a working prototype into something with your data in it.
Now connect it to the systems we actually run, so it works on real data
rather than the rows you seeded.
Anything in angle brackets is a placeholder. Swap it for whatever we use
instead, and have the app name the connection it wants rather than assume
a vendor, so changing my mind later is a config change and not a rewrite.
<Expensify>. Read submitted claims and write back the check result, so
reviewers work in one place.
<Brex>. Match claims to card transactions, which catches the duplicate and
the missing receipt.
<Okta>. Resolve the claimant and their manager, so a claim routes to
whoever actually manages them today.
<Slack>. Send the pre-submission result to the claimant, which is where
most breaches get fixed.
<NetSuite>. Post approved claims for reimbursement once the check clears,
so nobody rekeys them.
<Google Sheets>. Let the policy owner edit limits in a sheet, if that is
genuinely easier than a form.
Only write where I have said to write. Everything else is read only.
Do not write a key, a token or a connection string anywhere in the code,
and do not ask me to paste one. Tell me which connections you need and I
will create each as an authentication in my Helix workspace. Reference
them by alias. Worth knowing. Every name in angle brackets is a placeholder for whatever you run. Helix holds the credential as a workspace authentication, so the app references an alias and never the secret itself.
The last step of every build: a URL, and the right people on it.
Deploy my app. Worth knowing. Your assistant runs helix deploy underneath and the app comes back as a URL. Expense claims are personal data, so set Access Control before sharing: claimants see their own, reviewers see their team's.
The policy is yours to write. The claims and the receipts are already somewhere, and the checker should read them there.
Expensify
Read submitted claims and write back the check result, so reviewers work in one place.
Brex
Match claims to card transactions, which catches the duplicate and the missing receipt.
Okta
Resolve the claimant and their manager, so a claim routes to whoever actually manages them today.
Slack
Send the pre-submission result to the claimant, which is where most breaches get fixed.
NetSuite
Post approved claims for reimbursement once the check clears, so nobody rekeys them.
Google Sheets
Let the policy owner edit limits in a sheet, if that is genuinely easier than a form.
Each line says whether the app reads, writes or both. Anything not described as writing should be read only.
Named systems are the ones most teams actually run, not a list of the only ones that work. Swap in whatever you use.
Each connection is an authentication in your Helix workspace, referenced by alias. The app names the connection it wants and never holds the credential, so nothing here ends up in your code and any of it can be rotated or revoked without a redeploy.
The build gets you a working checker. It holds personal spending data and influences who gets paid back, so it needs to be run properly rather than shared as a link.
AI Deployment
One command takes the app from your assistant to a live address, so the people who need it get a link rather than instructions for running it locally.
App Security
Expense claims are personal data. SSO means people sign in with their existing account, and access is scoped so a claimant sees their own claims while reviewers see their team's.
App Security
If the checker reads claims from a finance or card system, granting that access to the app rather than pasting a key into it means it can be rotated or revoked without a redeploy.
App Registry
Every app carries a named owner and an entry IT can see, so the tool does not become nobody's problem when the person who built it changes role.
Cost Management
Per-app spend visibility, with budgets and caps, so an internal tool cannot quietly become a line item nobody can explain.
It evaluates an expense claim against your own policy rules and explains what it found, so reviewers only spend time on the claims that need judgement. It reads the claim for you rather than deciding it for you.
Rarely. Auto-approving clearly compliant claims saves real time with little risk. Auto-rejecting creates disputes over edge cases the rules did not anticipate, and the appeal costs more than the review would have. Block, explain, and route to a person.
In one editable file, loaded at runtime, in a format the policy owner can change without a code change. Limits vary by city, category, role and season, and a policy encoded across the codebase stops being maintainable almost immediately.
Version the rules with an effective-from date, and record which version each claim was checked against. Otherwise raising a limit silently rewrites the history of claims that were correctly assessed at the time.
Explaining rather than verdicting, and letting claimants check before they submit. Most breaches are people not knowing the limit, so a pre-submission check removes the claim from the queue before it enters it.
Yes. The prompts here are written for Claude Code, Codex or Cursor and build it in stages. What no tool decides for you is the severity of each rule, which is the judgement that makes the queue useful or useless.
Finance
Match invoices to what was approved, route the exceptions, and stop paying late because an email got buried. Prompts to build it, and what it takes to run it.
Finance
Route purchase requests by amount and category, hold an approval trail finance can audit, and stop chasing sign-off in email. Prompts to build it, and what it takes to run it.
Finance
Show budget owners where they stand before the month closes: committed versus actual, variance by owner, and a forecast they can act on. Prompts to build it, and what it takes to run it.
Last reviewed September 2026.
Helix is the governed runtime for AI-built apps. Deploy what you build, put SSO in front of it, connect it to your systems with managed credentials, and give it a named owner.
Your private status link is on its way to your inbox.