When Insurance Policy Changes Become a $100 Million Problem

When Insurance Policy Changes Become a $100 Million Problem

When Insurance Policy Changes Become a $100 Million Problem

Alec Skriloff (Software Engineer) & Flora Chang (Product Lead)

Sheets of thin, translucent paper stacked together

Most of us have a healthy disregard for policy updates.

Your credit card sends new terms. Apple would like you to review an updated agreement. Some service you’ve forgotten you pay for has made “important changes to our policies.” You give the email a quick skim before archiving it, and generally, life goes on.

Unfortunately, health insurance policy updates are less forgiving.

This July, five reimbursement policy changes landed at the center of a lawsuit between Jefferson Health and Independence Blue Cross. Jefferson alleges that Independence changed how it gets paid without renegotiating their contract, a move the health system expects to cost nearly $100 million this year. Independence disputes the claim. (The Philadelphia Inquirer, Becker’s Payer Issues)

Whatever the court decides, the lawsuit is arguably just a louder version of a problem that health systems manage quietly every day: payor policy updates keep coming, and without a way to sort what matters from what doesn’t, the impact can stay hidden until payments start coming in lower than expected.

We built Policy Intelligence at Kubera to solve this exact pain point – to help teams identify the policy changes that matter and understand how those changes relate to their contracts and claims.

From Contracts to Policies

For those unfamiliar with Kubera, we were already in the business of making sense of documents no one opens for fun before we built Policy Intelligence. Our existing Contract Intelligence product reads and organizes the rates, terms, and payment rules inside a health system’s contracts and then applies that information to claims so teams can easily identify underpayments from payors.

That work gave us a solid document-processing foundation to build on. But, of course, we needed to tailor our document ingestion pipeline to a new use case – payor policies.

While contracts tend to arrive in defined batches around onboarding or a major contracting event, policies are a moving target. New documents and revisions appear frequently and sometimes unpredictably throughout the year, and each one has to be understood in the context of what came before. Add a growing customer base, and the same pipeline was suddenly handling more volume across two very different rhythms.

The technical challenges: building a robust and observable pipeline

Our pipeline had to absorb that new workload without disrupting the contract workflows already moving through it.

We started by extending the pipeline we already had. Much of the underlying work was familiar, but the new workload quickly showed us which assumptions carried over from contracts and which did not.

A document’s path was short and linear. As soon as a file was uploaded to Kubera, we checked two things: that the file was a format our system could read and a document type we knew how to extract from. Everything after that happened in one go –  converting the pages to text, running the LLM extractions that pull out rates, terms, and payment rules, and saving the results into our customers’ workspaces. Several documents could move through at once, but the pass itself was indivisible. A failure anywhere sent the document back to the beginning, redoing the conversion and the model calls that had already succeeded.

That design leaned on one assumption, and it was a reasonable one at the time: a document was a single unit of work. Starting over was the only kind of recovery we needed, because documents were short, volume was predictable, and a rerun cost minutes.

As real policy volume began moving through the system, different parts of the pipeline started feeling the pressure at different times. Reading a file, structuring its contents, comparing versions, and connecting the result with customer data did not move at the same pace or fail for the same reasons. What had looked like one continuous process was beginning to behave like several systems sharing a name.

Provider manuals were the first thing to break that model. A manual can run several hundred pages, and the whole of it had to succeed or fail together: one unusable extraction on page 300 sent the manual back to page 1, re-converting every page and re-running every extraction, including the hundreds that had already succeeded. None of that work was saved, so every attempt cost the same as the first. 

Thus, we iterated from there. Different parts of the workflow began moving through separate stages, allowing each stage to run and recover more independently. We became more deliberate about how much work moved downstream at once, so a large batch of policies could wait its turn instead of overwhelming the rest of the system. Better visibility also helped us find where a document had stalled and why.

The first change was to stop treating an upload as the start of processing. Now an upload only checks the file and adds it to a line of work waiting to be done, and a worker that is always running picks up the next item when it's ready. That means a burst of policies arriving over an afternoon waits its turn and drains in order instead of all starting at once, and a large document isn't racing anything to finish.

The second, and more important, change was to make recovery smaller than a document. Reading a document and pulling out individual rules are now separate steps, each of which can fail and recover on its own. This means that if there’s a problem in the last step, we no longer need to reingest the entire file. Long provider manuals go further: they're broken into sections, and each section tracks whether it succeeded and how many times we've tried it.

The third change was visibility into the LLM itself. After evaluating different observability vendors, we decided to leverage Langfuse. Langfuse met the requirements that mattered most to us, HIPAA-compliant hosting and strong data security, and brought a tracing ecosystem we otherwise would have had to build internally. Every prompt we run against a document is now traced – which prompt version ran, what came back, any tool calls, how long it took, and what it cost – and we score those prompts against a set of real documents whenever we change them. When a policy comes out wrong, that's the difference between knowing a document failed and knowing which step produced the bad answer.

For Policy Intelligence, these changes meant new and updated policies could move through Kubera alongside existing contract workflows without either workload bringing the other to a crawl. If one step failed, the system could recover closer to where the problem occurred. When policies arrived in bursts, the pipeline could absorb the work more gradually.

Staying ahead of the underpayments

The changes we’ve described have bought us room, but the next version starts from a different foundation: a purpose-built queue instead of a list we check every few seconds. That will let many workers run at once while allowing urgent work to jump ahead of batch work that nobody is waiting on. We’re also building fallbacks for the pieces that can currently stop a document on their own – the service that reads PDFs and the models that extract from them – so one vendor’s outage doesn’t become every customer’s problem. And because AI agents now write a growing share of the changes to this pipeline, automated testing and deployment are what let us keep moving quickly without sacrificing the reliability we just built.

Which brings us back to that $100 million dispute. Whether or not a court ever weighs in, the underlying problem is the same for every health system: payors will keep updating how they pay, and the only real defense is knowing — quickly and specifically — which changes touch your contracts. With policy document volume unlikely to slow anytime soon, staying ahead of it is how the policy changes that matter reach healthcare teams before underpayments do.

Copyright © Kubera Health

Address

33 Irving Place, Floor 5
New York, New York 10003

Copyright © Kubera Health

Address

33 Irving Place, Floor 5
New York, New York 10003

Copyright © Kubera Health

Address

33 Irving Place

New York, New York 10003