Summary
getGivingSummary() performs zero live data fetches (verified: no fetch() call anywhere in the file). Every "platform" figure is a static division of a 2023/2024 published annual total by 365, every sampling/velocity field is hardcoded to 0, and the resulting composite "Activity Index" is stamped with the real request time via lastUpdated/generatedAt: new Date().toISOString() on every call. The panel's own info tooltip states the index "Combines live sampling with published annual reports" — this is false; no sampling of any kind occurs anywhere in this code path.
Evidence
server/worldmonitor/giving/v1/get-giving-summary.ts — confirmed via direct grep: zero fetch( calls in the file.
- Lines 38-47 (
getGoFundMeEstimate), 63-72 (getGlobalGivingEstimate), 76-85 (getJustGivingEstimate), 89-99 (getCryptoGivingEstimate), 103-112 (getInstitutionalBaseline) — all return static constants derived from published annual reports (e.g. dailyVolumeUsd: 9_000_000_000 / 365), with activeCampaignsSampled: 0, newCampaigns24h: 0, donationVelocity: 0, transactions24h: 0 hardcoded on every platform.
- Each platform object sets
lastUpdated: new Date().toISOString() (e.g. line 45) and the top-level handler sets generatedAt: new Date().toISOString() (line ~219) — the current real-time timestamp is attached to numbers that never change between requests.
computeActivityIndex() (~128-149) derives the headline "Activity Index" from these permanently-zero velocity/new-campaign fields, so the index is mathematically static across all requests (verified: totalVelocity/totalNew are always 0, so their conditional bonuses never fire); computeTrend() (~158-162) consequently always reports 'stable'.
- The handler unconditionally returns
dataAvailable: true (end of getGivingSummary) since the computation has no external dependency that can fail — there is no path by which this endpoint ever reports data as unavailable or stale.
src/locales/en.json:1700 — the panel's info tooltip: "Combines live sampling with published annual reports" and "GoFundMe, GlobalGiving, JustGiving campaign sampling" — verified false against the source above; no sampling occurs.
src/components/GivingPanel.ts (~36-60) — renders Activity Index, Trend, and Est. Daily Flow as color-coded headline stat boxes; verified via grep: zero calls to Panel.setDataBadge() (the app's standing live/cached/unavailable disclosure convention, src/components/Panel.ts:620) anywhere in the file. The per-platform breakdown further down the panel does show an honest "annual" freshness badge per row — only the headline composite lacks any qualifier.
Why this matters
This is presented as a "real-time global intelligence dashboard" metric with a moving trend indicator and an always-current timestamp, but it is entirely static arithmetic on 1-2 year old published totals, with an explicit, incorrect claim of "live sampling" in the product's own explanatory copy. A user has no way to know — and is actively told the opposite of — the fact that "rising/falling/stable" and the headline dollar figure never reflect anything that happened today.
Attack or failure scenario
Not applicable as a technical exploit — the failure mode is that every viewer of this panel is shown a fabricated "live" signal with a false description of its own methodology, indefinitely, with no code path that would ever surface this as stale, estimated, or non-live to the user.
Root cause
The feature was built entirely from published annual-report baselines (reasonable, given the difficulty of live-sampling GoFundMe/GlobalGiving/JustGiving), but the response schema and UI copy were written as if live sampling were happening, rather than being honestly labeled as a static/annual estimate composite.
Recommended fix
- Correct the info tooltip (
en.json:1700) to state plainly that the index is derived from published annual reports, not live sampling.
- Remove or repurpose
lastUpdated/generatedAt so they reflect the actual age of the underlying published data (e.g. oecdDataYear, report publication dates) instead of the current request time.
- Either implement genuine live sampling for at least one platform, or relabel
trend/activityIndex as a static "estimated composite" rather than an index with directional movement, since it structurally cannot move without live inputs.
- Apply
Panel.setDataBadge() (or equivalent) to the headline stats to disclose "annual estimate" the same way the per-platform table already does.
Acceptance criteria
- The tooltip and any other UI copy accurately describe the index as derived from static annual-report baselines, with no claim of live sampling that isn't true.
- Timestamps shown to the user reflect the actual freshness of the underlying published data, not request time.
- The headline stat boxes carry the same freshness disclosure the per-platform table already has.
Suggested labels
bug, documentation
Priority
P1
Severity
High — a flagship composite metric on a paid intelligence product is entirely fabricated arithmetic on stale published data, actively mislabeled as "live sampling" in the product's own UI copy, with a real-time timestamp attached to numbers that structurally cannot change.
Confidence
Confirmed — verified directly against source: zero fetch calls in the handler, all constants and zeroed sampling fields read directly, and the false tooltip text confirmed verbatim in en.json.
Summary
getGivingSummary()performs zero live data fetches (verified: nofetch()call anywhere in the file). Every "platform" figure is a static division of a 2023/2024 published annual total by 365, every sampling/velocity field is hardcoded to0, and the resulting composite "Activity Index" is stamped with the real request time vialastUpdated/generatedAt: new Date().toISOString()on every call. The panel's own info tooltip states the index "Combines live sampling with published annual reports" — this is false; no sampling of any kind occurs anywhere in this code path.Evidence
server/worldmonitor/giving/v1/get-giving-summary.ts— confirmed via direct grep: zerofetch(calls in the file.getGoFundMeEstimate), 63-72 (getGlobalGivingEstimate), 76-85 (getJustGivingEstimate), 89-99 (getCryptoGivingEstimate), 103-112 (getInstitutionalBaseline) — all return static constants derived from published annual reports (e.g.dailyVolumeUsd: 9_000_000_000 / 365), withactiveCampaignsSampled: 0,newCampaigns24h: 0,donationVelocity: 0,transactions24h: 0hardcoded on every platform.lastUpdated: new Date().toISOString()(e.g. line 45) and the top-level handler setsgeneratedAt: new Date().toISOString()(line ~219) — the current real-time timestamp is attached to numbers that never change between requests.computeActivityIndex()(~128-149) derives the headline "Activity Index" from these permanently-zero velocity/new-campaign fields, so the index is mathematically static across all requests (verified:totalVelocity/totalNeware always 0, so their conditional bonuses never fire);computeTrend()(~158-162) consequently always reports'stable'.dataAvailable: true(end ofgetGivingSummary) since the computation has no external dependency that can fail — there is no path by which this endpoint ever reports data as unavailable or stale.src/locales/en.json:1700— the panel's info tooltip: "Combines live sampling with published annual reports" and "GoFundMe, GlobalGiving, JustGiving campaign sampling" — verified false against the source above; no sampling occurs.src/components/GivingPanel.ts(~36-60) — rendersActivity Index,Trend, andEst. Daily Flowas color-coded headline stat boxes; verified via grep: zero calls toPanel.setDataBadge()(the app's standing live/cached/unavailable disclosure convention,src/components/Panel.ts:620) anywhere in the file. The per-platform breakdown further down the panel does show an honest "annual" freshness badge per row — only the headline composite lacks any qualifier.Why this matters
This is presented as a "real-time global intelligence dashboard" metric with a moving trend indicator and an always-current timestamp, but it is entirely static arithmetic on 1-2 year old published totals, with an explicit, incorrect claim of "live sampling" in the product's own explanatory copy. A user has no way to know — and is actively told the opposite of — the fact that "rising/falling/stable" and the headline dollar figure never reflect anything that happened today.
Attack or failure scenario
Not applicable as a technical exploit — the failure mode is that every viewer of this panel is shown a fabricated "live" signal with a false description of its own methodology, indefinitely, with no code path that would ever surface this as stale, estimated, or non-live to the user.
Root cause
The feature was built entirely from published annual-report baselines (reasonable, given the difficulty of live-sampling GoFundMe/GlobalGiving/JustGiving), but the response schema and UI copy were written as if live sampling were happening, rather than being honestly labeled as a static/annual estimate composite.
Recommended fix
en.json:1700) to state plainly that the index is derived from published annual reports, not live sampling.lastUpdated/generatedAtso they reflect the actual age of the underlying published data (e.g.oecdDataYear, report publication dates) instead of the current request time.trend/activityIndexas a static "estimated composite" rather than an index with directional movement, since it structurally cannot move without live inputs.Panel.setDataBadge()(or equivalent) to the headline stats to disclose "annual estimate" the same way the per-platform table already does.Acceptance criteria
Suggested labels
bug, documentation
Priority
P1
Severity
High — a flagship composite metric on a paid intelligence product is entirely fabricated arithmetic on stale published data, actively mislabeled as "live sampling" in the product's own UI copy, with a real-time timestamp attached to numbers that structurally cannot change.
Confidence
Confirmed — verified directly against source: zero fetch calls in the handler, all constants and zeroed sampling fields read directly, and the false tooltip text confirmed verbatim in
en.json.