Integration · People operations
How to build a training completion sync
An auditor asks who completed the required training, and the answer is a course report that does not know who left, who changed role, or who never needed it. Here is the model behind an answer that holds.
Built with Tray Headless
- System Workday roles
- Step Derive requirement
- Step Assign in LMS
- Step Carry completion back
- System Workday record
Assignment is derived from the worker record, so a role change changes the requirement without anybody maintaining a list.
The short answer
What is a training completion sync?
A training completion sync has four moving parts: requirements derived from the worker record instead of a maintained list, assignment that reacts to a role change, completions carried back onto the HRIS record with the version of the course, and evidence produced per person rather than as a percentage. Teams usually come unstuck on the spreadsheet of who needs what. It is correct on the day it is built and wrong from the first role change after that.
What matters here
- Derive the requirement from role and location. A maintained list is wrong from the first role change.
- A role change changes the requirement. Somebody moving into a people manager role needs training they did not need last week.
- Record the course version against the completion. Completing the 2024 course does not satisfy a 2026 requirement.
- Chase only those who are outstanding, and stop when they complete or leave.
- A completion percentage is not evidence. An auditor asks about a named person.
Who this is for
You run people operations or compliance. Required training is tracked in the LMS, the HRIS knows nothing about it, and the completion report cannot survive a question about one specific person.
How it works in practice
The path from somebody joining or changing role to the training record being right.
- 1
Requirements are derived from the worker record
Role, location, department and manager status, not a maintained list.
- 2
Assignment reacts to changes
A joiner, a promotion or a transfer changes what is required, immediately.
- 3
Assignments carry a due date
Relative to the event that created them, so a joiner and a transfer are not on the same clock.
- 4
Completions are carried back to the HRIS
With the course version and the completion date, on the worker record itself.
- 5
Only the outstanding are chased
And chasing stops on completion or on leaving.
- 6
Evidence is produced per person
Who, which course, which version, when, and what made it required.
What the sync is made of
Four parts, and the first is the one that decays if you get it wrong.
Derived requirements
Computed from role, location and manager status every time the worker record changes. A list is accurate on the day it is written and never again.
Reactive assignment
A promotion into a people manager role creates a requirement that did not exist the week before, and nobody should have to notice it.
Completions on the worker record
In the HRIS, with the course version. The LMS knows about courses; the HRIS is where a question about a person gets answered.
Per-person evidence
An auditor asks about one named individual, not about a percentage. The answer needs the course version and the reason it applied.
The Tray Headless prompts
Paste these into Claude Code or Codex with the Tray Headless plugin installed. Each stage runs on its own. The systems named in them are the worked example rather than a requirement, and every prompt says so.
Once per project, run
/tray-workflows:set-workspace
to pick the workspace these build in. Point it at a sandbox first.
- 1
First, derive the requirement from the worker record
A maintained list is wrong from the first role change.
Headless skills
build-workflowUse build-workflow. The systems in play are Workday and our LMS, or whatever we run in those seats. Derive required training per person from the worker record rather than from a list: role, job family, location, department, whether they manage people, and whether they handle regulated data. Compute this every time a worker record changes, not on a schedule. The requirement is a function of the record, and treating it as one is what stops the whole thing drifting. Record why each requirement applies. A person asking why they have been assigned a course deserves an answer better than the system said so, and so does an auditor asking why somebody was not assigned it.
- 2
Assign, and react to role changes
A promotion creates requirements that did not exist last week.
Headless skills
build-workflowUse build-workflow. On any change to the derived requirement: Newly required courses are assigned in the LMS with a due date relative to the event that created them, so a joiner and a transfer are on different clocks Courses no longer required are unassigned, but existing completions are never deleted A course already completed at the current version is not reassigned A course completed at an older version is reassigned, with the reason stated Handle the transfer case carefully. Somebody moving from an individual contributor role into a people manager role acquires manager training and keeps everything they already completed, and getting that wrong either buries them in duplicates or leaves a real gap.
Never delete a completion when a requirement goes away. The evidence that somebody completed a course in 2025 is still evidence, and the role they held then is part of the record.
- 3
Carry completions back onto the worker record
The HRIS is where a question about a person gets answered.
Write completions back to the HRIS on the worker record: The course, its version, and the completion date The score or pass result where the course has one The expiry date where the certification lapses The requirement that made it apply The version matters more than it looks. Somebody who completed the 2024 security course has not satisfied a 2026 requirement, and a completion record without a version quietly says they have. Track expiry as its own requirement. An annual certification completed eleven months ago is about to become a gap, and the whole point of this is to see that before it happens instead of afterwards.
- 4
Chase only the outstanding, and stop properly
Everything else is noise that trains people to ignore the notice.
Headless skills
tray-gotchasUse tray-gotchas, then chase only people with something outstanding: A reminder at a sensible interval before the due date An escalation to the manager after it, once, not repeatedly Nothing at all to somebody who has completed Stop on completion, on the requirement being removed, and on the person leaving. Chasing a leaver is the one that gets noticed, and it is entirely avoidable by reading the worker status before every send. Suppress chasing during a documented leave of absence, and resume with a recalculated due date rather than an overdue one.
- 5
Produce evidence a person can point at
An auditor asks about a named individual, not a percentage.
Report evidence instead of compliance rates: Per person: which courses are required, why, which are complete, at which version, and when Outstanding items grouped by manager, so the escalation has an owner Certifications expiring in the next ninety days People whose requirement changed in the last month and what changed Assignments that failed to create in the LMS That last one is the coverage measure. Every failed assignment is somebody who believes they have nothing outstanding and is wrong. A completion percentage is a management metric. It is not evidence, and the moment somebody asks about one specific person it stops helping.
- 6
Prove it works, then hand the rules to people operations
Because requirements change with regulation and with the org.
Run the per-step schema checks and the whole-workflow audit before this touches production. Move a test worker into a manager role and confirm the new requirement appears, the old completions survive and the due date runs from the transfer. Then open the same workflow in Tray Build so people operations can change which roles require which courses and adjust the due date windows in the visual canvas.
What it connects to
The HRIS defines who needs what, the LMS runs the training, and the evidence has to live where somebody can find it.
Workday
Read role, location and manager status to derive requirements, and write completions onto the worker record.
Reads and writes
Docebo
Assign courses, unassign what is no longer required, and read completions with their course version.
Reads and writes
Snowflake
Hold the requirement history, so a question about what applied to somebody in 2025 has an answer.
Writes
Same build, other stacks
The design does not change if you run something else in one of these seats. The same prompts build it against Google BigQuery, Microsoft Teams, SAP SuccessFactors, Databricks, Google Chat or BambooHR.
Named systems are the ones most teams run, not the only ones that work. Each is an authentication in your Tray workspace, referenced by name, so the workflow never holds a credential. Where we have a connector page, the name links to it.
Running it in production
This is evidence for an audit and a duty of care to employees. It has to be right about individuals.
This runs as infrastructure, not as a script
Requirements recompute when a worker record changes, so a Monday promotion creates the manager training requirement on Monday.
Completions are never deleted
A requirement that goes away does not undo the fact that somebody completed the course, and the role they held at the time is part of the record.
Credentials are managed, never in code
HRIS and LMS access covering worker records and enrolments, scoped to those objects and held in your workspace.
People operations own the rules
Which roles require which courses, the due date windows and the escalation path, all open in Tray Build.
Failed assignments are surfaced
Because somebody who believes they have nothing outstanding and does is the gap an audit finds.
Questions people ask
Why derive requirements instead of maintaining a list?
Because a list is correct on the day it is written and wrong from the first role change after that. Deriving from role, location and manager status keeps it current without anybody maintaining it.
Why does the course version matter?
Because somebody who completed the 2024 course has not satisfied a 2026 requirement. A completion record without a version quietly claims they have.
What happens when a requirement no longer applies?
The assignment is removed and the completion is kept. Evidence that somebody completed a course does not stop being true when their role changes.
How is this different from policy attestation tracking?
Attestation records that somebody read and accepted a document. This handles courses with content, versions, scores and expiry, and it is driven by role rather than by publication of a policy.
Why is a completion percentage not enough?
Because an auditor asks about one named person: what was required, why, which version they completed and when. A rate cannot answer that.
Vibe-coding app guides
Vibe-code an entire app with Helix
This moves the data between systems. It does not give anybody a screen to work in. Build that app in Claude Code, Codex or Cursor, then deploy and run it governed on Tray Helix. Same kind of guide, same kind of prompts.
How to build a policy attestation tracker (opens helix.tray.ai in a new tab)
Related guides
Legal and compliance
How to build policy attestation tracking
Assign from the HRIS continuously, version what was accepted, chase without nagging everybody, and keep evidence a person can point at. The prompts.
People operations
How to build employee onboarding provisioning
Drive it from the HRIS, derive access from the role instead of a copied colleague, sequence around the start date, and prove it happened. The prompts that build it.
People operations
How to build an HRIS to payroll sync
Sync effective-dated changes, respect the payroll cutoff, hold anything ambiguous instead of guessing, and reconcile every cycle. The prompts that build it.
Last reviewed September 2026.