Mapping VMRS Codes to DVIR Defect Taxonomy
A DVIR arrives with a defect described in whatever form the driver or device produced — a checkbox labeled “brakes,” free text reading “air leak on trailer glad hand,” or a telematics fault code. To route, score, and report that defect consistently, it has to land on one internal defect_category. The Vehicle Maintenance Reporting Standards (VMRS) codeset is the bridge: its system, assembly, and component (SAC) structure gives every truck part a stable numeric identity that maintenance shops, OEMs, and CMMS platforms already share. This guide builds a crosswalk that maps a free-text or checkbox DVIR defect to a VMRS code and then to the internal defect_category used across Defect Taxonomy Mapping for Heavy Trucks and the wider Core DVIR Architecture & FMCSA Compliance Mapping pipeline.
Getting the mapping wrong has a compliance edge. A defect that should carry the out-of-service weight of a brake system fault but gets mapped to a generic “chassis” bucket can slip past the severity floor the scoring engine expects. The crosswalk must therefore be conservative: map confidently when the evidence is strong, and route anything ambiguous to a human review queue rather than guessing a category that changes how the defect is handled downstream.
Prerequisites
Anchor link to "Prerequisites"- Python 3.10+ —
X | Yunions andmatch. - A licensed VMRS SAC codeset (VMRS is maintained by the American Trucking Associations’ Technology & Maintenance Council; a license is required to redistribute the codes).
- Pydantic 2.x — validated crosswalk rows and mapping results.
rapidfuzz(or equivalent) — token-based similarity for free-text matching; optional but recommended over naive substring checks.- The internal
defect_categoryvocabulary and severity conventions from the parent Defect Taxonomy Mapping for Heavy Trucks, whose codes feed the Severity Scoring Algorithms for DVIR Defects engine.
Step-by-Step Implementation
Anchor link to "Step-by-Step Implementation"Step 1: Model the crosswalk row and the mapping result
Anchor link to "Step 1: Model the crosswalk row and the mapping result"A crosswalk row ties one VMRS SAC code to one internal defect_category, carries the match keys (canonical phrases, checkbox labels), and is stamped with the crosswalk version it belongs to. The mapping result records the confidence and whether it needs review, so nothing is silently accepted.
from typing import Literal
from pydantic import BaseModel, Field
class CrosswalkRow(BaseModel):
model_config = {"frozen": True}
vmrs_sac: str # "SSS-AAA-CCC", e.g. "013-001-002"
defect_category: str # internal vocabulary
match_phrases: tuple[str, ...] # canonical text/checkbox labels
version: int
class MappingResult(BaseModel):
vmrs_sac: str | None
defect_category: str | None
confidence: float = Field(ge=0.0, le=1.0)
disposition: Literal["mapped", "review"]
crosswalk_version: int
Step 2: Normalize the raw defect text
Anchor link to "Step 2: Normalize the raw defect text"Lowercase, strip punctuation, expand common abbreviations (glad hand, l/h, brk), and collapse whitespace. Normalization is where most accuracy is won — the same rules that clean input for Automated Field Mapping & Data Normalization apply here, so keep one shared normalizer rather than two that drift apart.
import re
_ABBREV = {"brk": "brake", "l/h": "left hand", "r/h": "right hand",
"glad hand": "gladhand", "susp": "suspension"}
def normalize(raw: str) -> str:
text = raw.lower().strip()
for k, v in _ABBREV.items():
text = text.replace(k, v)
text = re.sub(r"[^a-z0-9 ]+", " ", text)
return re.sub(r"\s+", " ", text).strip()
Step 3: Match with a confidence score, fall back to review
Anchor link to "Step 3: Match with a confidence score, fall back to review"Score the normalized text against each row’s match_phrases with token-based similarity. Accept the best match only if it clears a threshold τ; otherwise return a review disposition. Return the confidence either way so the outcome is auditable.
from rapidfuzz import fuzz
THRESHOLD = 0.82 # tune against a labeled sample; err toward review
def map_defect(raw: str, rows: list[CrosswalkRow],
version: int) -> MappingResult:
text = normalize(raw)
best_row, best_score = None, 0.0
for row in rows:
score = max(fuzz.token_set_ratio(text, normalize(p)) / 100.0
for p in row.match_phrases)
if score > best_score:
best_row, best_score = row, score
if best_row is None or best_score < THRESHOLD:
return MappingResult(vmrs_sac=None, defect_category=None,
confidence=best_score, disposition="review",
crosswalk_version=version)
return MappingResult(vmrs_sac=best_row.vmrs_sac,
defect_category=best_row.defect_category,
confidence=best_score, disposition="mapped",
crosswalk_version=version)
Step 4: Handle many-to-one and unknown codes
Anchor link to "Step 4: Handle many-to-one and unknown codes"VMRS is finer-grained than the internal taxonomy, so many SAC codes legitimately map to one defect_category — that is expected and fine as long as it is one-directional (many VMRS → one category, never one VMRS → many categories). A VMRS code with no crosswalk row is not an error to swallow: emit it to the review queue with its raw text so a maintenance analyst can add a row, and version the crosswalk when they do.
def resolve_unknown(raw: str, vmrs_sac: str | None, version: int) -> MappingResult:
"""An unmapped but valid VMRS code, or free text that matched nothing,
goes to review — never a default 'chassis' bucket that hides severity."""
return MappingResult(vmrs_sac=vmrs_sac, defect_category=None,
confidence=0.0, disposition="review",
crosswalk_version=version)
Verification and Testing
Anchor link to "Verification and Testing"Assert three behaviors: a strong text match maps to the expected category, an ambiguous defect routes to review rather than guessing, and the many-to-one direction holds so two VMRS codes for the same system converge on one category.
import pytest
ROWS = [
CrosswalkRow(vmrs_sac="013-001-002", defect_category="brakes_air_service",
match_phrases=("air leak gladhand", "service brake air leak"), version=7),
CrosswalkRow(vmrs_sac="013-002-001", defect_category="brakes_air_service",
match_phrases=("slack adjuster out of stroke",), version=7),
CrosswalkRow(vmrs_sac="016-001-001", defect_category="tires_tread",
match_phrases=("tread depth below limit", "bald tire"), version=7),
]
def test_strong_match_maps_to_expected_category():
r = map_defect("Air leak on trailer glad hand", ROWS, version=7)
assert r.disposition == "mapped"
assert r.defect_category == "brakes_air_service"
assert r.confidence >= 0.82
def test_ambiguous_defect_routes_to_review():
r = map_defect("something feels off up front", ROWS, version=7)
assert r.disposition == "review"
assert r.defect_category is None
def test_many_vmrs_codes_converge_on_one_category():
a = map_defect("air leak gladhand", ROWS, version=7)
b = map_defect("slack adjuster out of stroke", ROWS, version=7)
assert a.vmrs_sac != b.vmrs_sac
assert a.defect_category == b.defect_category == "brakes_air_service"
Common Failure Modes and Gotchas
Anchor link to "Common Failure Modes and Gotchas"- Many-to-one collapses that hide severity. Mapping a fine VMRS brake code up to a broad
brakescategory is fine only if that category preserves the severity the scoring engine needs. If several VMRS codes with different out-of-service implications collapse to one bland category, split the category rather than lose the distinction — the mapping must never soften a defect that meets an OOS criterion. - Unknown codes silently bucketed. The most damaging bug is a
defaultbranch that assigns an unmatched defect to a catch-all category. That makes an unmapped brake fault look like a minor chassis note. Route every unknown to review with its raw text; a defect the system cannot classify is a defect a human must classify. - Crosswalk versioning drift. The crosswalk changes as analysts add rows, and a historical DVIR must be interpretable under the crosswalk that was active when it was mapped. Stamp every
MappingResultwithcrosswalk_versionand keep old versions immutable, so a re-run during an audit reproduces the original category rather than a today’s-rules category. - Normalizer divergence. If the matcher normalizes text differently from the ingestion normalizer, phrases that ingestion cleaned no longer match crosswalk rows authored against the cleaned form. Share one normalization function across ingestion and mapping so the two never drift.
Frequently Asked Questions
Anchor link to "Frequently Asked Questions"What is VMRS and why map DVIR defects to it?
VMRS — Vehicle Maintenance Reporting Standards, maintained by the ATA’s Technology & Maintenance Council — is a coded taxonomy that gives every vehicle system, assembly, and component a stable numeric identity in a system-assembly-component (SAC) structure. Mapping free-text or checkbox DVIR defects to VMRS gives you a shared vocabulary that maintenance shops, OEM fault trees, and CMMS platforms already speak, which is what lets a defect reported by a driver line up with the work order that fixes it and the parts that were replaced.
How should the crosswalk handle a defect it cannot confidently classify?
Route it to a human review queue with its original text, never to a default category. A confidence score below the acceptance threshold means the evidence is weak, and guessing a category can soften a safety-critical defect or misroute a routine one. A reviewer confirms the mapping, adds a crosswalk row, and the next identical defect maps automatically under a new crosswalk version.
Why version the crosswalk instead of just editing it in place?
Because a defect mapped last year must remain interpretable under the rules that were active then. If you edit the crosswalk in place, re-running an old DVIR during an audit could assign a different category than the one that actually drove the original routing decision. Stamping each mapping with a crosswalk_version and keeping prior versions immutable lets you reproduce any historical classification exactly.
Related
Anchor link to "Related"- Defect Taxonomy Mapping for Heavy Trucks — the internal defect vocabulary this crosswalk targets.
- Defect Code Standardization Across Fleets — reconciling divergent defect codes before they reach the crosswalk.
- Automated Field Mapping & Data Normalization — the shared normalizer that cleans defect text on ingest.
- Severity Scoring Algorithms for DVIR Defects — consumes the resolved defect_category to grade severity.
- Mapping DVIR Defects to CMMS Work Orders — where the VMRS-coded defect becomes a maintenance work order.
Back to Defect Taxonomy Mapping for Heavy Trucks, part of Core DVIR Architecture & FMCSA Compliance Mapping.