Skip to content

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

  1. System Workday
  2. Step Assign by rule
  3. Step Version the policy
  4. Step Chase the outstanding
  5. System Evidence store
Also Slack

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. 1

    Assignment rules run continuously

    Department, role, level, location and system access decide who needs which policy.

  2. 2

    A joiner is assigned on their start date

    Not at the next annual round, which is where the gap comes from.

  3. 3

    The exact version is shown and recorded

    With a hash, so what was accepted is reconstructable years later.

  4. 4

    Chasing targets only the outstanding

    Escalating to a manager rather than reminding everybody.

  5. 5

    A material change re-triggers attestation

    A typo fix does not; a change of obligation does, and somebody decides which it is.

  6. 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. 1

    First, make assignment a rule, not a list

    A list is a snapshot and joiners are missing from it.

    Headless skills build-workflow

    Use 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. 2

    Version what was accepted

    An attestation against a superseded policy proves nothing about the current one.

    Headless skills build-workflow

    Use 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. 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. 4

    Handle change, leave and exceptions

    A silent policy update makes every prior acceptance meaningless.

    Headless skills tray-gotchas tray-patterns

    Use 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. 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. 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

Slack

Assign, remind and escalate, reaching only the people who are actually outstanding.

Writes

Vanta

Push completion evidence in, so the attestation control is answerable from where audits are.

Writes

Snowflake

Land attestation history per person per version, retained beyond employment.

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)

Last reviewed September 2026.