Automation · Legal and compliance
How to build policy attestation tracking
An auditor asks who accepted the security policy and the answer is a spreadsheet from a campaign eight months ago. Below is the model behind evidence that stays current, the prompts that build it, and the parts that only bite once it is live.
Built with Tray Headless
- System Workday
- Step Assign by rule
- Step Version the policy
- Step Chase the outstanding
- System Evidence store
Assignment is continuous from the HRIS instead of a campaign, so a joiner is assigned on their start date instead of at the next annual round.
The short answer
What is policy attestation tracking?
Policy attestation tracking breaks into four parts: assignment derived continuously from the HRIS instead of a periodic campaign, the exact policy version recorded against each acceptance, chasing aimed only at the people who have not completed, and evidence a person can point at rather than a percentage. The common failure is the campaign. A one-off round leaves every joiner since unattested, and by the time an auditor asks, the gap is a year wide.
What matters here
- Assign continuously from the HRIS, not in campaigns. A campaign leaves every subsequent joiner unattested.
- Record the policy version accepted. An attestation against a policy that has since changed proves nothing about the current one.
- Chase only the people outstanding. Reminding everybody trains the compliant to ignore you.
- Keep evidence per person per version. An auditor asks who accepted what, not what the completion rate was.
- A material policy change re-triggers attestation. A silent update makes every prior acceptance meaningless.
Who this is for
You run compliance, security or people operations. Policies are attested in an annual push, joiners are caught late, and the evidence is assembled under pressure when somebody asks.
How it works in practice
What happens between a policy existing and being able to prove people accepted it.
- 1
Assignment rules run continuously
Department, role, level, location and system access decide who needs which policy.
- 2
A joiner is assigned on their start date
Not at the next annual round, which is where the gap comes from.
- 3
The exact version is shown and recorded
With a hash, so what was accepted is reconstructable years later.
- 4
Chasing targets only the outstanding
Escalating to a manager rather than reminding everybody.
- 5
A material change re-triggers attestation
A typo fix does not; a change of obligation does, and somebody decides which it is.
- 6
Evidence is per person per version
Who accepted what, when, from where, ready for the question when it comes.
What attestation tracking is made of
Four parts, and the first one closes the gap campaigns leave.
Continuous assignment
Rules over the HRIS, evaluated continuously. A campaign is a snapshot and everybody who joins afterwards is missing from it.
Versioned acceptance
The exact document accepted, hashed. A policy that changed since means the old attestation covers something else.
Targeted chasing
Only those outstanding, escalating by age. Reminding everybody teaches the people who complied to ignore the reminders.
Pointable evidence
Per person per version with a timestamp. An auditor asks who accepted what, and a completion percentage is not an answer.
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, make assignment a rule, not a list
A list is a snapshot and joiners are missing from it.
Headless skills
build-workflowUse build-workflow. The systems in play are Workday and Okta, or whatever we run in those seats. Build assignment as rules over attributes rather than as a list of people: Everybody: code of conduct, security policy, acceptable use Engineering: secure development, change management Finance and anybody with system access: segregation of duties Anybody handling personal data: data protection Regulated roles by jurisdiction: whatever applies there Evaluate continuously against the HRIS instead of in a campaign. A campaign is a snapshot, and everybody who joins afterwards is missing from it until the next one, which is where the audit gap comes from.
- 2
Version what was accepted
An attestation against a superseded policy proves nothing about the current one.
Headless skills
build-workflowUse build-workflow. Every policy is a versioned document with an effective date and a content hash. Record on each attestation: the person, the policy, the exact version and its hash, the timestamp, and the method of acceptance. Store the document version itself, not a link to the current one. A link resolves to whatever the policy says today, which proves nothing about what somebody agreed to two years ago. An attestation is only evidence for the version it was made against. Anything else is a completion statistic dressed up as a control.
- 3
Chase the outstanding, not everybody
Reminding everybody teaches the compliant to ignore you.
Assign with a due date from the start date or the policy publication, then chase only those outstanding: Day 7: a reminder to the person Day 14: a reminder copying their manager Day 21: escalation to the department head with the list Day 30: to compliance as a breach of the policy itself Never send a reminder to somebody who has already completed. It is the fastest way to make people filter your messages, and then the real escalations go unread too. Report by department and manager instead of as a company number. Outstanding attestations concentrate in specific teams, and a company average hides that entirely.
Escalating to the manager at day 14, not day 30 is what actually moves completion. Most non-completion is forgetting, not refusal.
- 4
Handle change, leave and exceptions
A silent policy update makes every prior acceptance meaningless.
Headless skills
tray-gotchastray-patternsUse tray-gotchas, then handle these: A material policy change re-triggers attestation for everybody it applies to. A typographical fix does not. Somebody decides which it is at publish time, and that decision is recorded. A role change re-evaluates assignment. Somebody moving into finance acquires the segregation of duties policy that day. A leaver stops being chased but their attestation history is retained, because the question is about the period they worked here. Somebody on long leave is excluded from chasing and reassigned on return rather than accruing an overdue record they could never have completed. A refusal is an escalation to compliance, not a retry loop.
- 5
Produce evidence, not a percentage
An auditor asks who accepted what.
Produce the evidence continuously instead of assembling it when asked: Per person: every policy, version and acceptance date Per policy version: everybody who accepted it and when Currently outstanding, with age and owner People who joined and were assigned within their first week Policy versions published without an attestation decision recorded Report coverage by department and by policy, and time from assignment to completion. Do not lead with a company completion percentage. It sits near ninety five, moves slowly, and hides the department at sixty which is the only part anybody needs to act on.
- 6
Test it, then hand the rules to compliance
Because policies and their audiences change constantly.
Run the per-step schema checks and the whole-workflow audit before this touches production. Then open the same workflow in Tray Build so compliance can maintain the assignment rules, the chase cadence and the material-change decision in the visual canvas.
What it connects to
People come from the HRIS, policies from a document store, and evidence has to outlive both.
Workday
Read joiners, leavers, role changes and departments, which is what assignment is derived from continuously.
Reads
Okta
Resolve managers for escalation, and read system access where that determines which policies apply.
Reads
Google Drive
Hold each versioned policy document, so what was accepted is stored rather than linked to.
Reads and writes
Vanta
Push completion evidence in, so the attestation control is answerable from where audits are.
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, Azure Active Directory, SAP SuccessFactors, SharePoint or Databricks.
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 produces evidence for auditors and regulators. The record has to outlive the employment.
It runs on the platform, not on somebody's machine
Continuous assignment and the chase ladder run on the same engine, so a joiner in August is assigned in August instead of at the next annual round.
Evidence is per person per version
With a content hash of what was shown. A link to the current policy proves nothing about what somebody accepted two years ago.
Credentials are managed, never in code
Reading the full employee record to derive assignment is a broad permission. Read-only, scoped, and held in your workspace.
Compliance own the rules
Assignment rules, chase cadence and the material-change decision open in Tray Build, owned by the team that answers the audit.
History outlives employment
Attestations are retained after somebody leaves, because the question is always about the period they worked here.
Questions people ask
Why continuous assignment, not campaigns?
Because a campaign is a snapshot. Everybody who joins afterwards is unattested until the next round, and by the time an auditor asks the gap can be a year wide.
Why record the policy version?
Because an attestation against a superseded policy proves nothing about the current one. Storing a link resolves to whatever the policy says today, which is not evidence of what was agreed.
Why chase only the outstanding?
Because reminding people who already completed is the fastest way to get your messages filtered, and then the genuine escalations go unread as well.
When should a policy change re-trigger attestation?
When the obligation changes. A typographical fix does not, a new requirement does, and somebody records that decision at publish time instead of leaving it ambiguous.
Why not lead with a completion percentage?
Because it sits near ninety five, moves slowly, and hides the one department at sixty percent, which is the only part anybody can act on.
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 vendor security review
Tier on what the vendor can reach, ask questions that match the tier, track conditions to closure, and re-review before the evidence expires. 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 a training completion sync
Assign from role rather than a spreadsheet, carry completions into the HRIS, and produce evidence per person instead of a percentage. The Headless prompts.
Last reviewed September 2026.