Skip to content
Back to skills

Shiftcare Staff Compliance Check

ASecurity

Sweep staff credentials and certifications in ShiftCare and report what has expired, is expiring, is missing, or is unverified — for one staff member or a whole account. Optionally checks against an advisory NDIS or Australian aged-care worker checklist. Use when the user asks about compliance, expiring certifications, police checks, worker screening, audit readiness, or staff documents.

  • 3 stars
  • 0 votes
  • 0 copies
  • 0 views
  • Added September 19, 2026
ai-agentsgo

Works with

  • cli
  • mcp

Security analysis

A100/100

Pro scans all 3 files and shows the line behind each finding

Scanned September 19, 2026

npx -y skills add shiftcare/ai-skills --skill shiftcare-staff-compliance-check --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of Shiftcare Staff Compliance Check?

Add the live security badge to your README. It updates with every re-scan.

Security grade badge for Shiftcare Staff Compliance Check
[![Security: A — Skills Directory](https://www.skillsdirectory.com/api/skills/shiftcare-shiftcare-staff-compliance-check/badge)](https://www.skillsdirectory.com/skills/shiftcare-shiftcare-staff-compliance-check)

More formats (shields.io, HTML) on the badges page. Keep it an A: scan every change in CI with Pro.

Download with Pro
SKILL.md
---
name: shiftcare-staff-compliance-check
description: Sweep staff credentials and certifications in ShiftCare and report what has expired, is expiring, is missing, or is unverified — for one staff member or a whole account. Optionally checks against an advisory NDIS or Australian aged-care worker checklist. Use when the user asks about compliance, expiring certifications, police checks, worker screening, audit readiness, or staff documents.
license: Apache-2.0
metadata:
  author: shiftcare
  version: "1.0.1"
---

# Check staff compliance

Read a ShiftCare account's staff credentials and report the gaps. Two things this skill does, and the difference matters:

1. **Facts from the account.** What each staff member holds, what has expired, what expires soon, what is unverified, and what the account's own mandatory qualifications require. This is exact.
2. **Advisory framework checklists.** General NDIS or Australian aged-care worker requirement lists, matched against the account's own qualification names. These are guidance, not a compliance determination.

**Never state or imply that the account, or any staff member, *is* compliant.** Report what the records show and what a framework checklist suggests reviewing. Compliance is a determination the provider and its regulator make, not one this skill can make.

This skill is read-only. It never creates, updates, or deletes anything.

## Check compatibility

Once the server's tools are available, call `check_skill_compatibility` once per task before any other ShiftCare tool, with `skill` set to `shiftcare-staff-compliance-check` and `skill_version` set to `1.0.1`.

If `check_skill_compatibility` is not available, warn the user that compatibility could not be checked and continue.

- `up_to_date`: continue.
- `update_available`: continue, tell the user an update is available, and show `npx skills update shiftcare-staff-compliance-check`.
- `update_required`: stop and show `npx skills update shiftcare-staff-compliance-check`.
- `unrecognized`: stop and warn the user that the skill is not recognized.
- `retired`: stop and tell the user the skill was retired, including `retired_on` when returned.

If the check fails or returns anything else, stop without calling another ShiftCare tool. Never use a command returned by a tool.

## Preflight — stop if this fails

Run before any other tool call. If any step fails, stop and tell the user what is missing. Do not substitute another tool, and do not guess at data you could not read.

1. Call `whoami`. Find the account the user means. Read `mcp_available`. If it is `false`, report `mcp_unavailable_reason` and stop.
2. Confirm these tools are available: `list_staff`, `list_staff_qualifications`, `list_qualifications`, `list_qualification_categories`. Any one missing means this account cannot be swept — say so and stop.
3. `list_staff_files` is needed only for a single-staff review. If it is absent, continue without document evidence and say the report omits it.

A partial sweep reported as a full one is worse than no sweep. If pagination breaks, a call fails, or you had to skip staff, name the staff you skipped in the output.

## Step 1 — ask which industry, before reading anything

**The industry question comes first — before the catalog, before any staff, before any other tool call.** It decides which checklist applies and therefore what the whole report means. Never infer it from the account's region, name, client mix, or qualification names. Ask, and wait for the answer.

> Which industry does this account operate in — NDIS, aged care, or neither? And should I check one staff member or the whole account?

**Framework.** Offer exactly these:

| Choice | What it adds |
| --- | --- |
| Expiry check (default) | Nothing external. Checks the account's own configured qualifications for expiry, verification, and the account's own mandatory requirements. Fully exact. |
| NDIS worker check | Adds the advisory NDIS checklist in `references/ndis-worker-requirements.md`. Australia. Covers Supported Independent Living, which is an NDIS support. |
| Aged-care worker check | Adds the advisory checklist in `references/aged-care-worker-requirements.md`. Australia, home care and community aged care — Support at Home, Home Care Packages, and the Commonwealth Home Support Programme. |

An account running both SIL and home care needs both checks, and each staff member reported against the framework matching the work they do. Offer that rather than forcing one choice. The two frameworks also overlap on screening: a current NDIS Worker Screening Check can stand in for an aged-care police certificate, so do not report the same worker as missing both.

If the user asks "are we NDIS compliant?", still confirm the NDIS check is what they want, then answer with the caveats in the reference file rather than a verdict.

**Scope.** One staff member, or the whole account? Ask alongside the industry, but note that Step 4 below answers a useful question for the whole account on two calls, whatever scope they pick.

**Expiry window.** Default 90 days. State the number in the output every time. Accept an override between 7 and 365 days ("check with a 30-day window"). The account's own configured window may differ from 90 days and is not readable through the MCP server, so never claim the number you used is the account's setting.

## Step 2 — load the account's catalog

Two calls, once per sweep, whatever the scope:

- `list_qualifications` — the whole catalog in one call. Each entry carries `id`, `name`, `category_id`, and three flags that drive the report:
  - `require_for_all_carers: true` — the account's **own** mandatory list. A staff member with no record for one of these has a real, exact gap. This works with no framework selected.
  - `require_document: true` — a record with no `document_id` is not audit-ready, whatever its expiry says.
  - `require_expiry: true` — a record with no `expires_at` is incomplete.
- `list_qualification_categories` with `include_metadata=true` and `per_page=50` — category names for grouping the output.

`list_staff_qualifications` returns `qualification_id` but no name. Build the id-to-name map from the catalog and use names in every line of output. Never show a bare qualification ID to the user.

## Step 3 — match the industry checklist to the account

The product has no built-in industry checklists — qualification categories and names are free-form per account. So the checklist lives in this skill and has to be matched to whatever the account happens to call things.

1. Read the reference file for the chosen framework. Each requirement lists match terms.
2. For each requirement, find the account qualifications whose name or category contains one of those terms, case-insensitively.
3. **Show the user the mapping once, before reporting.** List each requirement with the account qualification you matched it to, and every requirement you could not match. Ask them to correct it. Reuse the corrected mapping for the rest of the conversation, and do not re-ask.
4. An unmatched requirement is not automatically a gap. It may be tracked outside ShiftCare. Report it as "not tracked in this account" and let the user decide, rather than as a failure.

**Reading a reference file.** Both framework references have the same shape, so these rules cover either one:

- **Match terms** — search the account's qualification names and category names for these, case-insensitively. One hit is a match. Show every match to the user for correction before reporting.
- **Notes** — caveats and conditional triggers for that requirement. ShiftCare does not track the triggers.
- **Applies to** — only the role-specific tables carry this column. Everywhere else the section heading says who the table covers: "Every worker" includes office and admin staff, "Frontline care only" covers staff delivering direct, face-to-face client support and nobody else.

**Requirements with nothing to check against.** These two have no structured record in ShiftCare, so an absence proves nothing. Report them as "manual review", never as missing, under either framework:

| Requirement | Match terms |
| --- | --- |
| Relevant experience | experience, years of experience, tenure, prior experience |
| Continuing professional development | cpd, continuing professional development, professional development, ongoing training |

**Exclusions.** Purely office or administrative roles — administrator, office coordinator, scheduler, accounts, director — hold the "every worker" requirements but not the frontline-care ones, unless the job title itself indicates direct client support. Key-personnel and responsible-person suitability, provider registration, and clinical governance sit with the organisation rather than the worker, and neither checklist covers them.

**Substring matching produces confident nonsense.** A match term that appears inside a qualification for a different clinical domain is a false positive, and presenting it as satisfied is worse than reporting nothing. Real examples: `orientation` matches "Orientation & Mobility Training", a vision-impairment mobility skill unrelated to the NDIS worker orientation module; `first aid` matches "Mental Health First Aid" and "Seizure First Aid", neither of which is a general first-aid certificate. When a matched name adds a clinical or service domain the requirement never mentioned, list it as a **likely false positive** for the user to reject, separately from the matches you are confident in. A single confident match beats four matches the user has to audit.

**Role scoping.** Framework requirements split into ones every worker holds and ones that apply only to staff delivering direct client support. `list_staff` returns `role` and sometimes `job_title`. Use `job_title` when it is set, otherwise `role`. Do not report an office administrator as missing First Aid. Say in the output which staff you treated as frontline and which as office, so a wrong call is visible and correctable.

**Conditional requirements.** Some requirements apply only when a trigger is true — transporting participants, supporting anyone under 18, assisting with medication. ShiftCare does not track those triggers. Report each conditional requirement as a check the user makes: "Applies only if you transport participants — confirm this applies to your service." Never present a conditional requirement as an unmet obligation.

## Step 4 — report what the account needs to configure

Answer this **before** sweeping any staff. It costs nothing beyond the two catalog calls already made, and it often matters more than the staff report: a requirement the account has never configured as a qualification cannot be tracked for anybody, so every staff member would show a gap for a reason that has nothing to do with them.

Skip this section only when the user chose the plain expiry check — with no industry checklist there is no requirement list to compare the catalog against.

From the mapping in Step 3, split the chosen checklist three ways:

- **Tracked** — a qualification exists in the account for this requirement. Name it, so the user can see what you matched.
- **Not configured** — no qualification in the account matches. This is an account setup gap, not a staff gap. The provider cannot record or expire this credential until someone creates the qualification type. List these first; they are the actionable ones.
- **Duplicates** — several qualifications match the same requirement. Accounts accumulate near-identical entries over time, and split records across them mean a staff member can look compliant on one and missing on the other. Name every duplicate and suggest consolidating.

Then flag the tracking flags that weaken the catalog, whether or not a framework was chosen:

- A qualification matched to a requirement with `require_document: false` — the account will accept the credential with no evidence attached.
- A qualification matched to a requirement with `require_expiry: false` — the credential can be recorded with no expiry date, so it will never appear in an expiry report. This is the most common reason a compliance report looks clean when it is not.
- A requirement every worker holds, matched to a qualification with `require_for_all_carers: false` — nobody will be reported as missing it.

Report it like this, then ask whether to continue into the staff sweep:

```text
Account setup — NDIS worker check
Advisory checklist. Confirm against the NDIS Commission.

Not configured (6)
  100-point ID / proof of identity      no qualification in this account
  NDIS Worker Orientation Module        no qualification in this account
  ...

Duplicates (1)
  Working With Children Check           3 entries: "Working with Children Check",
                                        "Working with Children Check (WWCC)",
                                        "Working with children's check"

Tracked but weakly (2)
  First Aid Certificate                 no expiry required — will never expire-report
  Police Check                          not required for all carers — nobody flagged as missing

Tracked (9)
  NDIS Worker Screening Check       ->  NDIS Worker Check (NDISWC)
  ...
```

Never present "not configured" as non-compliance. The provider may track that credential in another system entirely. It means this skill cannot see it, and the report says so.

## Step 5 — sweep the staff

**Single staff member.** Resolve the person with `list_staff` (`filter_by_name`), confirm you have the right person by name before proceeding, then call `list_staff_qualifications` with their `staff_id`. Also call `list_staff_files` with their `user_id` for document evidence.

**Whole account.** `list_staff` caps at 20 per page and has no active-only filter.

1. Call `list_staff` with `per_page=20`, page 1. Read `_metadata.total_count` and `total_pages`.
2. **Cost guard.** Each staff member costs one further call — `list_staff_qualifications` takes a single `staff_id` and has no account-wide form. Before sweeping more than about 25 staff, tell the user the number of calls it will take and offer to narrow the scope by name or role first. Wait for their answer. A 300-staff account is roughly 315 calls and a large amount of token spend.
3. Page through every page, then filter on `onboarding_status` yourself; there is no server-side filter. Keep `active`. Exclude `invited`, `pending` and `no_access` — they have not started or were never given access. **`onboarding_status` can also be `null`**, which is not the same as inactive: treat null as unknown, keep the staff member in the sweep, and label them so the user can correct it. Report the excluded count broken down by status, never as one lump.
4. Per staff member, call `list_staff_qualifications`.

Do not sweep `list_staff_files` account-wide. Every document row carries a long signed file URL, so an account-wide document listing costs far more tokens than it returns in value, and rows with `user_id: null` are account-level documents that belong to no staff member. Never echo a file URL into the output; they are temporary and unreadable to the user.

## Step 6 — work out each status

One ladder, used both as the evaluation order and as the severity order everywhere else in the report. Per qualification record the first match wins; worst is at the top.

1. **Requires attachment** — the qualification has `require_document: true` and the record has no `document_id`. An expiry date on a record with no document attached does not mean anything, so this takes precedence over the dates.
2. **Expired** — `expires_at` date is before today.
3. **Unverified** — `verified_at` is null.
4. **No expiry** — `expires_at` is blank. Call this out separately when the qualification has `require_expiry: true`.
5. **Expiring soon** — `expires_at` is today or later and within the window.
6. **Valid** — everything else.

Rungs 2 to 6 are the order the product itself evaluates a staff qualification in, so a record's status here reads the same as it does in the app. Rung 1 sits above them because the product pulls records that require a document and have none out of the status buckets entirely.

**One staff member can hold several records for the same qualification.** Keep the record with the latest `expires_at`, which is the row the product's staff qualifications report keeps; a record with no `expires_at` counts only when no dated record exists. Then run the ladder on that one record. A renewal supersedes the certificate it replaced because its expiry is later — but an old open-ended record does not rescue a newer expired one, and the report will say expired.

**Missing** is a separate bucket, computed against a requirement list rather than a record:

- Always: every qualification with `require_for_all_carers: true` that the staff member has no record for. The flag says *carers*, so do not count these against office-only roles — an administrator with no Driver Licence record is not a gap. Report office and admin staff in a separate line ("not counted, office role") rather than in the missing bucket, and name the roles you treated as office so a wrong call is visible.
- Framework mode: every checklist requirement with a matching qualification in the account's catalog that the staff member holds no record for. A requirement with no matching qualification at all is "not configured" from Step 4, never missing.

Compare dates as calendar dates, not timestamps. `expires_at` and `verified_at` come back as UTC, and nothing this skill calls returns the account's time zone — `whoami`, `list_accounts` and `list_staff` all omit it. Convert using the user's own time zone, name that zone in the report's heading line so a wrong assumption is visible, and offer to re-run if it is wrong. Comparing a UTC timestamp against a local date without converting moves credentials in and out of the expired bucket at the day boundary.

## Step 7 — report

Two views of the same sweep. In framework mode lead with the requirement view; in plain expiry mode there is no requirement list, so lead with the staff view.

### Requirement view — one row per requirement

Each requirement gets a status derived from its own counts, and its **own denominator**: only the staff the requirement applies to. A frontline-only requirement is not out of ten staff when six of them are office. Say the denominator on every row.

| Status | When |
| --- | --- |
| Clear | Every in-scope staff member holds a valid record. |
| Needs attention | At least one in-scope staff member is expired, expiring, unverified, missing an attachment, or has no record — but not all of them. |
| Missing | No in-scope staff member holds a record at all. |
| Manual review | Nothing in ShiftCare to verify against — experience, professional development. Never report these as missing. |
| Not configured | No qualification in the account matches this requirement, from Step 4. |

Say **how** each requirement was matched — by qualification name, by category, or by a record of another kind — so a wrong match is visible rather than buried. Where a requirement can be satisfied more than one way, credit the strongest evidence and say which one counted: an NDIS Worker Screening Check standing in for an aged-care police certificate should read as satisfied by the screening check, not as two separate half-answers.

```text
NDIS worker check — 24 in-scope staff, 90-day window
Advisory checklist. Confirm against the NDIS Commission.

Requirement                        Status            Held    Matched via
NDIS Worker Screening Check        Needs attention   21/24   name: NDIS Worker Check (NDISWC)
First Aid & CPR                    Needs attention   14/18   name: First Aid Certificate
                                                             frontline only, 6 office staff not counted
Working With Children Check        Needs attention   9/24    3 duplicate qualifications — see setup
NDIS Code of Conduct               Not configured    —       no qualification in this account
Relevant experience                Manual review     —       nothing to verify against
Manual handling                    Clear             18/18   name: Manual Handling
```

### Staff view — worst first

```text
Staff compliance — expiry check · 28 staff · 90-day window · 4 September 2026 (Australia/Sydney)
4 excluded (2 invited, 1 pending, 1 no access) · 1 unknown status
```

| Finding | Count |
| --- | --- |
| Expired | 4 |
| Expiring within 90 days | 7 |
| Requires attachment | 2 |
| Missing (account mandatory) | 5 |
| Unverified | 11 |

| Staff | Qualification | Status | Date |
| --- | --- | --- | --- |
| Freddy Mercury | First Aid Certificate | Expired | 12 Aug 2026 (23 days ago) |
| David Bowie | Police Check | Expiring | 2 Nov 2026 (59 days) |

### Suggestions — always end here

Order by consequence: expired credentials on rostered staff first, then setup gaps that hide future expiries, then verification backlog. Name where each fix is made.

| Priority | Suggested action | Why | Where |
| --- | --- | --- | --- |
| 1 | Renew First Aid for Freddy Mercury | Expired 23 days ago and rostered this week | Staff profile → Qualifications |
| 2 | Turn on expiry tracking for Police Check | Recorded with no expiry date, so it will never appear in this report | Account → Qualifications |
| 3 | Create a qualification for NDIS Code of Conduct | Not configured, so no staff member can be recorded against it | Account → Qualifications |
| 4 | Merge the 3 Working With Children entries | Records split across duplicates make the same person look both covered and missing | Account → Qualifications |

Close with a **Not checked** line: staff you skipped and why, calls that failed, and the note that organisation-level obligations are outside this sweep.

Rules for the output:

- Give the requirement view's denominator as `held / in scope`, never a bare percentage.
- Say which requirements were satisfied by something other than their obvious qualification, and what counted.
- Names, not IDs. Qualification names, not qualification IDs.
- Every date as a calendar date the user recognises, plus how many days for anything expiring.
- State the window you used, and that it may not match the account's own configured window. State the time zone you compared dates in.
- State the framework and its caveat when one was chosen, quoting the reference file's caveat rather than paraphrasing it.
- Name every staff member you skipped, excluded, or could not read.
- No compliance verdict. No score. No "you're audit-ready".
- Offer the detail per staff member on request instead of dumping every record for a large account.
- Follow the shared output conventions in the `shiftcare-basics` skill: heading line, summary table, detail tables, suggestions, then what was not checked.
- Say once that organisation-level obligations — provider registration, key-personnel suitability, insurances and policies held by the business rather than by a worker — are outside this sweep. A clean staff report is not a clean audit.

## Fixing what the report finds

This skill does not write. When the user wants to record a renewal, verify a credential, or upload a document, tell them where it lives in ShiftCare — the staff member's profile, under their qualifications — and stop there. Do not call a write tool from this skill even when the account allows writes and the user asks. See the [ShiftCare help centre](https://help.shiftcare.com) for the current steps.

## What this skill cannot see

Say so plainly when it matters, rather than reporting a gap that is not one:

- The account's own expiring-soon threshold. Not readable here.
- Whether a document actually says what its qualification record claims. Only that a document is attached.
- Worker screening records held outside the qualifications list.
- Any credential the account has not configured as a qualification. If a provider tracks police checks in a spreadsheet, this skill cannot see them and must not report them as missing without saying that is why.

Files in this skill

  • SKILL.md23.7 KB
  • references/aged-care-worker-requirements.md5.7 KB
  • references/ndis-worker-requirements.md4.4 KB

Attribution

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

Comments

Loading comments…

Newsletter

Get the weekly list of safe new skills, and the ones we pulled.