Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/sputhenofficial/claimjumper/llms.txt

Use this file to discover all available pages before exploring further.

triage() in lib/pipeline/triage.ts accepts an AdjustmentLine and returns a DenialTriage. GPT-5.6 Sol reads Group Code, CARC, and RARC together to decide the lane, then produces a rationale, evidence list, confidence score, and recovery probability. After the model responds, enforceInvariants() runs synchronously — its result is the final, trusted triage decision that callers receive. The model’s raw output is never returned directly.

Function signature

export async function triage(line: AdjustmentLine): Promise<DenialTriage>
Input — AdjustmentLine is a Zod-validated object with the fields that drive the routing decision:
FieldTypeDescription
group_codestringClaim adjustment group code (e.g. CO, PR, OA)
carcstringClaim Adjustment Reason Code
rarcstring (optional)Remittance Advice Remark Code, if present
billed_amountnumberNonnegative billed amount
descriptionstringHuman-readable service description
notice_datestring (ISO 8601)Remittance notice date, used by prioritization
notesstring (optional)Any claim-level remark from the remittance
Output — DenialTriage is TriageModelOutput extended with overrides:
// TriageModelOutput with one additional field:
type DenialTriage = TriageModelOutput & {
  overrides: string[];
};
overrides is populated by enforceInvariants(). It contains the human-readable reason for each safety rule that fired. When overrides is non-empty, lane will always be "human_review".

Model output fields

TriageModelOutputSchema defines the six fields the model must produce: lane — the resolution lane for this denial. One of:
ValueMeaning
appealFile a formal appeal with the payer
corrected_claimResubmit with corrected information
patient_billPatient cost-share responsibility
write_offProvider contractual adjustment
human_reviewEscalate — confidence too low or rule fired
root_cause — a short description of why the claim was denied. Derived from the adjustment codes; no external knowledge is injected. rationale — a sentence citing the specific Group Code, CARC, and RARC combination that drove the lane decision. This is what the biller reads when reviewing a queue item. evidence_needed — an array of strings listing what the billing team must gather for the recommended lane to succeed (e.g. medical records, authorization number, corrected date of birth). Empty array if nothing additional is required. confidence — a 01 float expressing the model’s certainty in the lane assignment. Values below 0.6 are automatically overridden to human_review by enforceInvariants(). recovery_probability — a 01 float representing the likelihood that working this denial results in payment. Used by prioritize() to weight the priority score. A write_off will typically carry 0; a clear timely-filing appeal with documentation may carry 0.7 or higher.

Invariant enforcement

enforceInvariants() is exported from lib/pipeline/invariants.ts with the following signature:
export function enforceInvariants(
  line: AdjustmentLine,
  triage: DenialTriage,
): DenialTriage
After responseWithSchema() returns the model output, triage() calls enforceInvariants() and returns its result:
return enforceInvariants(line, { ...modelOutput, overrides: [] });
enforceInvariants() checks three rules:
  1. CO → not patient_bill — a contractual obligation is the provider’s to absorb; it can never be billed to the patient.
  2. CARC 197 → not write_off — a payer-responsibility denial cannot be automatically written off; a human must make that decision.
  3. confidence < 0.6human_review — routing below the automation threshold is always escalated.
When any rule fires, the lane becomes "human_review" and the reason is appended to overrides. The route handler trusts the returned DenialTriage directly — it never calls enforceInvariants() again on the same result.
Safety invariants are implemented in code, not in the prompt. The prompt instructs the model to avoid certain assignments, but the invariant layer guarantees them regardless of model output. See the Safety Invariants page for the full rule set and rationale.

Prompt design

The triage prompt at prompts/triage.md positions the model as a healthcare reimbursement attorney and certified professional coder with fifteen years of EOB experience. The key constraints it enforces:
Constraints:
- A CO group code is a provider write-off. NEVER assign it to patient_bill.
- PR group codes are patient cost-share. Route to patient_bill, not the denial
  workflow, unless a RARC contradicts it.
- Missing-information denials (e.g. CARC 16) are corrected claims, NOT appeals.
  The paired RARC names the missing element.
- Cite only codes and facts present in the parsed input. Never invent policy
  numbers, dates, LCD identifiers, or clinical facts.
- This output is reviewed by a human biller before any action. Never state or
  imply the claim will be submitted automatically.
The stop rules prevent the model from fabricating group codes or CARCs when they are missing from the line: it must set lane = human_review and name the missing field rather than guessing.
The model reasoning effort level is "high", set in the responseWithSchema() call inside triage.ts. This gives the model maximum deliberation time for lane decisions that will directly affect billing team workflows.

Build docs developers (and LLMs) love