Goal Evidence Engine

Security

Security

Goal Evidence Engine holds care records about people with disability. This page says how it is built, what is tested, and what is not finished. The last part is the part worth reading.

How it is put together

The app is a single web application. There is no separate mobile app to keep patched. Workers add it to the home screen on their phone and it behaves like an app from there.

Every screen and every action runs on the server. The phone holds no keys and talks to no other company. When there is no signal, notes are kept on the phone and sent when it comes back.

The application runs in Sydney. The database is in Sydney. Records do not leave Australia except for the report drafting described below and on the privacy page.

Keeping organisations apart

Every record carries the organisation that owns it. Every read and every write in the application filters on it, and the organisation is worked out on the server from who is signed in. It is never taken from the address bar, from a request body or from a token, because all three can be edited by whoever holds them.

The database also carries membership policies as a second layer. We will not tell you those policies are what keeps two providers apart, because the application connects with an account that bypasses them. The boundary that runs in production is the application code, so that is the thing that gets tested.

How it is tested. A database test suite of at least 121 assertions signs in as a user of one organisation and asserts they get zero rows of another organisation's data, on every table that holds any. A separate check reconciles every record in every such table against its owning organisation and fails on a single stray row. Both run on every change, alongside at least 201 browser tests that drive the real app and at least 893 unit tests. Those are floors a build is not allowed to drop below, so the real numbers are higher. A change that opens a hole between two providers fails a test rather than reaching anyone.

Getting in, and being locked out

  • Everything behind sign-in. There is no anonymous read of anything.
  • A worker is invited by their coordinator. An invite is a record, and what it grants is read from that record rather than from anything the person claims.
  • Sign-in codes are only ever sent to an address that already has an invite waiting.
  • Repeated failed sign-ins are recorded and slowed down. A person can be signed out of every device at once when they leave, and their access ends on their next request rather than whenever a token happens to expire.
  • Coordinators can be required to use a second step at sign-in.

What cannot be changed

A submitted shift note cannot be edited, by anyone, including us. Neither can a link between a note and a goal. The database refuses it, not the application, so there is no route and no screen that can get around it. A mistake is corrected by adding a correction, so both stay visible. The one deletion path is clearing a provider's whole workspace at their request, which needs an administrator account and a second code. Single notes cannot be deleted at all.

Every quote shown as evidence for a goal is checked, character by character, against the note it came from before it can exist. A claim the check cannot back is held out of the report the worker copies. That check proves the words are really there. Whether they show real progress is a human call, which is what the review step is for.

Who approved a report, and when, cannot be rewritten once it is recorded. Who opened which participant record, and when, is logged and cannot be edited.

Encryption

  • In transit: HTTPS everywhere, with strict transport security.
  • At rest: full disk encryption on the managed database.
  • A backup copy is encrypted on the machine that makes it, before it goes anywhere. See the backups section for what is and is not running today.
  • Passwords are never stored. Sign-in is handled by the managed authentication service.

The AI part, and its limits

The draft narrative of a shift report is written by Anthropic's model, in the United States. Four things bound it.

  • It is never on the write path. A worker can save a shift note with the AI service completely down. Capture does not call a model at all. That is tested two ways on every change, once with the feature switched off and once with the service made unreachable.
  • Contact details are stripped first. Phone numbers, email addresses and long identifying numbers are removed from the text before it is sent, and the number of removals is counted. The removed values are never logged. This reduces what is exposed. It does not make a shift note anonymous and we do not say it does.
  • No training, and a short retention. Anthropic is contractually barred from training on this content, and deletes it within 30 days by default. Sessions their safety systems flag can be held up to two years.
  • A person reads every report before it is saved. The support worker who was on the shift checks the AI draft and saves it in their own name, and that name and time are kept with the report. Where a coordinator has also approved one, their name and date are saved with it too. Every artefact that leaves the app says it was drafted with AI.

Report writing can be switched off from a phone in under two minutes without stopping anyone from recording a shift.

Backups, and the number we will not make up

Read this one carefully. The database provider takes a daily backup and keeps seven days of them. A script takes a separate encrypted copy off that provider entirely, because a deleted project takes its own backups with it, and that script is run by hand rather than on a schedule. That last part is the weak one, and it is being fixed rather than described away.

Point-in-time recovery is not enabled. It would bring the worst case down from about a day to a couple of minutes. It is a paid add-on that replaces the daily backups rather than adding to them, and it is not switched on, so the worst case stands: if this database ever has to be restored from a backup, up to a day of shift notes is gone. That is the number to plan around, and it is why a worker's phone keeps an unsent note until the app confirms it is saved.

Last restore drill: none has been run. There is a written, repeatable restore procedure. It has not been run end to end with a stopwatch, so there is no recovery-time figure on this page. When the drill is run, the measured number goes here and into customer contracts. Until then we would rather publish this sentence than a number nobody measured.

Subprocessors

Everyone who touches customer data, what they do, and where they are.

SubprocessorWhat they doLocationWhat limits it
SupabaseThe database, the sign-in service and the audit tables. Every note, report and goal is stored here.Australia (Sydney, ap-southeast-2)This is where the records live. They are not copied to any other region.
VercelRuns the application itself. Handles each request and renders each screen.Australia (Sydney, syd1) for the application. Static files are served from a worldwide network.Notes and reports are not stored here. They pass through in memory while a request is served.
AnthropicWrites the draft narrative of a shift report from the worker's own recorded notes.United StatesThis is the one place your content leaves Australia. See the section below, which states it plainly rather than burying it.
UpstashCounts requests, so that one account or one address cannot flood the app or burn the shared sign-in code budget. It holds counters and the identifier each counter is against: a user id, an organisation id, an email address on the sign-in path, and the network address a request came from.The region this project's counter store was created in.No note, no report, no goal and no participant record is in it. Counters expire on their own within the window they pace. It is not a copy of anything.

We will tell customers before adding a subprocessor that will hold their content, so they have a chance to object.

If something goes wrong

Customers are told within 48 hours of us becoming aware of any actual or suspected security incident affecting their data. We give them what they need for their own assessment: what happened, what kinds of information were involved, what we have done and what we recommend.

The decision about whether to notify individuals and the Information Commissioner is the provider's, because the records are theirs and they are the ones with the legal duty. We support that decision. We do not make it for them and we do not delay it.

There is a written incident procedure covering severities, who is called, the switches that stop things quickly, and how to roll back a bad release.

What is not done yet

A security page that lists only good news is not worth reading. As at the date below:

  • No formal certification. No ISO 27001, no SOC 2, no independent penetration test.
  • No restore drill has been run, so there is no recovery-time figure.
  • The off-site copy of the database is run by hand rather than on a schedule. The provider's own daily backups are running. The one that depends on somebody remembering is not.
  • Point-in-time recovery is not enabled, so restoring from a backup can cost up to a day of shift notes.
  • Report drafting happens in the United States. There is no Australian option for it today.
  • This is a small operation. There is no 24 hour security team. There is a person who answers, a written procedure, and switches that can be thrown from a phone.

Each of these is a decision with a cost attached rather than an oversight, and each one moves as the product does. Ask and we will tell you where any of them stands today.

Reporting a vulnerability

If you find a security problem, tell us and we will not come after you for looking. Write to the Privacy Officer at xmbraithwaite@gmail.com with enough detail to reproduce it. We will acknowledge it within two business days and tell you what we are doing about it.

Please do not access, change or keep anyone else's data while you are testing, and please give us a chance to fix it before you publish.

Using this with a screen reader or a keyboard

WCAG 2.2 AA is what we build against. We do not claim to have met it, because no one has audited the whole product against it, and a target is not a result.

What is built, and checked by the test suite on every change: every screen can be reached and operated from the keyboard, and each one starts with a link that skips past the navigation to the content. Every screen marks its main area, so a screen reader can jump straight there. A field that is refused says so through its own control rather than in a message that merely sits near it. Text is checked against a contrast ratio of at least 4.5 to 1 on the colour actually behind it, read from the rendered page rather than from the palette. Anything that moves holds still for a reader whose device asks for less motion. Controls you tap are at least 44 pixels on both sides.

If something here gets in your way, write to the Privacy Officer at xmbraithwaite@gmail.com and say what you were trying to do and what happened instead. A barrier is treated as a bug, not as feedback.

Effective 15 September 2026 · version 1.0

Questions about any of this go to the Privacy Officer at xmbraithwaite@gmail.com. The privacy policy covers what is collected and why.