AI Safety-Scanner Enforcement Automation: A Toggle That Saved, Read Back, and Blocked Nothing

Why a setting that saves correctly can still do nothing at all
A settings toggle that saves, persists across reloads, and even passes an automated test proving it persists looks, by every normal measure, like a working feature — persistence is usually the hard part to get right, and a passing test for it is real, reassuring evidence. What a persistence test can't tell you is whether anything downstream actually reads that setting at the moment it matters. A toggle can be perfectly, verifiably saved and simultaneously completely inert, and the gap between those two facts is invisible from the settings screen itself — it only becomes visible by tracing whether the real, live code path that's supposed to respect the setting actually asks for its value.
How the underlying problem shows up before you fix it
A safety or moderation toggle saves and displays correctly, and a test confirms it persists, but the feature it's supposed to control never actually consults it during real operation.
A scanning or checking function only ever gets called from its own settings/testing page, when someone manually tries it — never from the actual live path the setting is meant to govern.
An audit log records that an action was "blocked" at a point in the code where no blocking mechanism exists anywhere yet — the log entry describes something that structurally cannot have happened.
A ranking or severity comparison silently treats an unrecognized value as the safest, least-severe option, rather than flagging it as unknown or treating it with maximum caution.
A feature's test suite thoroughly covers the parts that are easy to verify (does the setting save? does it read back correctly?) while never testing the part that actually matters (does anything real change when the setting is on?).
Why a working settings screen and a working feature are two separate things to verify
Building and testing a settings screen — the form, the save call, the read-back, a persistence test — is a genuinely complete, verifiable piece of work on its own, which is exactly why it's easy to treat as proof the whole feature works. The setting only becomes meaningful the moment something else in the codebase actually branches its behavior on that stored value, and that wiring is a structurally separate piece of work that a settings-focused test never touches. When that second half never gets built, everything that WAS built continues to work exactly as tested — the setting still saves, still reads back, still shows the right toggle position — while doing nothing whatsoever for the actual behavior it claims to govern.
How Centriu Axiom connected the toggle to the actual AI path — and fixed a compounding audit-log lie
The gap was found as part of the same internal audit that rewrote Axiom's proof-of-action mechanism (covered on this pillar's companion page): a recurring pattern of a feature not yet fully wired presenting itself as complete. For the Safety Scanner specifically, the audit's own account is direct — the three settings (auto-scan prompts, auto-scan outputs, block on high threat) were correctly saved and read, with a passing persistence test to prove it, but the underlying `scan()` function was only ever invoked from the scanner's own settings page, when a person pasted text in to test it manually. The real AI conversation path — where prompts are actually sent and responses actually received — never called it at all. No prompt was ever automatically scanned, no output was ever automatically scanned, and nothing was ever actually blocked, regardless of what the toggle said.
A second, specific defect compounded the first: when that manual test scan found a threat, the existing code logged an audit event of type `safety_scan_blocked` — even though, at that point in the code's history, nothing anywhere had an actual blocking mechanism. The audit trail was recording a block that structurally could not have happened. An audit record describing an event that never occurred is worse than a missing record, because an audit record is specifically the thing people read as proof something happened.
The fix adds a new function, `scanAndEnforce()`, that checks the org's actual configuration, runs the real scan, and — critically — is confirmed by direct inspection of the current `hooks/useSession.ts` file to be genuinely called on both the real prompt-sending path and the real AI-output path, not just described as fixed in a historical commit message. It is now the ONLY code path in the entire scanner that is allowed to log a `safety_scan_blocked` event, and it does so only at the exact moment a block genuinely occurs — with the audit log write placed deliberately before the function throws, so the record exists even if whatever calls it doesn't handle the resulting error. The function also fails closed on a specific edge case: if the scan itself can't be completed for some reason and the organization's policy requires blocking on high threat, the request is refused rather than allowed through on the assumption that no news is good news.
A related, separate defect in the same file was fixed alongside it: the function computing a conversation's overall threat level compared detected threats' severity using `array.indexOf()` against a fixed severity list. An unrecognized severity value — a custom pattern an organization configured with a severity value outside the expected set, or a legacy database row — returns -1 from `indexOf()`, and -1 is never greater than the initial running maximum of 0, so an unrecognized threat silently ranked as the least severe possible outcome: safe. The fix replaces the array-and-indexOf approach with a closed, exhaustive mapping from every valid severity to a numeric rank that TypeScript's own type system forces to stay complete, with any value genuinely unrecognized at runtime now explicitly ranked as the MOST severe category rather than falling through to the least.
What is actually built today
A single enforcement function, confirmed genuinely called from both the real AI prompt-sending path and the real AI-output path, replacing a scanner that only ever ran from its own manual test page.
That function is now the only code path in the scanner allowed to log a genuine block event to the audit trail, and only when a block actually occurs.
A fail-closed rule: if the org's policy requires blocking on high threat and the scan itself cannot be completed, the request is refused rather than allowed through by default.
A closed, exhaustive severity-ranking structure replacing an array-and-`indexOf()` approach that silently treated any unrecognized severity as the safest possible outcome.
Any genuinely unrecognized runtime severity value now explicitly ranked as the most severe category rather than falling through to the least severe by default.
The audit trail no longer records a block event at any point where blocking could not have actually occurred.
A high-threat prompt actually stopped, not just logged (illustrative scenario, not a real client)
Someone sends a prompt containing a pattern the org has configured as high-severity, with the "block on high threat" setting turned on. Before the fix, that setting had no bearing on what actually happened — the prompt reached the AI regardless, because nothing in the real path ever checked the setting. After the fix, the same prompt is genuinely intercepted before it reaches the AI, and the block is both enforced and honestly recorded — not one without the other.
What changes operationally
A safety setting an administrator turns on now genuinely changes what happens to real prompts and real AI responses, rather than only changing what a settings screen displays. And because the audit trail can now only record a block when a block genuinely occurred, a compliance reviewer reading that log is reading a description of real events, not a record that could describe something that structurally never happened.
When this is not the right fit
This fix makes an existing, org-configurable safety policy actually enforceable — it does not add new threat-detection patterns beyond what the scanner already checked for, and it does not replace an organization's own judgment about which patterns to configure as high-severity in the first place. A team expecting an expanded built-in threat library from this specific fix will not find that here; what changed is that the existing scanning and blocking logic is now genuinely connected to the real conversation.
A setting that persists vs. a setting that is actually consulted
Building and testing a settings screen thoroughly is real, necessary work — but it proves only that the setting is stored correctly, never that anything downstream actually reads it at the moment that matters. Centriu Axiom's fix closes exactly that gap: the same three settings that always saved correctly are now genuinely read and enforced on the real path they were always meant to govern, verified directly against the live code rather than assumed from the settings screen working as designed.
Related systems
Main system: Centriu Axiom.
What it does NOT do
- Does not let the "block on high threat" setting exist purely as a display value — the real AI prompt and output paths now genuinely consult it via a single enforcement function, confirmed against the current code.
- Does not log a `safety_scan_blocked` audit event unless a real block genuinely occurred — that log write is now confined to the one function capable of actually blocking anything.
- Does not silently rank an unrecognized threat severity as safe — an unrecognized value is now explicitly treated as the most severe category, not the least.
- Does not allow a request through by default when the scan itself fails and the org's policy requires blocking on high threat — the request is refused rather than assumed safe.
- Does not add new threat-detection signatures beyond what already existed — the fix is scoped to actually enforcing the existing scan and policy, not expanding what is detected.
- Does not treat a passing persistence test as proof the feature works end to end — this fix exists precisely because that assumption was wrong for nearly two months in production.
Security and governance
The scanner's block decision is now enforced on the actual code path handling AI prompts and outputs, not only on a settings page. Audit log entries describing a block are written only when a block genuinely occurs. Any personal or business data referenced in a scanned prompt or output remains subject to Brazil's LGPD (Law No. 13,709/2018). Full detail on access control lives at /governanca and /iso.
Pricing and contracting
Available by monthly subscription, with tiered plans. Values and terms come from the official pricing table at /precos (Centriu's central source — never restated here).
Frequently asked questions
Did the Safety Scanner settings actually save correctly before this fix?
Yes — the three settings saved, read back correctly, and even had a passing automated test confirming persistence. The defect was that nothing in the real AI path ever consulted the stored values.
What exactly changed to make enforcement real?
A new function, confirmed genuinely called from both the real prompt-sending and AI-output code paths, now runs the scan and enforces the org's actual policy — replacing a scan that only ever ran from the scanner's own manual test page.
What was wrong with the audit log specifically?
When a manual test scan found a threat, the code logged a "blocked" event even though nothing in the code had a blocking mechanism yet — the audit trail recorded an event that structurally never happened.
What is the fail-open severity bug that was also fixed?
Threat severity was ranked using `array.indexOf()`, which returns -1 for an unrecognized value — and -1 never beats the initial maximum of 0, so an unrecognized threat silently ranked as harmless. It now ranks as the most severe category instead.
What happens if the scanner itself fails to run and the policy requires blocking?
The request is refused rather than allowed through — the fix fails closed specifically for this case, rather than assuming no scan result means no danger.
What does Centriu Axiom cost?
It is sold by subscription with a published starting price — exact current values are on the central pricing page.
See how Centriu Axiom actually enforces its AI safety policy
Reach our commercial team directly, or leave your details below — we'll follow up with guidance for your case.