Concept

Shift Attribution: Getting a Stop on the Right Shift

How Spall decides which shift a stop or a part belongs to, why cross-midnight and rotating patterns trip it up, and what a wrong schedule does to every downstream number.

8 min read · Last reviewed September 13, 2026

Every shift-scoped number on a floor, per-shift OEE, the Downtime Pareto split by crew, the handoff page’s numbers, depends on one quiet piece of plumbing working correctly: the moment a stop or a good part gets stamped with which shift it happened on. Get that wrong and nothing built on top of it can be trusted, not because the math is wrong, but because it’s answering the wrong question with confident precision.

The question is “what shift is running right now,” asked constantly

Attribution isn’t a lookup against a fixed table of shift names. It’s a point-in-time question, asked at the instant an event happens: given the shift schedule for this site, what shift is actually in progress at this exact timestamp. A stop that starts at 10:47pm gets checked against the schedule as it existed at 10:47pm, not against a guess at which shift “usually” covers that hour. That distinction only matters once a schedule gets more complicated than one shift running the same eight hours every day, which is most real schedules within a few weeks of go-live.

Cross-midnight shifts are where naive math breaks first

A night shift that runs 10pm to 6am spans two calendar dates, and a shift resolver that isn’t built for that will either attribute the whole night to whichever date it started on, or split it in half at midnight as if the crew changed at the clock rollover instead of at 6am. Spall’s shift resolution treats a shift whose start time is later than its end time as a cross-midnight window, so a stop at 2am on Tuesday correctly reads as the shift that started Monday night, not a phantom “Tuesday morning” shift that was never scheduled.

One shift, two calendar dates, one continuous window A cross-midnight shift is one window, not two 10pm Mon midnight 6am Tue 2am stop Attributed to Monday night's shift, the one actually running at 2am.
The date changes at midnight. The shift doesn't. Attribution follows the shift, not the calendar.

Rotating patterns need the day of the week, not just a time of day

A schedule where crew C only runs weekends, or where a shift’s hours shift by an hour every third week, needs the resolver to check which days of the week a shift definition actually applies to, not just match a start and end time against every day blindly. A shift with no day-of-week restriction is assumed to run every day, which is correct for a straight three-shift plant and wrong for anyone running a rotating or weekend-only pattern, so a schedule with gaps or rotation needs those days set explicitly per shift definition, not left on the every-day default and hoped into correctness.

Timezone is part of the schedule, not an afterthought

Shift start and end times are wall-clock times at the site, 6am means 6am where the machine actually sits, and the resolver reads the site’s own configured timezone to turn that wall-clock time into the correct absolute instant. A plant in Chicago and a plant in the same tenant sitting in Phoenix on the same shift schedule, “6am to 2pm,” are running different absolute windows, and attribution has to account for that per site instead of assuming one clock for the whole tenant.

What happens before a schedule exists, and what happens after

An event recorded at a site with no shift schedule configured yet, or with a schedule that doesn’t cover the specific time an event happened, comes back unattributed. Shift-scoped screens say so plainly, an incomplete picture stated as incomplete, instead of showing partial data as if it were the whole story. Adding or fixing a schedule closes the gap going forward, for every event from that point on. It doesn’t reach back and reassign events that already happened before the schedule existed, those stay unattributed permanently. Attribution answers “what shift was running when this happened,” and for an event before any schedule existed, the true answer is that nothing was configured to know.

That’s the practical argument for setting up shift schedules on day one rather than treating them as a later refinement. Every day without one is a day of events that can never be retroactively assigned to a shift, even after the schedule gets fixed.

What a wrong schedule breaks without announcing it

A shift schedule that’s wrong, hours that don’t match the real changeover time, a rotation that fell out of sync after a calendar change nobody updated, doesn’t fail loudly. It keeps producing numbers, just wrong ones, and the wrongness spreads into everything downstream that scopes by shift:

Per-shift OEE and output. A stop that happened at 5:58am on a shift that actually ends at 6am but is scheduled in the system as ending at 5:30am gets attributed to the wrong crew’s window entirely, inflating one shift’s downtime and understating the other’s.

The Downtime Pareto split by shift. A reason code total that looks concentrated on second shift might really be a scheduling error handing third shift’s early-morning stops to second by mistake, not an actual pattern in when the failures happen.

Shift comparison. Any conclusion drawn from comparing shift performance is only as good as the boundary each shift’s numbers were drawn against. A schedule that’s off by even thirty minutes on a busy changeover window can shift enough volume between two shifts to change which one looks better.

The handoff page. A supervisor reading the outgoing shift’s numbers at shift change is trusting that those numbers actually reflect what happened during that specific window, not a window offset by a schedule drift nobody caught.

None of these break in a way that throws an error. They just produce a plausible, wrong number, which is worse than an obvious failure because nobody goes looking for a bug that looks like a normal report.

Checking a schedule is right

The fastest check is a known event. Pick a stop or a shift change you remember happening at a specific time, real and recent, and confirm the system attributed it to the shift that was actually running. If the schedule was recently added or changed, check a case near a shift boundary specifically, the hour right around a start or end time is where a small configuration error shows up first, long before it’s obvious in an aggregate number three weeks later.

Quick recap

  • Attribution is a point-in-time question, asked at the moment an event happens, not a lookup against a fixed shift name.
  • Cross-midnight shifts are handled as one continuous window. A 2am stop belongs to the night shift that started the evening before, not a phantom morning shift.
  • Rotating or weekend-only patterns need day-of-week set explicitly on each shift definition. The every-day default is correct for a straight three-shift plant only.
  • Wall-clock shift times are read in the site’s own timezone, not a single tenant-wide clock.
  • Events before a schedule existed stay unattributed permanently. A fix closes the gap going forward, it doesn’t reach back.
  • A wrong schedule doesn’t fail loudly. It corrupts per-shift OEE, the downtime split, shift comparison, and the handoff page all at once, and every one of those numbers still looks plausible.

Related guides

From the Help Center

$200/machine/mo · pilots from $4,500 · hardware included

See full pricing →

Bring your machine list. We'll tell you exactly what plugs in.

30 days, hardware included, line pilot $4,500 or plant pilot $8,500, fully credited when you expand.