Cwa-app-ios: On >=13.7 app shows "unknown risk" in case of encounters

Created on 13 Sep 2020  路  8Comments  路  Source: corona-warn-app/cwa-app-ios

Mirrored from Jira:

On devices with iOS >= 13.7 the internal risk calculation of the ENF might return values outside of the expected range.

Currently the maximum allowed value is 40 (1158), which (when being normalised by deviding by 25) translates to a factor of 1.6. The maximum weighted time (45 minutes * 1.6) = 72 minutes. This is also the upper bound for the "red" risk level.*

However, we have observed on a device with 13.7 that a (theoretically impossible) score of 140 is returned, leading to a factor of 5.6. With this, the weighted time might exceed 72 in case of an exposure, meaning that the app can't map this value to a specific risk level. As a consequence, "unknown risk" is being displayed.

This issue has already been addressed to Apple, where it has been confirmed. Currently the internal cause has not been identified there.

As a temporary mitigation, we could raise the upper bound of the red risk level (to e.g. 500). As we don't know, how/why the risk level is actually being elevated, there seems to way to tell, what is "green" and what is "red" on iOS. Many users with only "green" might receive "red" warnings.


Internal Tracking ID: EXPOSUREAPP-2606

bug mirrored-to-jira

Most helpful comment

@daimpi This are the weighted time= 30min * 1 + 30min * 0.5
@ndegendogo The ENF uses 30min periods to fill the attenuation buckets. The detections runs the whole time.

All 8 comments

@thomasaugsten is there a specific reason why this issue has been closed? Because currently anyone else who has this problem will not easily find that this issue has already been raised which might lead to unnecessary duplicates. Also: just for tracking purposes it would make sense to have the status of issues which are not yet resolved as "open" imho.

Because the lifting of the upper limit was done and the next steps to restore the complete calculation we will commented on each issue separately/faq/blog. I think it makes sense to have separate issue for different ios version and not all Risikoermittlung gestoppt issues are related to this problem.

Ah ok I see, makes sense.
Thanks for the explanation 馃檪.

@heinezen one additional question:

You wrote

The maximum weighted time (45 minutes * 1.6) = 72 minutes.

(bolding mine)

How did you come to those 45 min? I though the maximal length ExposureSummary can provide for an encounter is 30 min?

45 minutes max? Now I am confused.
My understanding was that the ENF has all information to match all the temp. short-time keys from an infected person. So the detected exposure duration could be many hours then, isn't it?

@daimpi This are the weighted time= 30min * 1 + 30min * 0.5
@ndegendogo The ENF uses 30min periods to fill the attenuation buckets. The detections runs the whole time.

@thomasaugsten ahh, now i understand 馃憤
Thanks for the explanation 馃槉.

Very likely stuff like this is already done, but would it be possible to devise a regression test of the sort:

fixed sighting database + fixed diagnosis keys on server + CWA parametrization + iOS phone running the App

and then monitor that the log files for the risk computation on the phone give pre-specified values?

In the R notation of this risk scoring post something in the flavour of:

file <- tempfile()
purl("https://raw.githubusercontent.com/hoehleatsu/hoehleatsu.github.io/master/_source/2020-09-17-gaen_riskscoring.Rmd", output=file)
source(file)

> head(aisha)
# A tibble: 6 x 3
  key    valid        trl
  <chr>  <date>     <dbl>
1 36d5c8 2020-09-21     5
2 0956dd 2020-09-20     6
3 f3ca93 2020-09-19     8
4 a21f00 2020-09-18     8
5 e75fe2 2020-09-17     8
6 835292 2020-09-16     5
...

# Aisha's TRL keys contain the full TRL vector, so good for testing.
# Double data so observations in both attenuation buckets.
res <- bind_rows(aisha %>% mutate(attenuation = 40, duration=30),
          aisha %>% mutate(attenuation = 60, duration=30)) %>% 
  mutate(attenuation_lvl = get_lvl(attenuation, breaks=attenuation_breaks, lvl_table=attenuation_lvl, include.lowest = attenuation_include_lowest), 
         duration_lvl = get_lvl(duration, breaks=duration_breaks, lvl_table=duration_lvl, include.lowest = duration_include_lowest)) %>% 
  mutate(days_lvl=days_lvl) %>% cwa_classifier()

assertthat::assert_that(all.equal(res$combined_risk_score, 72))

where cwa_classifier is the black-box classifier from the GAEN framework.

Was this page helpful?
0 / 5 - 0 ratings