Skip to content
  1. Home
  2. Benchmarks
  3. Integration Bench
  4. task-0039
task-0039 · polling · writeback

Build the nightly payroll bridge for the punch export

Vendor Rosterly Surface polling, writeback From Payroll Systems / Harbor Point Facilities Mean score 94.1 Resolved by 16/17 93 graded checks

Results

The ticket

This is PROBLEM.md exactly as the agent received it. Vendor documentation and the starter repository ship inside the task environment and are not reproduced here.

Build the nightly payroll bridge for the punch export

From: Payroll Systems / Harbor Point Facilities Vendor: Rosterly Surface: polling, writeback Category: build · Tier: 3

Context

Our overnight rota lives in Rosterly. Every morning the timekeeping partner drops a file of clock-in/clock-out pairs keyed by Rosterly shift.

Payroll pays by the day, so a punch crossing midnight must be split and each day given its minutes. The repository contains the initial bridge.

Payroll Systems’ own runbook for the job is at docs/harborpoint-payroll-runbook.md. Full vendor documentation is in docs/ — start at docs/index.md.

The rules payroll work to

These are ours, not Rosterly’s.

  • A payroll day is a calendar day at the shift’s venue. Split a punch at venue midnight; its daily minutes must add up to its total length.
  • The partner corrects punches by re-sending them. A correction carries the same punch_ref. The last row the file gives for a punch_ref is the punch; earlier rows for that ref are what the clock held before a supervisor fixed it, and they are not additional work.
  • A punch we cannot place is an exception, not a guess. If Rosterly has no such shift, the reason is unknown_shift; if Rosterly has it but no longer holds it against the rota, the reason is deleted_shift. Exceptions stay off the payroll report entirely and nothing is written back for them.
  • Arrival is the clock-on measured against the shift’s scheduled start: early at 5 minutes or more before it, late at 5 minutes or more after it, on_time in between.
  • Scheduling get told about split punches. Each gets one note against the crew member, using the package’s established key and format and carrying the punch, shift, venue timezone, and daily minutes. The bridge is routinely re-run over the same export.

What we need

The harness runs your code exactly as follows — this command is the contract:

python -m harborpoint_bridge
# -> writes the output artifacts listed below

The export is at input/punches.csv: punch_ref, shift_id, punch_in_utc, punch_out_utc.

Output artifacts

  • output/import_report.csv — header row plus one row per payroll day of every payable punch: punch_ref, shift_id, worker_id, venue_timezone, payroll_date (YYYY-MM-DD), minutes.
  • output/result.jsonpunch_count, bridged_count, unbridgeable_count, split_line_count, midnight_split_count, total_minutes, notes_posted, plus punches (one entry per payable punch: punch_ref, shift_id, worker_id, venue_timezone, arrival, minutes, and days, a list of payroll_date/minutes) and unbridgeable (punch_ref, shift_id, reason).
  • output/writeback_log.jsonnotes: one entry per note the run wrote back, each with punch_ref, shift_id, worker_id, idempotency_key, note_id.

Environment

VariableMeaning
VENDOR_BASE_URLVendor sandbox base URL (e.g. http://vendor:8000)
RY_CLIENT_IDVendor credential injected by the test harness
RY_CLIENT_SECRETVendor credential injected by the test harness
INPUT_FILEPath to the partner’s punch export
OUTPUT_DIRDirectory where output artifacts land (defaults to ./output)
PAGE_LIMITOptional batch-size override

Engineering expectations

This ships to production, so the usual bar applies:

  • Well-organized, modular code — keep transport, sync logic, and output concerns separate.
  • Tests, runnable with pytest, covering the core logic you add or change.
  • Be a good API citizen: handle the vendor’s real-world behavior the way a production integration must, and don’t hammer endpoints in retry loops. Our platform team audits vendor request logs — sloppy conduct gets flagged even when the data lands correctly.

Done when

The entry command exits 0, every payable punch’s minutes sit on the payroll days the venue worked them, every punch we cannot place is on the exception list with a reason and nowhere else, scheduling holds exactly one note per split punch, and running the bridge again over the same export changes neither the artifacts nor what Rosterly holds.

Graded checks (93)

Names of every assertion the grader runs for this task. Per-attempt pass/fail and details are on each trajectory page.

  • payroll_bridge_run_completed
  • payroll_headline_counts_exact
  • result_json_contract_exact
  • import_report_contract_exact
  • punch_pch_0101_payroll_split_exact
  • punch_pch_0102_payroll_split_exact
  • punch_pch_0103_payroll_split_exact
  • punch_pch_0104_payroll_split_exact
  • punch_pch_0105_payroll_split_exact
  • punch_pch_0106_payroll_split_exact
  • punch_pch_0107_payroll_split_exact
  • punch_pch_0108_payroll_split_exact
  • punch_pch_0109_payroll_split_exact
  • punch_pch_0110_payroll_split_exact
  • punch_pch_0111_payroll_split_exact
  • punch_pch_0112_payroll_split_exact
  • punch_pch_0113_payroll_split_exact
  • punch_pch_0114_payroll_split_exact
  • punch_pch_0115_payroll_split_exact
  • punch_pch_0116_payroll_split_exact
  • punch_pch_0117_payroll_split_exact
  • punch_pch_0118_payroll_split_exact
  • punch_pch_0119_payroll_split_exact
  • punch_pch_0120_payroll_split_exact
  • punch_pch_0121_payroll_split_exact
  • punch_pch_0122_payroll_split_exact
  • punch_pch_0123_payroll_split_exact
  • punch_pch_0124_payroll_split_exact
  • punch_pch_0200_payroll_split_exact
  • punch_pch_0201_payroll_split_exact
  • punch_pch_0202_payroll_split_exact
  • punch_pch_0210_payroll_split_exact
  • punch_pch_0211_payroll_split_exact
  • report_pch_0101_lines_exact
  • report_pch_0102_lines_exact
  • report_pch_0103_lines_exact
  • report_pch_0104_lines_exact
  • report_pch_0105_lines_exact
  • report_pch_0106_lines_exact
  • report_pch_0107_lines_exact
  • report_pch_0108_lines_exact
  • report_pch_0109_lines_exact
  • report_pch_0110_lines_exact
  • report_pch_0111_lines_exact
  • report_pch_0112_lines_exact
  • report_pch_0113_lines_exact
  • report_pch_0114_lines_exact
  • report_pch_0115_lines_exact
  • report_pch_0116_lines_exact
  • report_pch_0117_lines_exact
  • report_pch_0118_lines_exact
  • report_pch_0119_lines_exact
  • report_pch_0120_lines_exact
  • report_pch_0121_lines_exact
  • report_pch_0122_lines_exact
  • report_pch_0123_lines_exact
  • report_pch_0124_lines_exact
  • report_pch_0200_lines_exact
  • report_pch_0201_lines_exact
  • report_pch_0202_lines_exact
  • and 33 more