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

The case-note mirror is short every morning

Vendor Rosterly Surface polling From Clinical Systems / Ellerby Health Mean score 94.1 Resolved by 16/17 159 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.

The case-note mirror is short every morning

From: Clinical Systems / Ellerby Health Vendor: Rosterly Surface: polling Category: harden · Tier: 3

Context

Our safeguarding team works from a nightly mirror of the case notes attached to carers in Rosterly. The job in repo/ came across from the pilot tenant and has been running successfully in production: it exits cleanly, writes both files, and gives the morning meeting a plausible-looking total.

The live tenant is now much larger than the pilot. During an audit, Clinical Governance sampled notes visible in Rosterly and found that a substantial number never reached import_report.csv. The missing notes do not fall into one date range, author, or carer status, and the job has not raised an operational error. We need the existing connector hardened so that a successful run means the mirror is genuinely complete.

Ellerby’s operating note for this job is at docs/ellerby-case-note-mirror-note.md. Full vendor documentation is in docs/ — start at docs/index.md.

What we need

The harness runs one nightly pass exactly as follows:

python -m ellerby_note_mirror

Keep the existing package and artifact shapes. A pass must read the complete Rosterly roster and mirror every case note the tenant currently holds, exactly once. A note remains part of the mirror for as long as Rosterly returns it, including notes and carers represented as retired upstream. The job must not report a partial pass as complete.

Output artifacts

  • output/import_report.csv — header row plus one row per case note, sorted by note_id: note_id, worker_id, author, body, created_utc, updated_utc, state. Both timestamps are UTC strings in YYYY-MM-DDTHH:MM:SSZ form. state is active or retired.
  • output/result.jsonworkers_on_roster, workers_polled, note_count, active_note_count, and retired_note_count for that same pass.

Keep transport, mirror decisions, and artifact writing separate.

Environment

VariableMeaning
VENDOR_BASE_URLRosterly sandbox base URL
RY_CLIENT_IDOAuth client id injected by the harness
RY_CLIENT_SECRETOAuth client secret injected by the harness
OUTPUT_DIRArtifact directory (defaults to ./output)
PAGE_LIMITOptional page-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

python -m ellerby_note_mirror exits 0, the report contains exactly one correct row for every case note Rosterly holds against the complete roster, the summary counts agree with that report, retired material is represented with the required state, and no incomplete pass is presented as a successful mirror.

Graded checks (159)

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

  • case_note_mirror_run_completed
  • case_note_mirror_headline_counts_exact
  • case_note_mirror_csv_contract_exact
  • case_note_note_0001_mirrored_exact
  • case_note_note_0002_mirrored_exact
  • case_note_note_0003_mirrored_exact
  • case_note_note_0004_mirrored_exact
  • case_note_note_0005_mirrored_exact
  • case_note_note_0006_mirrored_exact
  • case_note_note_0007_mirrored_exact
  • case_note_note_0008_mirrored_exact
  • case_note_note_0009_mirrored_exact
  • case_note_note_0010_mirrored_exact
  • case_note_note_0011_mirrored_exact
  • case_note_note_0012_mirrored_exact
  • case_note_note_0013_mirrored_exact
  • case_note_note_0014_mirrored_exact
  • case_note_note_0015_mirrored_exact
  • case_note_note_0016_mirrored_exact
  • case_note_note_0017_mirrored_exact
  • case_note_note_0018_mirrored_exact
  • case_note_note_0019_mirrored_exact
  • case_note_note_0020_mirrored_exact
  • case_note_note_0021_mirrored_exact
  • case_note_note_0022_mirrored_exact
  • case_note_note_0023_mirrored_exact
  • case_note_note_0024_mirrored_exact
  • case_note_note_0025_mirrored_exact
  • case_note_note_0026_mirrored_exact
  • case_note_note_0027_mirrored_exact
  • case_note_note_0028_mirrored_exact
  • case_note_note_0029_mirrored_exact
  • case_note_note_0030_mirrored_exact
  • case_note_note_0031_mirrored_exact
  • case_note_note_0032_mirrored_exact
  • case_note_note_0033_mirrored_exact
  • case_note_note_0034_mirrored_exact
  • case_note_note_0035_mirrored_exact
  • case_note_note_0036_mirrored_exact
  • case_note_note_0037_mirrored_exact
  • case_note_note_0038_mirrored_exact
  • case_note_note_0039_mirrored_exact
  • case_note_note_0040_mirrored_exact
  • case_note_note_0041_mirrored_exact
  • case_note_note_0042_mirrored_exact
  • case_note_note_0043_mirrored_exact
  • case_note_note_0044_mirrored_exact
  • case_note_note_0045_mirrored_exact
  • case_note_note_0046_mirrored_exact
  • case_note_note_0047_mirrored_exact
  • case_note_note_0048_mirrored_exact
  • case_note_note_0049_mirrored_exact
  • case_note_note_0050_mirrored_exact
  • case_note_note_0051_mirrored_exact
  • case_note_note_0052_mirrored_exact
  • case_note_note_0053_mirrored_exact
  • case_note_note_0054_mirrored_exact
  • case_note_note_0055_mirrored_exact
  • case_note_note_0056_mirrored_exact
  • case_note_note_0057_mirrored_exact
  • and 99 more