The Progress Corticon Rules engine provides an alternative path to compliance with the Transparency in Coverage Final Rule.
Much to the relief of the systems implementers for group health plans and health insurers, the United States Centers for Medicare and Medicaid Services (CMS) announced in August 2021 that they would delay their enforcement of the Transparency in Coverage Final Rule by six months.
For all covered healthcare items and services, the rule mandates that most group health plans and health insurance issuers offering health insurance coverage in individual and group markets make accessible patients’ personalized out-of-pocket cost information and underlying negotiated rates.
The largely privatized United States healthcare system, particularly since the onset of the COVID-19 pandemic, has buried Americans in medical debt. The sum total of Americans’ medical debt as of July 2021 was $140 billion, according to the Journal of the American Medical Association. The Transparency in Coverage final rule is a step towards demystifying the costs of individual medical services and procedures, which tend to be unknown to patients until they’re handed the bill, and can fluctuate wildly from patient to patient.
As with most tech-related regulatory measures aimed at delivering consumer protections, adherence to the rule requires that discrete business entities adopt a common, open data standard. Given the many parties involved in just one medical invoice, the absence of standardization rapidly produces a maze of medical codes from unknown origins—a knot that proved too immense for vendors to untie in time for the date that CMS originally planned to begin enforcement of the rule, January 1, 2022.
The Progress Corticon rules engine allows for an alternative path to compliance with data standards than to exert the effort needed to untie this knot. With Corticon, we can automatically import a data standard, as defined in its schema, thereby guaranteeing that no logic that is implemented will stray outside the lines of the prescribed standard.
The text of the Transparency in Coverage final rule illustrates a back and forth by its authors viz. which machine-readable format, if any, would be required for representing this data—
The final rules require each machine-readable file to use a non-proprietary, open format. The Departments considered requiring issuers and TPAs to post in-network rates, allowed amounts paid for out-of-network services, and prescription drug information using a specific file format, namely JSON. However, the Departments are of the view that being overly prescriptive regarding the file type will impose any unnecessary costs on issuers and TPAs despite the advantages of JSON, namely that JSON files are downloadable and readable for many health care consumers, and the potential for JSON to simplify the ability of price transparency tool developers to access the data. Therefore, the Departments are requiring that issuers and TPAs post the in-network rate, allowed amount, and prescription drug pricing information in three distinct machine-readable files using a non-proprietary, open format.
Because decision services created with Corticon are entirely stateless, it enables us to rapidly implement logic that conforms to the schema, in whichever format is required—there’s no need to accommodate Corticon by tweaking the prescribed data standard.
Here’s how:
First, I’ll create my rule project and rule vocabulary:
Next, I’ve taken the JSON schemas for the respective use cases from the CMS price transparency guide repository, and copied them into my rule project folder:
To generate a vocabulary from a JSON schema document, Corticon examines the contents of the document to identify the entities in the document, their attributes, and their associations. Where data types are not defined with JSON, Corticon infers the data type of attributes based on the present values. More information on how Corticon infers the schema can be found here.
As shown in the GIF below, generating a rule vocabulary from a JSON file takes just a moment, auto-populating the data model from which we can subsequently author business logic. A JSON payload can likewise be used for the same vocabulary generation function, but using the schema provides a critical advantage: the creation of enumerated data types.
Once the rule vocabulary is generated, we’ll drag and drop directly from it to define the business rules in Rulesheets. Later, once we’re ready to move to testing, we’ll drag and drop from the rule vocabulary onto Ruletests, and assign values to the rule vocabulary elements representing the ‘input’ data for the decision being made, or simply import existing test cases.
Shifting into a Rulesheet I’ve created in the same rule project, we can see the benefit derived from those custom data types that were generated. Custom data types are essentially refinements to ‘base’ data types, like alphanumeric strings, decimals, or integers. For example, the previously linked repository states that the base data type of Billing_class is a string, but not just any string:
As described in the Rule’s technical clarification FAQ, “Negotiated rates for professional claims have a service code associated with them. The service code attribute in the schema allows for the reporting of different negotiated rates based on that attribute’s value. Negotiated rates for institutional claims may not have a CMS service code immediately associated with the service… To allow for reporting of diverse negotiated rates, CMS added a contextual attribute called "billing_class" to the in-network schema to flag whether a negotiated rate is based on a professional or institutional claim.”
This change in the schema was thus reflected with an enum tag on this contextual attribute. That tag, in the same schema file from which the vocabulary was generated, told Corticon to create a custom data type: an enumerated string called Billing_classEnumeration, with the two allowed values:
Now, we can write rules using this Billing_classEnumeration data type, which has been assigned as the data type for the attribute “Billing_class”. As clarified in the linked FAQ above, negotiated rates for intuitional claims may not always come with a CMS service code, but a professional claim always will have at least one. Thus, we may want to create a data validation rule that posts a warning if there are 0 service_codes associated with a claim where billing_type = professional. We can implement this logic in Corticon through various rule modeling patterns: here we’ll do so with the ‘size’ collection rule operator.
Collection operators are much more easily understood when considering how the rule vocabulary is ‘mapped’ to a JSON payload. When a decision service is invoked, Corticon maps the JSON payload to the internal data model of the Corticon vocabulary to enable the rules to execute on it. To perform this mapping, Corticon must first examine the JSON payload to identify the top-level objects in the JSON and the vocabulary entities they correspond to. Once the top-level objects in the JSON payload are mapped to the vocabulary model, Corticon can map any nested objects in the JSON to associations in the vocabulary.
By generating the rule vocabulary from a JSON schema, Corticon automatically creates a top-level entity it calls the ‘Root’, and all the other entities created were given associations that show how they relate to that top level Root. As shown in one of the implementation guide’s examples, the data being transmitted about the in-network rates, when transmitted as JSON, will be structured similarly hierarchically. Below, in another visualization of the same example, the fields highlighted are the top-level objects mapped as the entities in the Corticon rule vocabulary.
In the example, we can see that the top-level root has an associated child entity, In_network, which has a child entity, Negotiated_prices, which has a child entity, service_code, which contains three discrete service codes.
We call these three service codes a ‘collection’ in Corticon—any number of the same type of Entity (service_code) with a parent Entity in common (negotiated_prices). To write rules using collections, we use syntax that tells Corticon to assess this collection of service codes only within the context of the common parent entity, Negotiated_prices, and any other parent objects up through the root object. Each parent/child level is separated with a simple period (.):
Root.in_network.negotiated_rates.negotiated_prices.service_code
To distinguish between other collections, and to keep things uncluttered, we can then assign collections an alias—
Now, we can define a rule that will count the number of services codes within this specific collection (given the collection alias negotiatedServiceCode), and if the parent entity to that collection, negotiatedPrices, has a billing_class attribute with a value of ‘professional’, Corticon will send a data violation message. The billing_class attribute has been assigned a data type of Billing_classEnumeration, so Corticon will pre-populate the rule’s conditional dropdown with the two enumerated data types:
Corticon’s completeness checker, when run on a rulesheet in which conditional values have been defined for an attribute with an enumerated data type, will auto-populate all other potential scenarios. Shown below, Corticon is essentially saying, “You have defined a rule to fire when both a) ‘billing_class’ has a value of ‘professional’ and b) the size of ‘negotiatedServiceCode’ is less than or equal to zero. Based upon those two attributes’ data types, there are at least two other scenarios, which have been auto populated in columns 2 and 3, for which you have defined no action.”
One other illustration of how Corticon can operate upon data standards that are developed entirely outside of the scope of Corticon is the ability to import test data to test the rules as we go. In the previously referenced implementation example, the JSON object is structured to be compliant with the defined schema and specifies values for the different data fields in the way they might be communicated in a machine-readable way per the standard.
Consider an expanded scenario where this JSON object is in fact the ‘input’ JSON payload that a calling application will pass to a Corticon decision service, wherein the payload contains the data to evaluate against the decision service’s rules. In this scenario, having test data housed in the form of JSON files like this means we can directly import that JSON as the input in a ruletest:
Summary
One would be hard-pressed to find any especially vocal detractor of the final rule on price transparency in healthcare costs, which mandates that providers give patients good faith estimates upfront for medical treatments and procedures. However, the pushed deadline for its implementation by providers points to the number of moving parts involved in making architectural changes to accommodate the requisite standardization.
Implementers can architect in such a way as to expand the scope of their current billing systems and their dependencies, with additional investments aimed at merely surfacing the cost data that the rule specifies they provide to patients. Corticon implementers can take a different approach, one which mitigates the risk of future exposure to fire drill implementations and punitive damages from noncompliance. By abstracting the components of a data model into the same Corticon rule vocabulary with which business logic is modeled, data standard compliance can be treated as step one and marked complete after a few clicks.
Seth Meldon
Seth Meldon is a Pre-Sales Engineer with a primary product focus area of Progress Corticon Business Rules Engine. His work is focused on educating and demoing Corticon’s expansive functionalities, use cases, and architectural strategies to internal and external audiences. You can follow Seth on LinkedIn.