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

Chrome extension manifest v3 proposal #338

Open
greghuc opened this Issue Dec 13, 2018 · 68 comments

Comments

Projects
None yet
@greghuc
Copy link

greghuc commented Dec 13, 2018

Description

This issue is a heads-up on the proposed Chrome extension manifest version 3, which will have a significant impact on ad-blockers.

There is a tracking bug at: https://bugs.chromium.org/p/chromium/issues/detail?id=896897

In-progress design doc: https://docs.google.com/document/d/1nPu6Wy4LWR66EFLeYInl3NzzhHzc-qnk4w4PX-0XMw8/edit#

Might be worth a review, and giving feedback via the tracking bug.

@uBlock-user uBlock-user changed the title Heads up: Chrome extension manifest v3 proposal Chrome extension manifest v3 proposal Dec 13, 2018

@uBlock-user

This comment has been minimized.

Copy link
Member

uBlock-user commented Dec 13, 2018

Yes this was announced back in October - https://blog.chromium.org/2018/10/trustworthy-chrome-extensions-by-default.html

Not much for uBO to do though..

@jspenguin2017

This comment has been minimized.

Copy link

jspenguin2017 commented Dec 13, 2018

I'm not sure how are they planning to change the background process and origin access, it might cause some issues. Beside that, I don't see anything else that can cause problems. As for remotely-hosted code, it really should've been forbidden since the beginning.

@joey04

This comment has been minimized.

Copy link

joey04 commented Jan 9, 2019

It appears that Google is phasing out the webRequest API in favor of their new declarativeNetRequest.

The current Manifest V3 draft states:

The declarativeNetRequest API is an alternative to the webRequest API. At its core, this API allows extensions to tell Chrome what to do with a given request, rather than have Chrome forward the request to the extension. Thus, instead of the above flow where Chrome receives the request, asks the extension, and then eventually gets the result, the flow is that the extension tells Chrome how to handle a request and Chrome can handle it synchronously. This allows us to ensure efficiency since a) we have control over the algorithm determining the result and b) we can prevent or disable inefficient rules. This is also better for user privacy, as the details of the network request are never exposed to the extension.

This API is currently being implemented, and will be available to both the current manifest version and Manifest V3, but will be the primary way to modify network requests in Manifest V3.

Looking at the new API page, it's a rather different way of doing things. I would expect big changes needed to uBO and other blockers. (Plus there's the change from background page to ServiceWorker.)

@uBlock-user uBlock-user added the Chromium label Jan 9, 2019

@uBlock-user

This comment has been minimized.

Copy link
Member

uBlock-user commented Jan 9, 2019

Another change would be dynamic Content Scripts similar to what Firefox has where extensions can inject contentScript and have it execute before page finishes loading.

@gwarser

This comment has been minimized.

Copy link
Member

gwarser commented Jan 9, 2019

declarativeNetRequest

Basic ABP-like syntax, 30000 filters MAX...

@uBlock-user

This comment has been minimized.

Copy link
Member

uBlock-user commented Jan 9, 2019

That was declarativeWebRequest, that was shelved.

@gwarser

This comment has been minimized.

Copy link
Member

gwarser commented Jan 9, 2019

I don't see limits to the number of the rules in declarativeWebRequest. declarativeNetRequest have better syntax, but number of rules is limited.

@gorhill

This comment has been minimized.

Copy link
Member

gorhill commented Jan 9, 2019

It appears that Google is phasing out the webRequest API

It is explicitly stated this is meant to phase out webRequest API? If so, where? Quickly perusing the page, I don't see such phase out being stated. If there is really such phase out planned, and if the declarativeNetRequest is strictly an implementation of static filtering à la ABP, this would be the death of uBO and uMatrix.

There is no way to transpose either either dynamic filtering, dynamic URL filtering, per-site/per-scope switch logic (let's refer to all these as "dynamic filtering"), into static filters. Dynamic filtering logic requires an arbitrary amount of block/allow rules overriding other block/allow rules based on specificity. There is no concept of specificity in static filtering -- and even more, there is no concept of dynamic filtering rules relinquishing filtering to static filters (dynamic filtering's noop rules).

Basic ABP-like syntax, 30000 filters MAX...

And there I was recently testing how uBO handled over half a million network filters with the 3rd-gen HNTrie...

a

Issues of performance and privacy lie with web sites, not uBO -- so I don't feel concerned with the issues of privacy and efficiency being put forth as advantages of using declarativeNetRequest over webRequest.

@uBlock-user

This comment has been minimized.

Copy link
Member

uBlock-user commented Jan 9, 2019

https://docs.google.com/document/d/1nPu6Wy4LWR66EFLeYInl3NzzhHzc-qnk4w4PX-0XMw8/edit#heading=h.ypclvihky0p6

Read the paragraph that's titled DeclarativeNetRequest. They will keep webRequest API but it will not block, modify or redirect anymore, that will be handled by NetRequest API with v3.

They do plan to discourage the use of webRequest API through with its new replacement - https://docs.google.com/document/d/1nPu6Wy4LWR66EFLeYInl3NzzhHzc-qnk4w4PX-0XMw8/edit#heading=h.xe5njuo7voeb

@uBlock-user

This comment has been minimized.

Copy link
Member

uBlock-user commented Jan 9, 2019

30000 is mentioned in https://developer.chrome.com/extensions/declarativeNetRequest#property-MAX_NUMBER_OF_RULES, not sure what to make of this, can you shed some light there ? I don't think it is related to 30K ABP styled filters.

@gorhill

This comment has been minimized.

Copy link
Member

gorhill commented Jan 9, 2019

Look at "Rule", it's clearly made to implement ABP-compatible filters:

'|' : Left/right anchor: If used at either end of the pattern, specifies the beginning/end of the url > respectively.

'||' : Domain name anchor: If used at the beginning of the pattern, specifies the start of a (sub-)domain of the URL.

'^' : Separator character: This matches anything except a letter, a digit or one of the following: _ - . %.
[and so on...]

@joey04

This comment has been minimized.

Copy link

joey04 commented Jan 9, 2019

This new API is even worse than being restricted to 30k ABP-style rules -- the rules must also be in a single, bundled json file. Thus any rule changes means a full extension update. (Blockers restricted to this API would be "static" in every way.)

Thinking big picture, it's not that surprising. Last year Google started to bundle a lightweight ad blocker in Chrome, and I recall thinking that something like this would happen. On the bright side, perhaps this could be a boon to Mozilla, assuming they don't foolishly neuter their API in the same way.

@Kusresa

This comment has been minimized.

Copy link

Kusresa commented Jan 9, 2019

It is still a draft but is really a big downgrade if it stays this way. Looks to me like Google is doing this to reduce the amount of damage malicious extensions could do using this API by severely limiting the existing one and calling it a privacy and efficiency win....while of course giving more control to Google over what ads/trackers/requests can be blocked. This affects trusted and more advanced extensions like uBO the most.

Hopefully Mozilla and other browser makers don't follow suit on this..

@jspenguin2017

This comment has been minimized.

Copy link

jspenguin2017 commented Jan 10, 2019

declarativeNetRequest in its current state is really underpowered and isn't going to be enough. However, assuming that they will implement a way to modify the rules and the 30k limit will be raised or removed, it looks like the only thing missing is RegExp rules.

Since we will be able to dynamically modify content scripts, we can still implement scriptlets and cosmetic filtering properly.

@uBlock-user

This comment has been minimized.

Copy link
Member

uBlock-user commented Jan 10, 2019

It's still not set in stone, so lets see where it goes.

@gorhill

This comment has been minimized.

Copy link
Member

gorhill commented Jan 21, 2019

It's still not set in stone

The fact that they are planning to remove a proper blocking webRequest API with no word of an equivalent replacement is a sign of intent, that is, reducing the level of user agency in their user agent (aka Google Chrome).

How to do this? Use privacy/performance as Trojan arguments to rationalize reducing user agency over what all bloated web sites throw at people's user agents. That new declarativeNetRequest API seriously reduces what blockers can do, to the point they will become distinguishable only by their UI, not their capabilities. As a user, I personally wouldn't accept browsing the world wild web without the advanced features in uBO, I find this unthinkable.

There are no issue of privacy/performance with uBO, rather the opposite by giving back to users the power of clamping down on what web sites throw at them, so that argument is just plain fallacious as far as uBO is concerned.

Chromium got its webRequest API at a time it was trying to gain market share against Firefox (Sep 2011), where Adblock Plus, Ghostery, Disconnect, NoScript, and other such extensions were the most or among the most popular extensions on Firefox.

I don't expect Firefox to follow suit and also deprecate its own webRequest API.[1] I am confident uBO will still exist on Firefox.[2]


[1] Actually Firefox's own webRequest API is better designed as it's possible to return a Promise, which makes it possible to defer returning an answer to some point in the future.

[2] Which is already better equipped than Chromium's version of uBO -- example, example -- (and also better equipped than the Firefox legacy version).

@uBlock-user

This comment has been minimized.

Copy link
Member

uBlock-user commented Jan 21, 2019

is a sign of intent

Yes, but they're not doing this specifically targeting uBO, other blockers will be affected by this too, won't they ? So I still think it won't end up like this. Like you said, it will be the death of these two extensions, why would they bother doing that after all this time ? If they wanted to kill uBO, they could have done this years ago by deprecating APIs or limiting them.

@gorhill

This comment has been minimized.

Copy link
Member

gorhill commented Jan 21, 2019

I'm not saying they are targeting uBO specifically, more that they are targeting the capabilities expressed in uBO/uMatrix.

What is being said now is that the maximum capabilities content blockers will be allowed come down to a maximum of 30,000 ABP-compatible filters.

Even without dynamic filtering and per-site switches, etc., uBO already enforces over 90,000 filters (which themselves go beyond ABP filter syntax) with just the default filter lists, not counting the regional one which may be activated automatically at first install, and other commonly used ones such as Fanboy Social. When I select only EasyList, uBO reports 42,000 network filters, so even EasyList alone won't be enforceable with the declarativeNetRequest API.

Beside the low maximum of 30,000, ABP-compatible filters have no sense of specificity, hence why dynamic filtering can't be implemented with such approach (and if they did it would be a pain to have to recompile the whole filtering profile when merely adding/removing a rule/switch through a click). Also, this makes it impossible to implement important filter option, which purpose is to override exception filters.

So I still think it won't end up like this.

My comments are made with what is being said now with regard to manifest v3.

@colbycdev

This comment was marked as off-topic.

Copy link

colbycdev commented Jan 21, 2019

@uBlock-user

This comment has been minimized.

Copy link
Member

uBlock-user commented Jan 21, 2019

At this juncture, assuming it will get implemented, can you do something about it like not updating to v3 ? or should Chromium users be ready to abandon ship for good ?

@gorhill

This comment has been minimized.

Copy link
Member

gorhill commented Jan 21, 2019

should Chromium users be ready to abandon ship for good ?

I won't tell people what to do. I am pointing out that removing the blocking ability of the webRequest API means the death of uBO, I won't work to make uBO less than what it is now. I quote the document (my emphasis):

WebRequest

Summary

In Manifest V3, we will strive to limit the blocking version of webRequest, potentially removing blocking options from most events (making them observational only). Content blockers should instead use declarativeNetRequest (see below). It is unlikely this will account for 100% of use cases (e.g., onAuthRequired), so we will likely need to retain webRequest functionality in some form.

Currently uBO uses blocking listeners on both webRequest.onBeforeRequest (to implement static-, rule-, switch-based network filtering) and webRequest.onHeadersReceived (to implement disabling or restricting JS execution, static filters' csp= options, large media filtering, and other filtering capabilities).[1]

With this information on hands, everybody is free to decide for themselves.


[1] There are four listeners in the webRequest API which can be used in blocking mode: onBeforeRequest(uBO, uMatrix), onBeforeSendHeaders(uMatrix), onAuthRequired, onHeadersReceived(uBO, uMatrix). uBO uses two of them, uMatrix uses three of them.

@colbycdev

This comment was marked as off-topic.

Copy link

colbycdev commented Jan 21, 2019

@Kusresa

This comment has been minimized.

Copy link

Kusresa commented Jan 22, 2019

I think the best thing people can really do for now is to get the word out to extension developers and browser developers (especially Google) that the proposed APIs and manifest should not be restricted to such an extent and that users should retain enough freedom and capabilities to easily control what to do with extensions and requests within their browser.

Once the requests API in the manifest v3 proposal is set in stone and implemented it will be too late of a surprise for the majority of unaware extension users who will notice a shifting of how and what ads/trackers/requests get blocked and it will be near impossible to rollback the changes as the browser market leader has a low incentive to do so.

I don't want to sound too dramatic but the implementation of the requests API in the manifest v3 proposal as it is right now could be the beginning of something that will have wider implications on the web and users' ability to decide how they can browse it. Due to Google's position of power on the web and influence on websites it will almost certainly affect more than just Chromium/Chrome users.

@uBlock-user

This comment has been minimized.

Copy link
Member

uBlock-user commented Jan 23, 2019

https://groups.google.com/a/chromium.org/d/msg/chromium-extensions/veJy9uAwS00/MZc9Q6nBGgAJ

Once v3 moves to production, there will be a transition period before support for v2 is removed. There is not a firm timeline yet, but we will announce it broadly once there is.

https://groups.google.com/a/chromium.org/d/msg/chromium-extensions/veJy9uAwS00/7Y7jVLTCGgAJ

@okiehsch

This comment has been minimized.

Copy link

okiehsch commented Jan 23, 2019

So far I haven't seen any comments coming from Adblock Plus/AdBlock people.

https://groups.google.com/a/chromium.org/d/msg/chromium-extensions/veJy9uAwS00/vIkW_hLCGgAJ

@colbycdev

This comment was marked as off-topic.

Copy link

colbycdev commented Jan 23, 2019

They can also do away with "inefficient" rules
How about ensuring their own ads can't be blocked? It's feasible with Chrome handling everything, and they are an ad driven company.
I've myself already completely switched to Firefox. Slower, but more privacy and user choices friendly

@uBlock-user

This comment has been minimized.

Copy link
Member

uBlock-user commented Jan 23, 2019

I am not sure when the declarativeNetRequest API became publicly documented

https://docs.google.com/document/d/1E5bV3nYlj6UvNblk_mG2DYbwFVK-qnl5KnEYHqKpgAM/edit?usp=sharing

Around since Feb 2017 as per c17 in that bug you found on the tracker.

@baraa272

This comment was marked as off-topic.

Copy link

baraa272 commented Jan 23, 2019

They can also do away with "inefficient" rules
How about ensuring their own ads can't be blocked? It's feasible with Chrome handling everything, and they are an ad driven company.
I've myself already completely switched to Firefox. Slower, but more privacy and user choices friendly

use waterfox its same speed as chrome and not bloat like original firefox

@lewisje

This comment was marked as off-topic.

Copy link

lewisje commented Jan 23, 2019

and even less compatible with the modern Web

@baraa272

This comment was marked as off-topic.

Copy link

baraa272 commented Jan 23, 2019

anyway adding to this matter its looks like users will have 2 choices either

  1. abandon chrome and its forks for good
  2. finding a way to implement ublock internally like brave adblocker
@baraa272

This comment was marked as off-topic.

Copy link

baraa272 commented Jan 23, 2019

@baraa272 That's what I use on desktop. No android version, unfortunately

Sent from my TETRA using FastHub

theres waterfox in play store lol
but I wont recommend it
Just Use Brave in android its the best

@gorhill

This comment has been minimized.

Copy link
Member

gorhill commented Jan 23, 2019

I am supposed to comment in the Google Groups thread how uBO is affected specifically, so I should spent some time to gather all the details about how the ABP-like matching engine does not cut it for uBO.

But as observed by @joey04 above, the biggest setback is that the API is declarative, all the rules are to be shipped in a JSON file in the extension.

How do you create custom filters? How do you point-and-click to create a rule which override one from a 3rd-party list? Etc.

The declarativeNetRequest API is actually really a replacement for declarativeWebContent (which has been lingering in beta for years). You can't replace a non-declarative API, webRequest, with a declarative one -- this makes no sense. The fact that declarativeNetRequest is presented as a replacement for webRequest tells me I would be just wasting time at this point.

I will keep watching the design doc to see if there is any meaningful change of interest to uBO.

@gorhill

This comment has been minimized.

Copy link
Member

gorhill commented Jan 23, 2019

Can you guys please stop posting off-topic comments? This issue is about "Chrome extension manifest v3 proposal". I am interested only in comments which specifically address the Chrome extension manifest v3 proposal.

@uBlockOrigin uBlockOrigin locked as off topic and limited conversation to collaborators Jan 23, 2019

@uBlockOrigin uBlockOrigin deleted a comment from colbycdev Jan 23, 2019

@uBlockOrigin uBlockOrigin deleted a comment from baraa272 Jan 23, 2019

@gorhill

This comment has been minimized.

Copy link
Member

gorhill commented Jan 23, 2019

https://groups.google.com/a/chromium.org/d/msg/chromium-extensions/veJy9uAwS00/7Y7jVLTCGgAJ:

Because of this, we are certain that we will need to keep the webRequest API around. We are discussing limiting its capabilities, though these exact limitations are still being discussed (and is the main reason we are gathering feedback about what can/cannot be accomplished today with declarativeNetRequest).

So maybe there is hope, ideally of course would be to keep the webRequest API as is.

@uBlockOrigin uBlockOrigin deleted a comment from baraa272 Jan 23, 2019

@gorhill

This comment has been minimized.

Copy link
Member

gorhill commented Jan 23, 2019

Thomas Greiner makes a good point:

Finally, I'd like to point out that due to the ever-evolving nature of the Web, it's quite tricky to provide specific examples for features that will be required from such a content filtering engine to provide a good enough quality

Example which came to mind is the new csp= option. We couldn't predict that the need for such an option would come up, it's the result of trying to find solutions to what web sites throw at users through their browser.

@mapx-

This comment has been minimized.

@okiehsch

This comment has been minimized.

Copy link

okiehsch commented Jan 23, 2019

Adblock/Plus can't be happy with the proposed changes, the 30,000 filters limit would cripple all ad/content-blockers and I really don't understand how nobody responsible for the draft proposal saw that beforehand, even Apple has a 50,000 limit which is bad enough.

@okiehsch

This comment has been minimized.

Copy link

okiehsch commented Jan 23, 2019

By the way, Mozilla has also announced that they will transition to manifest v3 in 2019.
https://blog.mozilla.org/addons/2018/10/26/firefox-chrome-and-the-future-of-trustworthy-extensions

They obviously do not have to use Chromium's version, but ....

@gwarser

This comment has been minimized.

Copy link
Member

gwarser commented Jan 23, 2019

@okiehsch

This comment has been minimized.

Copy link

okiehsch commented Jan 23, 2019

I would not be surprised, the goal of the migration to a WebExtensions API was to simplify cross-browser development by providing commonly-supported methods and interfaces.
Adding a different manifest works against that stated aim.

@gorhill

This comment has been minimized.

Copy link
Member

gorhill commented Jan 24, 2019

they begin to prepare the ground

Excerpt from the comment:

an extension will directly impact the amount of memory required

Pervasive bloated web sites is where the performance issue is. Content blockers are the solution for this. Anybody can see for themselves by loading a web page from most of almost any top site, and see the result with uBO enabled, and the result without uBO enabled. And somehow we are being misled to believe content blockers need fixing, while they are the solution to the rampant bloat (leaving aside the privacy nightmare of those bloated sites and the ubiquitousness of facebook.com, twitter.com, google.com, et al. as 3rd parties)

@gorhill

This comment has been minimized.

Copy link
Member

gorhill commented Jan 25, 2019

More interesting feedback in the discussion thread, which make me realize more issues than just a non-working webRequest API.

Here is another issue raised by others: the replacement of background pages with ServiceWorkers. My immediate understanding of this is that uBO won't be able to use document.createElement in its mani process. uBO uses this API to:

  • Create a div element which purpose is to detect whether a cosmetic filter is valid (code)
  • Create a script element to create dynamic content script which purpose is to wrap scriplet injection code (code)

The former is not trivially replaceable. Not sure how this would be fixed, if possible at all. The second might be fixable through some proposed dynamic content script API talked about in the design document.

@mapx-

This comment has been minimized.

Copy link

mapx- commented Jan 29, 2019

https://groups.google.com/a/chromium.org/forum/#!msg/chromium-extensions/qNqURIh4Nss/mjJ5npmAHAAJ

You could add your thoughts here @gorhill , for example about the maximum number of rules, dynamic rules etc

@gorhill

This comment has been minimized.

Copy link
Member

gorhill commented Jan 29, 2019

I already did leave feedback in the other official thread.

@uBlock-user uBlock-user pinned this issue Feb 2, 2019

@gwarser

This comment has been minimized.

Copy link
Member

gwarser commented Feb 15, 2019

https://groups.google.com/a/chromium.org/forum/#!msg/chromium-extensions/veJy9uAwS00/_mP63xBXAwAJ

Hi,
Cliqz engineer here.
We released a study about content-blockers performance today and found that the performance of the most popular ones is not an issue: https://whotracks.me/blog/adblockers_performance_study.html

TL;DR: they are all very efficient, having median decision times per request anywhere between 7 μs and 1 ms (depending on the extension), which is at least three orders of magnitude less than the requests themselves.
Their performance is also continuously evolving thanks to the innovations and hard work of developers, browser improvements, technologies like WebAssembly, etc. and we do not see how this will cause an issue in the future.[...]

@okiehsch

This comment has been minimized.

Copy link

okiehsch commented Feb 16, 2019

First "official" response.

https://groups.google.com/a/chromium.org/forum/#!topic/chromium-extensions/WcZ42Iqon_M

Dynamic Rule Support: We agree that this is valuable in creating sophisticated content blocking extensions, and will be adding support for declarative rules that can be added or removed at runtime to the declarativeNetRequest API.

Increased Ruleset Size: We will raise the rule limit from the draft 30K value. However, an upper limit is still necessary to ensure performance for users. Block lists have tended to be “push-only”, where new rules are added but obsolete rules are rarely, if ever, removed (external research has shown that 90% of EasyList blocking rules provided no benefit in common blocking scenarios). Having this list continue to grow unbounded is problematic.

Additional Actions and Conditions: We plan to add support for matching based on more conditions, such as resource size, and will provide actions to modify parts of a request instead of just blocking it, such as stripping cookies. We are also investigating other conditions and actions that may make sense to add, such as matching based on top-level domain. (One additional note: While we are investigating adding support for CSP modifications, adding a CSP header to disable JavaScript was frequently mentioned as a use-case; this is already possible through the contentSettings API. If this is insufficient, please let us know why.)

@uBlock-user

This comment has been minimized.

Copy link
Member

uBlock-user commented Feb 16, 2019

Dynamic Rule Support: We agree that this is valuable in creating sophisticated content blocking extensions, and will be adding support for declarative rules that can be added or removed at runtime to the declarativeNetRequest API.

So we will still be able to add filters to my Filters in uBO ?

We plan to add support for matching based on more conditions, such as resource size, and will provide actions to modify parts of a request instead of just blocking it, such as stripping cookies.

That sounds like modifying the response, no ? HTML Filtering ?

@gorhill

This comment has been minimized.

Copy link
Member

gorhill commented Feb 16, 2019

That sounds like modifying the response, no ? HTML Filtering ?

No, just some response headers, they will pick which ones can be modified.

Still no word on the nature of the matching algorithm -- Easylist-like matching algorithm does not work for uBO's dynamic filtering and uMatrix as a whole.

Strict blocking needs to generate a page on the fly according to what happened filter-wise, this can't happen with a declarative API.

Solution is incredibly simple, just keep the blocking ability of the webRequest API. Nothing of what was said in the post still properly justify removing this ability -- it's really, really hard to not suspect the real reasons are not technical neither altruistic.

The "push-only" nature of filter lists is a sound argument, but that is not a browser issue, this is an issue to be tackled by filter list maintainers and content blocker developers.

And as I already argued, one can use uBO without any filter lists in default-deny mode, but that would go away with an Easylist-like matching algorithm, so such worries can't be genuine when they remove the ability for a content blocker to not rely on any filter list.

With the declarativeNetRequest API, not only the browser gets to decide the limit on how matching algorithm work, but will also be in a position to collect what exact filter triggered a block. Content blockers using a still-working webRequest API would get in the way of this because the browser can only know that something was blocked, not what exactly caused the blocking.

Users are free to install whatever content blocker they wish, and they will be free to install the declarativeNetRequest-based ones if they are convinced by the arguments out there of why it's best for them. The only reason I can see for removing the blocking ability of the webRequest API is that it might interfere with the spread of content blockers relying on the declarativeNetRequest API because the webRequest ones will still give users greater agency.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.