Certifying Repairs Under 396.11(c)(2)
A defect listed on a DVIR is not closed when a mechanic fixes it — it is closed when the motor carrier certifies it. Under 49 CFR § 396.11©(2), before a vehicle with a reported defect is dispatched again, the carrier must certify that each listed defect was repaired or that repair was unnecessary; under § 396.11©(2)(iii) the next driver must review the prior report and sign that the required repairs were made or were not needed. A pipeline that dispatches on “the shop marked it done” without those certifications is operating a vehicle with a known, uncertified defect — the exact violation a roadside inspection under § 396.9 is built to catch. This guide implements the certification gate as an explicit state machine that blocks dispatch until the required certifications exist, extending the FMCSA DVIR Rule 396.11 Breakdown guides inside the Core DVIR Architecture & FMCSA Compliance Mapping pipeline.
The gate is where the reported-to-repaired lifecycle becomes enforceable code. A defect scored by the Severity Scoring Algorithms for DVIR Defects engine and mapped to a repair order must walk a fixed path — reported, repair pending, certified or repair-unnecessary, next-driver reviewed — before dispatch is allowed, and every transition is sealed into the tamper-evident record described in Immutable Audit Trail and WORM Retention.
Prerequisites
Anchor link to "Prerequisites"- Python 3.10+ —
enum.StrEnum,match/case, andX | Yunions. - Pydantic 2.x — the defect record, certification, and dispatch-decision models.
- An authorization service — to confirm a certifier is an authorized carrier representative and the reviewing driver is not the same person who reported the defect.
- The
defect_category,severity_score, andcompliance_guardrailfields from the parent pipeline, and theaudit_hashconvention for sealing each transition. - The OOS criteria from Out-of-Service Criteria and OOS Hold Triggers, which set which defects can never be certified “unnecessary.”
Step-by-Step Implementation
Anchor link to "Step-by-Step Implementation"Step 1: Define the states and legal transitions
Anchor link to "Step 1: Define the states and legal transitions"Model the lifecycle as an explicit enum with a transition table, so an illegal jump (reported straight to dispatch) is impossible by construction rather than caught by a scattered if.
from enum import StrEnum
class DefectState(StrEnum):
REPORTED = "reported"
REPAIR_PENDING = "repair_pending"
CERTIFIED = "certified" # repaired, § 396.11(c)(2)
REPAIR_UNNECESSARY = "repair_unnecessary" # certified not needed, non-OOS only
NEXT_DRIVER_REVIEWED = "next_driver_reviewed" # § 396.11(c)(2)(iii)
DISPATCH_ALLOWED = "dispatch_allowed"
_TRANSITIONS: dict[DefectState, set[DefectState]] = {
DefectState.REPORTED: {DefectState.REPAIR_PENDING},
DefectState.REPAIR_PENDING: {DefectState.CERTIFIED, DefectState.REPAIR_UNNECESSARY},
DefectState.CERTIFIED: {DefectState.NEXT_DRIVER_REVIEWED},
DefectState.REPAIR_UNNECESSARY: {DefectState.NEXT_DRIVER_REVIEWED},
DefectState.NEXT_DRIVER_REVIEWED: {DefectState.DISPATCH_ALLOWED},
DefectState.DISPATCH_ALLOWED: set(),
}
Step 2: Model the defect and the certification
Anchor link to "Step 2: Model the defect and the certification"The certification records who certified, when, and against which defect. Capture the certifier identity and timestamp — these are what an auditor inspects for a forged or self-certification.
from datetime import datetime
from pydantic import BaseModel
class Defect(BaseModel):
record_id: str
defect_category: str
severity_score: int # 0-100; 70-100 critical
compliance_guardrail: str # OOS | conditional | monitor_only
state: DefectState = DefectState.REPORTED
reported_by: str
class Certification(BaseModel):
model_config = {"frozen": True}
record_id: str
certified_by: str # must be an authorized carrier representative
unnecessary: bool # True => "repair not needed" path
certified_ts: datetime # sealed; compared against dispatch time
Step 3: Enforce the transition with an authorization and OOS guard
Anchor link to "Step 3: Enforce the transition with an authorization and OOS guard"The transition function rejects any move not in the table, refuses a repair_unnecessary certification for an out-of-service defect, and requires an authorized certifier who is permitted for this action. An OOS defect — anything with the immovable critical floor of 70 or tagged OOS — can only reach CERTIFIED by actual repair.
class DispatchBlocked(Exception):
...
def is_oos(defect: Defect) -> bool:
return defect.compliance_guardrail == "OOS" or defect.severity_score >= 70
def apply_certification(defect: Defect, cert: Certification,
authorized: set[str]) -> Defect:
if cert.certified_by not in authorized:
raise DispatchBlocked(f"{cert.certified_by} not an authorized certifier")
if cert.certified_by == defect.reported_by:
raise DispatchBlocked("certifier cannot be the reporting driver (self-cert)")
target = DefectState.REPAIR_UNNECESSARY if cert.unnecessary else DefectState.CERTIFIED
if cert.unnecessary and is_oos(defect):
# § 396.9 OOS condition can never be certified 'repair unnecessary'
raise DispatchBlocked("OOS defect cannot be certified repair-unnecessary")
if target not in _TRANSITIONS[defect.state]:
raise DispatchBlocked(f"illegal transition {defect.state} -> {target}")
return defect.model_copy(update={"state": target})
Step 4: Require the next-driver review before dispatch
Anchor link to "Step 4: Require the next-driver review before dispatch"After certification, § 396.11©(2)(iii) requires the next driver to review and sign the prior report. Record that review as its own transition, again by an identity distinct from the certifier, then and only then may the defect reach dispatch_allowed.
def next_driver_review(defect: Defect, driver_id: str) -> Defect:
if defect.state not in {DefectState.CERTIFIED, DefectState.REPAIR_UNNECESSARY}:
raise DispatchBlocked("no certification to review")
reviewed = defect.model_copy(update={"state": DefectState.NEXT_DRIVER_REVIEWED})
return reviewed
Step 5: Gate dispatch on every open defect
Anchor link to "Step 5: Gate dispatch on every open defect"Dispatch is allowed only when every defect on the vehicle has reached next_driver_reviewed and the certification timestamp precedes the dispatch time. A single un-certified defect holds the whole vehicle.
def can_dispatch(defects: list[Defect], certs: dict[str, Certification],
dispatch_ts: datetime) -> bool:
for d in defects:
if d.state != DefectState.NEXT_DRIVER_REVIEWED:
raise DispatchBlocked(f"{d.record_id}: not certified and reviewed")
cert = certs.get(d.record_id)
if cert is None or cert.certified_ts >= dispatch_ts:
# a certification stamped at or after dispatch is not a valid pre-dispatch cert
raise DispatchBlocked(f"{d.record_id}: certification not before dispatch")
return True
Verification and Testing
Anchor link to "Verification and Testing"Prove the two non-negotiable properties: dispatch is blocked without certification, and an OOS defect cannot be certified “unnecessary.”
import pytest
from datetime import datetime, timedelta, timezone
NOW = datetime.now(timezone.utc)
AUTH = {"carrier_rep_1"}
def _oos_defect() -> Defect:
return Defect(record_id="d1", defect_category="brakes_air_service",
severity_score=88, compliance_guardrail="OOS",
state=DefectState.REPAIR_PENDING, reported_by="driver_a")
def test_dispatch_blocked_without_certification():
d = _oos_defect() # still repair_pending, never certified
with pytest.raises(DispatchBlocked):
can_dispatch([d], certs={}, dispatch_ts=NOW)
def test_oos_defect_cannot_be_certified_unnecessary():
d = _oos_defect()
cert = Certification(record_id="d1", certified_by="carrier_rep_1",
unnecessary=True, certified_ts=NOW)
with pytest.raises(DispatchBlocked, match="repair-unnecessary"):
apply_certification(d, cert, AUTH)
def test_self_certification_is_rejected():
d = _oos_defect().model_copy(update={"reported_by": "carrier_rep_1"})
cert = Certification(record_id="d1", certified_by="carrier_rep_1",
unnecessary=False, certified_ts=NOW)
with pytest.raises(DispatchBlocked, match="self-cert"):
apply_certification(d, cert, AUTH)
def test_certification_after_dispatch_is_invalid():
d = _oos_defect().model_copy(update={"state": DefectState.NEXT_DRIVER_REVIEWED})
late = Certification(record_id="d1", certified_by="carrier_rep_1",
unnecessary=False, certified_ts=NOW + timedelta(minutes=5))
with pytest.raises(DispatchBlocked, match="before dispatch"):
can_dispatch([d], {"d1": late}, dispatch_ts=NOW)
Common Failure Modes and Gotchas
Anchor link to "Common Failure Modes and Gotchas"- Certifier not authorized. A certification signed by someone who is not an authorized carrier representative is not a certification. Check the certifier against an authorization service on every
apply_certification, and record the identity in the sealed transition so an auditor can confirm the signer’s authority months later. - Certification timestamp vs dispatch time. A certification stamped at or after the vehicle was dispatched does not satisfy the “before dispatch” requirement — it is a backfilled record, not a pre-trip certification. Compare
certified_tsagainst the dispatch time from a trusted clock and reject any certification that does not strictly precede dispatch. - Forged or self-certification. The reporting driver certifying their own defect, or a shared login masking who signed, defeats the control. Enforce distinct identities for reporter, certifier, and reviewing driver, and seal each identity into the tamper-evident chain so a forged certification cannot be swapped in later.
- OOS defect routed to repair-unnecessary. An out-of-service condition can never be dispatched on a “repair not needed” certification. Gate the
repair_unnecessarypath onis_oos, keyed to the immovable critical floor of 70, so a defect that meets an OOS criterion under § 396.9 must be actually repaired and certified before the vehicle moves.
Frequently Asked Questions
Anchor link to "Frequently Asked Questions"Who is allowed to certify that a DVIR defect was repaired?
An authorized motor carrier representative — not automatically the mechanic and never the driver who reported the defect. Under § 396.11©(2) the carrier certifies that each listed defect was repaired or that repair was unnecessary, so the certification must come from an identity the carrier has authorized for that action. The gate checks the certifier against an authorization service and rejects a self-certification where the reporter and certifier are the same person.
Can a defect ever be dispatched as “repair unnecessary”?
Only a non-out-of-service defect. § 396.11©(2) allows the carrier to certify that repair was unnecessary for a listed defect, but a condition that meets an out-of-service criterion under § 396.9 cannot be waived that way — it must be actually repaired and certified. The state machine blocks the repair_unnecessary transition for any defect at or above the critical floor of 70 or tagged OOS, so an OOS defect can only close through genuine repair.
What does § 396.11©(2)(iii) require the next driver to do?
Before driving, the next driver must review the prior driver’s report and sign that the required repairs were made or that repair was unnecessary. In the pipeline this is a distinct transition, performed by an identity separate from the certifier, that moves the defect to next_driver_reviewed. Dispatch is gated on that review existing for every open defect, so a certified-but-unreviewed defect still holds the vehicle.
Related
Anchor link to "Related"- FMCSA DVIR Rule 396.11 Breakdown — the clause-by-clause obligations this gate enforces.
- How to Map DVIR Fields to FMCSA 396.11 Requirements — the field-level mapping the certification records reference.
- Out-of-Service Criteria and OOS Hold Triggers — which defects can never be certified repair-unnecessary.
- Immutable Audit Trail and WORM Retention — where each certification transition is sealed and retained.
- Severity Scoring Algorithms for DVIR Defects — produces the score that decides whether a defect can take the unnecessary path.
Back to FMCSA DVIR Rule 396.11 Breakdown, part of Core DVIR Architecture & FMCSA Compliance Mapping.