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

Move the rota mirror onto instant storage

Vendor Rosterly Surface polling From Data Platform — Nordhavn Care Group Mean score 70.6 Resolved by 12/17 117 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.

Move the rota mirror onto instant storage

From: Data Platform — Nordhavn Care Group Vendor: Rosterly Surface: polling Category: migrate · Track: python · Tier: 2

Context

We keep a Postgres mirror of the rota rows that belong to our own crew on a shared Rosterly tenant. It has held them as two columns of text since it went in: the wall clock Rosterly printed, and the name of the clock that wall clock is on.

Group Reporting are building one capacity picture across every venue we staff and they cannot do it on text. Two stamps written on two different clocks do not sort, do not subtract and do not join. So the mirror moves onto instants.

The nightly refresh job in this repo is what feeds the mirror today. Your job is to make it emit the new shape instead of the old one. There is a note from when this was costed in docs/nordhavn-mirror-migration-spec.md.

What is in scope

input/crew_roster.csv is the crew we own on that tenant. In scope is every worker on it, plus every shift and every interview Rosterly holds that names one of those workers. Nothing else on the tenant is ours.

input/mirror_inventory.csv is a dump of what the mirror holds right now, in the old shape. Anything in scope that is not in it is new to us.

The new row shape

One row per in-scope record:

ColumnMeaning
entityworker, shift or interview
record_idRosterly’s id for the record
zonethe IANA clock name this record’s stamps are expressed in
local_wall_clockthe record’s updated_at wall clock, no zone suffix
updated_utcthe same moment as a UTC instant, YYYY-MM-DDTHH:MM:SSZ
utc_offsetthe difference between the two above it, +HH:MM / -HH:MM
stateactive, or retired if the tenant has retired the record

Run contract

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

python -m nordhavn_mirror_port

Output artifacts

  • output/import_report.csv — header row plus one row per in-scope record, in the column order of the table above.
  • output/result.json — an object with migrated_row_count, active_row_count, retired_row_count, adopted_row_count, adopted (the ids in scope that the mirror inventory did not already hold, sorted), and zone_offsets (an object mapping each clock name that appears in the report to the offset the run recorded for it).

Full vendor documentation is in docs/ — start at docs/index.md.

Environment

VariableMeaning
VENDOR_BASE_URLVendor sandbox base URL
RY_CLIENT_IDVendor credential injected by the test harness
RY_CLIENT_SECRETVendor credential injected by the test harness
CREW_ROSTER_FILEPath to the crew roster
MIRROR_INVENTORY_FILEPath to the mirror inventory dump
OUTPUT_DIRDirectory where output artifacts land

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 in-scope record appears exactly once in the report carrying the instant it really denotes, and the summary’s counts agree with the rows underneath them.

Graded checks (117)

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

  • no_credentials_in_query_string
  • no_secrets_echoed_to_vendor
  • reauth_per_request:/oauth/token
  • no_unnecessary_full_resync:interview
  • no_unnecessary_full_resync:shift
  • no_unnecessary_full_resync:worker
  • mirror_port_result_schema_exact
  • mirror_port_run_completed
  • mirror_port_headline_counts_exact
  • mirror_row_interview_interview_0002_exact
  • mirror_row_interview_interview_0009_exact
  • mirror_row_interview_interview_0014_exact
  • mirror_row_interview_interview_0018_exact
  • mirror_row_interview_interview_0025_exact
  • mirror_row_interview_interview_0029_exact
  • mirror_row_interview_interview_0053_exact
  • mirror_row_interview_interview_0068_exact
  • mirror_row_interview_interview_0070_exact
  • mirror_row_interview_interview_0080_exact
  • mirror_row_interview_interview_0082_exact
  • mirror_row_interview_interview_0098_exact
  • mirror_row_interview_interview_0106_exact
  • mirror_row_interview_interview_0109_exact
  • mirror_row_interview_interview_0111_exact
  • mirror_row_interview_interview_0113_exact
  • mirror_row_interview_interview_9001_exact
  • mirror_row_interview_interview_9002_exact
  • mirror_row_shift_shift_0013_exact
  • mirror_row_shift_shift_0023_exact
  • mirror_row_shift_shift_0026_exact
  • mirror_row_shift_shift_0037_exact
  • mirror_row_shift_shift_0044_exact
  • mirror_row_shift_shift_0053_exact
  • mirror_row_shift_shift_0059_exact
  • mirror_row_shift_shift_0067_exact
  • mirror_row_shift_shift_0069_exact
  • mirror_row_shift_shift_0087_exact
  • mirror_row_shift_shift_0098_exact
  • mirror_row_shift_shift_0103_exact
  • mirror_row_shift_shift_0105_exact
  • mirror_row_shift_shift_0106_exact
  • mirror_row_shift_shift_0109_exact
  • mirror_row_shift_shift_0112_exact
  • mirror_row_shift_shift_0116_exact
  • mirror_row_shift_shift_0117_exact
  • mirror_row_shift_shift_0127_exact
  • mirror_row_shift_shift_0135_exact
  • mirror_row_shift_shift_0142_exact
  • mirror_row_shift_shift_0143_exact
  • mirror_row_shift_shift_0150_exact
  • mirror_row_shift_shift_0152_exact
  • mirror_row_shift_shift_0153_exact
  • mirror_row_shift_shift_0163_exact
  • mirror_row_shift_shift_0179_exact
  • mirror_row_shift_shift_9001_exact
  • mirror_row_shift_shift_9002_exact
  • mirror_row_worker_worker_0001_exact
  • mirror_row_worker_worker_0002_exact
  • mirror_row_worker_worker_0003_exact
  • mirror_row_worker_worker_0004_exact
  • and 57 more