Skip to content

The rendered report names the same concept two ways, and neither matches the contract it renders #689

Description

@willhea

What's wrong

A rendered bill comparison labels the same kind of change by two different names in the same document, and neither name matches the published data contract the report is generated from. In one report, a modified passage is marked diff-mod in the body text and badge-modified in its heading, while the contract that produced both calls it modified.

The contract is schema/canonical-diff.md, the versioned JSON shape that every DeltaTrack consumer reads: the HTML report, the JSON export, and any outside tool. It already fixes the vocabulary. change_type is the enum "added" | "removed" | "modified" | "moved". The tree node level field is explicitly documented as "Shared GPO vocabulary": division, title, major, agency, account, section, subsection, grouping, preamble, heading. Those are the terms the source material uses for the parts of an appropriations bill.

The view names things its own way instead. Measured on the committed example examples/hr8752_pdf_diff.html, by counting class tokens in class="..." attributes:

View name Occurrences Contract term Problem
diff-mod 406 modified abbreviation, and disagrees with badge-modified in the same file
diff-add 134 added abbreviation, disagrees with badge-added
diff-del 1 removed abbreviation and a different word
fb-row, fb-text, fb-gutter 2513 each full_text, location.start_line abbreviation; the "gutter" holds the line number the contract calls start_line
fb-page 104 location.start_page abbreviation
toc, toc-child, toc-group 31 / 188 / 30 tree, children, level abbreviation, and it is a division/title/section tree rather than a table of contents
financial-summary, financial-table, financial-callout 1 / 1 / 3 amount_entries, own_amounts the contract says amounts, not "financial"
change-card, card-group 37 / 56 ChangeObject, grouped by path "card" names a UI pattern, not the thing being shown
removed-appendix, removed-block 1 / 1 change_type: "removed" "appendix" is an invented placement

Some of the view vocabulary is already correct and should stay: section-number matches the contract's section_number, v1 and v2 match versions.v1 and versions.v2, citation is the ordinary legal term, and disclosure is the correct accessibility pattern name for a <details> element.

How it surfaced

While consolidating DeltaTrack's stylesheets onto a single palette. Choosing between two competing token vocabularies raised the question of what the names ought to be measured against, and the contract turned out to already answer it.

The counts above were produced on branch worktree-phase1-shared-palette at commit 81850cc1, against the committed example, by extracting every class="..." attribute and counting the whitespace-separated tokens. Nothing about the numbers depends on that branch: it changes no class name.

Why it matters

The stated purpose of the report is that a reader can trace what they see back to the source it came from. A name that exists only in the view breaks that chain at the last step: given a highlighted passage, there is no way to get from fb-gutter to location.start_line without reading the renderer.

It also costs correctness confidence. Because diff-mod and badge-modified are separate strings for one contract value, a change to how modified passages are classified has two places to land in the view, and nothing makes them move together.

The audience is the reason it is worth doing rather than tolerating. The report is read by congressional staff checking a specific figure against a printed bill, and increasingly by language models asked to summarize what changed. Both are better served by a document whose parts are named what the source calls them.

Nothing is user-visibly broken today, so there is no urgency. The reason to act now rather than later is that this is cheaper before a redesign than after: a rename carried through a restyle is hard to review, because the reviewer cannot tell a colour change from a vocabulary change.

What to do

Reconcile the view's names against the contract. The mapping above is the starting inventory, not a settled proposal. Two decisions are worth making deliberately rather than by sweep:

  1. How far to go on UI-pattern names. change-card describes how a change is presented, not what it is. Renaming it to change aligns with the contract, at the cost of losing the hint that it is a self-contained block. Reasonable either way, and worth deciding once and applying consistently rather than case by case.
  2. Whether the tree navigation adopts level values directly. The contract's level enum is the GPO vocabulary, so a nav entry for a title could carry level-title rather than toc-child. That is the strongest version of the change and the one that most helps traceability, but it is also the largest.

Worth noting for whoever picks it up: the class names have consumers beyond the stylesheet. The report's embedded JavaScript selects on several of them, and tests/test_frontend_browser.py asserts on others. A rename is not confined to CSS.

Verification

A pure rename must change no pixel. Rendering the committed examples before and after and comparing the images should show them identical, with a deliberately altered colour used first to confirm the comparison can detect a difference at all. The existing byte-comparison gates in tests/test_committed_examples.py will fail on the regenerated artifacts by design, since the markup changes; they are not evidence for this change and should not be read as such.

Unverified

The claim that renaming is cheaper before a redesign than after is a judgement, not a measurement.

Refs #653 (the view re-deciding what the diff already settled, which is the architectural sibling of this naming question), #676 (the epic that made DeltaTrack's UI its own).

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions