Skip to main content

Pay Reconciliation Agent

Code location: product/mr-people-agents/recon/ Linear ticket: MRP-109 Status: LIVE — runs weekly, Syra reviews findings Uses AI: No. Purely rules-based, deterministic.

What it does

This agent audits Paylocity employee data by comparing CSV exports against a set of configurable rules. It catches data integrity issues, pay discrepancies, and compliance gaps before they become problems. Think of it as an automated auditor that runs the same checks a careful HR person would do manually, but every week without missing anything.

What it audits

AuditWhat it checksCadence
Field integrityRequired fields aren't blank, emails match expected domains, values are from allowed lists, conditional fields are correct (e.g., "if role is X, then field Y must be Z")Weekly (biweekly gate tied to payday)
Reporting structureManager assignments are valid, org hierarchy is consistentWeekly
Time-off / accrual assignmentAccrual banks match what the employee should have based on state, employment type, and roleWeekly
Zero hours workedFlags employees who weren't paid in a pay period. Classifies each as: new hire (expected), absent from Legion (investigate), or worked-but-unpaid (urgent)Weekly
Benefit class consistencyFull-time vs part-time status matches benefit class assignmentWeekly
Wage auditCompares hourly rates and salaries against federal, state, and local minimum wage floorsMonthly
Job change closeoutValidates that job changes processed last week were completed correctlyEvery Monday

Data flow

Paylocity
↓ Scheduled CSV reports (weekly, Sunday 2pm)
↓ via SFTP to MR's own server
GitHub Action (recon-report-bridge, lives in mr-people repo)
↓ Pulls from SFTP, deposits into Google Drive inbox folder
Apps Script (recon agent)
↓ Reads CSVs from Drive, validates headers/schemas
↓ Runs rules against each row
↓ Deduplicates findings against existing Exception Queue
Spreadsheet
├── Exception Queue tab (findings for Syra to review)
├── Audit Log tab (append-only record of everything)
└── Dry Run tabs (snapshot per run date, for review before go-live)

CSV reports consumed

The agent reads 6-7 different Paylocity report exports:

  • Biweekly integrity report (employee fields)
  • Base employee data
  • Accrual/time-off balances
  • ENP (Employees Not Paid) report
  • Benefit class report
  • Current rates (hourly/salary)
  • Job change report (Monday closeout)

Ingest validation

Before processing, the agent validates each CSV:

  • Schema drift protection — checks that column headers match expected schema. If Paylocity changes a column name, the agent fails loudly instead of silently processing wrong data.
  • Row-floor gates — if a report has suspiciously few rows (e.g., 3 employees when there should be 1,200), it flags it as a data quality issue rather than processing garbage.

Rules engine

Rules are defined as spreadsheet rows in the FieldRules tab, not as code. Each rule has:

ColumnWhat it means
rule_idUnique identifier (e.g., FI-001)
reportWhich CSV report this rule applies to
fieldWhich column to check
typeWhat kind of check: not_blank, email_domain, one_of, equals, matches_map, required_if, blank_if, etc.
paramThe expected value, list, or map name
severityHow urgent: error, warning, info

This means the People team can add, modify, or disable rules by editing spreadsheet rows. No code change or deploy needed.

Rule types (8 total)

  1. not_blank — field must have a value
  2. email_domain — email must end with expected domain (e.g., @madison-reed.com)
  3. one_of — value must be in an allowed list
  4. equals — value must exactly match a specific value
  5. matches_map — value must match a lookup table (e.g., department code maps to expected job title family)
  6. required_if — field is required only when another field has a certain value
  7. blank_if — field must be blank when another field has a certain value
  8. Additional conditional types for complex business rules

Exception handling

When the agent finds an issue:

  1. It creates a finding with a dedup key (so the same issue isn't flagged twice)
  2. It checks the Exception Queue for existing open findings with that key
  3. If it's new, it appends to the queue with status open
  4. It routes the finding to a named reviewer based on the Routing tab (exception type maps to a person's email)
  5. When the underlying data is fixed in Paylocity, the next run's auto-clear pass marks the finding as cleared

Syra is the primary reviewer. Findings that involve fields the employee controls (email, address) route to the employee for self-fix.

Webhook (optional)

The agent can also be triggered by Paylocity events via an HTTP webhook:

  • URL: https://script.google.com/macros/s/.../exec?k=<secret>&event=<name>
  • Events: payroll_processed, employee_change, new_hire, termination, job_change
  • Authentication: long secret in the URL query parameter
  • Response: 200 + JSON

This lets the agent react to real-time events (e.g., run an integrity check immediately after payroll processes) in addition to the scheduled weekly runs.

Current status and recent history

  • Week 1 results: Rules converged from 249 open findings to 19, every reduction attributable to a specific rule refinement
  • Rule refinements from Syra's first review (July 15): contractor scoping, LOA suppression, time-bank home-state fallback, benefit-class prior-month rule, CEO-direct exemption, suppression list, persistent reviewer notes
  • Hardening complete: rules goldens (baseline snapshots), janitor (cleanup), build stamps, handover docs (operator manual + rules codebook + report contracts) all set in mr-people
  • Auto-clear working: when Syra fixes something in Paylocity, the next run picks it up and clears the finding. 17 of her fixes were awaiting verification as of late July.

Open items

ItemStatusNotes
Benefit Class Report audit decisionWaiting on SyraWhether to expand the FT/PT check to a full composite (state x salaried/hourly = exact benefit class)
Legion by-day auto-ingest wiringOpenAutomating the daily Legion email pickup
Policy-sheet mapper phase 2OpenExtending the rule engine to handle more complex policy lookups
Time-bank eligibility rulesNeeds Syra's inputWhich accrual bank for which state/county/FT-PT combo
Code migration to mr-peopleDecidedMoves after first live cycle + Syra sign-off