Read 835 remittance advice (005010X221A1) - #4
Merged
Conversation
An 835 is a different transaction, not a variant of the 837 the app was built around, and the default path did not merely miss its structure -- it fabricated 837 structure over it. `LX` opened a group labelled "Line 1" when in an 835 it opens loop 2000, a grouping of claims; `NM1*82` opened "Rendering provider" and swallowed both service lines and `PLB`, a transaction-level segment that must never sit inside anything. So for an 835 the 837 anchors are switched off and replaced, gated on `ST-01` per transaction: a file with no 835 in it runs exactly the code it ran before, and a mixed interchange resolves each transaction correctly. 835 loop ids are deliberately absent from `ENTITY_LOOPS` and `ANCHOR_LOOPS`, which makes the 837 fallback inert by construction. Reading only, as scoped: loop resolution, segment and qualifier naming for the inspector, a separate 835 reference block, and three balancing checks -- line, claim, and transaction -- all warnings, each standing down rather than guessing when a figure is absent or unreadable. No payments table, no CSV export, no Limited Data Set. The transaction check is `BPR-02 = SUM(CLP-04) - SUM(PLB-04)`: a positive `PLB-04` reduces what the payer pays. That reads backwards and is the line most likely to be "corrected" into a bug, so it carries a comment, an explanation in docs/835-validation.md, and a test named for the convention that asserts the finding's detail text -- a flipped sign still produces a finding, just with the wrong number in it. Reversals (`CLP-02 = 22`) balance under the same rules with no special case anywhere; the fixture's second claim is one, carrying negative amounts throughout. The Claims tab is empty for an 835 by design and the Limited Data Set does not reach its patient identifiers -- both audited rather than assumed, and both pinned by tests. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Adds reading support for 835 remittance advice: loop resolution, inspector naming, and three balancing checks. No payments table, no CSV export, no Limited Data Set — those are deliberately left for later.
Why this one does not follow the PACDR pattern
PACDR's rule was detected → do more, never do differently, and it held because
005010X298is structurally the same transaction as the 837P. It does not hold here. A probe of a hand-written 835 through the current build found the tree actively wrong, not merely incomplete:LXopened a group labelled "Line 1" — in an 835 it opens loop 2000, a grouping of claims.NM1*82opened "Rendering provider" and swallowed bothSVCloops andPLB, a transaction-level segment that must never sit inside a claim.So for an 835 the 837 anchors are switched off and replaced, gated on
ST-01per transaction. What survives from PACDR is the gating discipline: a file with no 835 in it runs exactly the code it ran before, and a mixed interchange resolves each transaction correctly. 835 loop ids are deliberately kept out ofENTITY_LOOPS/ANCHOR_LOOPS— the omission is load-bearing, and makes the 837 fallback inert by construction.The three checks
All warnings, never errors, each standing down rather than guessing when a figure is absent or unreadable.
SVC-02− adjustments in that 2110 =SVC-03CLP-03− everyCASon the claim =CLP-04BPR-02= ΣCLP-04− ΣPLB-04The last one reads backwards on purpose: a positive
PLB-04reduces what the payer pays. It is the line most likely to be "corrected" into a bug, so it carries three separate treatments — a comment at the subtraction,docs/835-validation.mdexplaining why, and a test named for the convention. The test asserts the finding's detail text, not just that a finding fires: a flipped sign still produces a finding, only with the wrong number in it, so a pass/fail-only test would not catch the regression. Verified by flipping the sign and watching the suite go red.Reversals (
CLP-02 = 22) balance under the same rules with noCLP-02gate anywhere. The fixture's second claim is a reversal carrying negative amounts throughout.Also fixed, found in review
N1whose qualifier was notPR/PEreturned without pushing a leaf, so the segment vanished from the tree and from the interchange's own count — invisible to every existing assertion, since a missing segment breaks no structure. Now falls through to a plain leaf asNM1already did, pinned by a test that fails on the one-word revert.CLM-02reconciled — on a file with noCLMin it — while saying nothing about the three checks that actually ran.LXremittance the whole file collapsed to a single unselectable node.Verification
All 8 browser suites and the 11 Python tests pass. Tree 142→167, validate 74→93, deid 123→126, claims 106→108, outline 60→65;
parityuntouched at 77 and unaffected by construction — everything new inside the engine markers is reachable only fromvalidateDocument, which parity never calls.Existing 837P and PACDR assertions are unchanged — none was edited to make anything pass.
Sources
The X12 TR3 is paywalled and was not read, and no companion guide was used for this pass. What is asserted is limited to loop ids, segment ids, element positions and the balancing arithmetic the transaction's own definition implies. Every unconfirmed item is either cut (
Σ SVC-03 = CLP-04) or stands down (debit and zero-payment transactions). The fixture is wholly invented.🤖 Generated with Claude Code