Inspiration
Dental benefits are a market with a quiet failure built in. Plans reset every year, so benefits you don't use are forfeited. They're also written in vocabulary (deductible, annual maximum, downgrade clause) that almost nobody reads fluently. A dentist says "you need a crown," and the person in the chair has no way to price it.
The codeLinc 11 prompt asked us to simplify plan selection. We went one step further and asked why anyone who already holds a plan still loses money on it. Cusp is our answer: use your benefits before they run out.
What it does
Cusp is a dental-benefits copilot. Upload your plan as a PDF or a photo, say what you need in your own language, and it returns exactly what you pay, in network and out of network, with a plain explanation.
Then it plans your care across the year. On the sample plan, a crown is \$618.75 in network vs \$930 out. Four procedures cost \$2,206.25 done at once vs \$1,507.75 spread across the plan-year reset, a difference of \$698.50 for identical dental work.
It also tracks your annual maximum, warns you before benefits expire, reads answers aloud, speaks 10 languages, and has a 3D mouth you can tap.
How we built it
Cusp is built for Lincoln Financial's Path 1 challenge, around one constraint that matters in regulated benefits work: an estimate has to be auditable. So the rule is the model reads, the engine computes. Language models are good at documents and unreliable at arithmetic you have to trust, so no estimate is ever calculated by one.
Claude runs as an agent, not a chatbot. It works through a loop of tool calls: it pages through your plan PDF to find the clauses it needs, calls the estimate engine as a tool, and drives the app's UI itself, opening screens, highlighting the tooth on the 3D mouth and putting the estimate card in front of you. Two things keep that agent honest:
- Schema-constrained output. Every tool call and every extracted value has to match a strict Zod schema. The model can't invent a field, skip a citation or return a malformed number; anything that fails validation is rejected before it reaches the user.
Deterministic math instead of agent hallucination. The agent never "does" the arithmetic in prose and pretends it's right. It hands inputs to the engine and reports what comes back, so the same plan and procedures always give the same answer.
Claude reads the plan and explains outcomes. Every value it extracts carries its page and a verbatim quote, so it can be checked against the source before the engine uses it.
A deterministic engine (
@codelinc/dental-math, dependency-free TypeScript, integer cents throughout) does the math. For eligible amount E, remaining deductible D, coinsurance rate c and remaining annual maximum M:
d = min(D, E)
insurer pays = min(c × (E − d), M)
you pay = billed − insurer pays − write-off
Your annual maximum is spent one procedure at a time, so the order and dates of your procedures change what you pay. Sequencing takes advantage of that. Spreading work across the plan-year reset lets you use two years of benefits instead of one.
- Client: Expo and React Native with React Native Web, one TypeScript codebase for the web app and the sample-plan site. three.js drives the 3D mouth. iOS is a SwiftUI and WKWebView shell around the web export.
- Server: Node, Hono and Zod, with
unpdffor PDF text and a speech layer for voice input and read-aloud. - Infra: Built to run on AWS and live at cusp.teddytennant.com. The repo's
aws/folder has a Dockerfile and a CloudFormation stack: ECS Fargate behind a load balancer, EFS for the spend ledger, and Secrets Manager for the API key.
Challenges we ran into
- Making a refusal a first-class output. When a plan doesn't contain enough to answer, the engine returns
incompleteorinvalidwith a reason code instead of a plausible guess. Getting the product to say "I can't tell yet" gracefully took more work than the happy path. - Getting Voice Mode to work. A natural conversation requires careful timing and pauses, and the model has to know when it is its own turn to speak.
- iOS from Linux. A native React Native build needs macOS and Xcode. We built the SwiftUI shell with
xtoolinstead. It runs the same screens, but it is not a native RN binary, and the repo says so. - Ten languages. Insurance concepts don't translate word for word, and right-to-left scripts like Arabic flip the whole layout.
Accomplishments that we're proud of
- Auditable answers. Every plan value traces to a page and a quote.
- Savings found, not just prices listed. \$698.50 recovered on four procedures from scheduling alone.
What we learned
Separating comprehension from computation made the system safer and easier to test: the engine has plain unit tests, and the AI layer can be mocked. Integer cents removed a whole category of bugs. And plain language turned out to be an engineering constraint, not polish. We show the four or five numbers that matter first and put everything else behind "See all details."
What's next for Cusp
Into the app stores. The iOS build today is a sideloaded web shell. Next is a real native build for the App Store and Google Play, so an employee can install Cusp and get benefit-expiry reminders on their phone without finding a link.
We will keep developing and testing Cusp to make it ready to deploy, so that employees worldwide can use it to maximize their dental insurance benefits.
Thank you to Lincoln Financial and AWS for hosting, and to Cognizant, IBM, LTIMindtree, Accenture and Deloitte for sponsoring codeLinc 11.
Built With
- ai
- amazon-web-services
- anthropic
- claude
- expo.io
- generative-ai
- hono
- node.js
- react
- react-native
- swift
- three.js
- typescript
Log in or sign up for Devpost to join the conversation.