SCOPE: everything in progressdocs/business-rules.md · build 40bb41bdb460

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.

Loading 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
Back to top