Business rules
The business rules SCOPE applies: the decisions your company could make differently, such as thresholds, who may do what, and what counts as overdue or recordable. How the screens behave is not here. Read a rule, then mark it Looks right, ask a Question, or ask to Change it. Comments are saved for everyone who opens this page and can never be edited or deleted, so the page is the record of the review. There is no sign-in; the name you type is shown on your comments.
Who can do what8 rules
- ACC-02Not reviewed
A driver may start only two things: the daily vehicle inspection (DVIR) and an incident report.
Those are the two things a driver does on a truck; observations and investigations are supervision, not driver work.
packages/core/src/access.ts:37 · database: observation_insert, incident_update
Add your name - ACC-04Not reviewed
A driver cannot change an incident after reporting it (no investigation work), and the database refuses it too.
Investigations are supervision.
packages/core/src/access.ts:6 · database: incident_update
Add your name - ACC-05Not reviewed
The vehicle inspection (DVIR) button appears only for drivers and supervisors, not for a GM or VP.
The client's rule: a GM and VP do not pre-trip a truck, while at a small company the supervisor drives.
packages/core/src/access.ts:54
Add your name - ACC-08Not reviewed
The Reports tab is open to supervisors and above, never to drivers.
The client's rule: "a role-based reporting tab, supervisor and up".
packages/core/src/access.ts:78
Add your name - ACC-11Not reviewed
Supervisors and above may run training: add or replace material, assign a course, schedule and sign a class, and approve training taken elsewhere.
packages/core/src/access.ts:119 · database: add_training_material, assign_training, review_external_training
Add your name - ACC-12Not reviewed
Only a GM or VP may change the course catalog (add, edit or retire a course) or own and run the standing assignment rules.
A supervisor runs the courses that exist; deciding what the company teaches is a level above.
packages/core/src/access.ts:129 · database: upsert_training_course, retire_training_course, save_training_rule, apply_training_rules
Add your name - ACC-13Not reviewed
Nobody may approve their own outside training; it needs a supervisor or above other than the learner, at a site they cover.
packages/core/src/tasks.ts:476 · database: review_external_training
Add your name - ACC-14Not reviewed
Only a GM or VP may use "Mark all Safe" / "Mark all Not Observed" on an observation checklist; a supervisor must rate each line by hand.
The client's rule: the supervisor was the one watching, and bulk-filling is how a 25-line checklist gets verdicts nobody actually gave.
packages/core/src/access.ts:110
Add your name
DVIR inspections7 rules
- DVIR-01Not reviewed
The inspection checklist has 50 items: 33 for the truck itself, 4 for safety equipment, and 13 for the trailer.
Taken from the items that actually appear on DVIRs in the sample data, in the order of the paper form.
packages/core/src/checklist.ts:14
Add your name - DVIR-02Not reviewed
The 13 trailer items only have to be answered when the vehicle is pulling a trailer. The truck and safety equipment items are always required.
13 of the 50 items apply only to trailers.
packages/core/src/dvir.ts:107
Add your name - DVIR-06Not reviewed
Every DVIR records a reading: odometer miles for an on-road vehicle, engine hours for off-road equipment.
packages/core/src/dvir.ts:150
Add your name - DVIR-08Not reviewed
Every item on the checklist that applies to this vehicle must be answered before the DVIR can be submitted.
packages/core/src/dvir.ts:169
Add your name - DVIR-09Not reviewed
Every defect needs a severity (Minor, Major or Out of Service) and a description of at least 3 characters.
A defect with no description is useless to the mechanic who has to fix it.
packages/core/src/dvir.ts:177
Add your name - DVIR-10Not reviewed
The driver must sign the inspection before it can be submitted.
packages/core/src/dvir.ts:186
Add your name - DVIR-11Not reviewed
A vehicle is out of service when at least one of its defects is rated Out of Service.
Checked against 765 of 765 live out-of-service inspections.
packages/core/src/dvir.ts:91 · database: capture_dvir
Add your name
Equipment certification gate7 rules
- CERT-01Not reviewed
A driver can only file a DVIR for a vehicle when they hold every certification that vehicle type requires.
Both people filing a DVIR here (pre-trip and post-trip) are the person about to take the truck, so being allowed to inspect it and being allowed to drive it are the same question.
packages/core/src/operator-gate.ts:280 · database: app.person_could_operate_on, capture_dvir
Add your name - CERT-02Not reviewed
A vehicle type that has no certification requirements listed is not restricted for anyone.
packages/core/src/operator-gate.ts:59 · database: asset_type_requirement
Add your name - CERT-04Not reviewed
Certifications are judged as of the day of the inspection, never as of today.
Judging past inspections against today's status turned one expired CDL into 340 violations that were entirely lawful when they happened.
packages/core/src/operator-gate.ts:19 · database: app.person_could_operate_on
Add your name - CERT-09Not reviewed
A supervisor can release a blocked driver for one specific vehicle on one specific day. The database also limits a release to today or tomorrow and to one per person, vehicle and day, and supervisors cannot release themselves.
A standing exemption is a policy decision, not a supervisor's call at 05:00. Releasing the same person every morning leaves a pattern somebody can see.
packages/core/src/operator-gate.ts:276 · database: release_operator, operator_release_one_per_day, operator_release_not_self
Add your name - CERT-10Not reviewed
A release must give a reason of at least 20 characters, and the reason is recorded against the supervisor's name.
It must be a defensible sentence, not "ok".
packages/core/src/operator-gate.ts:358 · database: operator_release_reason_substantive
Add your name - CERT-11Not reviewed
A release can only be granted to someone whose job title involves operating certified equipment: Driver, Heavy Equipment Operator, Mechanic, Technician, Laborer or Maintenance Supervisor. A Supervisor, Manager, General Manager, VP, Dispatcher or Helper cannot be released.
Otherwise people who never drive were offered exceptions to a rule that was never about them.
packages/core/src/operator-gate.ts:346 · database: app.operates_equipment, release_operator
Add your name - CERT-12Not reviewed
Someone "covers" a machine only when both levels are valid today: the base license and the company certification for that machine.
The coverage report uses the same rule as the DVIR gate, so the two can never disagree about one person.
packages/core/src/coverage.ts:114
Add your name
Incidents15 rules
- INC-02Not reviewed
An incident has three statuses: New (reported, nobody has picked it up), Open (someone owns the investigation) and Closed (the owner has signed the investigation off).
A separate "Investigation Complete" would need exactly the same fields as Closed.
packages/core/src/incident.ts:45 · database: incident_status_check, incident_investigation_progress
Add your name - INC-03Not reviewed
Closing an incident does not mean the follow-up is finished. Corrective actions, tasks and remedial training keep their own statuses.
Those belong to the people they were assigned to.
packages/core/src/incident.ts:41
Add your name - INC-04Not reviewed
One report can be several kinds at once (injury, vehicle accident, property damage), and the most serious kind becomes the primary type, in the order injury, vehicle, property, near miss.
An injury outranks the collision that caused it, so TRIR and the accident rate keep counting the same incidents they always have.
packages/core/src/incident.ts:342
Add your name - INC-05Not reviewed
A near miss cannot be combined with any other kind. Ticking near miss clears the others, and ticking any other kind clears near miss.
By definition a near miss means nobody was hurt and nothing was damaged.
packages/core/src/incident.ts:368
Add your name - INC-06Not reviewed
A case is OSHA-recordable when it is classified as Medical Treatment, Restricted Work or Lost Time.
packages/core/src/incident.ts:202 · database: incident_recordable_matches
Add your name - INC-07Not reviewed
A case is a DART case (days away, restricted or transferred) when it is classified as Restricted Work or Lost Time.
packages/core/src/incident.ts:211 · database: incident_dart_matches
Add your name - INC-08Not reviewed
A case counts as a lost-time injury when it has more than zero lost days.
packages/core/src/incident.ts:212 · database: incident_lti_matches
Add your name - INC-10Not reviewed
Lost days can only be entered on a Lost Time case, and restricted days only on a Restricted Work case.
packages/core/src/incident.ts:220 · database: incident_lost_days_only_lost_time, incident_restricted_days_only_restricted
Add your name - INC-15Not reviewed
Whether the incident was on company premises follows from the chosen location: curbside, customer sites and public roads are off premises, everything else is on. The reporter is asked only when they typed in an "Other" location.
In all 352 sample incidents, the location and the premises answer never disagree.
packages/core/src/incident.ts:146
Add your name - INC-16Not reviewed
When someone was hurt, the report must record the type of injury, the body part, whether they got medical attention, and whether they finished the shift.
These are the facts the investigator needs to classify the case.
packages/core/src/incident.ts:512 · database: incident_intake_facts_need_injury
Add your name - INC-17Not reviewed
A report can list at most 4 contributing factors, and their order is their rank.
The investigation adds the rest.
packages/core/src/incident.ts:469 · database: rank between 1 and 4 on incident_contributing_factor
Add your name - INC-20Not reviewed
A Lost Time case records the first and the last day away from work. The days away are counted from those dates, both days included; while the last day is blank the person is still away and the count runs to today.
Which days somebody was off, not only how many, is what the lost time report and the OSHA log ask for.
packages/core/src/incident.ts:251 · database: incident_lost_time_days_match_dates, save_investigation
Add your name - INC-21Not reviewed
The first day away cannot be before the incident, the last day cannot be before the first, and neither can be in the future. Lost time dates exist only on a Lost Time case.
A return-to-work date is a fact once it has happened, not a plan.
packages/core/src/incident.ts:279 · database: incident_lost_time_start_after_incident, incident_lost_time_end_after_start, incident_lost_time_dates_only_lost_time
Add your name - INC-22Not reviewed
A Lost Time case with no last day away goes on its investigation owner's Tasks list (the site manager's when nobody owns it) a week after the first day away, and again a week after each "still away". Entering the last day away or answering "still away" clears it, and both work on a closed investigation without reopening it.
The last day away is usually known after the investigation is signed off; without a reminder the case runs on and the LTI days are wrong.
packages/core/src/tasks.ts:631 · database: my_lost_time_checkins, record_return_to_work, confirm_still_away
Add your name - INC-23Not reviewed
GMs and VPs see how many people are off work today on a lost-time case on the Lost-time key figure ("1 off work now"), opening the Lost time report on who is still away, with who answers for each case and whether its weekly check is late. It follows the site chosen on the dashboard, never the period, and prints nothing at zero.
It is a reading of the operation, not their task: the owner is the one who answers it.
packages/core/src/incident.ts:310 · database: report_lost_time
Add your name
Investigations8 rules
- INV-01Not reviewed
An incident can be marked Open only once it has an investigation owner.
packages/core/src/investigation.ts:102 · database: incident_investigation_progress
Add your name - INV-02Not reviewed
Only someone whose job title contains VP, Vice President, Director, Supervisor or Manager can own an investigation.
An investigation is supervision: all 352 existing investigations are owned by a Supervisor or a Manager. VPs and Directors are included because the client's workflow starts at the top.
packages/core/src/investigation.ts:287 · database: incident_owner_is_supervisory (app.is_supervisory)
Add your name - INV-04Not reviewed
Closing needs a root cause of at least 15 characters, a root cause category, an estimated cost of zero or more, and at least one contributing factor.
Closing with no contributing factor leaves an incident nobody learns anything from.
packages/core/src/investigation.ts:200 · database: incident_investigation_progress
Add your name - INV-05Not reviewed
An investigation cannot be closed while any request for input on it is still open. Each request must first be accepted, or cancelled with a reason.
The owner asked for that input, and the sign-off says the evidence is collected.
packages/core/src/investigation.ts:123 · database: app.assert_no_live_requests
Add your name - INV-07Not reviewed
To close, the owner confirms two things: photos, documents and statements are collected (or there were none), and a corrective action is assigned (or none is needed).
No query can check these. Attachments are often absent, and 35 incidents legitimately have no corrective action.
packages/core/src/investigation.ts:148
Add your name - INV-10Not reviewed
A Lost Time case must record the first day away from work.
The days away are counted from the dates, so without a first day there is no count.
packages/core/src/investigation.ts:240
Add your name - INV-12Not reviewed
A corrective action raised from an investigation needs a type, a description of at least 10 characters, and a due date.
packages/core/src/investigation.ts:243
Add your name - INV-13Not reviewed
Corrective actions from an investigation come in 12 types (from Coaching / Counseling to Equipment Replacement), four priorities (Low, Medium, High, Critical), and suggested due dates 7, 14, 30 or 45 days out.
Live incident actions are due 1 to 45 days out, with a median of 18.
packages/core/src/investigation.ts:27
Add your name
Requests for input7 rules
- REQ-01Not reviewed
The investigation owner keeps the file and sends a piece of it to someone else; this is different from handing over ownership.
packages/core/src/investigation-request.ts:3 · database: request_investigation_input
Add your name - REQ-02Not reviewed
Only the incident's investigation owner may ask for input, and only once an owner has been assigned.
The answer has to come back to someone accountable.
packages/core/src/investigation-request.ts:3 · database: request_investigation_input
Add your name - REQ-05Not reviewed
A returned answer goes to whoever owns the investigation now, not necessarily the person who sent the request.
If the file changes hands, the answer follows it.
packages/core/src/investigation-request.ts:38
Add your name - REQ-10Not reviewed
Sending an answer back needs a reason of at least 5 characters.
Without a reason the same argument happens twice.
packages/core/src/investigation-request.ts:102 · database: review_investigation_input
Add your name - REQ-11Not reviewed
Withdrawing a request needs a reason of at least 5 characters.
Withdrawing is the way past the sign-off block, so it has to be on the record.
packages/core/src/investigation-request.ts:104 · database: cancel_investigation_input
Add your name - REQ-12Not reviewed
A request must have a due date, and it cannot be before today.
packages/core/src/investigation-request.ts:142 · database: request_investigation_input
Add your name - REQ-20Not reviewed
The paper trail of a request can only be added to, never edited or deleted, by anyone.
packages/core/src/changelog.ts:22 · database: refuse_request_event_change
Add your name
Incident status and audit trail3 rules
- STAT-03Not reviewed
Taking ownership of an investigation moves an incident from New to Open, and only the owner can close it.
packages/core/src/tasks.ts:301 · database: incident_investigation_progress
Add your name - STAT-12Not reviewed
The incident audit trail is written automatically and can only be added to, never edited or deleted.
packages/core/src/changelog.ts:1 · database: incident_event_no_change, incident_log_event
Add your name - STAT-15Not reviewed
An incident export always includes the incident record and, by default, its corrective actions; the audit trail and prior history are off unless the person exporting ticks them.
Asked for explicitly: the trail is internal process and the sender should decide.
packages/core/src/changelog.ts:144
Add your name
Observations13 rules
- OBS-01Not reviewed
Nobody can file an observation on themselves.
This is the one hard rule on who may observe whom.
packages/core/src/observation.ts:339 · database: observation_observer_not_subject, capture_observation
Add your name - OBS-02Not reviewed
Any supervisor at the site may observe an employee. It does not have to be their own line manager.
Only 530 of 3,624 observations were filed by the direct supervisor.
packages/core/src/observation.ts:17
Add your name - OBS-04Not reviewed
Each checklist line is rated Safe, Unsafe or Not Observed.
"Not Observed" records that the behavior was on the form but was not watched, which shows when a checklist is wrong for the job.
packages/core/src/observation.ts:35 · database: observation_item_result_check
Add your name - OBS-05Not reviewed
An observation needs at least one focus area, and every line on the form must be rated.
packages/core/src/observation.ts:343
Add your name - OBS-06Not reviewed
At least one line must actually be rated Safe or Unsafe. A form marked entirely Not Observed is refused.
A form where nothing was observed is not an observation.
packages/core/src/observation.ts:357 · database: capture_observation
Add your name - OBS-07Not reviewed
An Unsafe line must say what was seen (at least 3 characters) and what corrective action was taken or is needed (at least 3 characters).
Client's rule: an unsafe call carries its own corrective detail. Without it, it is a complaint, not an observation.
packages/core/src/observation.ts:391 · database: observation_item_unsafe_has_notes, observation_item_unsafe_has_corrective_action
Add your name - OBS-08Not reviewed
A line added because of telematics events cannot be removed. If it is marked Not Observed, the supervisor must say why.
Otherwise "Not Observed" becomes a quiet way to defeat the risk-driven checklist.
packages/core/src/observation.ts:405 · database: observation_item_required_skip_has_reason
Add your name - OBS-10Not reviewed
Any Unsafe line makes the whole observation At-Risk. With none, it is Safe. Lines marked Not Observed count as neither.
Counting unwatched lines as at-risk would inflate every scorecard.
packages/core/src/observation.ts:262 · database: capture_observation
Add your name - OBS-11Not reviewed
An At-Risk observation always requires a corrective action and a Safe one never does. A Mixed result (legacy records only) is the supervisor's call.
This held across every live row.
packages/core/src/observation.ts:303 · database: capture_observation
Add your name - OBS-13Not reviewed
When a corrective action is required, it needs an action type, an owner, a description of at least 10 characters, and a follow-up due date that is not in the past.
packages/core/src/observation.ts:417 · database: capture_observation
Add your name - OBS-14Not reviewed
Suggested follow-up lead times are 7, 14, 21 or 30 days. The six action types are Coaching / Counseling, Retraining, PPE Issuance, JHA Review, Housekeeping Correction and Ride-Along Evaluation.
These are what the live data shows.
packages/core/src/observation.ts:66
Add your name - OBS-15Not reviewed
Remedial training from an observation is assigned only through its corrective action. It needs a course, a due date that is not in the past, and at least one Unsafe line it addresses.
The client asked for the link to be explicit: a training that addresses nothing in particular is a course, not a remedy.
packages/core/src/observation.ts:433 · database: training_observation_item
Add your name - OBS-17Not reviewed
An observation needs a written summary of at least 10 characters and the supervisor's signature.
packages/core/src/observation.ts:413
Add your name
Risk-driven observations12 rules
- RISK-01Not reviewed
A telematics event counts toward observation targeting only if its severity is 6 or more (on a 1-10 scale) and it happened in the last 30 days.
Matches the data: about 50% of vehicle incidents follow 3 or more severity-6+ events in the prior 30 days.
supabase/migrations/20260831250000_risk_rules.sql:95 · database: observation_setting
Add your name - RISK-02Not reviewed
Each telematics event type makes specific checklist lines mandatory on that driver's observation, with the evidence shown beside the line.
A flagged driver should not get the generic checklist; the conversation in the yard should be about something specific.
packages/core/src/risk.ts:73 · database: observation_risk_rule
Add your name - RISK-03Not reviewed
Following Distance and Harsh Braking events require the following-distance line (at least 5 seconds or two truck lengths).
supabase/migrations/20260831250000_risk_rules.sql:52 · database: observation_risk_rule (RR-01, RR-03)
Add your name - RISK-04Not reviewed
Harsh Acceleration, Harsh Cornering and Speeding events require the line on speed appropriate for conditions and the posted limit.
supabase/migrations/20260831250000_risk_rules.sql:55 · database: observation_risk_rule (RR-04 to RR-06)
Add your name - RISK-05Not reviewed
Rolling Stop events require the full-stop line; Distracted Driving requires the no-phone line; Seatbelt Violation requires the seatbelt line.
supabase/migrations/20260831250000_risk_rules.sql:58 · database: observation_risk_rule (RR-07, RR-10, RR-11)
Add your name - RISK-06Not reviewed
Lane Departure events require both the lane-discipline line and the mirrors line.
supabase/migrations/20260831250000_risk_rules.sql:59 · database: observation_risk_rule (RR-08, RR-09)
Add your name - RISK-07Not reviewed
Unsafe Backing events require both the spotter line and the Get Out And Look line.
supabase/migrations/20260831250000_risk_rules.sql:63 · database: observation_risk_rule (RR-12, RR-13)
Add your name - RISK-08Not reviewed
Harsh Braking no longer requires the brake line.
That line now says parking brake versus service brake, which a harsh-braking event does not suggest, and Harsh Braking already requires following distance.
supabase/migrations/20260930130000_last_four_lines_read_the_book.sql:21 · database: observation_risk_rule (RR-02 inactive)
Add your name - RISK-11Not reviewed
How often someone should be observed starts from tenure: under 1 year every 30 days, under 3 years every 60 days, otherwise every 90 days.
supabase/migrations/20260831250000_risk_rules.sql:86 · database: observation_cadence_rule (CR-01 to CR-03)
Add your name - RISK-12Not reviewed
High-severity telematics events can only shorten that interval: 3 or more events means at least every 30 days, and 5 or more means every 14 days.
A ten-year driver with six hard events lands on fortnightly, not quarterly.
packages/core/src/risk.ts:135 · database: observation_cadence_rule (CR-04, CR-05)
Add your name - RISK-13Not reviewed
Someone never observed, or last observed longer ago than their interval, is marked Overdue.
packages/core/src/risk.ts:172
Add your name - RISK-14Not reviewed
Someone not yet overdue is Elevated if they are under 1 year's tenure or have tripped an event rule, and Routine otherwise.
packages/core/src/risk.ts:180
Add your name
Photos and documents2 rules
- ATT-06Not reviewed
One incident report can carry at most 12 photos. The investigation has no limit.
Uploading a dozen photos over a yard connection already takes a minute of the driver's shift, and a report needing more is an investigation.
packages/core/src/attachment.ts:182
Add your name - ATT-07Not reviewed
Only photos can be attached while reporting an incident. Documents go on the investigation.
Nobody scans an invoice at the curbside.
packages/core/src/attachment.ts:219
Add your name
Corrective actions and tasks16 rules
- ACT-03Not reviewed
A row is overdue only once its due date has passed; on the due date itself it still reads "Due".
packages/core/src/tasks.ts:212
Add your name - ACT-07Not reviewed
Only the person a corrective action is assigned to may close it or mark its work done; a supervisor who wants it closed must ask that person.
packages/core/src/action-detail.ts:516 · database: action_update_own, complete_action, mark_action_work_done
Add your name - ACT-08Not reviewed
Whether a second person must sign off is a setting on the action itself, not on the rank of whoever is looking at it.
packages/core/src/action-detail.ts:480
Add your name - ACT-09Not reviewed
An action needing sign-off goes in two steps: the assignee presses "Mark Done" (I finished it), then a different person presses "Sign Off" (I have seen it).
Two different claims by two different people.
packages/core/src/tasks.ts:1110 · database: mark_action_work_done, verify_action
Add your name - ACT-10Not reviewed
An action needing sign-off cannot be closed outright by its assignee.
packages/core/src/action-detail.ts:527 · database: complete_action
Add your name - ACT-11Not reviewed
The sign-off person is chosen when the action is raised: first whoever raised it, then the assignee's own supervisor, then the site manager, skipping anyone who is the assignee.
Nobody signs off their own work.
packages/core/src/tasks.ts:330 · database: action_verifier
Add your name - ACT-12Not reviewed
If every step of that chain lands back on the assignee, no button is offered and the row says "Nobody but you could sign this off: ask a supervisor to reassign it".
Measured: 11 of 353 open sign-off actions, all site managers at the top of their own chart.
packages/core/src/tasks.ts:1105 · database: mark_action_work_done
Add your name - ACT-14Not reviewed
Only the named sign-off person may sign, and only after the work has been marked done.
packages/core/src/action-detail.ts:501 · database: verify_action
Add your name - ACT-16Not reviewed
An action waiting for sign-off keeps its original due date, not the date the work was marked done.
A signature three weeks late is still three weeks late.
packages/core/src/tasks.ts:692
Add your name - ACT-17Not reviewed
Closing an action also closes every unfinished task under it, including any escalated to someone else, and the confirmation says how many.
A reader who is not told has had two things happen and been shown one.
packages/core/src/tasks.ts:1195 · database: complete_action
Add your name - ACT-20Not reviewed
An escalated task appears on the escalation target's list as "Escalated to you" with no button: the original assignee still owes and closes the work.
Escalation moves accountability, never the assignment.
packages/core/src/tasks.ts:397 · database: task_update_own
Add your name - ACT-23Not reviewed
A course is marked finished by whoever delivers it, not by the learner ticking it.
Completion needs a date, a trainer and a score, which a self-tick does not supply.
packages/core/src/tasks.ts:936
Add your name - ACT-24Not reviewed
An action reads as overdue only when its recorded status says Overdue, not by re-working it from the due date.
A panel that disagrees with the dashboard tile that opened it is worse than one a day stale.
packages/core/src/action-detail.ts:174
Add your name - ACT-25Not reviewed
A driver's own Tasks list never shows actions raised off a vehicle inspection; a mechanic or technician on the same screen does see them.
Client question Q-A3: a defect a driver finds is the shop's repair; the driver closes the loop at the next pre-trip.
packages/core/src/tasks.ts:893
Add your name - ACT-28Not reviewed
Outside training waiting for review goes to the learner's own supervisor's list only.
A row belongs on one list, and that person signs off the rest of their file.
packages/core/src/tasks.ts:476
Add your name - ACT-29Not reviewed
A class appears on its trainer's list for sign-off from the day after it was held; until signed, nobody on the roster counts as trained.
Until the class has happened there is nothing to sign.
packages/core/src/tasks.ts:124
Add your name
Maintenance shop7 rules
- SHOP-01Not reviewed
A shop supervisor is a supervisor whose job title contains "maintenance", "shop" or "fleet"; he has normal supervisor access but sees a repair-focused screen.
A word match means "Shop Foreman" or "Fleet Maintenance Manager" needs no code change.
packages/core/src/shop.ts:24 · database: shop_owner_for_site
Add your name - SHOP-02Not reviewed
Anyone whose title contains mechanic, technician, maintenance, shop or fleet counts as shop staff and sees inspection repairs on their own list.
Repairs are dropped from a driver's list and are the whole of a mechanic's.
packages/core/src/shop.ts:35
Add your name - SHOP-03Not reviewed
Only two kinds of action are shop work: Maintenance Repair and Equipment Replacement; Corrective Action Notices and Procedure Updates belong to operations.
Shop work is decided by the kind of action, not who holds it, so a brake job that lands on an operations supervisor still shows.
packages/core/src/shop.ts:60 · database: dispatch_action
Add your name - SHOP-04Not reviewed
A defect on an inspection raises one repair, assigned to the site's shop supervisor (or the site manager where there is none) with no sign-off person yet.
Naming a sign-off person at that point would have named the driver who found the defect, and a driver does not sign off a brake job.
packages/core/src/tasks.ts:656 · database: raise_dvir_repair
Add your name - SHOP-06Not reviewed
Assigning a repair to a mechanic makes the person who assigned it the sign-off person, and the mechanic doing it cannot also be the one who signs it.
packages/core/src/tasks.ts:659 · database: dispatch_action
Add your name - SHOP-07Not reviewed
A repair moves through New (with the shop supervisor), Assigned (with a mechanic or technician), Awaiting sign-off (marked done) and Corrected (signed off).
"New" is read from who holds it, not a flag.
packages/core/src/shop.ts:313
Add your name - SHOP-08Not reviewed
Signing off a repair lifts the truck's out-of-service hold, unless another out-of-service repair on the same truck is still open.
Two defects on two mornings are two jobs.
packages/core/src/shop.ts:300 · database: release_hold_on_repair
Add your name
Assigning and finishing training13 rules
- TRN-01Not reviewed
Only a supervisor or above can assign a course, and only to people at a site they cover.
packages/core/src/training-assignment.ts:126 · database: assign_training
Add your name - TRN-02Not reviewed
A course cannot be assigned without a course and a due date, and the due date cannot be in the past.
A due date in the past is a course that is overdue the moment it is assigned.
packages/core/src/training-assignment.ts:126 · database: assign_training
Add your name - TRN-03Not reviewed
A retired course cannot be assigned.
supabase/migrations/20261007120000_lms_tier_1_2.sql:1692 · database: assign_training
Add your name - TRN-04Not reviewed
A person can hold only one open (not yet finished) assignment of the same course at a time.
Two open rows for one course would be a duplicate task; measured at zero before the rule was added.
packages/core/src/training-rule.ts:175 · database: training_one_open_per_course
Add your name - TRN-05Not reviewed
Finishing a course takes two steps: the learner marks it done, then someone else signs it off; until then it reads "Waiting for your supervisor to sign it off".
Stops a learner pressing the button twice and assuming the system lost it, the same failure the corrective-action two-step avoids.
packages/core/src/training-assignment.ts:158 · database: acknowledge_training, verify_training
Add your name - TRN-06Not reviewed
Only the learner can mark their own training done.
supabase/migrations/20261007120000_lms_tier_1_2.sql:2049 · database: acknowledge_training
Add your name - TRN-07Not reviewed
Nobody can sign off their own training.
The record has refused a person training themselves since the first schema.
packages/core/src/training-assignment.ts:192 · database: verify_training, training_not_own_trainer, training_not_own_evaluator
Add your name - TRN-09Not reviewed
A course that needs an evaluation counts as complete only with a "Passed" result, and a "Not yet" result leaves it open.
Training and evaluation are separate things (29 CFR 1910.178(l)(6)).
packages/core/src/training-session.ts:375 · database: training_evaluation_gate, training_not_yet_is_open, verify_training
Add your name - TRN-11Not reviewed
A training is overdue only when it is still owed and its due date is before today; one due today is not late, and one with no due date can never be overdue.
The stored word "Overdue" is never updated, so lateness is worked out from the due date when the data is read.
packages/core/src/training-assignment.ts:297 · database: app.training_is_overdue
Add your name - TRN-13Not reviewed
Retraining whose corrective action was withdrawn becomes "Cancelled · action withdrawn" and counts as neither owed nor finished, so it drops out of every open count, overdue count and the qualification file.
Nobody owes it and nobody finished it.
packages/core/src/training-assignment.ts:277 · database: training_status_check
Add your name - TRN-16Not reviewed
Course material is never edited: a change makes a new version, the old one is kept as history, and only the current version can be replaced.
Keeps the record of what was taught on a given day, as 49 CFR 172.704(d) and 29 CFR 1910.1030(h) require.
packages/core/src/training-assignment.ts:330 · database: replace_training_material
Add your name - TRN-17Not reviewed
The material a learner was shown is frozen onto their record when they mark the course done, and onto a session when the trainer signs it.
Keeps a record of what was taught.
packages/core/src/training-assignment.ts:407 · database: app.material_snapshot
Add your name - TRN-18Not reviewed
A course finished at a signed session or through approved outside training is already proven by that record, so no document upload is asked for.
Asking for paperwork implied the course was not finished.
packages/core/src/training-records.ts:156
Add your name
Standing training rules and renewals10 rules
- TRULE-01Not reviewed
Only a general manager or VP can create a standing assignment rule, run the rules or run renewals, and a rule can only cover sites they cover.
supabase/migrations/20261007120000_lms_tier_1_2.sql:1878 · database: save_training_rule, apply_training_rules, create_due_renewals
Add your name - TRULE-02Not reviewed
A rule names a course, a job title, either all sites or at least one site, and a number of days from 0 to 365 to complete it.
A longer offset is not a rule but a wish.
packages/core/src/training-rule.ts:87 · database: training_rule_offset, training_rule_sites_not_empty, save_training_rule
Add your name - TRULE-03Not reviewed
The days count either from the person's hire date or from the date the rule was made; with no hire date on file, they count from the rule's date.
packages/core/src/training-rule.ts:150 · database: training_rule_anchor
Add your name - TRULE-04Not reviewed
A rule applies to everyone who currently matches it, not only people hired after it was written.
packages/core/src/training-rule.ts:1 · database: apply_training_rules
Add your name - TRULE-06Not reviewed
Terminated people, and anyone whose termination date is today or earlier, are never assigned training; people on leave are.
People on leave come back, and the course should be waiting.
packages/core/src/training-rule.ts:116 · database: app.person_assignable
Add your name - TRULE-07Not reviewed
A due date set by a rule is never earlier than today; anyone already past the window is due today.
Otherwise a new rule would make every long-serving employee years overdue the moment it was saved.
packages/core/src/training-rule.ts:150
Add your name - TRULE-10Not reviewed
A renewal is raised once today is within the course's renewal window before expiry (30 days by default), or for a completion that has already expired; a completion with no expiry is never renewed.
packages/core/src/training-rule.ts:236 · database: create_due_renewals
Add your name - TRULE-11Not reviewed
A renewal is due on the expiry date itself, or today if the expiry has already passed.
So the certification never lapses.
packages/core/src/training-rule.ts:249 · database: create_due_renewals
Add your name - TRULE-12Not reviewed
Only the newest completion per person and course is considered for renewal, and no renewal is raised when the course is already open for them or they are no longer employed.
Renewing a card that a later one replaced would be noise.
packages/core/src/training-rule.ts:280 · database: create_due_renewals
Add your name - TRULE-15Not reviewed
A course "renews a certification" when the requirement it renews is a Certification or an Evaluation, not plain training.
packages/core/src/training-library.ts:41
Add your name
Training sessions13 rules
- SESS-01Not reviewed
Only a supervisor or above can schedule, change the roster of, cancel or sign a session, and only at a site they cover.
supabase/migrations/20261007120000_lms_tier_1_2.sql:2523 · database: schedule_training_session, set_session_roster, cancel_training_session, sign_training_session
Add your name - SESS-02Not reviewed
A session needs a course, a site, a named trainer, and a start and end time on the same day, with the end after the start.
Sessions spanning several days are deferred to a later phase.
packages/core/src/training-session.ts:104 · database: training_session_times, schedule_training_session
Add your name - SESS-03Not reviewed
A session may be entered after it happened, but must fall within a year of today either way.
A toolbox talk is often entered the day after it was given.
packages/core/src/training-session.ts:99 · database: schedule_training_session
Add your name - SESS-04Not reviewed
The trainer must be a current employee and cannot be on their own roster.
supabase/migrations/20261007120000_lms_tier_1_2.sql:2545 · database: schedule_training_session, set_session_roster
Add your name - SESS-06Not reviewed
Once signed or cancelled, nothing on the session or its roster can change; a correction is recorded separately, and a session is never deleted.
packages/core/src/training-session.ts:64 · database: lock_training_session, lock_training_attendee
Add your name - SESS-07Not reviewed
A signed session cannot be cancelled, and cancelling needs a reason.
packages/core/src/training-session.ts:69 · database: training_session_cancelled, cancel_training_session
Add your name - SESS-08Not reviewed
The trainer signs once for the whole session, and attendees do not sign.
OSHA letters of interpretation, 1997-08-14 and 2000-04-10.
packages/core/src/training-session.ts:4 · database: sign_training_session
Add your name - SESS-10Not reviewed
Signing needs at least one person on the roster, each person listed once, and everyone marked Attended, No-show or Excused, with nobody left as merely booked.
"We don't know if he came" is not a record.
packages/core/src/training-session.ts:289 · database: sign_training_session
Add your name - SESS-11Not reviewed
Nobody can sign a session they attended.
Nobody signs off their own training.
packages/core/src/training-session.ts:321 · database: sign_training_session
Add your name - SESS-12Not reviewed
On a course that needs an evaluation, every attendee must be marked Passed or Not yet before signing; a result can be given only to someone who attended, and only on an evaluated course.
A result on the wrong row is refused rather than silently dropped.
packages/core/src/training-session.ts:328 · database: training_attendee_result_needs_attendance, sign_training_session
Add your name - SESS-13Not reviewed
Signing completes an attendee's training (as "Attended") when they attended and the course has no evaluation or they passed; no-shows, excused people and "Not yet" stay open.
A no-show leaves the requirement open, and so does "Not yet".
packages/core/src/training-session.ts:375 · database: sign_training_session, training_attended_names_session, training_not_yet_is_open
Add your name - SESS-18Not reviewed
A "Passed" result on a course that renews a Certification or Evaluation requirement issues a new qualification marked "Company evaluation"; an evaluated course that renews nothing issues no qualification.
packages/core/src/training-library.ts:184 · database: app.issue_qualification_from_training
Add your name - SESS-19Not reviewed
A qualification issued by evaluation replaces the older card unless a card with a later expiry is already on file, and it opens a request to file the signed evaluation form within 14 days.
supabase/migrations/20261007120000_lms_tier_1_2.sql:1018 · database: app.issue_qualification_from_training
Add your name
Training taken elsewhere10 rules
- EXT-01Not reviewed
A learner can record outside training for themselves; a supervisor or above can record it for anyone they cover; a driver cannot record it for anyone else.
packages/core/src/external-training.ts:141 · database: submit_external_training
Add your name - EXT-02Not reviewed
An outside course must name the course (from the catalog or typed in), the provider and the completion date.
packages/core/src/external-training.ts:107 · database: submit_external_training
Add your name - EXT-03Not reviewed
The certificate is required.
The evidence is what makes this different from somebody saying they did a course.
packages/core/src/external-training.ts:102 · database: submit_external_training
Add your name - EXT-04Not reviewed
The completion date cannot be in the future but may be any earlier date, including before the person joined.
A card from before somebody joined is exactly the case this exists for.
packages/core/src/external-training.ts:115 · database: submit_external_training
Add your name - EXT-05Not reviewed
The database also refuses a completion date more than ten years ago.
supabase/migrations/20261007120000_lms_tier_1_2.sql:3063 · database: submit_external_training
Add your name - EXT-08Not reviewed
Only a supervisor or above can approve or reject outside training, and only for someone at a site they cover.
packages/core/src/external-training.ts:171 · database: review_external_training
Add your name - EXT-09Not reviewed
Nobody can approve their own outside training, but a supervisor who submitted it on someone else's behalf may still approve it.
The certificate is the evidence, and the person it vouches for is not them.
packages/core/src/external-training.ts:160 · database: external_training_not_own_reviewer, review_external_training
Add your name - EXT-10Not reviewed
Each record is reviewed once: it goes from Pending to Approved or Rejected and no further.
packages/core/src/external-training.ts:169 · database: external_training_reviewed, review_external_training
Add your name - EXT-11Not reviewed
Rejecting outside training requires a reason.
The learner cannot fix what they are not told.
packages/core/src/external-training.ts:177 · database: external_training_rejected_has_reason
Add your name - EXT-13Not reviewed
Outside training waiting more than 14 days for review is flagged as stuck.
packages/core/src/renewal-plan.ts:213
Add your name
Renewal plan and expiry5 rules
- RENEW-02Not reviewed
17 of the client's 20 requirements are renewed by a course; CDL Class A, CDL Class B and the DOT medical card are renewed outside the company, so the screen gives the outside step instead of offering a course.
You renew a CDL at the DMV and a medical card with an examiner.
packages/core/src/training-assignment.ts:30
Add your name - RENEW-03Not reviewed
The outside renewal step depends on the requirement: a DOT medical exam for a medical, the DMV for a licence, a road test for an evaluation, and otherwise renew and bring the certificate.
The wording matches the driver's own home screen so driver and supervisor are told the same thing.
packages/core/src/training-assignment.ts:80
Add your name - RENEW-04Not reviewed
For an outside renewal the supervisor's action is a dated request for the new document, which lands on the driver's own Tasks list.
Bringing the card is the driver's job, and the request leaves a record.
packages/core/src/training-assignment.ts:52 · database: request_document
Add your name - RENEW-05Not reviewed
A renewal's suggested due date is 14 days before the expiry; if that date has already passed (including an expired card) it is 14 days from today, and with no expiry it is 14 days from today.
The point of a renewal is that the certification never lapses; two weeks is enough margin to reschedule once.
packages/core/src/training-assignment.ts:105
Add your name - RENEW-11Not reviewed
A completed course that outlasts a person's card counts as having renewed it.
packages/core/src/renewal-plan.ts:313 · database: create_due_renewals
Add your name
Driver qualification file14 rules
- DQ-01Not reviewed
Every driver has a qualification file listing every line their job requires, what is held against it, from when, until when, and what is missing.
49 CFR 391.51 requires a carrier to keep one per driver and produce it on demand; an auditor asks for the index.
packages/core/src/dq-file.ts:12
Add your name - DQ-02Not reviewed
The file's export lists every required line, including missing ones.
A file listing only what is on file cannot show a gap, and the gap is what an audit looks for.
packages/core/src/dq-file.ts:124
Add your name - DQ-03Not reviewed
A line is "lapsed" (the person is not qualified today) when it is expired, overdue or never on file; expiring and due lines are upcoming work, not findings.
packages/core/src/dq-file.ts:41
Add your name - DQ-04Not reviewed
A line counts as "on file" only when it is valid, expiring or expired; a course that is due or overdue is an assignment, not a completion, so it is not on file.
Saying "On file: Yes" against an overdue course would tell an auditor the opposite of the truth.
packages/core/src/dq-file.ts:200
Add your name - DQ-05Not reviewed
A line counts as documented only when a checked and verified document is behind it; a document awaiting a check or sent back does not count.
Holding a qualification is not the same as having the card on file, and that gap is what the client came to fix.
packages/core/src/dq-file.ts:51 · database: dash_leading
Add your name - DQ-09Not reviewed
A person can file their own documents; only a supervisor or above can file one for somebody else, and only for someone they cover.
supabase/migrations/20260922110000_person_document.sql:831 · database: submit_person_document
Add your name - DQ-10Not reviewed
An outside course certificate must be attached to an assigned course.
supabase/migrations/20260922110000_person_document.sql:851 · database: submit_person_document
Add your name - DQ-11Not reviewed
Nobody can verify their own document; it is checked by the named verifier, or by a supervisor or above who covers that person.
packages/core/src/dq-document.ts:395 · database: app.can_verify_document, person_document_signer_is_not_subject, person_document_verifier_is_not_subject
Add your name - DQ-12Not reviewed
A document is checked once: it goes from awaiting check to verified or sent back, and a verified one is later marked replaced rather than deleted.
packages/core/src/dq-document.ts:141 · database: person_document_status, verify_person_document
Add your name - DQ-13Not reviewed
Sending a document back requires a reason.
A refusal a person cannot act on is worse than none.
packages/core/src/dq-document.ts:355 · database: person_document_rejected_has_reason, reject_person_document
Add your name - DQ-18Not reviewed
When a document is verified, an expiry date is required and cannot be before the issue date. The screen suggests one from the requirement's renewal period, and the verifier can change it.
49 CFR 391.43 leaves a medical card's term to the examiner (three months to two years); with no expiry a qualification never appears on any list again.
packages/core/src/dq-document.ts:410 · database: verify_person_document
Add your name - DQ-19Not reviewed
Only a supervisor or above can ask someone for a document, and only for someone they cover; the request needs a due date that is not in the past.
packages/core/src/dq-document.ts:446 · database: request_document
Add your name - DQ-21Not reviewed
A person can have only one open document request per requirement.
Two open requests for the same card would be two identical rows on a driver's Tasks list.
packages/core/src/dq-document.ts:323 · database: document_request_one_open
Add your name - DQ-23Not reviewed
Cancelling a document request requires a reason.
A request dropped in silence looks the same as one nobody noticed.
supabase/migrations/20260922110000_person_document.sql:610 · database: document_request_cancelled_has_reason, cancel_document_request
Add your name
Safety rates and dashboard numbers19 rules
- RATE-01Not reviewed
Every safety rate (TRIR, DART, AFR) is the number of cases multiplied by 200,000 and divided by the hours worked, which is the same as 100 full-time people for one year.
OSHA's basis: 100 employees at 2,000 hours.
packages/core/src/dashboard.ts:175
Add your name - RATE-02Not reviewed
TRIR counts OSHA-recordable incidents, DART counts days-away, restricted or transferred cases, and AFR counts incidents whose main type is a motor vehicle accident, each divided by the same hours.
AFR uses the same basis as TRIR so the two can be read side by side.
packages/core/src/metric-help.ts:63 · database: dash_headline
Add your name - RATE-03Not reviewed
Hours worked are the hours the route feed actually recorded for the people it covers, plus 2,000 hours a year (spread evenly over 365 days) for everyone else on the headcount.
Measured beats assumed; measured hours landed within 2.7% of the 2,000-hour assumption, so the assumption is now checkable rather than asserted.
packages/core/src/dashboard.ts:204 · database: dash_exposure
Add your name - RATE-04Not reviewed
A person with measured route hours contributes only those hours, never measured hours plus an assumed share for their rest days.
Topping up rest days at the assumed rate double-counted and put exposure 13% too high, which would have lowered every rate for no reason but arithmetic.
packages/core/src/dashboard.ts:209
Add your name - RATE-05Not reviewed
Mechanics and other non-route staff still use the assumed hours, and a driver's non-route time is not measured, so rates may be slightly overstated.
The route feed covers drivers on routes at hauling depots only (219 of 580 people).
packages/core/src/dashboard.ts:217
Add your name - RATE-07Not reviewed
Headcount for the rates is the total headcount of the active sites in scope.
database: dash_headline (supabase/migrations/20261007120000_lms_tier_1_2.sql:3392)
Add your name - RATE-08Not reviewed
Rates always count incidents in every status, even when the incident list is filtered to open or closed cases; only the count columns follow that filter.
There is no such thing as hours worked on cases that are still open, so a filtered top over an unfiltered bottom is not a rate anyone could report.
packages/core/src/dashboard.ts:27 · database: dash_headline, dash_sites
Add your name - RATE-09Not reviewed
An injury is any incident with an injury classification at any level, and an accident is any incident whose main type is Motor Vehicle Accident; property damage alone is not an accident.
Injuries, accidents and recordables overlap and none contains another.
packages/core/src/incident-table.ts:97 · database: dash_headline
Add your name - RATE-10Not reviewed
A lost-time injury is one where somebody was away from work the next day or later, and it is the most serious count on the page.
packages/core/src/metric-help.ts:95
Add your name - RATE-11Not reviewed
When sites are grouped by region or site type, the group's rate is recalculated from its own summed cases and its own hours, never averaged from the sites' rates.
Averaging lets a small site weigh as much as a large one and gives a number that is true of nowhere.
packages/core/src/dashboard.ts:300
Add your name - RATE-15Not reviewed
Training and qualification compliance counts always run from today and ignore the period being viewed.
"Expiring in 90 days" has to mean 90 days from now, whatever month someone is looking at.
packages/core/src/dashboard.ts:468 · database: dash_headline
Add your name - RATE-16Not reviewed
Open corrective actions are those Open, In Progress or Overdue; the overdue share is overdue actions divided by open actions, and neither depends on the period.
packages/core/src/dashboard.ts:993 · database: dash_headline, dash_sites
Add your name - RATE-17Not reviewed
"Training current" is the share of open training assignments that are not past their due date, judged from each due date as of today and not from a stored status.
Nothing ever updated the stored status, so the number is worked out from the date.
packages/core/src/metric-help.ts:99 · database: app.training_is_overdue
Add your name - RATE-18Not reviewed
"Qualifications current" is the share of licences and certifications that have not expired, ignoring cards already replaced by a renewal.
packages/core/src/metric-help.ts:107 · database: dash_headline
Add your name - RATE-19Not reviewed
DVIR completion is the number of truck-days with a pre-trip inspection divided by the number owed: one per on-road vehicle per day since it entered service, with Sundays left out unless the site runs seven days a week.
packages/core/src/dashboard.ts:992 · database: dash_sites (supabase/migrations/20261007120000_lms_tier_1_2.sql:3538)
Add your name - RATE-20Not reviewed
A site with no on-road vehicles owes no DVIRs, shows a dash, and always sorts last rather than appearing as the worst.
A site that cannot fail the measure must not be named as the worst at it.
packages/core/src/dashboard.ts:998
Add your name - RATE-21Not reviewed
A supervisor's KPI strip has no TRIR, DART or AFR tiles, only the counts.
A supervisor's TRIR rested on two recordables in eight months and swung from 2.68 to 5.37 on two more injuries; one site does not give a rate a big enough base.
packages/core/src/dashboard.ts:606
Add your name - RATE-24Not reviewed
The cost column is removed entirely for someone not allowed to see cost; it is not left blank.
A dash in a money column reads as "nothing was spent here".
packages/core/src/dashboard.ts:909
Add your name - RATE-25Not reviewed
Cost is the estimated reserve carried on the incident records, not a claims feed and not a settled figure; only a VP sees the actual cost of closed cases by default.
packages/core/src/metric-help.ts:87 · database: dash_headline (app.can_see_cost, app.can_see_actual_cost)
Add your name
Watchlist: sites8 rules
- WSITE-01Not reviewed
A site is put in Act now when pre-trip DVIR completion falls below 85%.
The daily DVIR is a federal obligation, not a KPI.
packages/core/src/watchlist.ts:380
Add your name - WSITE-02Not reviewed
A site is flagged as drifting when it has at least 5 incidents in the last 60 days of the period and that is at least double its first 60 days (and the first 60 days had at least one).
Comparing to the period average hides the trend, because a site climbing all year pulls its own average up with it.
packages/core/src/watchlist.ts:423 · database: dash_sites
Add your name - WSITE-03Not reviewed
A site is flagged for overdue actions when it has at least 20 overdue and its overdue share is at least 1.2 times the average across the sites the reader can see.
Every site runs 27% to 78% overdue, so a fixed line flags all ten; at 1.2, Castleton (78% against 63%) is the only site that trips.
packages/core/src/watchlist.ts:388
Add your name - WSITE-04Not reviewed
A site is flagged when it has at least 20 high-severity telematics events and fewer than 75% of them were coached.
No site trips it today (coaching runs 76% to 86%), which is a finding, not a reason to loosen the rule.
packages/core/src/watchlist.ts:451
Add your name - WSITE-05Not reviewed
A site is flagged when it has at least 50 observations and its at-risk share is at least 1.2 times the average across the reader's sites.
packages/core/src/watchlist.ts:463
Add your name - WSITE-06Not reviewed
A site is flagged for any expired qualification on site.
packages/core/src/watchlist.ts:481
Add your name - WSITE-07Not reviewed
A site is flagged for overdue training when it has at least 10 overdue courses and its overdue courses per head are at least 1.2 times the average across the reader's sites.
Counted per head, because raw counts just rank sites by size.
packages/core/src/watchlist.ts:488
Add your name - WSITE-08Not reviewed
The comparison-to-average site rules do not apply when the reader can see only one site.
A site is not above its own average.
packages/core/src/watchlist.ts:402
Add your name
Comparison bands6 rules
- BAND-01Not reviewed
TRIR is compared against 4.5 to 5.5 and DART against 2.5 to 3.5, the published BLS bands for NAICS 5621 (Waste Collection), 2026.
Published industry bands, not a target the operator has committed to.
packages/core/src/dashboard.ts:269 · database: benchmark (supabase/migrations/20260915120000_benchmark.sql:95)
Add your name - BAND-02Not reviewed
A rate below the band's low end reads as better than industry, a rate within the band (both ends included) reads as in band, and a rate above it reads as worse.
packages/core/src/dashboard.ts:274
Add your name - BAND-03Not reviewed
A metric with no band is shown in plain type with no color, labelled "no published band".
Coloring against a band somebody guessed is the failure to avoid.
packages/core/src/benchmark.ts:38
Add your name - BAND-04Not reviewed
AFR has no band and stays uncolored until someone enters one, after which it colors the same way as TRIR.
No published accident frequency band exists on a 200,000-hour basis; the trucking figure is per million miles and there is no mileage feed.
supabase/migrations/20260915120000_benchmark.sql:21
Add your name - BAND-07Not reviewed
Only a VP can add, change or remove a band; everyone signed in can read them.
A bad row changes what every screen appears to say (a TRIR band of 0 to 1 turns ten sites red).
supabase/migrations/20260915120000_benchmark.sql:71 · database: benchmark
Add your name - BAND-10Not reviewed
The band table holds externally published figures only, never a client's own targets.
A client goal is a different object with different politics and must be labelled as the client's own.
supabase/migrations/20260915120000_benchmark.sql:15
Add your name
Watchlist: people17 rules
- WPPL-01Not reviewed
A person is Act now with a hard stop or three or more signals, Watch with two, and Ready with one or none.
Signals are individually common and jointly rare; banding on each alone put 400 of 568 people on the list, while three signals gives 34 company-wide and 7 at Rutland.
packages/core/src/watchlist.ts:12
Add your name - WPPL-04Not reviewed
An expired qualification (not counting cards already replaced by a renewal) is a hard stop that puts the person in Act now on its own.
The person cannot lawfully do the job today.
packages/core/src/watchlist.ts:271 · database: watch_people
Add your name - WPPL-05Not reviewed
A qualification expiring within 90 days is a signal.
packages/core/src/watchlist.ts:281 · database: watch_people, app.expiring_within_days
Add your name - WPPL-06Not reviewed
Any training course still open and past its due date is a signal.
packages/core/src/watchlist.ts:287 · database: app.training_is_overdue
Add your name - WPPL-07Not reviewed
Three or more high-severity telematics events in the last 30 days is a signal.
packages/core/src/watchlist.ts:248 · database: watch_people
Add your name - WPPL-08Not reviewed
A driver's telematics events are flagged as trending up when the last 30 days hold at least 4 events and at least double their own monthly average over the 90 days before that.
Drivers are compared only against themselves; comparing drivers finds the hard route, not the driver who changed.
packages/core/src/watchlist.ts:250 · database: watch_people
Add your name - WPPL-09Not reviewed
Two or more observations rated At-Risk or Mixed in the last 90 days is a signal.
Two in a quarter is a pattern; one is a Tuesday.
packages/core/src/watchlist.ts:256 · database: watch_people
Add your name - WPPL-10Not reviewed
An observation follow-up that was required, is not closed and is past its due date is a signal.
packages/core/src/watchlist.ts:312 · database: watch_people
Add your name - WPPL-11Not reviewed
Any incident involving the person in the last 90 days is a signal.
packages/core/src/watchlist.ts:321
Add your name - WPPL-12Not reviewed
Never having been formally observed, or not observed for more than 180 days, is a signal.
It is the one signal that says the other signals may be missing rather than absent.
packages/core/src/watchlist.ts:327
Add your name - WPPL-13Not reviewed
Overdue corrective actions and unsigned DVIRs are not signals on an individual's row.
They are paperwork and compliance facts, not a prediction that somebody is about to be hurt.
packages/core/src/watchlist.ts:223
Add your name - WPPL-16Not reviewed
Rules for teams only apply to teams of at least 5 people, and only when at least 3 people are affected.
On a crew of 2, one problem is 50%; that is arithmetic, not judgment. Two of anything is a fortnight; three is a habit.
packages/core/src/watchlist.ts:769
Add your name - WPPL-17Not reviewed
A team is flagged when the share of its people in Act now or Watch, overdue on training, with a late observation follow-up, or with 2 or more unsigned DVIRs in 30 days is at least 1.2 times the average for leaders at the same level.
Fixed thresholds flagged all ten managers; comparing to the level's own average is what makes one rule work at every level.
packages/core/src/watchlist.ts:866
Add your name - WPPL-18Not reviewed
Anyone beneath a leader working on an expired qualification puts that leader in Act now.
That leader rosters someone who cannot lawfully do the job today.
packages/core/src/watchlist.ts:848
Add your name - WPPL-19Not reviewed
A leader is flagged for their own follow-through when they have 5 or more overdue corrective actions of their own or 3 or more of their own tasks escalated to the site manager.
One signal, not two, because the two agree 83% of the time; a fixed number because it is their own queue and does not grow with team size.
packages/core/src/watchlist.ts:906 · database: watch_people
Add your name - WPPL-20Not reviewed
A leader's own record counts as a signal on their team row only when it would put them in Act now as an individual, and it carries over their own hard stop.
Counting any personal signal put 30 of 56 supervisors on the list instead of 21.
packages/core/src/watchlist.ts:832
Add your name - WPPL-23Not reviewed
Only active employees appear on the people watchlist.
database: watch_people (supabase/migrations/20261007120000_lms_tier_1_2.sql:3608)
Add your name
Watchlist: vehicles9 rules
- WVEH-01Not reviewed
Vehicles use the same bands as people: a hard stop or three or more signals is Act now, two is Watch, one or none is Ready.
packages/core/src/watchlist.ts:170
Add your name - WVEH-02Not reviewed
An uncorrected defect that its inspector marked not safe to operate is a hard stop that puts the vehicle in Act now.
A truck with an open out-of-service defect cannot lawfully roll; the inspector's own judgement is what puts a truck out of service.
packages/core/src/watchlist.ts:561 · database: watch_assets
Add your name - WVEH-03Not reviewed
A Major or Out of Service defect open for more than 14 days is a signal.
Left that long, it has stopped being a repair and become a decision.
packages/core/src/watchlist.ts:553
Add your name - WVEH-04Not reviewed
Three or more Major or Out of Service defects in the same component category within 90 days is a signal.
packages/core/src/watchlist.ts:556 · database: watch_assets
Add your name - WVEH-05Not reviewed
Any incident involving the vehicle in the last 90 days is a signal.
packages/core/src/watchlist.ts:580
Add your name - WVEH-06Not reviewed
A vehicle marked Down for Repair while it still has Major defects open is a signal.
packages/core/src/watchlist.ts:586
Add your name - WVEH-07Not reviewed
A defect stays open until it is marked corrected, the truck passes a later inspection with nothing outstanding, or the shop signs off the repair it raised.
Without the later-inspection rule, 602 of 633 "open" defects were ones the fleet had already moved past.
packages/core/src/vehicle-record.ts:49 · database: watch_assets (supabase/migrations/20260924100000_dvir_raises_the_repair.sql:359)
Add your name - WVEH-08Not reviewed
A clean inspection on the same day a defect was written up does not close that defect; only a later day's does.
packages/core/src/vehicle-record.ts:56
Add your name - WVEH-09Not reviewed
Only on-road vehicles are on the watchlist; off-road equipment is not.
database: watch_assets (supabase/migrations/20260924100000_dvir_raises_the_repair.sql:437)
Add your name
Driver home screen4 rules
- HOME-02Not reviewed
A licence, card or certificate is Expired once its expiry date has passed, Expiring within 90 days of it, and Valid otherwise.
90 days is the client's own word, used everywhere so one card cannot be expiring on one screen and not on another.
packages/core/src/driver-home.ts:100 · database: app.expiring_within_days
Add your name - HOME-08Not reviewed
With no open assignment, the latest completion decides, and a completed course with no expiry date never lapses.
packages/core/src/driver-home.ts:408
Add your name - HOME-14Not reviewed
The 14-hour on-duty window starts at the earliest pre-trip DVIR filed today, and once 14 hours have passed it shows as used up.
49 CFR 395.3: a property-carrying driver may not drive beyond the 14th consecutive hour after coming on duty, and the pre-trip is the first on-duty act.
packages/core/src/driver-home.ts:532
Add your name - HOME-18Not reviewed
Service exceptions are deliberately left off the driver's own screen.
They are a performance reading for a supervisor; on a driver's screen at 5 a.m. they become a scorecard he is marked against.
packages/core/src/driver-home.ts:663
Add your name