mirror of
https://github.com/MBombeck/HealthLog.git
synced 2026-11-11 13:52:20 +00:00
Screen the whole comprehensive-insight prose surface before it persists
The briefing gate grades numbers only, and only the paragraph, signals and key-findings blocks -- so a digit-free risk assertion with a dose suggestion attached passed it untouched, and recommendations and summary were not graded at all. Screen every readable prose field against the insights contracts. A safety violation cannot be surgically stripped the way an ungrounded number can: the offending sentence may sit in any field, and deleting one would leave the rest referring to it. So the background generator fails the whole run and persists nothing, leaving the previous cached payload in place, while the user-initiated route returns an explicit error for the same reason.
This commit is contained in:
1 parent
70e6e5e374
commit
0becc2a56d
3 files changed
+115
No files matched your search
@@ -58,6 +58,7 @@ import {
|
||||
runRawCompletionWithFallback,
|
||||
} from "@/lib/ai/provider-runner";
|
||||
import { assertConsentForChain } from "@/lib/ai/consent-guard";
|
||||
import { screenInsightPayloadProse } from "@/lib/ai/safety/insight-payload-screen";
|
||||
import {
|
||||
findUngroundedBriefingNumbers,
|
||||
readBriefingBlock,
|
||||
@@ -895,6 +896,26 @@ export const POST = apiHandler((request: NextRequest) =>
|
||||
}
|
||||
}
|
||||
|
||||
// Outbound safety screen over the whole prose surface, before the persist.
|
||||
//
|
||||
// This route is user-initiated but writes the SAME cached payload the
|
||||
// background generator writes, so a violation must not be persisted here
|
||||
// either. The user is waiting, so unlike the background path they get an
|
||||
// explicit error rather than silence -- and because nothing was written,
|
||||
// the previous cached insight is still what the app renders.
|
||||
const screened = screenInsightPayloadProse(insights, locale);
|
||||
if (screened) {
|
||||
annotate({
|
||||
action: { name: "insights.generate.outbound_blocked" },
|
||||
meta: { locale, reason: screened },
|
||||
});
|
||||
return apiError(
|
||||
"The generated insight did not pass the safety check and was discarded. Try regenerating.",
|
||||
502,
|
||||
{ errorCode: "insights.generate.outboundScreened" },
|
||||
);
|
||||
}
|
||||
|
||||
await prisma.user.update({
|
||||
where: { id: userId },
|
||||
data: {
|
||||
|
||||
Reference in new issue
Block a user