-
Notifications
You must be signed in to change notification settings - Fork 0
fix: codebase-review remediations (clinical-path numeric-verify, coalescing, security hardening) #510
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
fix: codebase-review remediations (clinical-path numeric-verify, coalescing, security hardening) #510
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,23 @@ | ||
| import { timingSafeEqual } from "node:crypto"; | ||
| import { env } from "@/lib/env"; | ||
|
|
||
| // Shared operator gate for internal health/status detail. A caller proves it is an operator | ||
| // (not an anonymous internet client) by presenting HEALTH_DEEP_PROBE_SECRET via the | ||
| // `x-health-deep-token` header. Used by /api/health (deep Supabase probe) and | ||
| // /api/setup-status (detailed setup checks) so both surfaces gate internal error text and | ||
| // project posture behind the same secret. Constant-time compare; fails closed when the secret | ||
| // is unset or the token length/value differs. | ||
| export function allowDeepHealthProbe(request: Request): boolean { | ||
| const secret = env.HEALTH_DEEP_PROBE_SECRET; | ||
| if (!secret) return false; | ||
| const token = request.headers.get("x-health-deep-token"); | ||
| if (!token) return false; | ||
| // Compare UTF-8 BYTE lengths, not JS string (UTF-16 code-unit) lengths: a crafted multi-byte | ||
| // token with the same code-unit count but a different byte count would otherwise pass a | ||
| // `token.length === secret.length` check and make timingSafeEqual throw on mismatched buffers | ||
| // (an unhandled RangeError → crafted-header 500). Build the buffers first, then length-gate. | ||
| const expected = Buffer.from(secret, "utf8"); | ||
| const received = Buffer.from(token, "utf8"); | ||
| if (expected.length !== received.length) return false; | ||
| return timingSafeEqual(expected, received); | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -69,6 +69,7 @@ import { | |
| cacheIndexingVersion, | ||
| cloneAnswer, | ||
| getCachedAnswer, | ||
| attachAdjacentContext, | ||
| getCachedSearch, | ||
| getSharedCachedAnswer, | ||
| getSharedCachedSearch, | ||
|
|
@@ -3611,15 +3612,22 @@ export async function answerQuestionWithScope(args: AnswerQuestionWithScopeArgs) | |
| message: "Waiting for an identical cited answer request already in progress.", | ||
| reason: "answer_inflight_coalesced", | ||
| }); | ||
| const answer = cloneAnswer(await existing); | ||
| answer.routingReason = answer.routingReason | ||
| ? `${answer.routingReason}; answer_inflight_coalesced` | ||
| : "answer_inflight_coalesced"; | ||
| answer.latencyTimings = { | ||
| ...answer.latencyTimings, | ||
| total_latency_ms: Date.now() - startedAt, | ||
| }; | ||
| return answer; | ||
| try { | ||
| const answer = cloneAnswer(await existing); | ||
| answer.routingReason = answer.routingReason | ||
| ? `${answer.routingReason}; answer_inflight_coalesced` | ||
| : "answer_inflight_coalesced"; | ||
| answer.latencyTimings = { | ||
| ...answer.latencyTimings, | ||
| total_latency_ms: Date.now() - startedAt, | ||
| }; | ||
| return answer; | ||
| } catch { | ||
| // The in-flight request we coalesced onto failed — most often because the ORIGINATING | ||
| // caller aborted mid-flight (its AbortSignal is not ours) or its search phase threw. Do | ||
| // not propagate another caller's failure to this still-connected request: fall through to | ||
| // an independent, uncoalesced run so this request is decided only by its own inputs. | ||
| } | ||
|
Comment on lines
+3625
to
+3630
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
When two or more identical callers are awaiting the same Useful? React with 👍 / 👎. |
||
| } | ||
|
|
||
| const pending = answerQuestionWithScopeUncoalesced(args, startedAt).finally(() => { | ||
|
|
@@ -4640,6 +4648,11 @@ ${qualityRetryInstruction}` | |
| // citations from the retrieved results, so trigger recovery whenever the | ||
| // generated answer is unusable and we have retrieved results to extract from. | ||
| const canRecoverExtractively = !usedStrongModel && (answer.citations.length > 0 || answerInputResults.length > 0); | ||
| // Numeric faithfulness at finalize time must verify against the packed context the model | ||
| // actually generated from, not the unpacked answer.sources — otherwise a figure copied from | ||
| // a neighbour chunk's adjacent_context reads as unverified and blanks a correct dose/threshold | ||
| // answer. Only the model path needs this; the extractive branch verifies against its own sources. | ||
| let numericVerificationSources: SearchResult[] | undefined; | ||
| if (canRecoverExtractively && isUnusableGeneratedAnswer(answer)) { | ||
| answer = buildExtractiveAnswer({ | ||
| query: args.query, | ||
|
|
@@ -4661,6 +4674,7 @@ ${qualityRetryInstruction}` | |
| } else { | ||
| answer = boldRagAnswerHighYieldText(answer, args.query); | ||
| answer.sources = answerInputResults; | ||
| numericVerificationSources = attachAdjacentContext(answerInputResults, packedContextResults); | ||
| answer.quoteCards = reconcileQuoteCards(answer.quoteCards, answerInputResults, args.query); | ||
| answer.documentBreakdown = documentBreakdown; | ||
| answer.evidenceSummary = evidenceSummary; | ||
|
|
@@ -4692,7 +4706,7 @@ ${qualityRetryInstruction}` | |
| ...retrievalDiagnostics, | ||
| routeMode: answer.routingMode ?? retrievalDiagnostics.routeMode, | ||
| }); | ||
| answer = finalizeRagAnswerQuality(answer, args.query, queryClass); | ||
| answer = finalizeRagAnswerQuality(answer, args.query, queryClass, numericVerificationSources); | ||
|
|
||
| if (args.logQuery !== false) | ||
| await logRagQuery({ | ||
|
|
||
Uh oh!
There was an error while loading. Please reload this page.