Summary: This UI can use the setDrag call to reduce clutter on the reodering dialog.
Test Plan:
Reorder some columns, save.
{F4959906}
Reviewers: epriestley
Reviewed By: epriestley
Subscribers: Korvin
Differential Revision: https://secure.phabricator.com/D17898
Summary: Various little fixes, mostly moves information from the "Details" section either into the curtain or into the specific watchers or members list based on user viewership. I think this page is both cleaner and more informative.
Test Plan:
Lock, Unlock, Watch, Join, various projects with multiple users.
{F4959101}
Reviewers: epriestley
Reviewed By: epriestley
Subscribers: Korvin
Differential Revision: https://secure.phabricator.com/D17891
Summary: Fixes T12713. We don't need to show watching and member info on other views other than ApplicationSearch (for now) so add a few methods to restrict the calls.
Test Plan: Visit project search, profile, project home, project home with subprojects
Reviewers: epriestley
Reviewed By: epriestley
Subscribers: Korvin
Maniphest Tasks: T12713
Differential Revision: https://secure.phabricator.com/D17883
Summary: Slightly nicer, more consistent UI. Also removed "Column History" from dropdowns as this is available on the general board manage page.
Test Plan: Review Board and Column management pages.
Reviewers: epriestley
Reviewed By: epriestley
Subscribers: Korvin
Differential Revision: https://secure.phabricator.com/D17881
Summary:
Fixes T12710. See that task for discussion. This is pretty ugly/redundant but not broken.
(Feel free to reject this and pursue something else.)
Test Plan:
- For a project with active subprojects/milestones, viewed the project profile and subprojects tabs.
- After patch: they're ugly, but no longer fatal.
Reviewers: chad
Reviewed By: chad
Maniphest Tasks: T12710
Differential Revision: https://secure.phabricator.com/D17882
Summary: Moves "reorder columns" and "change background" up a level, redesigns "manage" page to be a little cleaner.
Test Plan: Change colors, reorder columns, manage page, disable board, re-enable board.
Reviewers: epriestley
Reviewed By: epriestley
Subscribers: Korvin
Differential Revision: https://secure.phabricator.com/D17879
Summary: Fixes T12707 Adds additional information to search results for if user is a member or a watcher of a project. Also removed the icon colors, which I'll find a better way to denote in future.
Test Plan: Join a project, watch a project, view results list in /projects/
Reviewers: epriestley
Reviewed By: epriestley
Subscribers: Korvin
Maniphest Tasks: T12707
Differential Revision: https://secure.phabricator.com/D17880
Summary: This brings up "Edit Column" as an action item under the main column dropdown as well as a "Column History" for completeness. Unsure column history is actually useful, but leaving it in anyways. It might be nice to have some sort of dialog version of a history page.
Test Plan: Make a workboard, add a column, edit column name, stay on workboard.
Reviewers: #blessed_reviewers, epriestley
Reviewed By: #blessed_reviewers, epriestley
Subscribers: epriestley
Differential Revision: https://secure.phabricator.com/D17874
Summary: Ref T12707. Adds a simple filter for the viewer if logged in.
Test Plan: Watch a project, click on watching list, see project I'm watching.
Reviewers: epriestley
Reviewed By: epriestley
Subscribers: epriestley
Maniphest Tasks: T12707
Differential Revision: https://secure.phabricator.com/D17873
Summary: The ports over a similar "profile image" menu item to Projects. It gives us some room to use the project icon in the sidenav along with a larger photo. It also will open up some room in the sub-page headers for us to focus on that page, and not the identity of the project at hand. Expect a few more project related touch up diffs.
Test Plan:
Review new projects menu on a few projects, update the image, see new image. Great for team photos.
{F4951264}
Reviewers: epriestley, amckinley
Reviewed By: epriestley
Subscribers: Korvin
Differential Revision: https://secure.phabricator.com/D17869
Summary: Fixes T12659. Previously this would lead to an error when trying to run `arc diff` on a revision that had a milestone as a reviewer (or any non-octothorpe'd Object Name)
Test Plan: Followed repro steps in T12659 and didn't get the error described. Also clicked around and didn't notice any obvious regressions in projects or differential
Reviewers: epriestley, #blessed_reviewers
Reviewed By: epriestley, #blessed_reviewers
Subscribers: Korvin, yelirekim
Maniphest Tasks: T12659
Differential Revision: https://secure.phabricator.com/D17807
Summary:
D17384 added a "keywords" field but only partially implemented it.
- Remove this field.
- Index project slugs as part of the document body instead.
Test Plan:
- Ran `bin/search index PHID-PROJ-... --force`.
- Found project by searching for a unique slug.
Reviewers: chad, 20after4
Reviewed By: chad
Differential Revision: https://secure.phabricator.com/D17596
Summary:
The goal is to make fulltext search back-ends more extensible, configurable and robust.
When this is finished it will be possible to have multiple search storage back-ends and
potentially multiple instances of each.
Individual instances can be configured with roles such as 'read', 'write' which control
which hosts will receive writes to the index and which hosts will respond to queries.
These two roles make it possible to have any combination of:
* read-only
* write-only
* read-write
* disabled
This 'roles' mechanism is extensible to add new roles should that be needed in the future.
In addition to supporting multiple elasticsearch and mysql search instances, this refactors
the connection health monitoring infrastructure from PhabricatorDatabaseHealthRecord and
utilizes the same system for monitoring the health of elasticsearch nodes. This will
allow Wikimedia's phabricator to be redundant across data centers (mysql already is,
elasticsearch should be as well).
The real-world use-case I have in mind here is writing to two indexes (two elasticsearch clusters
in different data centers) but reading from only one. Then toggling the 'read' property when
we want to migrate to the other data center (and when we migrate from elasticsearch 2.x to 5.x)
Hopefully this is useful in the upstream as well.
Remaining TODO:
* test cases
* documentation
Test Plan:
(WARNING) This will most likely require the elasticsearch index to be deleted and re-created due to schema changes.
Tested with elasticsearch versions 2.4 and 5.2 using the following config:
```lang=json
"cluster.search": [
{
"type": "elasticsearch",
"hosts": [
{
"host": "localhost",
"roles": { "read": true, "write": true }
}
],
"port": 9200,
"protocol": "http",
"path": "/phabricator",
"version": 5
},
{
"type": "mysql",
"roles": { "write": true }
}
]
Also deployed the same changes to Wikimedia's production Phabricator instance without any issues whatsoever.
```
Reviewers: epriestley, #blessed_reviewers
Reviewed By: epriestley, #blessed_reviewers
Subscribers: Korvin, epriestley
Tags: #elasticsearch, #clusters, #wikimedia
Differential Revision: https://secure.phabricator.com/D17384
Summary: Ref T10390. Dashboard usability is high enough that I think we should pin it by default for users to create custom home pages.
Test Plan: Review order of applications in sandbox.
Reviewers: epriestley
Reviewed By: epriestley
Subscribers: Korvin
Maniphest Tasks: T10390
Differential Revision: https://secure.phabricator.com/D17527
Summary: These were once ordered, but I think we switched to being defined in the Engine and never implemented the sorts there. This adds sort ordering to Tasks, Projects, and Repositories.
Test Plan: Review Favorites Menu in local install, see order is now set per the engine. Click Edit Favorites, and re-order. See order sticks.
Reviewers: epriestley
Reviewed By: epriestley
Subscribers: Korvin
Differential Revision: https://secure.phabricator.com/D17490
Summary: This should be blue, not grey.
Test Plan: Add a milestone and subproject to a project
Reviewers: epriestley
Reviewed By: epriestley
Subscribers: Korvin
Differential Revision: https://secure.phabricator.com/D17477
Summary:
Ref T12314. Ref T6064. Ref T11580. If an install defines several different task create forms (like "Create Plant" and "Create Animal"), allow any of them to be created directly onto a workboard column.
This is just a general consistency improvement that makes Custom Forms and Workboards work together a bit better. We might do something fancier eventually for T6064 (which wants fewer clicks) and/or T11580 (which wants per-workboard control over forms or defaults).
Test Plan:
- Created several different types of tasks directly onto a workboard.
- Faked just one create form, saw the UI unchanged (except that it respects any renaming).
{F3492928}
Reviewers: chad
Reviewed By: chad
Maniphest Tasks: T12314, T11580, T6064
Differential Revision: https://secure.phabricator.com/D17446
Summary:
Ref T12314. When we pick an "Edit" form for a subtyped object, only consider forms with the same subtype.
For example, editing an "Animal" uses the forms with subtype "animal" which are marked as edit forms.
This also makes "Create Subtask" carry the parent task's type.
Test Plan:
- Edited an Animal, got an animal edit form.
- Edited a normal task, got a normal task form.
- Edited a paste, got the normal workflow.
Reviewers: chad
Reviewed By: chad
Maniphest Tasks: T12314
Differential Revision: https://secure.phabricator.com/D17445
Summary: Fixes T12330. Minor UI nit, since we use "disabled" to usually mean "no permission". Makes these links always normal looking.
Test Plan: Review a new project in sandbox.
Reviewers: epriestley
Reviewed By: epriestley
Subscribers: Korvin
Maniphest Tasks: T12330
Differential Revision: https://secure.phabricator.com/D17436
Summary:
Ref T12319. Currently, `bin/lipsum` uses substring matches against human-readable text to chose which objects to generate.
Instead:
- Use separate selector keys which are guaranteed to be unique.
- When a match is exact, select only that generator.
- When a match is ambiguous, fail and warn the user.
Test Plan: Generated several types of objects, tried to generate ambiguous objects like "e".
Reviewers: chad
Reviewed By: chad
Maniphest Tasks: T12319
Differential Revision: https://secure.phabricator.com/D17420
Summary: Ref T10390. Simplifies dropdown by rolling out canUseInPanel in useless panels
Test Plan: Add a query panel, see less options.
Reviewers: epriestley
Reviewed By: epriestley
Subscribers: Korvin
Maniphest Tasks: T10390
Differential Revision: https://secure.phabricator.com/D17341
Summary: Moves profile/project to use more standard colored boxes. Reverts dashboard border colors. Ensures better High-Contrast application more consistently across these projects. Also fix T12211.
Test Plan: Home, People, Projects in High Contrast / Standard
Reviewers: epriestley
Reviewed By: epriestley
Subscribers: Korvin
Maniphest Tasks: T12211
Differential Revision: https://secure.phabricator.com/D17321
Summary: Lots of little details, fix workboard bg colors, darken up global backgrounds just a hair, add more "widgety" look to dashboard panels, remove underline on anchors on mobile. Also Fixes T12210
Test Plan: Use lots of pages on mobile and desktop.
Reviewers: epriestley
Reviewed By: epriestley
Subscribers: Korvin
Maniphest Tasks: T12210
Differential Revision: https://secure.phabricator.com/D17315
Summary:
Ref T12174. This isn't really a "newManageItem()" since Projects have a separate manage screen.
That is, I incorrectly changed the "Manage [This Project]" item into a "Edit Menu" item, so some options (like "Archive Project") incorrectly became inaccessible.
Test Plan: Viewed a project, saw the right menu item, clicked it, could archive/etc project. Also edited the menu.
Reviewers: chad
Reviewed By: chad
Maniphest Tasks: T12174
Differential Revision: https://secure.phabricator.com/D17275
Summary:
Ref T12174. This fixes more bugs than it creates, I think:
- Dashboards now show the whole menu.
- Project and home items now show selected state correctly.
- The "choose global vs personal" thing is now part of MenuEngine, and the same code builds it for Home and Favorites.
- Home now handles defaults correctly, I think.
Maybe regression/bad/still buggy?:
- Mobile home is now whatever the default thing was, not the menu?
- Title for dashboard content or other items that render their own content is incorrectly always "Configure Menu" (this was preexisting).
Test Plan:
- Created, edited, reordered, disabled, deleted and pinned personal and global items on home, favorites, and projects.
- Also checked User profiles.
Reviewers: chad
Reviewed By: chad
Maniphest Tasks: T12174
Differential Revision: https://secure.phabricator.com/D17273
Summary: Ref T11957. Needs some more polish, but I think everything here is square.
Test Plan: Add personal/global items to home, test mobile. Test workboards / colors.
Reviewers: epriestley
Reviewed By: epriestley
Subscribers: 20after4, rfreebern, Korvin
Maniphest Tasks: T11957
Differential Revision: https://secure.phabricator.com/D17259
Summary:
Ref T11957. When you click a dashboard item, it now sends you to `/<app>/item/view/123/`, which renders the proper crumbs, navigation, etc., with the dashboard as page content.
This works as you'd expect in Projects:
{F2508568}
It's sliiiightly odd in Favorites since we nuke the nav menu, but seems basically fine?
{F2508571}
Test Plan:
- Created a dashboard panel on a project.
- Clicked it, saw it render.
- Made it the default panel, viewed project default screen, saw dashboard.
- Disabled every panel I could, still saw reasonable behavior (this is silly anyway).
Reviewers: chad
Reviewed By: chad
Maniphest Tasks: T11957
Differential Revision: https://secure.phabricator.com/D17255
Summary: Ref T5867. Instead of hard-coding projects, tasks and repositories, let EditEngines say "I want a quick create item" so third-party code can also hook into the menu without upstream changes.
Test Plan: Saw same default items in menu.
Reviewers: chad
Reviewed By: chad
Maniphest Tasks: T5867
Differential Revision: https://secure.phabricator.com/D17215
Summary:
Ref T12074. This uses more consistent Conduit keys for constraint names.
This is a minor compatibility break on watchers/members but since these methods are more useful now this is probably a good time to try to get away with it, and a more consistent API is better in the long run. I need to issue compatibility guidance for the milestones thing anyway and that one isn't avoidable, so try to rip the bandage off all in one go.
Test Plan: Reviewed new constraint names from console, called methods using them.
Reviewers: chad
Reviewed By: chad
Maniphest Tasks: T12074
Differential Revision: https://secure.phabricator.com/D17161
Summary:
Ref T12074. The "v3" API methods (`*.search`, `*.edit`) are currently marked as "unstable", but they're pretty stable and essentially all new code should be using them.
Although these methods are seeing some changes, almost all changes are additive (support for new constraints or attachemnts) and do not break backward compatibility. We have no major, compatibility-breaking changes planned.
I don't want to mark the older methods "deprecated" yet since `arc` still uses a lot of them and there are some capabilities not yet available on the v3 methods, but introduce a new "frozen" status with pointers to the new methods.
Overall, this should gently push users toward the newer methods.
Test Plan: {F2325323}
Reviewers: chad
Reviewed By: chad
Maniphest Tasks: T12074
Differential Revision: https://secure.phabricator.com/D17158
Summary:
Ref T12074. Provide a basic but functional v3 API endpoint for reading workboard column information.
There is no equivalent to this in the UI yet, although there may be some day (perhaps adjacent to T5024).
Test Plan:
- Queried for all columns.
- Queried for columns on a particular board using `projectPHIDs`.
Reviewers: chad
Reviewed By: chad
Maniphest Tasks: T12074
Differential Revision: https://secure.phabricator.com/D17157
Summary:
Ref T12074. This allows callers to identify which columns an object appears in (currently, always tasks).
There are a few major cases:
- Object is in a normal column: we return column information.
- Object is in a proxy column (subproject or milestone). For example, when you look at the board for "Some Parent Project", the task might show up in a milestone column. I've chosen to not return anything in this case: you can figure out that the task is there by looking at the project structure, and this is kind of an internal artifact of the implementation and probably not useful to callers.
- Project does not have a workboard: we return nothing.
These seem fairly reasonable, I think?
Test Plan:
- Queried for tasks, using the "columns" attachment.
- Dragged a task across a board, querying it repeatedly. Got expected results for normal column (the column), subprojects with no board (nothing), milestones with no board (nothing) and mielstones/subprojects with a board (the column on //that// board, only, not the proxy column on the parent).
Reviewers: chad
Reviewed By: chad
Maniphest Tasks: T12074
Differential Revision: https://secure.phabricator.com/D17156
Summary:
Ref T12074. Allows querying for project by direct parent (find only immediate children) or any ancestor (find all descendants) using the API.
There's no proper web UI for this since I'm not sure how useful it is, but you can `/project/?parent=PHID-PROJ-...` or `/project/?ancestor=...` for now. We can add UI later if/when use cases arise, but it's not immediately clear to me that this is useful to do from the web.
Test Plan:
- From API, queried with `parentPHIDs` and `ancestorPHIDs`, finding direct children only and all descendants, respectively.
- From web UI, fiddled with `?parent=...` and `?ancestor=...` to make sure they work too. This isn't intended to be a user-facing feature.
Reviewers: chad
Reviewed By: chad
Maniphest Tasks: T12074
Differential Revision: https://secure.phabricator.com/D17155
Summary:
Ref T12074.
- Adds a new "parent" property on main results. This shows an abbreviated version of the project's parent, or `null` if the project is a root project.
- Adds a new "ancestor" attachment to pull the entire ancestor list.
- Adds a new "depth" property on main results.
- You can use "parent" or "depth" to tell if a project is a subproject or not.
These attempt to balance convenience, power, and performance: the full ancestor list can be big so I made it an attachment, but the other stuff isn't too big and is cheap and seems reasonable to always include.
Test Plan:
In API results:
- Saw null parent (root projects) and non-null parent (subprojects/milestones).
- Used "ancestors" attchment, got full list of ancestors.
- Saw appropriate "depth" values.
Reviewers: chad
Reviewed By: chad
Maniphest Tasks: T12074
Differential Revision: https://secure.phabricator.com/D17154
Summary:
Ref T12074.
- `project.search` now returns milestones by default.
- A new constraint, `isMilestone`, allows filtering to milestones, non-milestones, or both (API and web UI).
- `project.search` now returns a milestone number for milestones, or `null` for non-milestones.
NOTE: Existing custom saved queries in projects which previously did not return milestones now will. I expect this to have little-to-no impact on users, and these queries are easy to correct, but I'll note this in changelogs.
Test Plan:
- Ran various queries with `project.search` and in the web UI, searching for milestones, non-milestones, and both.
- Web UI default behavior (no milestones) is unchanged, but you can now get milestones if you want them.
- Queried a milestone by ID/PHID via API.
Reviewers: chad
Reviewed By: chad
Maniphest Tasks: T12074
Differential Revision: https://secure.phabricator.com/D17153
Summary:
Ref T9058. The stricter filtering is over-filtering Handles. For example, in the Phacility cluster, users can not see Almanac services.
So this filtering happens:
- The AlmanacServiceQuery filters the service beacuse they can't see the application.
- The HandleQuery generates a "you can't see this" handle.
- But then the HandleQuery filters that handle! It has a "service" PHID and the user can't see Almanac.
This violates the assumption that all application code makes about handles: it's OK to query handles for objects you can't see, and you'll get something back.
Instead, don't do application filtering on handles.
Test Plan:
- Added a failing test and made it pass.
- As a user who can not see Almanac, viewed an Instances timeline.
- Before patch: fatal on trying to load a handle for a Service.
- After patch: smooth sailing.
Reviewers: chad
Maniphest Tasks: T9058
Differential Revision: https://secure.phabricator.com/D17152
Summary:
Fixes T9058. Normally, "Query" classes apply an application check and just don't load anything if it fails.
However, in some cases (like email recipient filtering) we run policy checks without having run a Query check first. In that case, one user (the actor) loads the object, then we filter it against other users (the recipeints).
Explicitly apply the application check during normal filtering.
Test Plan: Added a failing test case and made it pass.
Reviewers: chad
Reviewed By: chad
Maniphest Tasks: T9058
Differential Revision: https://secure.phabricator.com/D17127
Summary:
Ref T11114. This creates `differential.revision.edit` (a modern, v3 API method) and redefines the existing methods in terms of it.
Both `differential.createrevision` and `differential.updaterevision` are now internally implemented by building a `differential.revision.edit` API call and then executing it.
I //think// this covers everything except custom fields, which need some tweaking to work with EditEngine. I'll clean that up in the next change.
Test Plan:
- Created, updated, and edited revisions via `arc`.
- Called APIs manually via test console.
- Stored custom fields ("Blame Rev", "Revert Plan") aren't exposed yet.
Reviewers: chad
Reviewed By: chad
Maniphest Tasks: T11114
Differential Revision: https://secure.phabricator.com/D17067
Summary: Ref T11957.
Test Plan:
- Viewed an existing project profile.
- Viewed a user profile.
- Created a new project.
- Edited a profile menu.
- Added new profile items.
- Grepped for renamed symbols.
Reviewers: chad
Reviewed By: chad
Maniphest Tasks: T11957
Differential Revision: https://secure.phabricator.com/D17028
Summary:
Ref T11957. This renames the Configuration storage, transaction, query, and PHID type.
No rename on the actual menu item types yet, that's next (and should be the end of this, I think).
Test Plan:
- Viewed projects.
- Viewed profiles.
- Edited a project menu.
- Grepped for all renamed symbols, I think?
Reviewers: chad
Reviewed By: chad
Maniphest Tasks: T11957
Differential Revision: https://secure.phabricator.com/D17027
Summary:
Fixes T11955. Currently, milestones have an internal name of "Parent (Milestone) ...".
This makes them look like they're prefix matches for "Parent", but they're actually prefix matches for "Milestone".
Reorder the names so that the internal name is "Milestone Parent ...".
Test Plan: Created a project "AAA" with milestone "BBB". Searched for "AAA", found "AAA" and milestone "AAA (BBB)".
Reviewers: chad
Reviewed By: chad
Maniphest Tasks: T11955
Differential Revision: https://secure.phabricator.com/D17013
Summary: This is still reasonably functional and useful to people, and we don't have better mechanics to offset the change.
Test Plan: New Workboard, set Workboard color, test mobile, desktop.
Reviewers: epriestley
Reviewed By: epriestley
Subscribers: Korvin
Differential Revision: https://secure.phabricator.com/D16964
Summary: Ref T11034. Try to produce a roughly-one-sentence summary instead of a roughly-one-paragraph summary for the browse dialog.
Test Plan:
- Added unit tests, ran unit tests.
- Wrote a longer summary for a project, browsed to it, saw a shorter summary.
Reviewers: chad
Reviewed By: chad
Maniphest Tasks: T11034
Differential Revision: https://secure.phabricator.com/D16892
Summary:
Ref T8510. Use "\n" as a delimiter between name sections. Specifically, project "AAA" with tag "zzz" should be a better match for query "AAA" than project "AAA BBB" is.
Make use of this delimiter slighlty more obvious in the UI.
Test Plan:
- Created projects "Phacility" and "Phacility Core Access".
- Typed "Phacility".
- Before patch: first hit is "Phacility Core Access".
- After patch: first hit is "Phacility".
- Viewed debugging output table, saw visual explanation of behavior.
Reviewers: chad
Reviewed By: chad
Maniphest Tasks: T8510
Differential Revision: https://secure.phabricator.com/D16886
Summary: Visually, I think these are much cleaner (with colors), and provide more workspace. I also don't really use the sidenav here and if I did, it would be to go back to the project homepage. I think this is overall better. If navigation page to project home is difficult or hard to find, we can maybe make a better header / crumbs bar to reduce that.
Test Plan: New project -> basic new board. Existing project -> color board. Desktop, Mobile, Fullscreen
Reviewers: epriestley
Reviewed By: epriestley
Subscribers: Korvin
Differential Revision: https://secure.phabricator.com/D16882
Summary:
Ref T11853. My CSS change for the more enormous policy dialog was a little too broad, and affected the "You shall not pass!" dialog too.
Narrow the scope of the CSS rules.
Also add a missing "." that I caught.
Test Plan:
- Looked at policy exception dialogs.
- Looked at policy explanation dialogs.
- Looked at the end of that sentence.
Reviewers: chad
Reviewed By: chad
Maniphest Tasks: T11853
Differential Revision: https://secure.phabricator.com/D16841
Summary:
Fixes T11853. To set this up:
- Create "Project A".
- Join "Project A".
- Create a subproject, "Project A Subproject 1".
- This causes Project A to become a parent project.
- This moves you to be a member of "Project A Subproject 1" instead of "Project A" directly.
- Create another subproject, "Project A Subproject 2".
- Do not join this subproject.
- Set the second subproject's policy to "Visible To: Members of Project A".
- Try to edit the second subproject.
Before this change, this fails:
- When querying projects, we sometime try to skip loading the viewer's membership in ancestor projects as a small optimization.
- Via `PhabricatorExtendedPolicyInterface`, we may then return the parent project to the policy filter for extended checks.
- The PolicyFilter has an optimization: if we're checking an object, and we already have that object, we can just use the object we already have. This is common and useful.
- However, in this case it causes us to reuse an incomplete object (an object without proper membership information). We fail a policy check which we should pass.
Instead, don't skip loading the viewer's membership in ancestor projects.
Test Plan:
- Did all that stuff above.
- Could edit the subproject.
- Ran `arc unit --everything`.
Reviewers: chad
Reviewed By: chad
Maniphest Tasks: T11853
Differential Revision: https://secure.phabricator.com/D16840