Who can do what on Notes & Audit
Who is admitted
Two groups of actions, ten in total, split across two shared rules.
| Group | Actions | Rule |
|---|---|---|
| Notes | 6 | Staff, a site director, an organisation administrator or a super admin |
| The audit trail | 4 | A site director, a regional director, an organisation administrator or a super admin |
Neither group narrows or widens its rule further at the individual-action level, and neither is open to anyone who has not signed in. That makes two shared rules the entire access story for both modules.
One rule that no written policy actually expresses is enforced inside the action itself rather than as a gate in front of it: editing or removing a note requires the note's own owner, or a super admin. See ownership.
Notes, 6 actions
Shared rule: Staff, a site director, an organisation administrator or a super admin.
| Action | What it does | Reachable by |
|---|---|---|
| List notes | Every note in the organisation, optionally filtered by what it is attached to, pinned first, then newest first, with no limit on how many | Notes; the Notes area wherever it is shown |
| Read one note | One note. No ownership check and no check that it is attached to what you expect | Built, and nothing calls it |
| Create a note | Creates a note. Its title is worked out automatically from the first 100 characters of the content; owner and author are your own account | Notes, Create Note |
| Update a note | Updates the content and category, and re-derives the title. Owner or super admin only | Notes, the edit icon |
| Remove a note | Keeps the record and marks it removed. Owner or super admin only | Notes, the removal icon |
| Toggle pin | Flips whether a note is pinned. No ownership check of any kind | Notes, the pin icon |
Every one of the six writes a matching audit entry in the same save.
Ownership
Updating and removing a note both apply the same rule: your own account owns the note, or your account is a super admin, or your account holds a role named "Admin".
"Admin" is not a role PTRS actually has. The seven it does have are super admin, organisation administrator, regional director, site director, Staff, guardian and read-only. Nothing grants that third clause to anyone, so the rule that actually applies is: the note's own owner, or a super admin. An organisation administrator cannot edit or remove a note written by a colleague who has since left.
Toggling pin has no such check at all, so anyone who can manage members can pin or unpin any note in the organisation. Reading one note by its own id has no ownership check either, and no check that it is attached to what a reader would expect; the organisation boundary keeps both inside the organisation and no further.
Field rules
Four checks cover six actions; the two reads have none.
| Field | Rule |
|---|---|
| Content | Required, up to 50,000 characters |
| Category | Optional, up to 100 characters, plain text |
| Attached-to type | Optional, up to 100 characters, plain text |
| Attached-to id | Optional, unconstrained |
| Title | Not accepted from whoever is writing the note; worked out automatically from the first 100 characters of the content, and returned by no read |
Updating a note applies the same content and category rules; removing a note and toggling its pin only check that the id itself is present.
There is no fixed list of categories on PTRS's own side, so the ten choices the screen offers can never disagree with what PTRS accepts; PTRS accepts any text at all. This module cannot produce the mismatch several other modules have between a screen's own dropdown and a fixed list PTRS actually enforces, and it does not.
The audit trail, 4 actions
Shared rule: a site director, a regional director, an organisation administrator or a super admin.
| Action | What it does | Reachable by |
|---|---|---|
| List entries | Paged entries with optional filters for record type, record id, start date, end date and search. Returns a paged result | The audit trail; the incident detail screen's own audit panel |
| List activity | A paged activity feed for the organisation | Nothing today |
| List one person's activity | The same, limited to one person | Nothing today |
| Verify | Replays the fingerprint chain and reports the first break | The audit trail, Verify Integrity |
All four refuse when the account has no organisation, and all four add their own explicit organisation limit by hand.
The identity mismatch two of the three reads share
The person behind an audit entry is stored as their sign-in identity, not their PTRS account id. Listing entries resolves this correctly, joining on the right identifier.
Listing activity, and listing one person's activity, both join on the wrong identifier instead, a PTRS-generated id rather than the sign-in identity. The two are never the same value, so neither join can ever match.
Both then fall back to a stored email address, and nothing ever actually writes that field either. So the resolved name is empty on every row of both of these two reads.
This is latent today because nothing calls either, but it is the exact same mistake the Notes module makes in all three of its own read paths, where it is not latent at all.
Summary
| Notes | The audit trail | Total | |
|---|---|---|---|
| Reachable from a screen | 5 | 2 | 7 |
| Not reachable from any screen | 1 | 2 | 3 |
| Total actions | 6 | 4 | 10 |
Reading one note by its own id is built, with a working client function and hook, and nothing calls it. Listing activity and listing one person's activity are the same shape: both built, both with a working client function and hook, and nothing calls either.
A paged result described to the screen as a plain list
Both of the two unreached audit reads return a paged result: items, a total count, the current page and the page size.
The screen-side code describes both as a plain list instead, with no paging fields at all.
This is the third time this exact mismatch has been recorded across this documentation site. It is latent because neither has a consumer yet; the moment one was added, it would either show an empty list over real data, or fail outright trying to read the list directly.
The one audit read that is actually used describes its own paged result correctly, so the one in use is right and the two that are not are wrong.
What the audit screen sends to PTRS, and what it does not
| Filter | Sent to PTRS | Applies to |
|---|---|---|
| Search | Yes | The whole log: description, resolved name, record id |
| Start date | Yes | The whole log |
| End date | Yes, with the day's final second included | The whole log |
| Page | Yes | Not applicable |
| Action | No | Only the 50 rows already on screen |
| Record type | No, even though PTRS can filter by it on its own side | Only the 50 rows already on screen |
Both dropdowns also build their own choices from the rows already on screen, so a value that is not on the current page is not even offered.
What is captured in the record, and what is never written
The saved record has fifteen fields.
| Field | Actually written? |
|---|---|
| Id, timestamp, organisation, site | Yes |
| What happened, kind of record, record id, who made the request | Yes |
| Description | Yes, for an activity entry |
| Values before and after | Yes, for a tracked change |
| Where the request came from | Yes |
| The two chain fingerprints | Yes |
| Their email | Never |
| A trace id | Never |
| Which part of PTRS made it | Never |
The buffered activity record carries both a specific action name and which part of PTRS logged it, and neither is copied onto the saved record. The saved record has no field at all for the specific action name, so every activity entry is saved with the fixed word Activity, and its real name survives only inside the description sentence.
The only rows that carry a value for which part of PTRS made them are the handful written directly as a development copy's own starter data. Any search built around that field matches nothing in a real installation; a user's own activity log elsewhere in Administration happens to be exactly that kind of search.
Neither of the two "values before and after" fields is returned by any read, so what actually changed is captured and never shown on any screen.
Why both modules scope themselves by hand
PTRS gives most record types an automatic organisation boundary. That automatic boundary only applies to a record type built a specific way, and the saved audit entry is deliberately not built that way, because it must never be changed or removed once written.
A note is built the ordinary way, so its own organisation boundary is automatic.
The saved audit entry is not, so it is skipped by that automatic mechanism entirely, and all four audit actions add their own explicit organisation limit by hand, refusing outright when the account has none. That is the same discipline the account-management actions apply to account records elsewhere in Administration; both are the two record types in PTRS that know their own automatic boundary does not cover them, and both compensate for it themselves.
Written messages these two modules do not actually use
The Notes module has three ready-made failure messages: a missing note, a missing organisation, missing content. None is actually used; every action writes its own failure inline instead.
The audit module has one ready-made message, for a missing organisation, and all four of its actions actually use it. The contrast is the point: the one module whose documented message is small is also the one that actually returns it.
The two checks against the two rules
| Screen | Wider, first check | The screen's own check | The actual rule | Who the screen admits and the rule refuses |
|---|---|---|---|---|
| Notes | The four administrator roles plus Staff and a read-only account | None; the screen only hides the New Note button and the per-card controls | The note-management rule | A regional director, a read-only account |
| The audit trail | The same six | The reporting bucket, which also includes a read-only account | The reporting rule | A read-only account |
Both fail visibly: the audit trail shows a clear failure message with detail, and notes shows a clear failure message too, rather than the empty list several other modules would show in the same situation. That is the mild form of this divergence.
Two kinds of note
| This module's note | The Members module's note | |
|---|---|---|
| Attached to | Anything, by a type and an id | A specific member, directly |
| Category | Plain text | A fixed, typed list |
| Confidentiality | None | A flag |
| Follow-up | None | Required, a date, and completed |
| Communication | None | Direction and method |
| Pinning | Yes | Yes |
| Ownership | Enforced on edit and removal | None |
| Read on | Notes | The child's own record |
Both can hold a staff note about a child. Neither module reads the other's notes, so a note written in one place is invisible in the other, and a note written here can never be marked confidential.
Checked against PTRS on 7 September 2026.