audacity-and-the-telemetry-pull-request.md

  1---
  2title: "Audacity and the telemetry pull request"
  3author: ["Amolith"]
  4lastmod: 2023-01-27T13:00:37-05:00
  5tags: ["Open source culture", "Audio editing", "Music", "Drama"]
  6categories: ["Technology"]
  7draft: true
  8---
  9
 10Five days ago at the time of writing, [Dmitry Vedenko](https://github.com/crsib)
 11opened a Pull Request (PR) in [Audacity's GitHub
 12repository](https://github.com/audacity/audacity/pull/835) entitled [_Basic
 13telemetry for the Audacity_.](https://github.com/audacity/audacity/pull/835)
 14About two days later, all hell broke loose. That PR now has over 3.3 thousand
 15downvotes and more than one thousand comments from nearly 400 individuals. I
 16started reading the posts shortly after they began and kept up with them over
 17the following days, reading every single new post. I recognise that few people
 18are going to feel like wading through over 1k comments so this is my attempt to
 19provide a summary of the PR itself using the community's code reviews along with
 20a summary of the various opinions conveyed in the comments.
 21
 22When I reference comments, I'll provide a footnote that includes a link to the
 23comment and a link to a screenshot just in case it's removed or edited in the
 24future.
 25
 26## Audacity's acquisition
 27
 28I haven't been able to find _much_ information in this area so forgive me if I'm
 29scant on details.
 30
 31On 30 April, a company called [Muse Group](https://mu.se/) acquired
 32[Audacity.](https://www.audacityteam.org/) According to [their
 33website](https://mu.se), Muse is the parent company behind many musical
 34applications and tools. It was founded by Eugeny Naidenov just days before it
 35acquired Audacity. Before all of this, Eugeny Naidenov founded [Ultimate
 36Guitar](https://www.ultimate-guitar.com/) (UG) in 1998. The service grew rather
 37quickly and now has over 300 million users. UG acquired [Dean Zelinsky
 38Guitars](https://deanzelinsky.com/) in 2012, [Agile
 39Partners](http://agilepartners.com/) in 2013,
 40[MuseScore](https://musescore.org/) in 2017, and
 41[Crescendo](http://trycrescendo.com/) in 2018. Muse Group was established in
 422021 and it seems as if all of the services UG acquired were (or will be)
 43transferred to Muse Group, as well as UG itself. Immediately following its
 44establishment, Muse not only acquired Audacity but also
 45[StaffPad.](https://www.staffpad.net/)
 46
 47I say 30 April because that's when Muse published their [press
 48release](https://mu.se/newsroom/tpost/6dhedma301-muse-group-acquires-audacity-expanding-c)
 49and when Martin Keary (Tantacrul) published a video entitled [_I’m now in charge
 50of Audacity. Seriously._](https://www.youtube.com/watch?v=RMWNvwLiXIQ) According
 51to his comment,[^fn:1] Martin will help with proposing Audacity's roadmap and
 52many of its future features as well as working with the community. This has been
 53his role with MuseScore since he joined that project and he will be continuing
 54it here.
 55
 56`-----BEGIN PERSONAL OPINION-----`
 57
 58Looking at [his website,](https://www.martinkeary.com/) I also suspect he will
 59play a large role in redesigning Audacity's interface. Considering that he was
 60instrumental in designing [the best mobile interface I've ever had the absolute
 61pleasure of experiencing,](https://www.martinkeary.com/#/ubuntu-touch-os/) I
 62have high hopes that this is the case.
 63
 64`------END PERSONAL OPINION------`
 65
 66## Telemetry implementation
 67
 68### Implementation Basics
 69
 70A few days after the acquisition, a PR was opened that adds _Basic telemetry for
 71the Audacity_. This implementation collects "application opened" events and
 72sends those to Yandex to estimate the number of Audacity users. It also collects
 73session start and end events, errors for debugging, file used for import and
 74export, OS and Audacity versions, and the use of effects, generators, and
 75analysis tools so they can prioritise future improvements. Sending this data
 76would be optional and the user would be presented with a dialogue the first time
 77they launch the application after installation or after they update to the
 78including release. This description was mostly copied directly from [the PR
 79description
 80itself.](https://github.com/audacity/audacity/pull/835#issue-629891447)
 81
 82### Frontend Implementation
 83
 84This is fairly straightforward and a pretty standard UI for prompting users to
 85consent to analytics and crash logging. This section is included because the
 86community has strong opinions regarding the language used and its design, but
 87that will be discussed later. The screenshot below is copied directly from the
 88PR.
 89
 90{{< figure src="~/repos/sites/secluded/static/assets/pngs/audacity-pr/consentdialogue.png" link="~/repos/sites/secluded/static/assets/pngs/audacity-pr/consentdialogue.png" >}}
 91
 92### Backend Implementation
 93
 94Many of the code reviews include the reviewer's personal opinion so I will
 95summarise the comment, provide the code block in question, and link directly to
 96the comment in a footnote.[^fn:2]
 97
 98```c
 99  if (!inputFile.Write (wxString::FromUTF8 (ClientID + "\n")))
100    return false;
101```
102
103[Lines 199-200 of
104TelemetryManager.cpp](https://github.com/crsib/audacity/blob/c9264d2478fe2af82aeb6e2a0295b00b3a27ce53/libraries/lib-telemetry/TelemetryManager.cpp#L199-L200)
105save the user's unique client ID to a file.[^fn:3] This allows the analytics
106tool (in this case, Google Analytics) to aggregate data produced by a single
107user.
108
109```c
110  def_vars()
111
112    set( CURL_DIR "${_INTDIR}/libcurl" )
113    set( CURL_TAG "curl-7_76_0")
114```
115
116[Lines 3-6 of
117CMakeLists.txt](https://github.com/crsib/audacity/blob/c9264d2478fe2af82aeb6e2a0295b00b3a27ce53/cmake-proxies/libcurl/CMakeLists.txt#L3-L6)
118"vendor in" libcurl.[^fn:4] This is when an application directly includes
119sources for a utility rather than making use utilities provided by the system
120itself.
121
122```c
123  ExternalProject_Add(curl
124     PREFIX "${CURL_DIR}"
125     INSTALL_DIR "${CURL_DIR}"
126     GIT_REPOSITORY https://github.com/curl/curl
127     GIT_TAG ${CURL_TAG}
128     GIT_SHALLOW Yes
129     CMAKE_CACHE_ARGS ${CURL_CMAKE_ARGS}
130  )
131```
132
133[Lines 29-36 of
134CMakeLists.txt](https://github.com/crsib/audacity/blob/c9264d2478fe2af82aeb6e2a0295b00b3a27ce53/cmake-proxies/libcurl/CMakeLists.txt#L29-L36)
135add curl as a remote dependency.[^fn:5] This means that the machine building
136Audacity from its source code has to download curl during that build.
137
138```c
139  S.Id (wxID_NO).AddButton (rejectButtonTitle);
140  S.Id (wxID_YES).AddButton (acceptButtonTitle)->SetDefault ();
141```
142
143[Lines 93-94 of
144TelemetryDialog.cpp](https://github.com/crsib/audacity/blob/c9264d2478fe2af82aeb6e2a0295b00b3a27ce53/src/telemetry/TelemetryDialog.cpp#L93-L94)
145add buttons to the dialogue asking the user whether they consent to data
146collection.[^fn:6] `SetDefault` focuses the button indicating that the user does
147consent. This means that if the user doesn't really look at the dialogue and
148presses Spacebar or Enter, or if they do so accidentally by simply bumping the
149key, they unintentionally consent to data collection. If the user desires, this
150can later be changed in the settings menu. However, if they weren't aware what
151they were consenting to _or that they did consent_, they won't know to go back
152and opt out.
153
154There are other problems with the code that include [simple
155mistakes,](https://github.com/audacity/audacity/pull/835#discussion_r628816050)
156[styling that's inconsistent with the rest of the
157project,](https://github.https//github.com/audacity/audacity/pull/835#discussion_r628774985)
158[unhandled return values resulting in skewed
159data,](https://github.com/audacity/audacity/pull/835#discussion_r628500849) [use
160of inappropriate
161functions,](https://github.com/audacity/audacity/pull/835#discussion_r628792423)
162and [spelling errors in the
163comments.](https://github.com/audacity/audacity/pull/835#discussion_r628818054)
164I believe these are less important than those above so they won't be discussed.
165
166## Community opinions
167
168There were many strong opinions regarding both the frontend and backend
169implementations of this PR, from the wording of the dialogue and highlighting
170the consent button to devices running something other than Windows and macOS not
171being able to send telemetry and thus skewing the data that _was_ collected.
172
173### Opinions on the frontend
174
175Really, the only frontend here is the consent dialogue. However, there are
176_many_ comments about it, the most common of which is probably that the wording
177is not only too vague[^fn:7] but also inaccurate.[^fn:8] The assertion that
178Google Analytics are not anonymous and any data sent can be trivially
179de-anonymised (or de-pseudonymised) is repeated many times over. Below are a few
180links to comments stating such. I searched for the term _"anonymous"_, copied
181relevant links, and stopped when my scrollbar reached halfway down the page.
182
183- [r628156527](https://github.com/audacity/audacity/pull/835#discussion_r628156527)
184- [833969780](https://github.com/audacity/audacity/pull/835#issuecomment-833969780)
185- [833969933](https://github.com/audacity/audacity/pull/835#issuecomment-833969933)
186- [r627995927](https://github.com/audacity/audacity/pull/835#discussion_r627995927)
187- [834358022](https://github.com/audacity/audacity/pull/835#issuecomment-834358022)
188- [834377549](https://github.com/audacity/audacity/pull/835#issuecomment-834377549)
189- [834382007](https://github.com/audacity/audacity/pull/835#issuecomment-834382007)
190- [834385463](https://github.com/audacity/audacity/pull/835#issuecomment-834385463)
191- [834405825](https://github.com/audacity/audacity/pull/835#issuecomment-834405825)
192- [834531779](https://github.com/audacity/audacity/pull/835#issuecomment-834531779)
193- [834546874](https://github.com/audacity/audacity/pull/835#issuecomment-834546874)
194- [834638000](https://github.com/audacity/audacity/pull/835#issuecomment-834638000)
195
196The next most pervasive comment is regarding the consent buttons at the bottom
197of the dialogue where users opt in or out.[^fn:9] Many individuals call this
198design a _dark pattern_. Harry Brignull, a UX specialist focusing on deceptive
199interface practises, describes dark patterns as [_tricks used in websites and
200apps that make you do things that you didn't mean
201to_.](https://www.darkpatterns.org/) The dark pattern in this situation is the
202opt-in button being highlighted. Many community members assert that users will
203see the big blue button and click it without actually reading the dialogue's
204contents. They just want to record their audio and this window is a distraction
205that prevents them from doing so; it needs to get out of the way and the
206quickest way to dismiss it is clicking that blue button. Below is a list of some
207comments criticising this design.
208
209- [834286641](https://github.com/audacity/audacity/pull/835#issuecomment-834286641)
210- [834358022](https://github.com/audacity/audacity/pull/835#issuecomment-834358022)
211- [834399813](https://github.com/audacity/audacity/pull/835#issuecomment-834399813)
212- [834479968](https://github.com/audacity/audacity/pull/835#issuecomment-834479968)
213- [835250737](https://github.com/audacity/audacity/pull/835#issuecomment-835250737)
214- [835253882](https://github.com/audacity/audacity/pull/835#issuecomment-835253882)
215- [835291066](https://github.com/audacity/audacity/pull/835#issuecomment-835291066)
216- [835445481](https://github.com/audacity/audacity/pull/835#issuecomment-835445481)
217
218Another issue that was brought up by a couple of individuals was the lack of a
219privacy policy.[^fn:10] The consent dialogue links to one, but, at the time of
220writing, one does not exist at [the provided
221URL.](https://www.audacityteam.org/contact/privacy-policy/) I have [archived the
222state of the
223page](https://web.archive.org/web/20210510012924/https://www.audacityteam.org/contact/privacy-policy/)
224in case that changes in the future.
225
226### Opinions on the backend
227
228```c
229  if (!inputFile.Write (wxString::FromUTF8 (ClientID + "\n")))
230    return false;
231```
232
233The issue many individuals take with this snippet is saving the `ClientID`. Say
234an individual has an odd file that causes Audacity to crash any time they try to
235open it. Say they attempt to open it a hundred times. Without giving the client
236a unique ID, it could look like there are 100 people having an issue opening a
237file instead of just the one. However, by virtue of each installation having an
238entirely unique ID, this telemetry _is not anonymous_. Anonymity would be
239sending statistics in such a way that connecting those failed attempts to a
240single user would be impossible. At best, this implementation is _pseudonymous_
241because the client is given a random ID, you don't have to sign in with an
242account or something.
243
244```c
245  def_vars()
246
247    set( CURL_DIR "${_INTDIR}/libcurl" )
248    set( CURL_TAG "curl-7_76_0")
249```
250
251Timothe Litt's comment gives a good description of why "vendoring in" libcurl is
252a bad idea[^fn:11] and Tyler True's comment gives a good overview of the pros
253and cons of doing so.[^fn:12] Many people take issue with this _specifically_
254because it's libcurl. Security flaws in it are _very_ common and Audacity's copy
255would need to be _manually_ kept up to date with every upstream release to
256ensure none of its vulnerabilities can be leveraged to compromise users. If the
257Audacity team was going to stay on top of all of the security fixes, they would
258need to release a new version every week or so.
259
260```c
261  ExternalProject_Add(curl
262     PREFIX "${CURL_DIR}"
263     INSTALL_DIR "${CURL_DIR}"
264     GIT_REPOSITORY https://github.com/curl/curl
265     GIT_TAG ${CURL_TAG}
266     GIT_SHALLOW Yes
267     CMAKE_CACHE_ARGS ${CURL_CMAKE_ARGS}
268  )
269```
270
271The problem with downloading curl at build-time is that it's simply disallowed
272for many Linux- and BSD-based operation systems. When a distribution builds an
273application from source, its build dependencies are often downloaded ahead of
274time and, as a security measure, the build machine is cut off from the internet
275to prevent any interference. Because this is disallowed, the build will fail and
276the application won't be available on those operation systems.
277
278Note, however, that these build machines would have the option to disable
279telemetry at build-time. This means the machine wouldn't attempt to download
280curl from GitHub and the build would succeed but, again, telemetry would be
281disabled for anyone not on Windows or macOS. This defeats the whole purpose of
282adding telemetry in the first place.
283
284```c
285  S.Id (wxID_NO).AddButton (rejectButtonTitle);
286  S.Id (wxID_YES).AddButton (acceptButtonTitle)->SetDefault ();
287```
288
289There was a lot of feedback about the decision to highlight the consent button
290but that was mentioned up in the frontend section; I won't rehash it here.
291
292### Broader and particularly well-structured comments
293
294These are simply some comments I feel deserve particular attention.
295
296From SndChaser...
297
298- [834037351](https://github.com/audacity/audacity/pull/835#issuecomment-834037351)
299-
300
301## The Audacity team's response
302
303---
304
305## The privacy policy modification
306
307<https://github.com/audacity/audacity/issues/1213#issuecomment-875274890>
308
309[^fn:1]:
310    [Link to the
311    comment](https://github.com/audacity/audacity/pull/835#issuecomment-836069326)
312    and [link to the screenshot](/assets/pngs/audacity-pr/tantacrulrole.png)
313
314[^fn:2]:
315    Note that because I am not a C programmer, these reviews might not be
316    entirely accurate and I wouldn't be able to catch the reviewer's error. I am
317    relying on other community members to catch issues and comment on them; none
318    of the reviews I link to have such comments so I'm assuming they are
319    correct.
320
321[^fn:3]:
322    [Link to the
323    review](https://github.com/audacity/audacity/pull/835#discussion_r627993755) and
324    [link to the screenshot](/assets/pngs/audacity-pr/writeanalyticsid.png)
325
326[^fn:4]:
327    [Link to the
328    review](https://github.com/audacity/audacity/pull/835#discussion_r628005925) and
329    [link to the screenshot](/assets/pngs/audacity-pr/vendorcurl.png)
330
331[^fn:5]:
332    [Link to the
333    review](https://github.com/audacity/audacity/pull/835#discussion_r628008821) and
334    [link to the screenshot](/assets/pngs/audacity-pr/externaldependency.png)
335
336[^fn:6]:
337    [Link to the
338    review](https://github.com/audacity/audacity/pull/835#discussion_r628124998) and
339    [link to the screenshot](/assets/pngs/audacity-pr/defaultconsentbutton.png)
340
341[^fn:7]:
342    [Link to the
343    comment](https://github.com/audacity/audacity/pull/835#discussion_r627756976)
344    and [link to the screenshot](/assets/pngs/audacity-pr/vaguedialogue.png)
345
346[^fn:8]:
347    [Link to the
348    comment](https://github.com/audacity/audacity/pull/835#discussion_r627764300)
349    and the screenshot is the same as previous
350
351[^fn:9]:
352    [Link to the
353    comment](https://github.com/audacity/audacity/pull/835#issuecomment-834286641)
354    and [link to the screenshot](/assets/pngs/audacity-pr/darkpattern.png)
355
356[^fn:10]:
357    [Link to the
358    comment](https://github.com/audacity/audacity/pull/835#discussion_r627762185)
359    and [link to the screenshot](/assets/pngs/audacity-pr/missingprivacypolicy.png)
360
361[^fn:11]:
362    [Link to the
363    comment](https://github.com/audacity/audacity/pull/835#issuecomment-834451187)
364    and [link to the screenshot](/assets/pngs/audacity-pr/privatelibcurl.png)
365
366[^fn:12]:
367    [Link to the
368    comment](https://github.com/audacity/audacity/pull/835#issuecomment-834010117)
369    and [link to the screenshot](/assets/pngs/audacity-pr/vendorproscons.png)