Skip to Content
ConceptsCustodian DomainWorkforce Compliance

Custodian Workforce Compliance

Companion to Custodian Compliance (the supply side: what a custodian holds, for whom, and when it lapses) and Custodian Onboarding (how documents become Tier-2 attestations). This adds the demand side: what each person is required to hold, and where they fall short.

Take a large engineering contractor: tens of thousands of staff and subcontractors, working across client sites, each with its own entry rules. The compliance team asks: for this role on this site, what must a person hold? Of the people starting Monday, who is short, of what? What lapses next quarter, so training capacity can be booked? Can we show a client or auditor the state of all of it without handing over documents?

This inherits Custodian Compliance’s guardrails unchanged — a requirement is met only by a custodian’s own attestation, never a stored/cached gap state, never a DID-keyed link, and never a read of the wallet without consent.

Workforce compliance itself still never delivers training — but a gap can now resolve via an assigned online course as well as a proof link or a waiver; see Course Delivery & Retakes (planned) for that capability, which workforce compliance would consume, not own.

Direction, as of 2026-09-28: the product direction is for the custodian portal to grow into a full end-to-end workforce & compliance management platform — compliance (this doc), course delivery/LMS, rostering, and payroll all included. Course delivery is scoped (Course Delivery & Retakes). Payroll and rostering are not — they are a named, unscoped direction only; see Workforce Platform Expansion before treating either as actionable. Nothing in this doc’s existing compliance model (read-only register, attestation-only gap resolution, no cached state) changes because of that direction.

Concepts

Three new concepts, all custodian-owned configuration, never touching the Program Catalog:

  • Group — a named set of people that share requirements: a role, a site, a project, a department, or a contractor cohort. One mechanism, not separate role/site/project models — a person in several groups owes the union of their requirements. kind is cosmetic (icon/filter only, never behavior).
  • Requirement — “members of this group must hold this policy’s credential,” pointing at an existing Credential Catalog entry, with an optional grace period for new starters.
  • Membership — this person is in this group, keyed by the same normalized holder key the roster uses.

Deliberately not introduced: a separate “profile” object (a group already is one), a recommended-vs-mandatory flag (everything is required until proven otherwise), or a group hierarchy (flat until proven insufficient).

Derived state — computed at read time, never stored

If a person owes the same policy through several groups, it’s one requirement row with the earliest due date used — never double-counted. IN_PROGRESS and SCHEDULED are independent flags that annotate a state without replacing it (an expired credential with a renewal already in review still reads EXPIRED + IN_PROGRESS, never a hopeful “in progress” that hides an active lapse). Waived is its own outcome — a time-bound admin-approved exemption, counted separately from MET everywhere a roll-up appears, and never a permanent exemption (every waiver has an expiry).

Portal

People becomes a tabbed page:

TabContent
RosterThe existing People table, plus a Group filter, a Groups column, and a Requirements roll-up badge per person
GroupsGroup list with kind, members, requirements, roll-up split; a group’s own page has a requirements editor and member table
GapsStat tiles (Has gaps / Lapsing soon / Needs action / Requirements met / Waived), a filterable table, per-row Attest credential / Schedule / Request waiver actions, and a CSV report

Every screen naming a requirement state carries the Tier-2 provenance badge and the standard disclosure. Forbidden in this feature’s copy: certified, cleared, qualified, approved, authorised to work, fit for work, verified — a roll-up is always “requirements met” or “has gaps,” with “per credentials attested by ‹organisation›” as the basis line.

Bulk import

The browser parses a CSV client-side; the server never receives a file. email is the required key; groups is a semicolon-separated KIND:Name list. A preview call returns a diff with nothing written (people to add/update, memberships to add, groups to create, per-row errors); a commit call applies exactly that. Import is additive-only — it never removes someone from a group — and idempotent (a blank cell means “leave unchanged,” never “clear”; re-importing the same file is a no-op).

Gap-driven scheduling

An Admin can schedule a single outstanding requirement, or schedule every outstanding requirement in a group in one bulk, best-effort call (capped, idempotent). Automation only ever creates an obligation — never an attestation — and nothing is sent to anyone beyond the existing notification channels an ordinary schedule already uses.

Readiness and forecast

Two pure reads, gating nothing:

  • Readiness (GET /groups/{id}/readiness?on=) — classifies every requirement as of a future date, so a credential that will have lapsed by then reads EXPIRED there. A person is ready when every requirement is MET or EXPIRING_SOON (still standing) on that date.
  • Forecast (GET /forecast?months=) — per month and group, which attested credentials reach expiry and which NOT_YET_DUE requirements fall due — reports demand for booking training capacity; it books nothing and notifies no one.

Consented evidence and client-facing proof

A custodian can ask a holder to share a credential they already hold (through the same consent flow as Custodian Compliance), or a holder can push a credential straight into a custodian’s intake unprompted. Either way, the shared credential lands as a CONSENTED_SHARE/EVIDENCE intake item — no document bytes, and it goes through review → attest like any other document; a requirement is met only by the custodian’s own attestation, never by the presented credential alone.

Separately, a holder can create a signed, expiring, revocable proof link: a snapshot of selected requirement states (never documents) shared with a named recipient, only after the holder’s explicit consent. The wallet resolves only a custodian-provided group context against the signed-in holder’s own membership — it never lists or browses workforce groups. Revocation is immediate; expiry is required (maximum one year).

Contractor groups

CONTRACTOR is a cosmetic group kind for people employed by another company. Creating one requires the Admin to confirm a lawful basis (audited), and the portal links to the contractor-specific privacy-policy section.

Out of scope

Within-custodian roster duplicates (the same real worker entered twice under two email addresses on one custodian’s own roster) are a separate data-entry problem this feature does not solve — see Cross-Wallet Identity Consolidation for the cross-wallet fragmentation problem this is sometimes confused with.