Skip to content

Commit b7f9cab

Browse files
Sync public snapshot from freebuff-private
Source: CodebuffAI/freebuff-private@f23663064303affaafc132292952be7432ad78c2
1 parent de0ef2f commit b7f9cab

3 files changed

Lines changed: 163 additions & 0 deletions

File tree

‎.gitignore‎

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,9 @@ npm-app/src/__tests__/data/
2525
debug/
2626
.context/
2727
docs/bot-detection.md
28+
# Issue-specific plans/specs belong in Linear, not the repository. Existing
29+
# tracked historical specs remain tracked; this keeps new local artifacts out.
30+
docs/specs/
2831
.codex
2932

3033
# Nx cache directories

‎common/src/util/__tests__/axiom-only-log.test.ts‎

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import {
88
ADS_FIRST_PARTY_SETTLEMENT_EVENT,
99
ADS_FIRST_PARTY_VIEW_ACK_EVENT,
1010
ADS_EXTERNAL_CONVERSION_POSTBACK_EVENT,
11+
ADS_IMPREZIA_FETCH_COMPLETED_EVENT,
1112
CONTEXT_PRUNING_COMPLETED_EVENT,
1213
getAxiomOnlyLogEvent,
1314
STREAM_RECOVERY_EVENT,
@@ -272,6 +273,71 @@ describe('getAxiomOnlyLogEvent', () => {
272273
})
273274
})
274275

276+
test('keeps Imprezia completion telemetry bounded and identity-free', () => {
277+
expect(
278+
getAxiomOnlyLogEvent({
279+
axiomEvent: ADS_IMPREZIA_FETCH_COMPLETED_EVENT,
280+
outcome: 'provider_error',
281+
selection_reason: 'fallback',
282+
experiment_arm: 'control',
283+
surface: 'freebuff_web_chat',
284+
ad_count: 0,
285+
duration_ms: 42,
286+
test_mode: false,
287+
failure_class: 'provider_failure',
288+
userId: 'user-private',
289+
sessionId: 'session-private',
290+
requestId: 'request-private',
291+
request: 'private prompt',
292+
response: 'private response',
293+
ad: { title: 'private creative' },
294+
clickUrl: 'https://private.example/click',
295+
error: new Error('private raw provider error'),
296+
}),
297+
).toEqual({
298+
event: ADS_IMPREZIA_FETCH_COMPLETED_EVENT,
299+
data: {
300+
outcome: 'provider_error',
301+
selection_reason: 'fallback',
302+
experiment_arm: 'control',
303+
surface: 'freebuff_web_chat',
304+
ad_count: 0,
305+
duration_ms: 42,
306+
test_mode: false,
307+
failure_class: 'provider_failure',
308+
},
309+
})
310+
})
311+
312+
test('rejects unbounded or incomplete Imprezia completion dimensions', () => {
313+
const valid = {
314+
axiomEvent: ADS_IMPREZIA_FETCH_COMPLETED_EVENT,
315+
outcome: 'no_fill',
316+
selection_reason: 'primary',
317+
experiment_arm: 'imprezia_first',
318+
surface: 'freebuff_web_chat',
319+
ad_count: 0,
320+
duration_ms: 42,
321+
test_mode: false,
322+
}
323+
for (const invalid of [
324+
{ ...valid, outcome: 'private raw error' },
325+
{ ...valid, selection_reason: 'campaign-123' },
326+
{ ...valid, experiment_arm: 'user-123' },
327+
{ ...valid, surface: 'https://private.example' },
328+
{ ...valid, ad_count: 2 },
329+
{ ...valid, outcome: 'fill', ad_count: 0 },
330+
{ ...valid, duration_ms: -1 },
331+
{ ...valid, duration_ms: 60_001 },
332+
{ ...valid, failure_class: 'raw upstream stack trace' },
333+
{ ...valid, test_mode: 'false' },
334+
// Every dimension except failure_class is required.
335+
{ ...valid, experiment_arm: undefined },
336+
]) {
337+
expect(getAxiomOnlyLogEvent(invalid)).toBeNull()
338+
}
339+
})
340+
275341
test('names and sanitizes first-party selection telemetry', () => {
276342
expect(
277343
getAxiomOnlyLogEvent({

‎common/src/util/axiom-only-log.ts‎

Lines changed: 94 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,11 @@ export const ADS_FIRST_PARTY_IMPRESSION_RECORDED_EVENT =
5050
* opaque click/event identifiers never leave the request handler. */
5151
export const ADS_EXTERNAL_CONVERSION_POSTBACK_EVENT =
5252
'ads.external_conversion_postback' as const
53+
/** Browser-side Imprezia decisions. The route deliberately reports only
54+
* bounded serving dimensions: request/content/creative identifiers, URLs, and
55+
* raw provider errors never enter this event. */
56+
export const ADS_IMPREZIA_FETCH_COMPLETED_EVENT =
57+
'ads.imprezia_fetch_completed' as const
5358

5459
type AxiomOnlyFieldType = 'string' | 'number' | 'boolean'
5560
type AxiomOnlyFieldSchema = Record<string, AxiomOnlyFieldType>
@@ -164,6 +169,90 @@ const ADS_FETCH_COMPLETED_FIELDS = {
164169
yield_live_evidence_status: 'string',
165170
} as const satisfies AxiomOnlyFieldSchema
166171

172+
const ADS_IMPREZIA_FETCH_COMPLETED_FIELDS = {
173+
outcome: 'string',
174+
selection_reason: 'string',
175+
experiment_arm: 'string',
176+
surface: 'string',
177+
ad_count: 'number',
178+
duration_ms: 'number',
179+
test_mode: 'boolean',
180+
failure_class: 'string',
181+
} as const satisfies AxiomOnlyFieldSchema
182+
183+
const ADS_IMPREZIA_FETCH_OUTCOMES = [
184+
'fill',
185+
'no_fill',
186+
'timeout',
187+
'provider_error',
188+
'not_configured',
189+
'not_eligible',
190+
] as const
191+
const ADS_IMPREZIA_SELECTION_REASONS = ['primary', 'fallback'] as const
192+
const ADS_IMPREZIA_EXPERIMENT_ARMS = [
193+
'imprezia_forced',
194+
'imprezia_first',
195+
'control',
196+
] as const
197+
const ADS_IMPREZIA_BROWSER_SURFACES = [
198+
'freebuff_web_chat',
199+
'chat_assistant',
200+
] as const
201+
const ADS_IMPREZIA_FAILURE_CLASSES = [
202+
'missing_api_key',
203+
'missing_user_agent',
204+
'invalid_source_url',
205+
'provider_timeout',
206+
'provider_failure',
207+
'client_exception',
208+
] as const
209+
const ADS_IMPREZIA_MAX_DURATION_MS = 60_000
210+
211+
function sanitizeImpreziaFetchCompletedFields(
212+
record: Record<string, unknown>,
213+
): AxiomOnlyLogEvent['data'] | null {
214+
const data = sanitizeAllowlistedFields(
215+
record,
216+
ADS_IMPREZIA_FETCH_COMPLETED_FIELDS,
217+
)
218+
const outcome = data.outcome
219+
const selectionReason = data.selection_reason
220+
const experimentArm = data.experiment_arm
221+
const surface = data.surface
222+
const adCount = data.ad_count
223+
const durationMs = data.duration_ms
224+
const testMode = data.test_mode
225+
const failureClass = data.failure_class
226+
227+
if (
228+
!ADS_IMPREZIA_FETCH_OUTCOMES.includes(
229+
outcome as (typeof ADS_IMPREZIA_FETCH_OUTCOMES)[number],
230+
) ||
231+
!ADS_IMPREZIA_SELECTION_REASONS.includes(
232+
selectionReason as (typeof ADS_IMPREZIA_SELECTION_REASONS)[number],
233+
) ||
234+
!ADS_IMPREZIA_EXPERIMENT_ARMS.includes(
235+
experimentArm as (typeof ADS_IMPREZIA_EXPERIMENT_ARMS)[number],
236+
) ||
237+
!ADS_IMPREZIA_BROWSER_SURFACES.includes(
238+
surface as (typeof ADS_IMPREZIA_BROWSER_SURFACES)[number],
239+
) ||
240+
(adCount !== 0 && adCount !== 1) ||
241+
(outcome === 'fill' ? adCount !== 1 : adCount !== 0) ||
242+
typeof durationMs !== 'number' ||
243+
durationMs < 0 ||
244+
durationMs > ADS_IMPREZIA_MAX_DURATION_MS ||
245+
typeof testMode !== 'boolean' ||
246+
(failureClass !== undefined &&
247+
!ADS_IMPREZIA_FAILURE_CLASSES.includes(
248+
failureClass as (typeof ADS_IMPREZIA_FAILURE_CLASSES)[number],
249+
))
250+
) {
251+
return null
252+
}
253+
return data
254+
}
255+
167256
/**
168257
* First-party inventory selection is operational telemetry only. In
169258
* particular, campaign/creative/placement arrays and user/session IDs stay
@@ -314,6 +403,7 @@ export type AxiomOnlyLogEvent = {
314403
| typeof ADS_FIRST_PARTY_CLICK_RECORDED_EVENT
315404
| typeof ADS_FIRST_PARTY_IMPRESSION_RECORDED_EVENT
316405
| typeof ADS_EXTERNAL_CONVERSION_POSTBACK_EVENT
406+
| typeof ADS_IMPREZIA_FETCH_COMPLETED_EVENT
317407
data: Record<string, string | number | boolean>
318408
}
319409

@@ -378,6 +468,10 @@ export function getAxiomOnlyLogEvent(
378468
data: sanitizeAllowlistedFields(record, ADS_FETCH_COMPLETED_FIELDS),
379469
}
380470
}
471+
if (eventName === ADS_IMPREZIA_FETCH_COMPLETED_EVENT) {
472+
const data = sanitizeImpreziaFetchCompletedFields(record)
473+
return data ? { event: eventName, data } : null
474+
}
381475
if (eventName === ADS_FIRST_PARTY_DECISION_EVENT) {
382476
return {
383477
event: eventName,

0 commit comments

Comments
 (0)