From 501e4175846affc79700ab3de33035a40b018586 Mon Sep 17 00:00:00 2001 From: justin Date: Tue, 2 Jun 2026 21:42:55 -0500 Subject: [PATCH] =?UTF-8?q?DOT=20D&A=20binder:=20add=20Section=2011=20?= =?UTF-8?q?=E2=80=94=20Practical=20Guidance=20for=20the=20Administrator?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Adds the real-world know-how a first-time DER needs beyond the bare regs: - Owner-operators / one-driver companies (must use a consortium; cannot self-test or self-select) — the most misunderstood case. - Audits & penalties: what the new-entrant safety audit asks for and the consequences of no program (civil penalties, failed audit, out-of-service). - Problem test results: dilute, shy bladder, cancelled test, split-specimen. - Prescriptions / marijuana / CBD (marijuana prohibited regardless of state law; CBD trap; route medical questions to the MRO). - What counts as a refusal (treated as a positive). - Costs & timeline expectations. - DER do's and don'ts (act same-day, keep records separate/confidential, never tip off a random selection, don't interpret results yourself). --- .../templates/dot_da_binder_generator.py | 155 ++++++++++++++++++ 1 file changed, 155 insertions(+) diff --git a/scripts/document_gen/templates/dot_da_binder_generator.py b/scripts/document_gen/templates/dot_da_binder_generator.py index b958923..bedf828 100644 --- a/scripts/document_gen/templates/dot_da_binder_generator.py +++ b/scripts/document_gen/templates/dot_da_binder_generator.py @@ -17,6 +17,8 @@ program under the applicable DOT testing regulation: 8. Recordkeeping instructions + retention schedule 9. All required compliance forms (Forms A-G), each on its own page 10. The regulations (citations + how to read the actual rule text) + 11. Practical guidance for the administrator (owner-operators, audits/ + penalties, problem results, marijuana/CBD, refusals, costs, do's & don'ts) (+ optional state Drug-Free Workplace addendum) Output is **DOCX** so an attorney or the carrier can review and edit it. Each @@ -428,6 +430,10 @@ def generate_da_binder( "use, each on its own page.", "**Section 10 — The Regulations.** Citations and how to read the actual " "rule text.", + "**Section 11 — Practical Guidance for the Administrator.** Real-world " + "answers: owner-operators, audits and penalties, problem test results, " + "prescriptions/marijuana/CBD, what counts as a refusal, costs, and the " + "DER's do's and don'ts.", ]) if state_dfwp: b.body( @@ -985,6 +991,9 @@ def generate_da_binder( "counsel review this program before adoption. Questions: " "compliance@performancewest.com.") + # ── Section 11 — Practical guidance for the administrator ─────────────── + _section_practical_guidance(b, meta, company, random_rate) + # ── Optional state DFWP addendum ─────────────────────────────────────── if state_dfwp: b.page_break() @@ -1019,6 +1028,152 @@ def generate_da_binder( return str(out) +# ── Section 11 — Practical guidance ───────────────────────────────────────── +def _section_practical_guidance(b, meta, company, random_rate): + b.page_break() + b.h1("Section 11 — Practical Guidance for the Administrator") + b.body( + "The regulations tell you what to do; this section covers the real-" + "world questions a program administrator runs into. It is practical " + "guidance, not legal advice — when a situation is serious or unclear, " + "call your C-TPA/MRO or counsel.") + + b.h2("Owner-operators and one-driver companies") + b.body( + "This is the most misunderstood situation. If you are an owner-operator " + "or a one-driver carrier, you are **both the employer and the covered " + "employee** — and you may **not** test yourself or run your own random " + "selection.") + b.bullets([ + "You **must** join a consortium (C-TPA). The consortium puts you in a " + "pool with other drivers and does the random selection for you, so the " + "selection is genuinely random and out of your hands.", + "You cannot be your own DER for results handling in a way that defeats " + "the rule; the C-TPA/MRO handles results and notifies you.", + "You still need a pre-employment negative, you are still subject to " + "random/post-accident/reasonable-suspicion (someone else must observe " + "for reasonable suspicion), and you still keep all records.", + "When you add a driver, you become the employer for that driver and " + "take on full DER duties for them.", + ]) + + b.h2("Audits, penalties, and the new-entrant safety audit") + b.body( + "A new motor carrier typically gets a **new-entrant safety audit** in " + "its first 12 months, and any carrier can be audited later. The " + "auditor will ask to see your testing program. Have these ready:") + b.bullets([ + "Your written policy and signed employee acknowledgments (Form A).", + "Proof of consortium/C-TPA enrollment and your random-selection records " + "and annual rate calculation.", + "Pre-employment negative results for every driver before they drove.", + "Supervisor training certificates (Form F).", + "Any post-accident, reasonable-suspicion, return-to-duty, and follow-up " + "records.", + ]) + if meta.get("clearinghouse"): + b.bullets([ + "FMCSA Clearinghouse: proof of pre-employment full queries and " + "annual limited queries on every CDL driver, and that you reported " + "any violations.", + ]) + b.body( + "**Why this matters:** missing or no testing program is one of the most " + "common automatic safety-audit failures. It can lead to civil " + "penalties, a failed new-entrant audit (revoked operating authority), " + "and drivers placed **out of service**. A driver who tests positive, " + "refuses, or is 'prohibited' may not operate a CMV.") + + b.h2("Problem test results — what to do") + b.body("Not every test comes back a clean negative. Know these:") + b.bullets([ + "**Dilute (negative-dilute):** usually you may (and sometimes must) " + "direct an immediate recollection under your policy — follow the MRO's " + "instruction. A positive-dilute is treated as a positive.", + "**Shy bladder / insufficient specimen:** the collector follows a set " + "procedure (water, up to three hours). If the employee still cannot " + "provide enough, the MRO refers them for a medical evaluation; an " + "unexplained failure is a **refusal**.", + "**Cancelled test:** a test cancelled for a fatal/correctable flaw is " + "neither positive nor negative; the MRO/C-TPA will tell you whether a " + "recollection is required (for pre-employment, return-to-duty, and " + "follow-up tests, a recollection is required).", + "**Split-specimen request:** an employee may, within 72 hours of being " + "told of a verified positive/adulterated/substituted result, request " + "that the split (Bottle B) be tested at a second lab — at their cost. " + "Do not remove this right; the MRO handles it.", + ]) + + b.h2("Prescriptions, marijuana, and CBD") + b.bullets([ + "**Marijuana is prohibited** for safety-sensitive employees under " + "federal law **regardless of state legalization** or a state medical-" + "marijuana card. A marijuana positive is a violation.", + "**CBD is a trap.** CBD products are unregulated and may contain enough " + "THC to cause a positive. Using CBD is **not** a valid medical " + "explanation to the MRO. Warn your drivers in writing.", + "**Legitimate prescriptions:** the MRO — not you — evaluates whether a " + "prescription explains a positive. Drivers should keep prescriptions " + "current and tell the MRO (not the employer) if contacted. A driver " + "must not perform safety-sensitive duty on any medication a prescriber " + "has warned against.", + "Do not ask drivers to disclose their medications to you; that can " + "create ADA/privacy problems. Route medical questions to the MRO.", + ]) + + b.h2("What counts as a refusal") + b.body( + "A refusal is treated exactly like a verified positive and triggers the " + "full return-to-duty process. Refusals include:") + b.bullets([ + "Failing to appear for a test within a reasonable time, or leaving the " + "collection site before the process is complete.", + "Failing to provide a specimen (without a valid medical reason), or " + "failing the shy-bladder/insufficient-specimen evaluation.", + "Refusing to be observed for a directly observed (return-to-duty or " + "follow-up) collection.", + "Adulterating, substituting, or tampering with a specimen, or admitting " + "the specimen was altered.", + "Failing or declining to take a second test the employer or collector " + "directs.", + ]) + b.body( + "Document the time and circumstances (Form C is useful here) and treat " + "it as a violation — do not let the employee continue safety-sensitive " + "work.") + + b.h2("Costs and timeline — set expectations") + b.bullets([ + "Typical out-of-pocket costs: consortium/C-TPA enrollment and per-" + "driver annual fees, the per-test collection/lab/MRO fee, and " + "supervisor training. Your provider can give you current pricing.", + "A pre-employment result is usually back within a couple of business " + "days (longer if the MRO must investigate a non-negative).", + "After a violation, the SAP and return-to-duty process is typically " + "weeks to months and is generally at the employee's expense; you are " + "not required to return anyone to duty.", + ]) + + b.h2("DER do's and don'ts") + b.bullets([ + "**Do** act on a positive/refusal the **same day** — remove the " + "employee from safety-sensitive duty immediately.", + "**Do** keep D&A records **separate and confidential** — not in the " + "general personnel file, and not shared with people who don't need to " + "know.", + "**Do** keep your consortium roster current; an out-of-date roster " + "skews your random rate and fails audits.", + "**Don't** warn or 'tip off' a randomly selected employee, delay their " + "collection, or let them go home first.", + "**Don't** accept a home/instant test or a non-DOT test in place of a " + "DOT-required test.", + "**Don't** try to interpret results yourself — the MRO verifies; you " + "act on what the MRO/C-TPA reports.", + "**When in doubt, call** your C-TPA, MRO, or counsel before acting. " + "Questions: compliance@performancewest.com.", + ]) + + # ── Header / footer ───────────────────────────────────────────────────────── def _add_header_footer(doc, meta, carrier_name): section = doc.sections[0]