← All standards
Open specificationDraftPublished September 2026Changelog

The Timesheet Check Build Standard

How every hour on the payroll comes to trace to a person, a day and a job, with the odd ones looked at by somebody and nothing paid that a person did not release. Written so you can build it yourself.

Used by

  • Payroll Officer
  • Office Manager
  • Construction Administrator
  • Bookkeeper

11 min read · Published by AI Pathway

Using Claude? This standard installs as a skill. Guides for ServiceM8, Xero and Simpro.

How to get this live in your business

Build it for mePick a time and we scope the check against your roster, your job system and your payroll.
Build it myself

DIY. The objects, the checks in order, and the pass test.

What this is

An open build standard for the check between the hours people capture and the payroll run, for a trades, construction or services business with a roster and a job system.

The core rule

Totals derive from entries. A penalty applied names the rule edition it came from. An anomaly leaves the queue only with a person's name and a reason. Nothing reaches payroll without a release.

What it does not do

It does not decide which award clause applies to an odd shift, does not clear an anomaly on its own, and does not put anything into payroll that a named person did not release.

The hard part

Not the arithmetic. The award edition that moved between periods, and the export that ran twice because nobody read back whether it already had.

The sheet said forty hours. The site app said forty-three and a half, two of them on a job the person was never on, and Saturday was paid at the weekday rate because the spreadsheet formula was written before the award changed. Nobody did anything wrong on purpose. The check that would have caught all three did not exist, so the payroll run was the check.

One period, entries to payroll

  1. The period closes.
  2. Every entry is traced to a person, a day and a job that person was allocated. An entry that does not trace is an anomaly, not a line.
  3. Daily and weekly totals are computed from entries, never typed. Overlaps, over-hours days, missing breaks and unrostered days join the anomaly queue with an owner each.
  4. Every penalty or allowance applied cites a rule with an edition and an effective date. An entry the dated rule does not plainly cover is parked for a person.
  5. Are the anomalies at zero, each resolved by a person with a reason, and has a named person released the period? If no, the period waits with the queue in front of its owners, and the run still publishes hours, anomalies found and resolved, and that nobody has released.
  6. If yes, one export is written into payroll with its id back.
  7. Has the period stayed unchanged since the export? If yes, the run publishes hours, anomalies found and resolved, and the release. If no, the export is updated, never duplicated.
The entry traces first, because an hour that does not belong to a person, a day and an allocated job is not a line. The filled diamond is the release: nothing reaches payroll without a named person. The loop is the anomaly queue, cleared by a person with a reason and never by the check itself.

Take the spec to Claude, ChatGPT or Copilot. The sentence to paste is one click away.

1. What this standard covers

Any business where hours are captured somewhere other than the payroll system: a site app, a kiosk, a paper sheet, the job system itself. Trades, construction, cleaning, labour hire, anything with a roster and jobs. If a person’s pay depends on entries somebody else made, this applies.

It covers the check, not the pay. Interpreting which award clause applies to an unusual shift is a question for a person with a cited rule in front of them, and the shape of that question is the Cited Answer standard. This standard reads a dated rule, cites it, and parks what it does not plainly cover. The timesheet paper is the argument beside it.

The failure this prevents is specific. Not the wrong number on one sheet. The period that reached payroll with an anomaly nobody looked at, a penalty from an edition that had lapsed, and no name on the release.

2. The closed list of anomalies

Six kinds. A closed list, so an anomaly always has a name and an owner, and a new kind is a change to the standard rather than a note somebody typed.

KindWhat it isWho owns it
over_hoursMore hours in a day than the business's own limitThe person's supervisor
overlapTwo entries for one person that share a minuteThe person's supervisor
missing_breakA long entry with no break recordedThe person's supervisor
not_rosteredAn entry on a day the roster did not have them workingWhoever keeps the roster
not_allocatedAn entry on a job the person was never allocated toThe job's owner
rule_unclearA situation the dated rule does not plainly coverWhoever answers for the award

An entry with an open anomaly is not a line on the sheet. It is not paid at a guessed figure and it is not quietly dropped. It waits, in front of its owner, with a reason.

3. The objects, and what is in them

Seven objects. The card and the release are the two most timesheet tools leave out, because a total that adds up looks finished.

For your developer. Show the fields
Entry                             # captured on site, in the app, on paper
  - id, person_id, date, job_id (null if none was given)
  - start, end, break_minutes, source (site | app | paper)
  - flags[] (what the capture app noticed: a disputed break, an odd shift)

Allocation                        # theirs, from the job system
  - person_id, job_id, date

Roster
  - person_id, date, rostered

Rule                              # the award, as a dated instrument
  - id, instrument, edition, effective_from, effective_to
  - text, covers[] (the situations this edition plainly names)

Anomaly
  - id, entry_id, kind (from the closed list), owner (a person)
  - decision { by, reason, at } (a person's), resolution { by, reason, at }
  - evidence[]

Card                              # one per rule applied to an entry
  - entry_id, rule_id, edition, effective_from

Period
  - id, from, to
  - released_by (a person; null until they do)
  - export_external_id (payroll's own id; null means the export failed)

A Period with an export_external_id and no released_by is the defect this standard exists to make unrepresentable. An Anomaly with a resolution and no decision by a person is the other, and neither should be writable.

4. The checks, in order

The order is the claim. The entry is traced before it is totalled, the rule is read before a card is written, and the anomalies are at zero before the release is even asked for.

  1. Every entry traces to a person, a day and a job. Every entry carries a person id from the contact list, a date, and a job id from the job system that the person was allocated on that day. An entry with no job, or a job the person was not allocated, is an anomaly and never a line on the sheet.
  2. Daily and weekly totals are computed from entries, never typed. A total is the sum of the entries it names, computed at run time. A total that names no entries, or whose hours differ from the sum of the entries it names, is a typed total and fails.
  3. An anomaly is one of a closed list of kinds, and it has an owner. Over-hours in a day, overlapping entries, a missing break, an entry on a day not rostered, a job not allocated, and a rule that does not plainly apply. Each anomaly carries a kind from that list and the name of the person who owns it. A kind outside the list, or an anomaly with no owner, fails.
  4. Any penalty, overtime or allowance applied cites the rule, its edition and its effective date. An entry that attracts overtime, a weekend penalty or an allowance carries a card naming the rule, its edition and the date it took effect, read from the rule store at run time. A rule applied with no card fails.
  5. A retired rule edition cannot apply to the next period. Once a rule edition is retired, the next period applies the edition in force for its dates or parks the entry. A card for a period after the retirement that cites the retired edition fails.
  6. An entry the dated rule does not plainly cover is parked for a person. A disputed break, an unusual shift, a situation the rule text does not plainly name: the entry is parked with kind rule_unclear and an owner, and no card is written for it. The build never decides which clause applies.
  7. An anomaly leaves the queue only with a person's name and a reason. A resolution is a person's name, a reason from the list approved, corrected or rejected, and the time. The person's decision is attached as evidence. An anomaly resolved with no name, or with no decision behind it, fails.
  8. Nothing reaches payroll without a release by a named person. The period export is written only after a named person releases the period, and only when every anomaly in it is resolved. A run with no release writes nothing. An export with no release behind it, or with an open anomaly, fails.
  9. One export per period, written once, updated on a second release. The export is keyed to the period. A second release for the same period updates the existing export or refuses; it never writes a second one. A null external id is a failed export, not a success.
  10. Every period publishes hours, anomalies found and resolved, and the release, including a clean one. Each run publishes a report for the period: the hours by person and day, how many anomalies were found and how many resolved, and who released it or that nobody has. A clean period publishes too, so silence never means clean.
  11. Entries, anomalies, resolutions, rules cited and the release are retrievable by person and period. When a person disputes their pay, the record for that person and period shows every entry, every anomaly with who resolved it and why, every rule card, and who released the period.
  12. It survives the builder. Someone other than the builder can explain what it does, and it runs on an account the business owns.
  13. The pass test passes. On a real period with real entries: one overlapping pair caught, one unallocated job caught, one rule edition change parking the next period, one release by a person, and one export in the payroll system with its id.

5. The award is a rule you read, not one you interpret

Overtime after eight hours, a Saturday penalty, a meal allowance: each is a clause in an instrument with an edition and an effective date. The check applies one only when the entry plainly matches a situation that edition names, and when it does, the line carries a card saying which rule, which edition, from when. When the edition changes, the next period cites the new one, and the old one cannot produce a card.

An entry the rule does not plainly cover, a disputed break, a split shift nobody has seen before, is parked with the kind rule_unclear and an owner. The machine does not decide which clause applies. That is the one decision on this page that can end up in front of a tribunal, and it stays with a person who has the clause in front of them.

6. What stays with a person

  • Every anomaly resolution, with their name and a reason: approved, corrected, or rejected.
  • The release of the period to payroll.
  • Which award applies to the business, and which clause applies to the odd shift.
  • Any dispute with the person whose hours they are. The check shows the entry; a person has the conversation.

The parts that move

Checked as at 26 September 2026

Modern award rates, penalties and allowances change on a schedule set by the Fair Work Commission, usually from the first full pay period on or after 1 July, and sometimes between. Hold each edition as a dated rule with an effective date, and let the period decide which edition applies. A formula copied into a spreadsheet in 2024 does not know that.

Check these against the primary instrument before you rely on them, and store the date you checked beside the value rather than hard-coding it. This standard tells you the shape and where to look. It is not legal advice and it does not tell you that anything complies.

8. Provider: what to stub, and what not to hand-roll

One step not to hand-roll: the release gate and the idempotent export into payroll, with an id back. Everything else a coding agent builds against the stub in an afternoon.

For your developer. Show the provider config
provider:
  stub:       local.mock_roster
  production: none                       # no hosted step; runs on your own systems

stays local                          # yours, and the standard
  - the trace against the roster and the allocations
  - the totals, the anomaly queue, the cards
  - the rule store with its editions and dates

the live step
  - the release by a named person, then one export per period into
    the payroll system with its id back. Runs on your own systems;
    there is no hosted product for it.

A vendor selling timesheet automation is usually selling the capture and the arithmetic, and is silent about who released the last period and which award edition the Saturday rate came from. Ask them those two first.

The pass test. On a real period, with the entries people actually captured. Seed two entries for one person that overlap: both must be in the anomaly queue with a supervisor’s name. Seed an entry on a job the person was never allocated: it must be an anomaly, not a line. Retire the current award edition and load the next with a later effective date: the following period must cite the new edition only, and an entry the new edition does not plainly cover must park with the kind rule_unclear. Clear every anomaly as a named person with a reason, release the period as a named person, and run twice an hour apart: exactly one export must exist in payroll with its own id, and the record for any person must show their entries, their anomalies with resolutions, the cards, and the release with a name. If the export exists without a release, or a card cites the retired edition, the standard is not implemented.

9. Conformance checklist

Hold a DIY build or a vendor to this. If a box is empty, it is not in production.

  • 1. Every entry traces to a person, a day and a job. Every entry carries a person id from the contact list, a date, and a job id from the job system that the person was allocated on that day. An entry with no job, or a job the person was not allocated, is an anomaly and never a line on the sheet.
  • 2. Daily and weekly totals are computed from entries, never typed. A total is the sum of the entries it names, computed at run time. A total that names no entries, or whose hours differ from the sum of the entries it names, is a typed total and fails.
  • 3. An anomaly is one of a closed list of kinds, and it has an owner. Over-hours in a day, overlapping entries, a missing break, an entry on a day not rostered, a job not allocated, and a rule that does not plainly apply. Each anomaly carries a kind from that list and the name of the person who owns it. A kind outside the list, or an anomaly with no owner, fails.
  • 4. Any penalty, overtime or allowance applied cites the rule, its edition and its effective date. An entry that attracts overtime, a weekend penalty or an allowance carries a card naming the rule, its edition and the date it took effect, read from the rule store at run time. A rule applied with no card fails.
  • 5. A retired rule edition cannot apply to the next period. Once a rule edition is retired, the next period applies the edition in force for its dates or parks the entry. A card for a period after the retirement that cites the retired edition fails.
  • 6. An entry the dated rule does not plainly cover is parked for a person. A disputed break, an unusual shift, a situation the rule text does not plainly name: the entry is parked with kind rule_unclear and an owner, and no card is written for it. The build never decides which clause applies.
  • 7. An anomaly leaves the queue only with a person's name and a reason. A resolution is a person's name, a reason from the list approved, corrected or rejected, and the time. The person's decision is attached as evidence. An anomaly resolved with no name, or with no decision behind it, fails.
  • 8. Nothing reaches payroll without a release by a named person. The period export is written only after a named person releases the period, and only when every anomaly in it is resolved. A run with no release writes nothing. An export with no release behind it, or with an open anomaly, fails.
  • 9. One export per period, written once, updated on a second release. The export is keyed to the period. A second release for the same period updates the existing export or refuses; it never writes a second one. A null external id is a failed export, not a success.
  • 10. Every period publishes hours, anomalies found and resolved, and the release, including a clean one. Each run publishes a report for the period: the hours by person and day, how many anomalies were found and how many resolved, and who released it or that nobody has. A clean period publishes too, so silence never means clean.
  • 11. Entries, anomalies, resolutions, rules cited and the release are retrievable by person and period. When a person disputes their pay, the record for that person and period shows every entry, every anomaly with who resolved it and why, every rule card, and who released the period.
  • 12. It survives the builder. Someone other than the builder can explain what it does, and it runs on an account the business owns.
  • 13. The pass test passes. On a real period with real entries: one overlapping pair caught, one unallocated job caught, one rule edition change parking the next period, one release by a person, and one export in the payroll system with its id.
  1. 1

    Hold the build to the checklist

    The checks in this standard are what a working build looks like. Implement it yourself, hand it to a developer, or hand the page to an AI with the button below.

  2. 2

    Do not hand-roll

    There is no product for this step. Highest option: none. Checklist plus a build.

  3. 3

    If you are stuck

    Exceptions, three systems, a team that will not maintain a Zap, or an owner who wants it done. We implement when it has to survive the business.

Related reading

Want the whole thing by email?

This paper, plus the rest of the library. One click to stop them.

Run these checks yourself

Every check on this page is published as structured data. This prints them with what to inject, what to assert, and which ones can be proved on your own machine rather than against the live thing.

npx @aipathway/conformance show timesheet-check-build-standard

Free and open source, CC BY 4.0. The checks are fetched from this page rather than bundled, so a correction here reaches you without a release, and you cannot end up conformant against a stale copy. The raw JSON is there if you would rather wire it into your own harness, and the package shows how to drive your build through the ports.

Built it, and one check failed?

Tell us which one. You have already read the standard and tried it, so the answer is a fixed price to finish that step, not a call to work out what you need.