for (;;);{"error":null,"payload":{"timeline":"\u003cdiv class=\"phui-timeline-older-transactions-are-hidden\" data-sigil=\"show-older-block\"\u003eThere are a very large number of changes, so older changes are hidden. \u003ca href=\"\/transactions\/showolder\/PHID-TASK-gdzyw267wfavjfuqhmus\/?after=5726875&quoteTargetID=UQ0_5&quoteRef=T240307\" data-mustcapture=\"1\" data-sigil=\"show-older-link\"\u003eShow Older Changes\u003c\/a\u003e\u003c\/div\u003e\u003cdiv class=\"phui-timeline-event-view phui-timeline-spacer\"\u003e\u003c\/div\u003e\u003cdiv class=\"phui-timeline-shell\" data-sigil=\"transaction anchor-container\" data-meta=\"0_235\"\u003e\u003cdiv class=\"phui-timeline-event-view phui-timeline-minor-event\"\u003e\u003cdiv class=\"phui-timeline-content\"\u003e\u003ca style=\"background-image: url(https:\/\/phab.wmfusercontent.org\/file\/data\/xgl3wy55ovinfnucvwhx\/PHID-FILE-zocnksypiqutzf5oubpi\/profile)\" class=\"visual-only phui-timeline-image\" href=\"\/p\/tstarling\/\" aria-hidden=\"true\"\u003e\u003c\/a\u003e\u003cdiv class=\"phui-timeline-wedge\" style=\"\"\u003e\u003c\/div\u003e\u003cdiv class=\"phui-timeline-group\"\u003e\u003ca name=\"5726875\" id=\"5726875\" class=\"phabricator-anchor-view\"\u003e\u003c\/a\u003e\u003cdiv class=\"phui-timeline-title phui-timeline-title-with-icon\"\u003e\u003cspan class=\"phui-timeline-icon-fill\"\u003e\u003cspan class=\"visual-only phui-icon-view phui-font-fa fa-pencil phui-timeline-icon\" data-meta=\"0_233\" aria-hidden=\"true\"\u003e\u003c\/span\u003e\u003c\/span\u003e\u003ca href=\"\/p\/tstarling\/\" class=\"phui-handle handle-availability-partial phui-link-person\" data-sigil=\"hovercard\" data-meta=\"0_0\"\u003e\u003cspan class=\"perfect-circle\"\u003e\u2022\u003c\/span\u003e tstarling\u003c\/a\u003e updated the task description. \u003ca href=\"\/transactions\/detail\/PHID-XACT-TASK-spy5am7lhzybpmb\/\" data-sigil=\"workflow\"\u003e(Show Details)\u003c\/a\u003e\u003cspan class=\"phui-timeline-extra\"\u003e\u003ca href=\"#5726875\" data-sigil=\"has-tooltip\" data-meta=\"0_232\"\u003e\u003cspan class=\"screen-only\"\u003eDec 10 2019, 5:23 AM\u003c\/span\u003e\u003cspan class=\"print-only\" aria-hidden=\"true\"\u003e2019-12-10 05:23:55 (UTC+0)\u003c\/span\u003e\u003c\/a\u003e\u003c\/span\u003e\u003c\/div\u003e\u003cdiv class=\"phui-timeline-title phui-timeline-title-with-icon\"\u003e\u003cspan class=\"phui-timeline-icon-fill\"\u003e\u003cspan class=\"visual-only phui-icon-view phui-font-fa fa-pencil phui-timeline-icon\" data-meta=\"0_234\" aria-hidden=\"true\"\u003e\u003c\/span\u003e\u003c\/span\u003e\u003ca href=\"\/p\/tstarling\/\" class=\"phui-handle handle-availability-partial phui-link-person\" data-sigil=\"hovercard\" data-meta=\"0_72\"\u003e\u003cspan class=\"perfect-circle\"\u003e\u2022\u003c\/span\u003e tstarling\u003c\/a\u003e updated the task description. \u003ca href=\"\/transactions\/detail\/PHID-XACT-TASK-uarn5az33gyawxm\/\" data-sigil=\"workflow\"\u003e(Show Details)\u003c\/a\u003e\u003c\/div\u003e\u003c\/div\u003e\u003c\/div\u003e\u003c\/div\u003e\u003c\/div\u003e\u003cdiv class=\"phui-timeline-event-view phui-timeline-spacer\"\u003e\u003c\/div\u003e\u003cdiv class=\"phui-timeline-shell\" data-sigil=\"transaction anchor-container\" data-meta=\"0_239\"\u003e\u003cdiv class=\"phui-timeline-event-view phui-timeline-minor-event\"\u003e\u003cdiv class=\"phui-timeline-content\"\u003e\u003ca style=\"background-image: url(https:\/\/phab.wmfusercontent.org\/file\/data\/56zbzcroo7msdftfgxbi\/PHID-FILE-w6eqlpokawu7gkm3faia\/alphanumeric_lato-dark_B.png-_3c5da0-255%2C255%2C255%2C0.7.png)\" class=\"visual-only phui-timeline-image\" href=\"\/p\/Bawolff\/\" aria-hidden=\"true\"\u003e\u003c\/a\u003e\u003cdiv class=\"phui-timeline-wedge\" style=\"\"\u003e\u003c\/div\u003e\u003cdiv class=\"phui-timeline-group\"\u003e\u003ca name=\"5726890\" id=\"5726890\" class=\"phabricator-anchor-view\"\u003e\u003c\/a\u003e\u003cdiv class=\"phui-timeline-title phui-timeline-title-with-icon\"\u003e\u003cspan class=\"phui-timeline-icon-fill\"\u003e\u003cspan class=\"visual-only phui-icon-view phui-font-fa fa-trophy phui-timeline-icon\" data-meta=\"0_237\" aria-hidden=\"true\"\u003e\u003c\/span\u003e\u003c\/span\u003e\u003cspan class=\"visual-only phui-icon-view sprite-tokens tokens-like-1 phui-timeline-token\" data-meta=\"0_238\" aria-hidden=\"true\"\u003e\u003c\/span\u003e\u003ca href=\"\/p\/Bawolff\/\" class=\"phui-handle phui-link-person\" data-sigil=\"hovercard\" data-meta=\"0_73\"\u003eBawolff\u003c\/a\u003e awarded a token.\u003cspan class=\"phui-timeline-extra\"\u003e\u003ca href=\"#5726890\" data-sigil=\"has-tooltip\" data-meta=\"0_236\"\u003e\u003cspan class=\"screen-only\"\u003eDec 10 2019, 5:28 AM\u003c\/span\u003e\u003cspan class=\"print-only\" aria-hidden=\"true\"\u003e2019-12-10 05:28:37 (UTC+0)\u003c\/span\u003e\u003c\/a\u003e\u003c\/span\u003e\u003c\/div\u003e\u003c\/div\u003e\u003c\/div\u003e\u003c\/div\u003e\u003c\/div\u003e\u003cdiv class=\"phui-timeline-event-view phui-timeline-spacer\"\u003e\u003c\/div\u003e\u003cdiv class=\"phui-timeline-shell\" data-sigil=\"transaction anchor-container\" data-meta=\"0_242\"\u003e\u003cdiv class=\"phui-timeline-event-view phui-timeline-minor-event\"\u003e\u003cdiv class=\"phui-timeline-content\"\u003e\u003ca style=\"background-image: url(https:\/\/phab.wmfusercontent.org\/file\/data\/pftw7tn2jgpwaqdmxbtd\/PHID-FILE-4peudqvgp45hlsggbblo\/profile)\" class=\"visual-only phui-timeline-image\" href=\"\/p\/TK-999\/\" aria-hidden=\"true\"\u003e\u003c\/a\u003e\u003cdiv class=\"phui-timeline-wedge\" style=\"\"\u003e\u003c\/div\u003e\u003cdiv class=\"phui-timeline-group\"\u003e\u003ca name=\"5728302\" id=\"5728302\" class=\"phabricator-anchor-view\"\u003e\u003c\/a\u003e\u003cdiv class=\"phui-timeline-title phui-timeline-title-with-icon\"\u003e\u003cspan class=\"phui-timeline-icon-fill\"\u003e\u003cspan class=\"visual-only phui-icon-view phui-font-fa fa-user-plus phui-timeline-icon\" data-meta=\"0_241\" aria-hidden=\"true\"\u003e\u003c\/span\u003e\u003c\/span\u003e\u003ca href=\"\/p\/TK-999\/\" class=\"phui-handle phui-link-person\" data-sigil=\"hovercard\" data-meta=\"0_74\"\u003eTK-999\u003c\/a\u003e subscribed.\u003cspan class=\"phui-timeline-extra\"\u003e\u003ca href=\"#5728302\" data-sigil=\"has-tooltip\" data-meta=\"0_240\"\u003e\u003cspan class=\"screen-only\"\u003eDec 10 2019, 2:55 PM\u003c\/span\u003e\u003cspan class=\"print-only\" aria-hidden=\"true\"\u003e2019-12-10 14:55:39 (UTC+0)\u003c\/span\u003e\u003c\/a\u003e\u003c\/span\u003e\u003c\/div\u003e\u003c\/div\u003e\u003c\/div\u003e\u003c\/div\u003e\u003c\/div\u003e\u003cdiv class=\"phui-timeline-event-view phui-timeline-spacer\"\u003e\u003c\/div\u003e\u003cdiv class=\"phui-timeline-shell\" data-sigil=\"transaction anchor-container\" data-meta=\"0_253\"\u003e\u003cdiv class=\"phui-timeline-event-view phui-timeline-major-event\"\u003e\u003cdiv class=\"phui-timeline-content\"\u003e\u003ca style=\"background-image: url(https:\/\/phab.wmfusercontent.org\/file\/data\/ms665yc73j6nadjitytk\/PHID-FILE-mocohumlrcbe2lcuplml\/profile)\" class=\"visual-only phui-timeline-image\" href=\"\/p\/Anomie\/\" aria-hidden=\"true\"\u003e\u003c\/a\u003e\u003cdiv class=\"phui-timeline-badges\"\u003e\u003cul class=\"phui-badge-flex-view grouped flex-view-collapsed \"\u003e\u003cli class=\"phui-badge-flex-item\"\u003e\u003ca class=\"phui-badge-mini phui-badge-mini-orange \" href=\"\/badges\/view\/5\/\" data-sigil=\"has-tooltip\" data-meta=\"0_251\"\u003e\u003cspan class=\"visual-only phui-icon-view phui-font-fa fa-rocket\" data-meta=\"0_252\" aria-hidden=\"true\"\u003e\u003c\/span\u003e\u003c\/a\u003e\u003c\/li\u003e\u003c\/ul\u003e\u003c\/div\u003e\u003cdiv class=\"phui-timeline-wedge\" style=\"\"\u003e\u003c\/div\u003e\u003cdiv class=\"phui-timeline-group\"\u003e\u003cdiv class=\"phui-timeline-inner-content\"\u003e\u003ca name=\"5728354\" id=\"5728354\" class=\"phabricator-anchor-view\"\u003e\u003c\/a\u003e\u003cdiv class=\"phui-timeline-title phui-timeline-title-with-icon phui-timeline-title-with-menu\"\u003e\u003cspan class=\"phui-timeline-icon-fill\"\u003e\u003cspan class=\"visual-only phui-icon-view phui-font-fa fa-comment phui-timeline-icon\" data-meta=\"0_250\" aria-hidden=\"true\"\u003e\u003c\/span\u003e\u003c\/span\u003e\u003ca href=\"\/p\/Anomie\/\" class=\"phui-handle phui-link-person\" data-sigil=\"hovercard\" data-meta=\"0_75\"\u003eAnomie\u003c\/a\u003e added a comment.\u003cspan class=\"phui-timeline-extra\"\u003e\u003ca href=\"#5728354\" data-sigil=\"has-tooltip\" data-meta=\"0_249\"\u003e\u003cspan class=\"screen-only\"\u003eDec 10 2019, 3:08 PM\u003c\/span\u003e\u003cspan class=\"print-only\" aria-hidden=\"true\"\u003e2019-12-10 15:08:08 (UTC+0)\u003c\/span\u003e\u003c\/a\u003e\u003c\/span\u003e\u003c\/div\u003e\u003ca href=\"#\" class=\"phui-timeline-menu\" aria-haspopup=\"true\" aria-expanded=\"false\" data-sigil=\"phui-dropdown-menu\" data-meta=\"0_247\"\u003e\u003cspan class=\"aural-only\"\u003eComment Actions\u003c\/span\u003e\u003cspan class=\"visual-only phui-icon-view phui-font-fa fa-caret-down\" data-meta=\"0_248\" aria-hidden=\"true\"\u003e\u003c\/span\u003e\u003c\/a\u003e\u003cdiv class=\"phui-timeline-core-content\"\u003e\u003cspan class=\"transaction-comment\" data-sigil=\"transaction-comment\" data-meta=\"0_76\"\u003e\u003cdiv class=\"phabricator-remarkup\"\u003e\u003cp\u003eI note that for cases where ExtensionFoo wants to add a listener for a hook from ExtensionBar but also wants to maintain the ability to be used when ExtensionBar is not installed, it will need to register a separate listener just for ExtensionBar's hooks because the requisite interfaces won't be available when ExtensionBar is not available. That seems easily possible with the design described here, but may warrant documentation as it may not be immediately obvious.\u003c\/p\u003e\n\n\u003cblockquote\u003e\u003cp\u003eExtensions may implement their own HookRunner style classes along the same lines.\u003cbr \/\u003e\n[...]\u003cbr \/\u003e\nOn what level of modularity should HookRunner and listener interfaces be grouped? I am proposing one HookRunner class in core, and grouping of all core interfaces under a single namespace. Having a single HookRunner in core means that only one service needs to be added to MediaWikiServices, instead of a collection of services or a factory which delivers a module-specific HookRunner.\u003c\/p\u003e\u003c\/blockquote\u003e\n\n\u003cp\u003eThis probably means that MediaWikiServices will wind up being cluttered with global services like "ExtensionFooHookRunner", "ExtensionBarHookRunner", "ExtensionBazHookRunner", and so on.\u003c\/p\u003e\n\n\u003cp\u003eIs the HookRunner meant to actually have any persistent state that justifies it being an actual service, or anything to override for testing that couldn't as well be satisfied by an overridden HookContainer instead? If not, instead of a service it could be more of an internal utility class wrapping HookContainer, intended for uses by composition.\u003c\/p\u003e\n\n\u003cdiv class=\"remarkup-code-block\" data-code-lang=\"php\" data-sigil=\"remarkup-code-block\"\u003e\u003cdiv class=\"remarkup-code-header\"\u003eSome extension class that calls a hook\u003c\/div\u003e\u003cpre class=\"remarkup-code\"\u003e\u003cspan class=\"k\"\u003eclass\u003c\/span\u003e \u003cspan class=\"no\"\u003eMyExt\u003c\/span\u003e \u003cspan class=\"o\"\u003e{\u003c\/span\u003e\n \u003cspan class=\"k\"\u003eprivate\u003c\/span\u003e \u003cspan class=\"nv\"\u003e$hookRunner\u003c\/span\u003e\u003cspan class=\"o\"\u003e;\u003c\/span\u003e\n\n \u003cspan class=\"k\"\u003epublic\u003c\/span\u003e \u003cspan class=\"k\"\u003efunction\u003c\/span\u003e \u003cspan class=\"no\"\u003e__construct\u003c\/span\u003e\u003cspan class=\"o\"\u003e(\u003c\/span\u003e \u003cspan class=\"no\"\u003eHookContainer\u003c\/span\u003e \u003cspan class=\"nv\"\u003e$hookContainer\u003c\/span\u003e \u003cspan class=\"o\"\u003e)\u003c\/span\u003e \u003cspan class=\"o\"\u003e{\u003c\/span\u003e\n \u003cspan class=\"nv\"\u003e$this\u003c\/span\u003e\u003cspan class=\"o\"\u003e->\u003c\/span\u003e\u003cspan class=\"na\" data-symbol-name=\"hookRunner\"\u003ehookRunner\u003c\/span\u003e \u003cspan class=\"o\"\u003e=\u003c\/span\u003e \u003cspan class=\"k\"\u003enew\u003c\/span\u003e \u003cspan class=\"nc\" data-symbol-name=\"MyExtHookRunner\"\u003eMyExtHookRunner\u003c\/span\u003e\u003cspan class=\"o\"\u003e(\u003c\/span\u003e \u003cspan class=\"nv\"\u003e$hookContainer\u003c\/span\u003e \u003cspan class=\"o\"\u003e);\u003c\/span\u003e\n \u003cspan class=\"o\"\u003e}\u003c\/span\u003e\n\n \u003cspan class=\"k\"\u003epublic\u003c\/span\u003e \u003cspan class=\"k\"\u003efunction\u003c\/span\u003e \u003cspan class=\"no\"\u003edoThings\u003c\/span\u003e\u003cspan class=\"o\"\u003e()\u003c\/span\u003e \u003cspan class=\"o\"\u003e{\u003c\/span\u003e\n \u003cspan class=\"cm\"\u003e\/* ... *\/\u003c\/span\u003e\n \u003cspan class=\"nv\"\u003e$this\u003c\/span\u003e\u003cspan class=\"o\"\u003e->\u003c\/span\u003e\u003cspan class=\"na\" data-symbol-name=\"hookRunner\"\u003ehookRunner\u003c\/span\u003e\u003cspan class=\"o\"\u003e->\u003c\/span\u003e\u003cspan class=\"na\" data-symbol-name=\"onMyExtDoThings\"\u003eonMyExtDoThings\u003c\/span\u003e\u003cspan class=\"o\"\u003e(\u003c\/span\u003e \u003cspan class=\"nv\"\u003e$things\u003c\/span\u003e \u003cspan class=\"o\"\u003e);\u003c\/span\u003e\n \u003cspan class=\"cm\"\u003e\/* ... *\/\u003c\/span\u003e\n \u003cspan class=\"o\"\u003e}\u003c\/span\u003e\n\u003cspan class=\"o\"\u003e}\u003c\/span\u003e\u003c\/pre\u003e\u003c\/div\u003e\u003c\/div\u003e\u003c\/span\u003e\u003c\/div\u003e\u003c\/div\u003e\u003c\/div\u003e\u003c\/div\u003e\u003c\/div\u003e\u003c\/div\u003e\u003cdiv class=\"phui-timeline-event-view phui-timeline-spacer\"\u003e\u003c\/div\u003e\u003cdiv class=\"phui-timeline-shell\" data-sigil=\"transaction anchor-container\" data-meta=\"0_262\"\u003e\u003cdiv class=\"phui-timeline-event-view phui-timeline-major-event\"\u003e\u003cdiv class=\"phui-timeline-content\"\u003e\u003ca style=\"background-image: url(https:\/\/phab.wmfusercontent.org\/file\/data\/xgl3wy55ovinfnucvwhx\/PHID-FILE-zocnksypiqutzf5oubpi\/profile)\" class=\"visual-only phui-timeline-image\" href=\"\/p\/tstarling\/\" aria-hidden=\"true\"\u003e\u003c\/a\u003e\u003cdiv class=\"phui-timeline-wedge\" style=\"\"\u003e\u003c\/div\u003e\u003cdiv class=\"phui-timeline-group\"\u003e\u003cdiv class=\"phui-timeline-inner-content\"\u003e\u003ca name=\"5728815\" id=\"5728815\" class=\"phabricator-anchor-view\"\u003e\u003c\/a\u003e\u003cdiv class=\"phui-timeline-title phui-timeline-title-with-icon phui-timeline-title-with-menu\"\u003e\u003cspan class=\"phui-timeline-icon-fill\"\u003e\u003cspan class=\"visual-only phui-icon-view phui-font-fa fa-comment phui-timeline-icon\" data-meta=\"0_261\" aria-hidden=\"true\"\u003e\u003c\/span\u003e\u003c\/span\u003e\u003ca href=\"\/p\/tstarling\/\" class=\"phui-handle handle-availability-partial phui-link-person\" data-sigil=\"hovercard\" data-meta=\"0_77\"\u003e\u003cspan class=\"perfect-circle\"\u003e\u2022\u003c\/span\u003e tstarling\u003c\/a\u003e added a comment.\u003cspan class=\"phui-timeline-extra\"\u003e\u003ca href=\"#5728815\" data-sigil=\"has-tooltip\" data-meta=\"0_260\"\u003e\u003cspan class=\"screen-only\"\u003eDec 10 2019, 5:27 PM\u003c\/span\u003e\u003cspan class=\"print-only\" aria-hidden=\"true\"\u003e2019-12-10 17:27:13 (UTC+0)\u003c\/span\u003e\u003c\/a\u003e\u003c\/span\u003e\u003c\/div\u003e\u003ca href=\"#\" class=\"phui-timeline-menu\" aria-haspopup=\"true\" aria-expanded=\"false\" data-sigil=\"phui-dropdown-menu\" data-meta=\"0_258\"\u003e\u003cspan class=\"aural-only\"\u003eComment Actions\u003c\/span\u003e\u003cspan class=\"visual-only phui-icon-view phui-font-fa fa-caret-down\" data-meta=\"0_259\" aria-hidden=\"true\"\u003e\u003c\/span\u003e\u003c\/a\u003e\u003cdiv class=\"phui-timeline-core-content\"\u003e\u003cspan class=\"transaction-comment\" data-sigil=\"transaction-comment\" data-meta=\"0_78\"\u003e\u003cdiv class=\"phabricator-remarkup\"\u003e\u003cblockquote class=\"remarkup-reply-block\"\u003e\n\u003cdiv class=\"remarkup-reply-head\"\u003eIn \u003ca href=\"\/T240307#5728354\" class=\"phui-tag-view phui-tag-type-object \" data-sigil=\"hovercard\" data-meta=\"0_1\"\u003e\u003cspan class=\"phui-tag-core-closed\"\u003e\u003cspan class=\"phui-tag-core phui-tag-color-object\"\u003eT240307#5728354\u003c\/span\u003e\u003c\/span\u003e\u003c\/a\u003e, \u003ca href=\"\/p\/Anomie\/\" class=\"phui-tag-view phui-tag-type-person \" data-sigil=\"hovercard\" data-meta=\"0_2\"\u003e\u003cspan class=\"phui-tag-core phui-tag-color-person\"\u003e@Anomie\u003c\/span\u003e\u003c\/a\u003e wrote:\u003c\/div\u003e\n\u003cdiv class=\"remarkup-reply-body\"\u003e\u003cp\u003eI note that for cases where ExtensionFoo wants to add a listener for a hook from ExtensionBar but also wants to maintain the ability to be used when ExtensionBar is not installed, it will need to register a separate listener just for ExtensionBar's hooks because the requisite interfaces won't be available when ExtensionBar is not available.\u003c\/p\u003e\u003c\/div\u003e\n\u003c\/blockquote\u003e\n\n\u003cp\u003eYes, true.\u003c\/p\u003e\n\n\u003cblockquote\u003e\u003cp\u003eIf not, instead of a service it could be more of an internal utility class wrapping HookContainer, intended for uses by composition.\u003c\/p\u003e\u003c\/blockquote\u003e\n\n\u003cp\u003eGood idea. It has no state apart from the HookContainer. I'll just edit the task description to call it a class rather than a service for now.\u003c\/p\u003e\u003c\/div\u003e\u003c\/span\u003e\u003c\/div\u003e\u003c\/div\u003e\u003c\/div\u003e\u003c\/div\u003e\u003c\/div\u003e\u003c\/div\u003e\u003cdiv class=\"phui-timeline-event-view phui-timeline-spacer\"\u003e\u003c\/div\u003e\u003cdiv class=\"phui-timeline-shell\" data-sigil=\"transaction anchor-container\" data-meta=\"0_265\"\u003e\u003cdiv class=\"phui-timeline-event-view phui-timeline-minor-event\"\u003e\u003cdiv class=\"phui-timeline-content\"\u003e\u003ca style=\"background-image: url(https:\/\/phab.wmfusercontent.org\/file\/data\/xgl3wy55ovinfnucvwhx\/PHID-FILE-zocnksypiqutzf5oubpi\/profile)\" class=\"visual-only phui-timeline-image\" href=\"\/p\/tstarling\/\" aria-hidden=\"true\"\u003e\u003c\/a\u003e\u003cdiv class=\"phui-timeline-wedge\" style=\"\"\u003e\u003c\/div\u003e\u003cdiv class=\"phui-timeline-group\"\u003e\u003ca name=\"5728816\" id=\"5728816\" class=\"phabricator-anchor-view\"\u003e\u003c\/a\u003e\u003cdiv class=\"phui-timeline-title phui-timeline-title-with-icon\"\u003e\u003cspan class=\"phui-timeline-icon-fill\"\u003e\u003cspan class=\"visual-only phui-icon-view phui-font-fa fa-pencil phui-timeline-icon\" data-meta=\"0_264\" aria-hidden=\"true\"\u003e\u003c\/span\u003e\u003c\/span\u003e\u003ca href=\"\/p\/tstarling\/\" class=\"phui-handle handle-availability-partial phui-link-person\" data-sigil=\"hovercard\" data-meta=\"0_79\"\u003e\u003cspan class=\"perfect-circle\"\u003e\u2022\u003c\/span\u003e tstarling\u003c\/a\u003e updated the task description. \u003ca href=\"\/transactions\/detail\/PHID-XACT-TASK-u5du7sww2flgkqz\/\" data-sigil=\"workflow\"\u003e(Show Details)\u003c\/a\u003e\u003cspan class=\"phui-timeline-extra\"\u003e\u003ca href=\"#5728816\" data-sigil=\"has-tooltip\" data-meta=\"0_263\"\u003e\u003cspan class=\"screen-only\"\u003eDec 10 2019, 5:29 PM\u003c\/span\u003e\u003cspan class=\"print-only\" aria-hidden=\"true\"\u003e2019-12-10 17:29:18 (UTC+0)\u003c\/span\u003e\u003c\/a\u003e\u003c\/span\u003e\u003c\/div\u003e\u003c\/div\u003e\u003c\/div\u003e\u003c\/div\u003e\u003c\/div\u003e\u003cdiv class=\"phui-timeline-event-view phui-timeline-spacer\"\u003e\u003c\/div\u003e\u003cdiv class=\"phui-timeline-shell\" data-sigil=\"transaction anchor-container\" data-meta=\"0_274\"\u003e\u003cdiv class=\"phui-timeline-event-view phui-timeline-major-event\"\u003e\u003cdiv class=\"phui-timeline-content\"\u003e\u003ca style=\"background-image: url(https:\/\/phab.wmfusercontent.org\/file\/data\/xgl3wy55ovinfnucvwhx\/PHID-FILE-zocnksypiqutzf5oubpi\/profile)\" class=\"visual-only phui-timeline-image\" href=\"\/p\/tstarling\/\" aria-hidden=\"true\"\u003e\u003c\/a\u003e\u003cdiv class=\"phui-timeline-wedge\" style=\"\"\u003e\u003c\/div\u003e\u003cdiv class=\"phui-timeline-group\"\u003e\u003cdiv class=\"phui-timeline-inner-content\"\u003e\u003ca name=\"5728830\" id=\"5728830\" class=\"phabricator-anchor-view\"\u003e\u003c\/a\u003e\u003cdiv class=\"phui-timeline-title phui-timeline-title-with-icon phui-timeline-title-with-menu\"\u003e\u003cspan class=\"phui-timeline-icon-fill\"\u003e\u003cspan class=\"visual-only phui-icon-view phui-font-fa fa-comment phui-timeline-icon\" data-meta=\"0_273\" aria-hidden=\"true\"\u003e\u003c\/span\u003e\u003c\/span\u003e\u003ca href=\"\/p\/tstarling\/\" class=\"phui-handle handle-availability-partial phui-link-person\" data-sigil=\"hovercard\" data-meta=\"0_80\"\u003e\u003cspan class=\"perfect-circle\"\u003e\u2022\u003c\/span\u003e tstarling\u003c\/a\u003e added a comment.\u003cspan class=\"phui-timeline-extra\"\u003e\u003ca href=\"#5728830\" data-sigil=\"has-tooltip\" data-meta=\"0_272\"\u003e\u003cspan class=\"screen-only\"\u003eDec 10 2019, 5:31 PM\u003c\/span\u003e\u003cspan class=\"print-only\" aria-hidden=\"true\"\u003e2019-12-10 17:31:50 (UTC+0)\u003c\/span\u003e\u003c\/a\u003e\u003c\/span\u003e\u003c\/div\u003e\u003ca href=\"#\" class=\"phui-timeline-menu\" aria-haspopup=\"true\" aria-expanded=\"false\" data-sigil=\"phui-dropdown-menu\" data-meta=\"0_270\"\u003e\u003cspan class=\"aural-only\"\u003eComment Actions\u003c\/span\u003e\u003cspan class=\"visual-only phui-icon-view phui-font-fa fa-caret-down\" data-meta=\"0_271\" aria-hidden=\"true\"\u003e\u003c\/span\u003e\u003c\/a\u003e\u003cdiv class=\"phui-timeline-core-content\"\u003e\u003cspan class=\"transaction-comment\" data-sigil=\"transaction-comment\" data-meta=\"0_81\"\u003e\u003cdiv class=\"phabricator-remarkup\"\u003e\u003cp\u003eThat change weakened the rationale for having a centralized HookRunner class for all core hooks, do you think I should reconsider that?\u003c\/p\u003e\u003c\/div\u003e\u003c\/span\u003e\u003c\/div\u003e\u003c\/div\u003e\u003c\/div\u003e\u003c\/div\u003e\u003c\/div\u003e\u003c\/div\u003e\u003cdiv class=\"phui-timeline-event-view phui-timeline-spacer\"\u003e\u003c\/div\u003e\u003cdiv class=\"phui-timeline-shell\" data-sigil=\"transaction anchor-container\" data-meta=\"0_285\"\u003e\u003cdiv class=\"phui-timeline-event-view phui-timeline-major-event\"\u003e\u003cdiv class=\"phui-timeline-content\"\u003e\u003ca style=\"background-image: url(https:\/\/phab.wmfusercontent.org\/file\/data\/ms665yc73j6nadjitytk\/PHID-FILE-mocohumlrcbe2lcuplml\/profile)\" class=\"visual-only phui-timeline-image\" href=\"\/p\/Anomie\/\" aria-hidden=\"true\"\u003e\u003c\/a\u003e\u003cdiv class=\"phui-timeline-badges\"\u003e\u003cul class=\"phui-badge-flex-view grouped flex-view-collapsed \"\u003e\u003cli class=\"phui-badge-flex-item\"\u003e\u003ca class=\"phui-badge-mini phui-badge-mini-orange \" href=\"\/badges\/view\/5\/\" data-sigil=\"has-tooltip\" data-meta=\"0_283\"\u003e\u003cspan class=\"visual-only phui-icon-view phui-font-fa fa-rocket\" data-meta=\"0_284\" aria-hidden=\"true\"\u003e\u003c\/span\u003e\u003c\/a\u003e\u003c\/li\u003e\u003c\/ul\u003e\u003c\/div\u003e\u003cdiv class=\"phui-timeline-wedge\" style=\"\"\u003e\u003c\/div\u003e\u003cdiv class=\"phui-timeline-group\"\u003e\u003cdiv class=\"phui-timeline-inner-content\"\u003e\u003ca name=\"5728876\" id=\"5728876\" class=\"phabricator-anchor-view\"\u003e\u003c\/a\u003e\u003cdiv class=\"phui-timeline-title phui-timeline-title-with-icon phui-timeline-title-with-menu\"\u003e\u003cspan class=\"phui-timeline-icon-fill\"\u003e\u003cspan class=\"visual-only phui-icon-view phui-font-fa fa-comment phui-timeline-icon\" data-meta=\"0_282\" aria-hidden=\"true\"\u003e\u003c\/span\u003e\u003c\/span\u003e\u003ca href=\"\/p\/Anomie\/\" class=\"phui-handle phui-link-person\" data-sigil=\"hovercard\" data-meta=\"0_82\"\u003eAnomie\u003c\/a\u003e added a comment.\u003cspan class=\"phui-timeline-extra\"\u003e\u003ca href=\"#5728876\" data-sigil=\"has-tooltip\" data-meta=\"0_281\"\u003e\u003cspan class=\"screen-only\"\u003eDec 10 2019, 5:44 PM\u003c\/span\u003e\u003cspan class=\"print-only\" aria-hidden=\"true\"\u003e2019-12-10 17:44:24 (UTC+0)\u003c\/span\u003e\u003c\/a\u003e\u003c\/span\u003e\u003c\/div\u003e\u003ca href=\"#\" class=\"phui-timeline-menu\" aria-haspopup=\"true\" aria-expanded=\"false\" data-sigil=\"phui-dropdown-menu\" data-meta=\"0_279\"\u003e\u003cspan class=\"aural-only\"\u003eComment Actions\u003c\/span\u003e\u003cspan class=\"visual-only phui-icon-view phui-font-fa fa-caret-down\" data-meta=\"0_280\" aria-hidden=\"true\"\u003e\u003c\/span\u003e\u003c\/a\u003e\u003cdiv class=\"phui-timeline-core-content\"\u003e\u003cspan class=\"transaction-comment\" data-sigil=\"transaction-comment\" data-meta=\"0_83\"\u003e\u003cdiv class=\"phabricator-remarkup\"\u003e\u003cp\u003eI don't feel strongly either way on that. If we often had code calling hooks from different subsystems there would be advantage to not requiring that code to have multiple HookRunner-type objects, but that doesn't seem likely to actually be the case. Usually code only has one hook, or a few that are related enough they'd probably be in the same runner anyway.\u003c\/p\u003e\u003c\/div\u003e\u003c\/span\u003e\u003c\/div\u003e\u003c\/div\u003e\u003c\/div\u003e\u003c\/div\u003e\u003c\/div\u003e\u003c\/div\u003e\u003cdiv class=\"phui-timeline-event-view phui-timeline-spacer\"\u003e\u003c\/div\u003e\u003cdiv class=\"phui-timeline-shell\" data-sigil=\"transaction anchor-container\" data-meta=\"0_296\"\u003e\u003cdiv class=\"phui-timeline-event-view phui-timeline-major-event\"\u003e\u003cdiv class=\"phui-timeline-content\"\u003e\u003ca style=\"background-image: url(https:\/\/phab.wmfusercontent.org\/file\/data\/q4xtskw4ul5dvrupkmqs\/PHID-FILE-ezxrezgeehrb4vjobxgz\/profile)\" class=\"visual-only phui-timeline-image\" href=\"\/p\/Krinkle\/\" aria-hidden=\"true\"\u003e\u003c\/a\u003e\u003cdiv class=\"phui-timeline-badges\"\u003e\u003cul class=\"phui-badge-flex-view grouped flex-view-collapsed \"\u003e\u003cli class=\"phui-badge-flex-item\"\u003e\u003ca class=\"phui-badge-mini phui-badge-mini-orange \" href=\"\/badges\/view\/8\/\" data-sigil=\"has-tooltip\" data-meta=\"0_294\"\u003e\u003cspan class=\"visual-only phui-icon-view phui-font-fa fa-life-ring\" data-meta=\"0_295\" aria-hidden=\"true\"\u003e\u003c\/span\u003e\u003c\/a\u003e\u003c\/li\u003e\u003c\/ul\u003e\u003c\/div\u003e\u003cdiv class=\"phui-timeline-wedge\" style=\"\"\u003e\u003c\/div\u003e\u003cdiv class=\"phui-timeline-group\"\u003e\u003cdiv class=\"phui-timeline-inner-content\"\u003e\u003ca name=\"5728938\" id=\"5728938\" class=\"phabricator-anchor-view\"\u003e\u003c\/a\u003e\u003cdiv class=\"phui-timeline-title phui-timeline-title-with-icon phui-timeline-title-with-menu\"\u003e\u003cspan class=\"phui-timeline-icon-fill\"\u003e\u003cspan class=\"visual-only phui-icon-view phui-font-fa fa-comment phui-timeline-icon\" data-meta=\"0_293\" aria-hidden=\"true\"\u003e\u003c\/span\u003e\u003c\/span\u003e\u003ca href=\"\/p\/Krinkle\/\" class=\"phui-handle phui-link-person\" data-sigil=\"hovercard\" data-meta=\"0_84\"\u003eKrinkle\u003c\/a\u003e added a comment.\u003cspan class=\"phui-timeline-extra\"\u003e\u003ca href=\"#5728938\" data-sigil=\"has-tooltip\" data-meta=\"0_292\"\u003e\u003cspan class=\"screen-only\"\u003eDec 10 2019, 6:04 PM\u003c\/span\u003e\u003cspan class=\"print-only\" aria-hidden=\"true\"\u003e2019-12-10 18:04:44 (UTC+0)\u003c\/span\u003e\u003c\/a\u003e\u003c\/span\u003e\u003c\/div\u003e\u003ca href=\"#\" class=\"phui-timeline-menu\" aria-haspopup=\"true\" aria-expanded=\"false\" data-sigil=\"phui-dropdown-menu\" data-meta=\"0_290\"\u003e\u003cspan class=\"aural-only\"\u003eComment Actions\u003c\/span\u003e\u003cspan class=\"visual-only phui-icon-view phui-font-fa fa-caret-down\" data-meta=\"0_291\" aria-hidden=\"true\"\u003e\u003c\/span\u003e\u003c\/a\u003e\u003cdiv class=\"phui-timeline-core-content\"\u003e\u003cspan class=\"transaction-comment\" data-sigil=\"transaction-comment\" data-meta=\"0_85\"\u003e\u003cdiv class=\"phabricator-remarkup\"\u003e\u003cp\u003eFrom a quick glance,\u003c\/p\u003e\n\n\u003cp\u003eGood:\u003c\/p\u003e\n\n\u003cul class=\"remarkup-list\"\u003e\n\u003cli class=\"remarkup-list-item\"\u003eI like the minimal and light approach to the problem.\u003c\/li\u003e\n\u003cli class=\"remarkup-list-item\"\u003eI note that this also gets us most (if not, all) the way toward solving the (otherwise orthogonal) "hooks documentation" problem.\u003c\/li\u003e\n\u003c\/ul\u003e\n\n\u003cp\u003eUnsure:\u003c\/p\u003e\n\n\u003cul class=\"remarkup-list\"\u003e\n\u003cli class=\"remarkup-list-item\"\u003eI'd like to start embracing modularity more within core, perhaps starting by encouraging that these hook interfaces are namespaced within specific sub components and not generic to "core" (thus stepping away from how we do API modules and Special pages in core). Long-term direction being that core namespaces would be more akin to extension namespaces in that MediaWiki\\Watchlist would not only contain the value classes and service classes, but also the API\/Special subclasses. Perhaps the hook interfaces would also be better off starting out in that category of things, and not in the "legacy" style of all in one directory where there is no clear ownership. This closely relates to the finishing of \u003ca href=\"\/T166010\" class=\"phui-tag-view phui-tag-type-object \" data-sigil=\"hovercard\" data-meta=\"0_3\"\u003e\u003cspan class=\"phui-tag-core phui-tag-color-object\"\u003eT166010\u003c\/span\u003e\u003c\/a\u003e and modularization in general, but I think we can find a way to not make it dependent on that. E.g. we can say that it should be within namespaces where possible, and that as fallback (but not encouraged\/promoted\/examplifed) it would go in a generic namespace.\u003c\/li\u003e\n\u003c\/ul\u003e\n\n\u003cul class=\"remarkup-list\"\u003e\n\u003cli class=\"remarkup-list-item\"\u003eThe idea of sharing a single hook container in extension with multiple hook callbacks seems fine at first, but it's not clear to me why we want to encourage this. In particular, I think this has worked out somewhat negatively in the Wikibase-family of extensions. Their hook singletons are too monolithic and closely coupled. It makes the code hard to maintain, and (more to my own interest) creates a performance nightmare in that to invoke \u003cem\u003eany\u003c\/em\u003e hook, you end up constructing an expensive tree of services for all dependencies of all hooks. See \u003ca href=\"\/T177311\" class=\"phui-tag-view phui-tag-type-object \" data-sigil=\"hovercard\" data-meta=\"0_4\"\u003e\u003cspan class=\"phui-tag-core-closed\"\u003e\u003cspan class=\"phui-tag-core phui-tag-color-object\"\u003eT177311\u003c\/span\u003e\u003c\/span\u003e\u003c\/a\u003e and \u003ca href=\"\/T160678\" class=\"phui-tag-view phui-tag-type-object \" data-sigil=\"hovercard\" data-meta=\"0_5\"\u003e\u003cspan class=\"phui-tag-core-closed\"\u003e\u003cspan class=\"phui-tag-core phui-tag-color-object\"\u003eT160678\u003c\/span\u003e\u003c\/span\u003e\u003c\/a\u003e for examples of this.\u003cul class=\"remarkup-list\"\u003e\n\u003cli class=\"remarkup-list-item\"\u003eCan you think of examples where there would be an explicit gain in maintainability and (de)coupling by sharing a container instance with two (related) hooks? Intuitively, I think this goes against some of what we wrote at \u003ca href=\"\/T212482\" class=\"phui-tag-view phui-tag-type-object \" data-sigil=\"hovercard\" data-meta=\"0_6\"\u003e\u003cspan class=\"phui-tag-core phui-tag-color-object\"\u003eT212482\u003c\/span\u003e\u003c\/a\u003e about how closely related hooks are likely an anti-pattern (think of the pre-AuthManager hooks).\u003c\/li\u003e\n\u003c\/ul\u003e\u003c\/li\u003e\n\u003c\/ul\u003e\u003c\/div\u003e\u003c\/span\u003e\u003c\/div\u003e\u003c\/div\u003e\u003c\/div\u003e\u003c\/div\u003e\u003c\/div\u003e\u003c\/div\u003e\u003cdiv class=\"phui-timeline-event-view phui-timeline-spacer\"\u003e\u003c\/div\u003e\u003cdiv class=\"phui-timeline-shell\" data-sigil=\"transaction anchor-container\" data-meta=\"0_307\"\u003e\u003cdiv class=\"phui-timeline-event-view phui-timeline-major-event\"\u003e\u003cdiv class=\"phui-timeline-content\"\u003e\u003ca style=\"background-image: url(https:\/\/phab.wmfusercontent.org\/file\/data\/ms665yc73j6nadjitytk\/PHID-FILE-mocohumlrcbe2lcuplml\/profile)\" class=\"visual-only phui-timeline-image\" href=\"\/p\/Anomie\/\" aria-hidden=\"true\"\u003e\u003c\/a\u003e\u003cdiv class=\"phui-timeline-badges\"\u003e\u003cul class=\"phui-badge-flex-view grouped flex-view-collapsed \"\u003e\u003cli class=\"phui-badge-flex-item\"\u003e\u003ca class=\"phui-badge-mini phui-badge-mini-orange \" href=\"\/badges\/view\/5\/\" data-sigil=\"has-tooltip\" data-meta=\"0_305\"\u003e\u003cspan class=\"visual-only phui-icon-view phui-font-fa fa-rocket\" data-meta=\"0_306\" aria-hidden=\"true\"\u003e\u003c\/span\u003e\u003c\/a\u003e\u003c\/li\u003e\u003c\/ul\u003e\u003c\/div\u003e\u003cdiv class=\"phui-timeline-wedge\" style=\"\"\u003e\u003c\/div\u003e\u003cdiv class=\"phui-timeline-group\"\u003e\u003cdiv class=\"phui-timeline-inner-content\"\u003e\u003ca name=\"5729089\" id=\"5729089\" class=\"phabricator-anchor-view\"\u003e\u003c\/a\u003e\u003cdiv class=\"phui-timeline-title phui-timeline-title-with-icon phui-timeline-title-with-menu\"\u003e\u003cspan class=\"phui-timeline-icon-fill\"\u003e\u003cspan class=\"visual-only phui-icon-view phui-font-fa fa-comment phui-timeline-icon\" data-meta=\"0_304\" aria-hidden=\"true\"\u003e\u003c\/span\u003e\u003c\/span\u003e\u003ca href=\"\/p\/Anomie\/\" class=\"phui-handle phui-link-person\" data-sigil=\"hovercard\" data-meta=\"0_86\"\u003eAnomie\u003c\/a\u003e added a comment.\u003cspan class=\"phui-timeline-extra\"\u003e\u003ca href=\"#5729089\" data-sigil=\"has-tooltip\" data-meta=\"0_303\"\u003e\u003cspan class=\"screen-only\"\u003eDec 10 2019, 7:15 PM\u003c\/span\u003e\u003cspan class=\"print-only\" aria-hidden=\"true\"\u003e2019-12-10 19:15:01 (UTC+0)\u003c\/span\u003e\u003c\/a\u003e\u003c\/span\u003e\u003c\/div\u003e\u003ca href=\"#\" class=\"phui-timeline-menu\" aria-haspopup=\"true\" aria-expanded=\"false\" data-sigil=\"phui-dropdown-menu\" data-meta=\"0_301\"\u003e\u003cspan class=\"aural-only\"\u003eComment Actions\u003c\/span\u003e\u003cspan class=\"visual-only phui-icon-view phui-font-fa fa-caret-down\" data-meta=\"0_302\" aria-hidden=\"true\"\u003e\u003c\/span\u003e\u003c\/a\u003e\u003cdiv class=\"phui-timeline-core-content\"\u003e\u003cspan class=\"transaction-comment\" data-sigil=\"transaction-comment\" data-meta=\"0_87\"\u003e\u003cdiv class=\"phabricator-remarkup\"\u003e\u003cblockquote class=\"remarkup-reply-block\"\u003e\n\u003cdiv class=\"remarkup-reply-head\"\u003eIn \u003ca href=\"\/T240307#5728938\" class=\"phui-tag-view phui-tag-type-object \" data-sigil=\"hovercard\" data-meta=\"0_7\"\u003e\u003cspan class=\"phui-tag-core-closed\"\u003e\u003cspan class=\"phui-tag-core phui-tag-color-object\"\u003eT240307#5728938\u003c\/span\u003e\u003c\/span\u003e\u003c\/a\u003e, \u003ca href=\"\/p\/Krinkle\/\" class=\"phui-tag-view phui-tag-type-person \" data-sigil=\"hovercard\" data-meta=\"0_11\"\u003e\u003cspan class=\"phui-tag-core phui-tag-color-person\"\u003e@Krinkle\u003c\/span\u003e\u003c\/a\u003e wrote:\u003c\/div\u003e\n\u003cdiv class=\"remarkup-reply-body\"\u003e\u003cp\u003eLong-term direction being that core namespaces would be more akin to extension namespaces in that MediaWiki\\Watchlist would not only contain the value classes and service classes, but also the API\/Special subclasses.\u003c\/p\u003e\u003c\/div\u003e\n\u003c\/blockquote\u003e\n\n\u003cp\u003eToo bad we have to pick one. I find it convenient in maintaining the Action API that all the relevant classes in core are in one place rather than scattered about the codebase, but obviously that's less convenient for someone who wants to maintain "the watchlist" including the relevant API modules.\u003c\/p\u003e\n\n\u003cblockquote\u003e\u003cul class=\"remarkup-list\"\u003e\n\u003cli class=\"remarkup-list-item\"\u003eThe idea of sharing a single hook container in extension with multiple hook callbacks seems fine at first, but it's not clear to me why we want to encourage this.\u003c\/li\u003e\n\u003c\/ul\u003e\u003c\/blockquote\u003e\n\n\u003cp\u003eDid you mean "hook listener" in that sentence? In this proposal "HookContainer" is the equivalent of the Hooks class, that manages registration of listeners and dispatching calls to them.\u003c\/p\u003e\n\n\u003cblockquote\u003e\u003cp\u003eIntuitively, I think this goes against some of what we wrote at \u003ca href=\"\/T212482\" class=\"phui-tag-view phui-tag-type-object \" data-sigil=\"hovercard\" data-meta=\"0_8\"\u003e\u003cspan class=\"phui-tag-core phui-tag-color-object\"\u003eT212482\u003c\/span\u003e\u003c\/a\u003e about how closely related hooks are likely an anti-pattern (think of the pre-AuthManager hooks).\u003c\/p\u003e\u003c\/blockquote\u003e\n\n\u003cp\u003eI saw the opposite there, actually. I tried to call that out in \u003ca href=\"\/T212482#4869654\" class=\"phui-tag-view phui-tag-type-object \" data-sigil=\"hovercard\" data-meta=\"0_9\"\u003e\u003cspan class=\"phui-tag-core phui-tag-color-object\"\u003eT212482#4869654\u003c\/span\u003e\u003c\/a\u003e; your reply in \u003ca href=\"\/T212482#5248239\" class=\"phui-tag-view phui-tag-type-object \" data-sigil=\"hovercard\" data-meta=\"0_10\"\u003e\u003cspan class=\"phui-tag-core phui-tag-color-object\"\u003eT212482#5248239\u003c\/span\u003e\u003c\/a\u003e doesn't seem to have really addressed it.\u003c\/p\u003e\u003c\/div\u003e\u003c\/span\u003e\u003c\/div\u003e\u003c\/div\u003e\u003c\/div\u003e\u003c\/div\u003e\u003c\/div\u003e\u003c\/div\u003e\u003cdiv class=\"phui-timeline-event-view phui-timeline-spacer\"\u003e\u003c\/div\u003e\u003cdiv class=\"phui-timeline-shell\" data-sigil=\"transaction anchor-container\" data-meta=\"0_316\"\u003e\u003cdiv class=\"phui-timeline-event-view phui-timeline-major-event\"\u003e\u003cdiv class=\"phui-timeline-content\"\u003e\u003ca style=\"background-image: url(https:\/\/phab.wmfusercontent.org\/file\/data\/xgl3wy55ovinfnucvwhx\/PHID-FILE-zocnksypiqutzf5oubpi\/profile)\" class=\"visual-only phui-timeline-image\" href=\"\/p\/tstarling\/\" aria-hidden=\"true\"\u003e\u003c\/a\u003e\u003cdiv class=\"phui-timeline-wedge\" style=\"\"\u003e\u003c\/div\u003e\u003cdiv class=\"phui-timeline-group\"\u003e\u003cdiv class=\"phui-timeline-inner-content\"\u003e\u003ca name=\"5729964\" id=\"5729964\" class=\"phabricator-anchor-view\"\u003e\u003c\/a\u003e\u003cdiv class=\"phui-timeline-title phui-timeline-title-with-icon phui-timeline-title-with-menu\"\u003e\u003cspan class=\"phui-timeline-icon-fill\"\u003e\u003cspan class=\"visual-only phui-icon-view phui-font-fa fa-comment phui-timeline-icon\" data-meta=\"0_315\" aria-hidden=\"true\"\u003e\u003c\/span\u003e\u003c\/span\u003e\u003ca href=\"\/p\/tstarling\/\" class=\"phui-handle handle-availability-partial phui-link-person\" data-sigil=\"hovercard\" data-meta=\"0_88\"\u003e\u003cspan class=\"perfect-circle\"\u003e\u2022\u003c\/span\u003e tstarling\u003c\/a\u003e added a comment.\u003cspan class=\"phui-timeline-extra\"\u003e\u003ca href=\"#5729964\" data-sigil=\"has-tooltip\" data-meta=\"0_314\"\u003e\u003cspan class=\"screen-only\"\u003eDec 10 2019, 10:32 PM\u003c\/span\u003e\u003cspan class=\"print-only\" aria-hidden=\"true\"\u003e2019-12-10 22:32:20 (UTC+0)\u003c\/span\u003e\u003c\/a\u003e\u003c\/span\u003e\u003c\/div\u003e\u003ca href=\"#\" class=\"phui-timeline-menu\" aria-haspopup=\"true\" aria-expanded=\"false\" data-sigil=\"phui-dropdown-menu\" data-meta=\"0_312\"\u003e\u003cspan class=\"aural-only\"\u003eComment Actions\u003c\/span\u003e\u003cspan class=\"visual-only phui-icon-view phui-font-fa fa-caret-down\" data-meta=\"0_313\" aria-hidden=\"true\"\u003e\u003c\/span\u003e\u003c\/a\u003e\u003cdiv class=\"phui-timeline-core-content\"\u003e\u003cspan class=\"transaction-comment\" data-sigil=\"transaction-comment\" data-meta=\"0_89\"\u003e\u003cdiv class=\"phabricator-remarkup\"\u003e\u003cblockquote class=\"remarkup-reply-block\"\u003e\n\u003cdiv class=\"remarkup-reply-head\"\u003eIn \u003ca href=\"\/T240307#5728938\" class=\"phui-tag-view phui-tag-type-object \" data-sigil=\"hovercard\" data-meta=\"0_14\"\u003e\u003cspan class=\"phui-tag-core-closed\"\u003e\u003cspan class=\"phui-tag-core phui-tag-color-object\"\u003eT240307#5728938\u003c\/span\u003e\u003c\/span\u003e\u003c\/a\u003e, \u003ca href=\"\/p\/Krinkle\/\" class=\"phui-tag-view phui-tag-type-person \" data-sigil=\"hovercard\" data-meta=\"0_15\"\u003e\u003cspan class=\"phui-tag-core phui-tag-color-person\"\u003e@Krinkle\u003c\/span\u003e\u003c\/a\u003e wrote:\u003c\/div\u003e\n\u003cdiv class=\"remarkup-reply-body\"\u003e\u003cul class=\"remarkup-list\"\u003e\n\u003cli class=\"remarkup-list-item\"\u003eThe idea of sharing a single hook container in extension with multiple hook callbacks seems fine at first, but it's not clear to me why we want to encourage this. In particular, I think this has worked out somewhat negatively in the Wikibase-family of extensions. Their hook singletons are too monolithic and closely coupled. It makes the code hard to maintain, and (more to my own interest) creates a performance nightmare in that to invoke \u003cem\u003eany\u003c\/em\u003e hook, you end up constructing an expensive tree of services for all dependencies of all hooks. See \u003ca href=\"\/T177311\" class=\"phui-tag-view phui-tag-type-object \" data-sigil=\"hovercard\" data-meta=\"0_12\"\u003e\u003cspan class=\"phui-tag-core-closed\"\u003e\u003cspan class=\"phui-tag-core phui-tag-color-object\"\u003eT177311\u003c\/span\u003e\u003c\/span\u003e\u003c\/a\u003e and \u003ca href=\"\/T160678\" class=\"phui-tag-view phui-tag-type-object \" data-sigil=\"hovercard\" data-meta=\"0_13\"\u003e\u003cspan class=\"phui-tag-core-closed\"\u003e\u003cspan class=\"phui-tag-core phui-tag-color-object\"\u003eT160678\u003c\/span\u003e\u003c\/span\u003e\u003c\/a\u003e for examples of this.\u003c\/li\u003e\n\u003c\/ul\u003e\u003c\/div\u003e\n\u003c\/blockquote\u003e\n\n\u003cp\u003eThis system provides the option of splitting up listener classes as finely as you like. If you're writing an extension and want one class per callback, then fine, do it that way. I'm tired of the architectural improvements in MediaWiki that take an all-or-nothing approach, linking virtues, so that code can either be perfect or terrible. Faced with that choice, many developers will choose to stick with terrible code. The goal of this proposal is to remediate the existing hook system as far as possible, providing an easy migration path for existing code.\u003c\/p\u003e\n\n\u003cp\u003eI would be fine with discouraging the use of kitchen sink hook listener classes in documentation and by our own virtuous examples. I would not want to discourage it by making it impossible by technical means.\u003c\/p\u003e\u003c\/div\u003e\u003c\/span\u003e\u003c\/div\u003e\u003c\/div\u003e\u003c\/div\u003e\u003c\/div\u003e\u003c\/div\u003e\u003c\/div\u003e\u003cdiv class=\"phui-timeline-event-view phui-timeline-spacer\"\u003e\u003c\/div\u003e\u003cdiv class=\"phui-timeline-shell\" data-sigil=\"transaction anchor-container\" data-meta=\"0_325\"\u003e\u003cdiv class=\"phui-timeline-event-view phui-timeline-major-event\"\u003e\u003cdiv class=\"phui-timeline-content\"\u003e\u003ca style=\"background-image: url(https:\/\/phab.wmfusercontent.org\/file\/data\/xgl3wy55ovinfnucvwhx\/PHID-FILE-zocnksypiqutzf5oubpi\/profile)\" class=\"visual-only phui-timeline-image\" href=\"\/p\/tstarling\/\" aria-hidden=\"true\"\u003e\u003c\/a\u003e\u003cdiv class=\"phui-timeline-wedge\" style=\"\"\u003e\u003c\/div\u003e\u003cdiv class=\"phui-timeline-group\"\u003e\u003cdiv class=\"phui-timeline-inner-content\"\u003e\u003ca name=\"5733085\" id=\"5733085\" class=\"phabricator-anchor-view\"\u003e\u003c\/a\u003e\u003cdiv class=\"phui-timeline-title phui-timeline-title-with-icon phui-timeline-title-with-menu\"\u003e\u003cspan class=\"phui-timeline-icon-fill\"\u003e\u003cspan class=\"visual-only phui-icon-view phui-font-fa fa-comment phui-timeline-icon\" data-meta=\"0_324\" aria-hidden=\"true\"\u003e\u003c\/span\u003e\u003c\/span\u003e\u003ca href=\"\/p\/tstarling\/\" class=\"phui-handle handle-availability-partial phui-link-person\" data-sigil=\"hovercard\" data-meta=\"0_90\"\u003e\u003cspan class=\"perfect-circle\"\u003e\u2022\u003c\/span\u003e tstarling\u003c\/a\u003e added a comment.\u003cspan class=\"phui-timeline-extra\"\u003e\u003ca href=\"#5733085\" data-sigil=\"has-tooltip\" data-meta=\"0_323\"\u003e\u003cspan class=\"screen-only\"\u003eDec 11 2019, 6:06 PM\u003c\/span\u003e\u003cspan class=\"print-only\" aria-hidden=\"true\"\u003e2019-12-11 18:06:13 (UTC+0)\u003c\/span\u003e\u003c\/a\u003e\u003c\/span\u003e\u003c\/div\u003e\u003ca href=\"#\" class=\"phui-timeline-menu\" aria-haspopup=\"true\" aria-expanded=\"false\" data-sigil=\"phui-dropdown-menu\" data-meta=\"0_321\"\u003e\u003cspan class=\"aural-only\"\u003eComment Actions\u003c\/span\u003e\u003cspan class=\"visual-only phui-icon-view phui-font-fa fa-caret-down\" data-meta=\"0_322\" aria-hidden=\"true\"\u003e\u003c\/span\u003e\u003c\/a\u003e\u003cdiv class=\"phui-timeline-core-content\"\u003e\u003cspan class=\"transaction-comment\" data-sigil=\"transaction-comment\" data-meta=\"0_91\"\u003e\u003cdiv class=\"phabricator-remarkup\"\u003e\u003cp\u003eIt's true that the performance implications would be concerning if the plan was to migrate all extension hook classes to use DI without splitting them up. I think existing massive hook classes in extensions could initially continue to use MediaWikiServices::getInstance() but switch from static functions to non-static functions with interfaces. That way, they get documentation and strong typing, they just don't get DI for now.\u003c\/p\u003e\u003c\/div\u003e\u003c\/span\u003e\u003c\/div\u003e\u003c\/div\u003e\u003c\/div\u003e\u003c\/div\u003e\u003c\/div\u003e\u003c\/div\u003e\u003cdiv class=\"phui-timeline-event-view phui-timeline-spacer\"\u003e\u003c\/div\u003e\u003cdiv class=\"phui-timeline-shell\" data-sigil=\"transaction anchor-container\" data-meta=\"0_329\"\u003e\u003cdiv class=\"phui-timeline-event-view phui-timeline-minor-event\"\u003e\u003cdiv class=\"phui-timeline-content\"\u003e\u003ca style=\"background-image: url(https:\/\/phab.wmfusercontent.org\/file\/data\/pftw7tn2jgpwaqdmxbtd\/PHID-FILE-4peudqvgp45hlsggbblo\/profile)\" class=\"visual-only phui-timeline-image\" href=\"\/p\/TK-999\/\" aria-hidden=\"true\"\u003e\u003c\/a\u003e\u003cdiv class=\"phui-timeline-wedge\" style=\"\"\u003e\u003c\/div\u003e\u003cdiv class=\"phui-timeline-group\"\u003e\u003ca name=\"5733092\" id=\"5733092\" class=\"phabricator-anchor-view\"\u003e\u003c\/a\u003e\u003cdiv class=\"phui-timeline-title phui-timeline-title-with-icon\"\u003e\u003cspan class=\"phui-timeline-icon-fill\"\u003e\u003cspan class=\"visual-only phui-icon-view phui-font-fa fa-trophy phui-timeline-icon\" data-meta=\"0_327\" aria-hidden=\"true\"\u003e\u003c\/span\u003e\u003c\/span\u003e\u003cspan class=\"visual-only phui-icon-view sprite-tokens tokens-medal-3 phui-timeline-token\" data-meta=\"0_328\" aria-hidden=\"true\"\u003e\u003c\/span\u003e\u003ca href=\"\/p\/TK-999\/\" class=\"phui-handle phui-link-person\" data-sigil=\"hovercard\" data-meta=\"0_92\"\u003eTK-999\u003c\/a\u003e awarded a token.\u003cspan class=\"phui-timeline-extra\"\u003e\u003ca href=\"#5733092\" data-sigil=\"has-tooltip\" data-meta=\"0_326\"\u003e\u003cspan class=\"screen-only\"\u003eDec 11 2019, 6:08 PM\u003c\/span\u003e\u003cspan class=\"print-only\" aria-hidden=\"true\"\u003e2019-12-11 18:08:07 (UTC+0)\u003c\/span\u003e\u003c\/a\u003e\u003c\/span\u003e\u003c\/div\u003e\u003c\/div\u003e\u003c\/div\u003e\u003c\/div\u003e\u003c\/div\u003e\u003cdiv class=\"phui-timeline-event-view phui-timeline-spacer\"\u003e\u003c\/div\u003e\u003cdiv class=\"phui-timeline-shell\" data-sigil=\"transaction anchor-container\" data-meta=\"0_333\"\u003e\u003cdiv class=\"phui-timeline-event-view phui-timeline-minor-event\"\u003e\u003cdiv class=\"phui-timeline-content\"\u003e\u003ca style=\"background-image: url(https:\/\/phab.wmfusercontent.org\/file\/data\/247abt7phqlbitgglyxa\/PHID-FILE-tx36db6dprvfuxu72bcj\/alphanumeric_aleo-white_D.png-_ec9da1-0%2C0%2C0%2C0.png)\" class=\"visual-only phui-timeline-image\" href=\"\/p\/Daimona\/\" aria-hidden=\"true\"\u003e\u003c\/a\u003e\u003cdiv class=\"phui-timeline-wedge\" style=\"\"\u003e\u003c\/div\u003e\u003cdiv class=\"phui-timeline-group\"\u003e\u003ca name=\"5733143\" id=\"5733143\" class=\"phabricator-anchor-view\"\u003e\u003c\/a\u003e\u003cdiv class=\"phui-timeline-title phui-timeline-title-with-icon\"\u003e\u003cspan class=\"phui-timeline-icon-fill\"\u003e\u003cspan class=\"visual-only phui-icon-view phui-font-fa fa-trophy phui-timeline-icon\" data-meta=\"0_331\" aria-hidden=\"true\"\u003e\u003c\/span\u003e\u003c\/span\u003e\u003cspan class=\"visual-only phui-icon-view sprite-tokens tokens-like-1 phui-timeline-token\" data-meta=\"0_332\" aria-hidden=\"true\"\u003e\u003c\/span\u003e\u003ca href=\"\/p\/Daimona\/\" class=\"phui-handle phui-link-person\" data-sigil=\"hovercard\" data-meta=\"0_93\"\u003eDaimona\u003c\/a\u003e awarded a token.\u003cspan class=\"phui-timeline-extra\"\u003e\u003ca href=\"#5733143\" data-sigil=\"has-tooltip\" data-meta=\"0_330\"\u003e\u003cspan class=\"screen-only\"\u003eDec 11 2019, 6:23 PM\u003c\/span\u003e\u003cspan class=\"print-only\" aria-hidden=\"true\"\u003e2019-12-11 18:23:06 (UTC+0)\u003c\/span\u003e\u003c\/a\u003e\u003c\/span\u003e\u003c\/div\u003e\u003c\/div\u003e\u003c\/div\u003e\u003c\/div\u003e\u003c\/div\u003e\u003cdiv class=\"phui-timeline-event-view phui-timeline-spacer\"\u003e\u003c\/div\u003e\u003cdiv class=\"phui-timeline-shell\" data-sigil=\"transaction anchor-container\" data-meta=\"0_338\"\u003e\u003cdiv class=\"phui-timeline-event-view phui-timeline-minor-event\"\u003e\u003cdiv class=\"phui-timeline-content\"\u003e\u003ca style=\"background-image: url(https:\/\/phab.wmfusercontent.org\/file\/data\/v5wmnfiaelrd6nztxd3a\/PHID-FILE-s57znldbv3qchtewuryd\/profile)\" class=\"visual-only phui-timeline-image\" href=\"\/p\/daniel\/\" aria-hidden=\"true\"\u003e\u003c\/a\u003e\u003cdiv class=\"phui-timeline-wedge\" style=\"\"\u003e\u003c\/div\u003e\u003cdiv class=\"phui-timeline-group\"\u003e\u003ca name=\"5733280\" id=\"5733280\" class=\"phabricator-anchor-view\"\u003e\u003c\/a\u003e\u003cdiv class=\"phui-timeline-title phui-timeline-title-with-icon\"\u003e\u003cspan class=\"phui-timeline-icon-fill\"\u003e\u003cspan class=\"visual-only phui-icon-view phui-font-fa fa-trophy phui-timeline-icon\" data-meta=\"0_335\" aria-hidden=\"true\"\u003e\u003c\/span\u003e\u003c\/span\u003e\u003cspan class=\"visual-only phui-icon-view sprite-tokens tokens-heart-1 phui-timeline-token\" data-meta=\"0_336\" aria-hidden=\"true\"\u003e\u003c\/span\u003e\u003ca href=\"\/p\/daniel\/\" class=\"phui-handle phui-link-person\" data-sigil=\"hovercard\" data-meta=\"0_94\"\u003edaniel\u003c\/a\u003e awarded a token.\u003cspan class=\"phui-timeline-extra\"\u003e\u003ca href=\"#5733280\" data-sigil=\"has-tooltip\" data-meta=\"0_334\"\u003e\u003cspan class=\"screen-only\"\u003eDec 11 2019, 7:02 PM\u003c\/span\u003e\u003cspan class=\"print-only\" aria-hidden=\"true\"\u003e2019-12-11 19:02:49 (UTC+0)\u003c\/span\u003e\u003c\/a\u003e\u003c\/span\u003e\u003c\/div\u003e\u003cdiv class=\"phui-timeline-title phui-timeline-title-with-icon\"\u003e\u003cspan class=\"phui-timeline-icon-fill\"\u003e\u003cspan class=\"visual-only phui-icon-view phui-font-fa fa-link phui-timeline-icon\" data-meta=\"0_337\" aria-hidden=\"true\"\u003e\u003c\/span\u003e\u003c\/span\u003e\u003ca href=\"\/p\/daniel\/\" class=\"phui-handle phui-link-person\" data-sigil=\"hovercard\" data-meta=\"0_95\"\u003edaniel\u003c\/a\u003e added a project: \u003ca href=\"\/tag\/user-daniel\/\" class=\"phui-handle\" data-sigil=\"hovercard\" data-meta=\"0_96\"\u003eUser-Daniel\u003c\/a\u003e.\u003c\/div\u003e\u003c\/div\u003e\u003c\/div\u003e\u003c\/div\u003e\u003c\/div\u003e\u003cdiv class=\"phui-timeline-event-view phui-timeline-spacer\"\u003e\u003c\/div\u003e\u003cdiv class=\"phui-timeline-shell\" data-sigil=\"transaction anchor-container\" data-meta=\"0_341\"\u003e\u003cdiv class=\"phui-timeline-event-view phui-timeline-minor-event\"\u003e\u003cdiv class=\"phui-timeline-content\"\u003e\u003ca style=\"background-image: url(https:\/\/phab.wmfusercontent.org\/file\/data\/chvngxnqoko6t3z6hc6b\/PHID-FILE-apmfbzbqf4i24fx5ac7l\/profile)\" class=\"visual-only phui-timeline-image\" href=\"\/p\/Nikerabbit\/\" aria-hidden=\"true\"\u003e\u003c\/a\u003e\u003cdiv class=\"phui-timeline-wedge\" style=\"\"\u003e\u003c\/div\u003e\u003cdiv class=\"phui-timeline-group\"\u003e\u003ca name=\"5733428\" id=\"5733428\" class=\"phabricator-anchor-view\"\u003e\u003c\/a\u003e\u003cdiv class=\"phui-timeline-title phui-timeline-title-with-icon\"\u003e\u003cspan class=\"phui-timeline-icon-fill\"\u003e\u003cspan class=\"visual-only phui-icon-view phui-font-fa fa-user-plus phui-timeline-icon\" data-meta=\"0_340\" aria-hidden=\"true\"\u003e\u003c\/span\u003e\u003c\/span\u003e\u003ca href=\"\/p\/Nikerabbit\/\" class=\"phui-handle phui-link-person\" data-sigil=\"hovercard\" data-meta=\"0_97\"\u003eNikerabbit\u003c\/a\u003e subscribed.\u003cspan class=\"phui-timeline-extra\"\u003e\u003ca href=\"#5733428\" data-sigil=\"has-tooltip\" data-meta=\"0_339\"\u003e\u003cspan class=\"screen-only\"\u003eDec 11 2019, 7:28 PM\u003c\/span\u003e\u003cspan class=\"print-only\" aria-hidden=\"true\"\u003e2019-12-11 19:28:33 (UTC+0)\u003c\/span\u003e\u003c\/a\u003e\u003c\/span\u003e\u003c\/div\u003e\u003c\/div\u003e\u003c\/div\u003e\u003c\/div\u003e\u003c\/div\u003e\u003cdiv class=\"phui-timeline-event-view phui-timeline-spacer\"\u003e\u003c\/div\u003e\u003cdiv class=\"phui-timeline-shell\" data-sigil=\"transaction anchor-container\" data-meta=\"0_344\"\u003e\u003cdiv class=\"phui-timeline-event-view phui-timeline-minor-event\"\u003e\u003cdiv class=\"phui-timeline-content\"\u003e\u003ca style=\"background-image: url(https:\/\/phab.wmfusercontent.org\/file\/data\/v5wmnfiaelrd6nztxd3a\/PHID-FILE-s57znldbv3qchtewuryd\/profile)\" class=\"visual-only phui-timeline-image\" href=\"\/p\/daniel\/\" aria-hidden=\"true\"\u003e\u003c\/a\u003e\u003cdiv class=\"phui-timeline-wedge\" style=\"\"\u003e\u003c\/div\u003e\u003cdiv class=\"phui-timeline-group\"\u003e\u003ca name=\"5733815\" id=\"5733815\" class=\"phabricator-anchor-view\"\u003e\u003c\/a\u003e\u003cdiv class=\"phui-timeline-title phui-timeline-title-with-icon\"\u003e\u003cspan class=\"phui-timeline-icon-fill\"\u003e\u003cspan class=\"visual-only phui-icon-view phui-font-fa fa-columns phui-timeline-icon\" data-meta=\"0_343\" aria-hidden=\"true\"\u003e\u003c\/span\u003e\u003c\/span\u003e\u003ca href=\"\/p\/daniel\/\" class=\"phui-handle phui-link-person\" data-sigil=\"hovercard\" data-meta=\"0_98\"\u003edaniel\u003c\/a\u003e moved this task from \u003ca href=\"\/project\/board\/52\/\" class=\"phui-handle\" data-sigil=\"hovercard\" data-meta=\"0_99\"\u003eP1: Define\u003c\/a\u003e to \u003ca href=\"\/project\/board\/52\/\" class=\"phui-handle handle-status-closed\" data-sigil=\"hovercard\" data-meta=\"0_100\"\u003eUnder discussion\u003c\/a\u003e on the \u003ca href=\"\/tag\/techcom-rfc\/\" class=\"phui-handle handle-status-closed\" data-sigil=\"hovercard\" data-meta=\"0_101\"\u003eTechCom-RFC\u003c\/a\u003e board.\u003cspan class=\"phui-timeline-extra\"\u003e\u003ca href=\"#5733815\" data-sigil=\"has-tooltip\" data-meta=\"0_342\"\u003e\u003cspan class=\"screen-only\"\u003eDec 11 2019, 9:41 PM\u003c\/span\u003e\u003cspan class=\"print-only\" aria-hidden=\"true\"\u003e2019-12-11 21:41:59 (UTC+0)\u003c\/span\u003e\u003c\/a\u003e\u003c\/span\u003e\u003c\/div\u003e\u003c\/div\u003e\u003c\/div\u003e\u003c\/div\u003e\u003c\/div\u003e\u003cdiv class=\"phui-timeline-event-view phui-timeline-spacer\"\u003e\u003c\/div\u003e\u003cdiv class=\"phui-timeline-shell\" data-sigil=\"transaction anchor-container\" data-meta=\"0_349\"\u003e\u003cdiv class=\"phui-timeline-event-view phui-timeline-minor-event\"\u003e\u003cdiv class=\"phui-timeline-content\"\u003e\u003ca style=\"background-image: url(https:\/\/phab.wmfusercontent.org\/file\/data\/k6upc2k7xtcmo5i5kapd\/PHID-FILE-2udpfnlxfzglivyk7hrn\/profile)\" class=\"visual-only phui-timeline-image\" href=\"\/p\/apaskulin\/\" aria-hidden=\"true\"\u003e\u003c\/a\u003e\u003cdiv class=\"phui-timeline-wedge\" style=\"\"\u003e\u003c\/div\u003e\u003cdiv class=\"phui-timeline-group\"\u003e\u003ca name=\"5734277\" id=\"5734277\" class=\"phabricator-anchor-view\"\u003e\u003c\/a\u003e\u003cdiv class=\"phui-timeline-title phui-timeline-title-with-icon\"\u003e\u003cspan class=\"phui-timeline-icon-fill\"\u003e\u003cspan class=\"visual-only phui-icon-view phui-font-fa fa-trophy phui-timeline-icon\" data-meta=\"0_346\" aria-hidden=\"true\"\u003e\u003c\/span\u003e\u003c\/span\u003e\u003cspan class=\"visual-only phui-icon-view sprite-tokens tokens-like-1 phui-timeline-token\" data-meta=\"0_347\" aria-hidden=\"true\"\u003e\u003c\/span\u003e\u003ca href=\"\/p\/apaskulin\/\" class=\"phui-handle phui-link-person\" data-sigil=\"hovercard\" data-meta=\"0_102\"\u003eapaskulin\u003c\/a\u003e awarded a token.\u003cspan class=\"phui-timeline-extra\"\u003e\u003ca href=\"#5734277\" data-sigil=\"has-tooltip\" data-meta=\"0_345\"\u003e\u003cspan class=\"screen-only\"\u003eDec 12 2019, 12:49 AM\u003c\/span\u003e\u003cspan class=\"print-only\" aria-hidden=\"true\"\u003e2019-12-12 00:49:05 (UTC+0)\u003c\/span\u003e\u003c\/a\u003e\u003c\/span\u003e\u003c\/div\u003e\u003cdiv class=\"phui-timeline-title phui-timeline-title-with-icon\"\u003e\u003cspan class=\"phui-timeline-icon-fill\"\u003e\u003cspan class=\"visual-only phui-icon-view phui-font-fa fa-user-plus phui-timeline-icon\" data-meta=\"0_348\" aria-hidden=\"true\"\u003e\u003c\/span\u003e\u003c\/span\u003e\u003ca href=\"\/p\/apaskulin\/\" class=\"phui-handle phui-link-person\" data-sigil=\"hovercard\" data-meta=\"0_103\"\u003eapaskulin\u003c\/a\u003e subscribed.\u003c\/div\u003e\u003c\/div\u003e\u003c\/div\u003e\u003c\/div\u003e\u003c\/div\u003e\u003cdiv class=\"phui-timeline-event-view phui-timeline-spacer\"\u003e\u003c\/div\u003e\u003cdiv class=\"phui-timeline-shell\" data-sigil=\"transaction anchor-container\" data-meta=\"0_352\"\u003e\u003cdiv class=\"phui-timeline-event-view phui-timeline-minor-event\"\u003e\u003cdiv class=\"phui-timeline-content\"\u003e\u003ca style=\"background-image: url(https:\/\/phab.wmfusercontent.org\/file\/data\/ied4uhepf36ypa3nofxt\/PHID-FILE-3wexu5vn7ik2tafjyzdk\/profile-profile-baselogo135.png)\" class=\"visual-only phui-timeline-image\" href=\"\/p\/Base\/\" aria-hidden=\"true\"\u003e\u003c\/a\u003e\u003cdiv class=\"phui-timeline-wedge\" style=\"\"\u003e\u003c\/div\u003e\u003cdiv class=\"phui-timeline-group\"\u003e\u003ca name=\"5742139\" id=\"5742139\" class=\"phabricator-anchor-view\"\u003e\u003c\/a\u003e\u003cdiv class=\"phui-timeline-title phui-timeline-title-with-icon\"\u003e\u003cspan class=\"phui-timeline-icon-fill\"\u003e\u003cspan class=\"visual-only phui-icon-view phui-font-fa fa-user-plus phui-timeline-icon\" data-meta=\"0_351\" aria-hidden=\"true\"\u003e\u003c\/span\u003e\u003c\/span\u003e\u003ca href=\"\/p\/Base\/\" class=\"phui-handle phui-link-person\" data-sigil=\"hovercard\" data-meta=\"0_104\"\u003eBase\u003c\/a\u003e subscribed.\u003cspan class=\"phui-timeline-extra\"\u003e\u003ca href=\"#5742139\" data-sigil=\"has-tooltip\" data-meta=\"0_350\"\u003e\u003cspan class=\"screen-only\"\u003eDec 15 2019, 1:41 AM\u003c\/span\u003e\u003cspan class=\"print-only\" aria-hidden=\"true\"\u003e2019-12-15 01:41:43 (UTC+0)\u003c\/span\u003e\u003c\/a\u003e\u003c\/span\u003e\u003c\/div\u003e\u003c\/div\u003e\u003c\/div\u003e\u003c\/div\u003e\u003c\/div\u003e\u003cdiv class=\"phui-timeline-event-view phui-timeline-spacer\"\u003e\u003c\/div\u003e\u003cdiv class=\"phui-timeline-shell\" data-sigil=\"transaction anchor-container\" data-meta=\"0_355\"\u003e\u003cdiv class=\"phui-timeline-event-view phui-timeline-minor-event\"\u003e\u003cdiv class=\"phui-timeline-content\"\u003e\u003ca style=\"background-image: url(https:\/\/phab.wmfusercontent.org\/file\/data\/xgl3wy55ovinfnucvwhx\/PHID-FILE-zocnksypiqutzf5oubpi\/profile)\" class=\"visual-only phui-timeline-image\" href=\"\/p\/tstarling\/\" aria-hidden=\"true\"\u003e\u003c\/a\u003e\u003cdiv class=\"phui-timeline-wedge\" style=\"\"\u003e\u003c\/div\u003e\u003cdiv class=\"phui-timeline-group\"\u003e\u003ca name=\"5742953\" id=\"5742953\" class=\"phabricator-anchor-view\"\u003e\u003c\/a\u003e\u003cdiv class=\"phui-timeline-title phui-timeline-title-with-icon\"\u003e\u003cspan class=\"phui-timeline-icon-fill\"\u003e\u003cspan class=\"visual-only phui-icon-view phui-font-fa fa-pencil phui-timeline-icon\" data-meta=\"0_354\" aria-hidden=\"true\"\u003e\u003c\/span\u003e\u003c\/span\u003e\u003ca href=\"\/p\/tstarling\/\" class=\"phui-handle handle-availability-partial phui-link-person\" data-sigil=\"hovercard\" data-meta=\"0_105\"\u003e\u003cspan class=\"perfect-circle\"\u003e\u2022\u003c\/span\u003e tstarling\u003c\/a\u003e updated the task description. \u003ca href=\"\/transactions\/detail\/PHID-XACT-TASK-5wac346uk4tr2co\/\" data-sigil=\"workflow\"\u003e(Show Details)\u003c\/a\u003e\u003cspan class=\"phui-timeline-extra\"\u003e\u003ca href=\"#5742953\" data-sigil=\"has-tooltip\" data-meta=\"0_353\"\u003e\u003cspan class=\"screen-only\"\u003eDec 16 2019, 12:25 AM\u003c\/span\u003e\u003cspan class=\"print-only\" aria-hidden=\"true\"\u003e2019-12-16 00:25:13 (UTC+0)\u003c\/span\u003e\u003c\/a\u003e\u003c\/span\u003e\u003c\/div\u003e\u003c\/div\u003e\u003c\/div\u003e\u003c\/div\u003e\u003c\/div\u003e\u003cdiv class=\"phui-timeline-event-view phui-timeline-spacer\"\u003e\u003c\/div\u003e\u003cdiv class=\"phui-timeline-shell\" data-sigil=\"transaction anchor-container\" data-meta=\"0_358\"\u003e\u003cdiv class=\"phui-timeline-event-view phui-timeline-minor-event\"\u003e\u003cdiv class=\"phui-timeline-content\"\u003e\u003ca style=\"background-image: url(https:\/\/phab.wmfusercontent.org\/file\/data\/vujzl5hgii6pty7gvjgn\/PHID-FILE-dyybnatmpguzojq462gd\/92b8c4-alphanumeric_lato-white_D.png-0%2C0%2C0%2C0.3.png)\" class=\"visual-only phui-timeline-image\" href=\"\/p\/DannyS712\/\" aria-hidden=\"true\"\u003e\u003c\/a\u003e\u003cdiv class=\"phui-timeline-wedge\" style=\"\"\u003e\u003c\/div\u003e\u003cdiv class=\"phui-timeline-group\"\u003e\u003ca name=\"5742960\" id=\"5742960\" class=\"phabricator-anchor-view\"\u003e\u003c\/a\u003e\u003cdiv class=\"phui-timeline-title phui-timeline-title-with-icon\"\u003e\u003cspan class=\"phui-timeline-icon-fill\"\u003e\u003cspan class=\"visual-only phui-icon-view phui-font-fa fa-user-plus phui-timeline-icon\" data-meta=\"0_357\" aria-hidden=\"true\"\u003e\u003c\/span\u003e\u003c\/span\u003e\u003ca href=\"\/p\/DannyS712\/\" class=\"phui-handle phui-link-person\" data-sigil=\"hovercard\" data-meta=\"0_106\"\u003eDannyS712\u003c\/a\u003e subscribed.\u003cspan class=\"phui-timeline-extra\"\u003e\u003ca href=\"#5742960\" data-sigil=\"has-tooltip\" data-meta=\"0_356\"\u003e\u003cspan class=\"screen-only\"\u003eDec 16 2019, 12:39 AM\u003c\/span\u003e\u003cspan class=\"print-only\" aria-hidden=\"true\"\u003e2019-12-16 00:39:37 (UTC+0)\u003c\/span\u003e\u003c\/a\u003e\u003c\/span\u003e\u003c\/div\u003e\u003c\/div\u003e\u003c\/div\u003e\u003c\/div\u003e\u003c\/div\u003e\u003cdiv class=\"phui-timeline-event-view phui-timeline-spacer\"\u003e\u003c\/div\u003e\u003cdiv class=\"phui-timeline-shell\" data-sigil=\"transaction anchor-container\" data-meta=\"0_361\"\u003e\u003cdiv class=\"phui-timeline-event-view phui-timeline-minor-event\"\u003e\u003cdiv class=\"phui-timeline-content\"\u003e\u003ca style=\"background-image: url(https:\/\/phab.wmfusercontent.org\/file\/data\/zpv23ylmg4lfeb2wa4a6\/PHID-FILE-ysgblokpidaco52exifh\/profile)\" class=\"visual-only phui-timeline-image\" href=\"\/p\/MGChecker\/\" aria-hidden=\"true\"\u003e\u003c\/a\u003e\u003cdiv class=\"phui-timeline-wedge\" style=\"\"\u003e\u003c\/div\u003e\u003cdiv class=\"phui-timeline-group\"\u003e\u003ca name=\"5743025\" id=\"5743025\" class=\"phabricator-anchor-view\"\u003e\u003c\/a\u003e\u003cdiv class=\"phui-timeline-title phui-timeline-title-with-icon\"\u003e\u003cspan class=\"phui-timeline-icon-fill\"\u003e\u003cspan class=\"visual-only phui-icon-view phui-font-fa fa-user-plus phui-timeline-icon\" data-meta=\"0_360\" aria-hidden=\"true\"\u003e\u003c\/span\u003e\u003c\/span\u003e\u003ca href=\"\/p\/MGChecker\/\" class=\"phui-handle phui-link-person\" data-sigil=\"hovercard\" data-meta=\"0_107\"\u003eMGChecker\u003c\/a\u003e subscribed.\u003cspan class=\"phui-timeline-extra\"\u003e\u003ca href=\"#5743025\" data-sigil=\"has-tooltip\" data-meta=\"0_359\"\u003e\u003cspan class=\"screen-only\"\u003eDec 16 2019, 2:35 AM\u003c\/span\u003e\u003cspan class=\"print-only\" aria-hidden=\"true\"\u003e2019-12-16 02:35:45 (UTC+0)\u003c\/span\u003e\u003c\/a\u003e\u003c\/span\u003e\u003c\/div\u003e\u003c\/div\u003e\u003c\/div\u003e\u003c\/div\u003e\u003c\/div\u003e\u003cdiv class=\"phui-timeline-event-view phui-timeline-spacer\"\u003e\u003c\/div\u003e\u003cdiv class=\"phui-timeline-shell\" data-sigil=\"transaction anchor-container\" data-meta=\"0_365\"\u003e\u003cdiv class=\"phui-timeline-event-view phui-timeline-minor-event\"\u003e\u003cdiv class=\"phui-timeline-content\"\u003e\u003ca style=\"background-image: url(https:\/\/phab.wmfusercontent.org\/file\/data\/zpv23ylmg4lfeb2wa4a6\/PHID-FILE-ysgblokpidaco52exifh\/profile)\" class=\"visual-only phui-timeline-image\" href=\"\/p\/MGChecker\/\" aria-hidden=\"true\"\u003e\u003c\/a\u003e\u003cdiv class=\"phui-timeline-wedge\" style=\"\"\u003e\u003c\/div\u003e\u003cdiv class=\"phui-timeline-group\"\u003e\u003ca name=\"5743028\" id=\"5743028\" class=\"phabricator-anchor-view\"\u003e\u003c\/a\u003e\u003cdiv class=\"phui-timeline-title phui-timeline-title-with-icon\"\u003e\u003cspan class=\"phui-timeline-icon-fill\"\u003e\u003cspan class=\"visual-only phui-icon-view phui-font-fa fa-trophy phui-timeline-icon\" data-meta=\"0_363\" aria-hidden=\"true\"\u003e\u003c\/span\u003e\u003c\/span\u003e\u003cspan class=\"visual-only phui-icon-view sprite-tokens tokens-like-1 phui-timeline-token\" data-meta=\"0_364\" aria-hidden=\"true\"\u003e\u003c\/span\u003e\u003ca href=\"\/p\/MGChecker\/\" class=\"phui-handle phui-link-person\" data-sigil=\"hovercard\" data-meta=\"0_108\"\u003eMGChecker\u003c\/a\u003e awarded a token.\u003cspan class=\"phui-timeline-extra\"\u003e\u003ca href=\"#5743028\" data-sigil=\"has-tooltip\" data-meta=\"0_362\"\u003e\u003cspan class=\"screen-only\"\u003eDec 16 2019, 2:39 AM\u003c\/span\u003e\u003cspan class=\"print-only\" aria-hidden=\"true\"\u003e2019-12-16 02:39:48 (UTC+0)\u003c\/span\u003e\u003c\/a\u003e\u003c\/span\u003e\u003c\/div\u003e\u003c\/div\u003e\u003c\/div\u003e\u003c\/div\u003e\u003c\/div\u003e\u003cdiv class=\"phui-timeline-event-view phui-timeline-spacer\"\u003e\u003c\/div\u003e\u003cdiv class=\"phui-timeline-shell\" data-sigil=\"transaction anchor-container\" data-meta=\"0_368\"\u003e\u003cdiv class=\"phui-timeline-event-view phui-timeline-minor-event\"\u003e\u003cdiv class=\"phui-timeline-content\"\u003e\u003ca style=\"background-image: url(https:\/\/phab.wmfusercontent.org\/file\/data\/3iigldu33itwnv6qred6\/PHID-FILE-crux7ijupvjze2tyjdst\/profile)\" class=\"visual-only phui-timeline-image\" href=\"\/p\/Osnard\/\" aria-hidden=\"true\"\u003e\u003c\/a\u003e\u003cdiv class=\"phui-timeline-wedge\" style=\"\"\u003e\u003c\/div\u003e\u003cdiv class=\"phui-timeline-group\"\u003e\u003ca name=\"5743366\" id=\"5743366\" class=\"phabricator-anchor-view\"\u003e\u003c\/a\u003e\u003cdiv class=\"phui-timeline-title phui-timeline-title-with-icon\"\u003e\u003cspan class=\"phui-timeline-icon-fill\"\u003e\u003cspan class=\"visual-only phui-icon-view phui-font-fa fa-user-plus phui-timeline-icon\" data-meta=\"0_367\" aria-hidden=\"true\"\u003e\u003c\/span\u003e\u003c\/span\u003e\u003ca href=\"\/p\/Osnard\/\" class=\"phui-handle phui-link-person\" data-sigil=\"hovercard\" data-meta=\"0_109\"\u003eOsnard\u003c\/a\u003e subscribed.\u003cspan class=\"phui-timeline-extra\"\u003e\u003ca href=\"#5743366\" data-sigil=\"has-tooltip\" data-meta=\"0_366\"\u003e\u003cspan class=\"screen-only\"\u003eDec 16 2019, 7:09 AM\u003c\/span\u003e\u003cspan class=\"print-only\" aria-hidden=\"true\"\u003e2019-12-16 07:09:24 (UTC+0)\u003c\/span\u003e\u003c\/a\u003e\u003c\/span\u003e\u003c\/div\u003e\u003c\/div\u003e\u003c\/div\u003e\u003c\/div\u003e\u003c\/div\u003e\u003cdiv class=\"phui-timeline-event-view phui-timeline-spacer\"\u003e\u003c\/div\u003e\u003cdiv class=\"phui-timeline-shell\" data-sigil=\"transaction anchor-container\" data-meta=\"0_371\"\u003e\u003cdiv class=\"phui-timeline-event-view phui-timeline-minor-event\"\u003e\u003cdiv class=\"phui-timeline-content\"\u003e\u003ca style=\"background-image: url(https:\/\/phab.wmfusercontent.org\/file\/data\/qg6iwggo535pagkoqbkr\/PHID-FILE-pj4bbpforckskr5bm42m\/alphanumeric_aleo-white_W.png-_ce9793-255%2C255%2C255%2C0.4.png)\" class=\"visual-only phui-timeline-image\" href=\"\/p\/WMDE-leszek\/\" aria-hidden=\"true\"\u003e\u003c\/a\u003e\u003cdiv class=\"phui-timeline-wedge\" style=\"\"\u003e\u003c\/div\u003e\u003cdiv class=\"phui-timeline-group\"\u003e\u003ca name=\"5743564\" id=\"5743564\" class=\"phabricator-anchor-view\"\u003e\u003c\/a\u003e\u003cdiv class=\"phui-timeline-title phui-timeline-title-with-icon\"\u003e\u003cspan class=\"phui-timeline-icon-fill\"\u003e\u003cspan class=\"visual-only phui-icon-view phui-font-fa fa-user-plus phui-timeline-icon\" data-meta=\"0_370\" aria-hidden=\"true\"\u003e\u003c\/span\u003e\u003c\/span\u003e\u003ca href=\"\/p\/WMDE-leszek\/\" class=\"phui-handle phui-link-person\" data-sigil=\"hovercard\" data-meta=\"0_110\"\u003eWMDE-leszek\u003c\/a\u003e subscribed.\u003cspan class=\"phui-timeline-extra\"\u003e\u003ca href=\"#5743564\" data-sigil=\"has-tooltip\" data-meta=\"0_369\"\u003e\u003cspan class=\"screen-only\"\u003eDec 16 2019, 9:15 AM\u003c\/span\u003e\u003cspan class=\"print-only\" aria-hidden=\"true\"\u003e2019-12-16 09:15:38 (UTC+0)\u003c\/span\u003e\u003c\/a\u003e\u003c\/span\u003e\u003c\/div\u003e\u003c\/div\u003e\u003c\/div\u003e\u003c\/div\u003e\u003c\/div\u003e\u003cdiv class=\"phui-timeline-event-view phui-timeline-spacer\"\u003e\u003c\/div\u003e\u003cdiv class=\"phui-timeline-shell\" data-sigil=\"transaction anchor-container\" data-meta=\"0_382\"\u003e\u003cdiv class=\"phui-timeline-event-view phui-timeline-major-event\"\u003e\u003cdiv class=\"phui-timeline-content\"\u003e\u003ca style=\"background-image: url(https:\/\/phab.wmfusercontent.org\/file\/data\/hotylf4lvnhjvd5qh5pp\/PHID-FILE-qxupl4r6iysu6fa22spb\/profile-Avatar-BassMan.png)\" class=\"visual-only phui-timeline-image\" href=\"\/p\/MaxSem\/\" aria-hidden=\"true\"\u003e\u003c\/a\u003e\u003cdiv class=\"phui-timeline-badges\"\u003e\u003cul class=\"phui-badge-flex-view grouped flex-view-collapsed \"\u003e\u003cli class=\"phui-badge-flex-item\"\u003e\u003ca class=\"phui-badge-mini phui-badge-mini-orange \" href=\"\/badges\/view\/5\/\" data-sigil=\"has-tooltip\" data-meta=\"0_380\"\u003e\u003cspan class=\"visual-only phui-icon-view phui-font-fa fa-rocket\" data-meta=\"0_381\" aria-hidden=\"true\"\u003e\u003c\/span\u003e\u003c\/a\u003e\u003c\/li\u003e\u003c\/ul\u003e\u003c\/div\u003e\u003cdiv class=\"phui-timeline-wedge\" style=\"\"\u003e\u003c\/div\u003e\u003cdiv class=\"phui-timeline-group\"\u003e\u003cdiv class=\"phui-timeline-inner-content\"\u003e\u003ca name=\"5743953\" id=\"5743953\" class=\"phabricator-anchor-view\"\u003e\u003c\/a\u003e\u003cdiv class=\"phui-timeline-title phui-timeline-title-with-icon phui-timeline-title-with-menu\"\u003e\u003cspan class=\"phui-timeline-icon-fill\"\u003e\u003cspan class=\"visual-only phui-icon-view phui-font-fa fa-user-plus phui-timeline-icon\" data-meta=\"0_379\" aria-hidden=\"true\"\u003e\u003c\/span\u003e\u003c\/span\u003e\u003ca href=\"\/p\/MaxSem\/\" class=\"phui-handle phui-link-person\" data-sigil=\"hovercard\" data-meta=\"0_112\"\u003eMaxSem\u003c\/a\u003e subscribed.\u003cspan class=\"phui-timeline-extra\"\u003e\u003ca href=\"#5743953\" data-sigil=\"has-tooltip\" data-meta=\"0_378\"\u003e\u003cspan class=\"screen-only\"\u003eDec 16 2019, 10:48 AM\u003c\/span\u003e\u003cspan class=\"print-only\" aria-hidden=\"true\"\u003e2019-12-16 10:48:37 (UTC+0)\u003c\/span\u003e\u003c\/a\u003e\u003c\/span\u003e\u003c\/div\u003e\u003ca href=\"#\" class=\"phui-timeline-menu\" aria-haspopup=\"true\" aria-expanded=\"false\" data-sigil=\"phui-dropdown-menu\" data-meta=\"0_376\"\u003e\u003cspan class=\"aural-only\"\u003eComment Actions\u003c\/span\u003e\u003cspan class=\"visual-only phui-icon-view phui-font-fa fa-caret-down\" data-meta=\"0_377\" aria-hidden=\"true\"\u003e\u003c\/span\u003e\u003c\/a\u003e\u003cdiv class=\"phui-timeline-core-content\"\u003e\u003cspan class=\"transaction-comment\" data-sigil=\"transaction-comment\" data-meta=\"0_111\"\u003e\u003cdiv class=\"phabricator-remarkup\"\u003e\u003cp\u003eOne thing to discuss here is the guidelines of how to evolve code using this approach: previously, you could add a new parameter to a hook and it will just work\u2122\ufe0f with existing hook handlers. Even some parameter type changes were possible. Not the case in this RFC: existing hook handlers can't be changed easily.\u003c\/p\u003e\n\n\u003cp\u003eShould we do hook versioning e.g\u003c\/p\u003e\n\n\u003cdiv class=\"remarkup-code-block\" data-code-lang=\"text\" data-sigil=\"remarkup-code-block\"\u003e\u003cpre class=\"remarkup-code\"\u003e$this->hookRunner->onUserLoginComplete( $user, $injected_html, $direct );\n$this->hookRunner->onUserLoginComplete2( $user, $injected_html, $direct, $newParameter );\n. . .\n$this->hookRunner->onUserLoginComplete15( $userLoginCompleteArgs3 );\u003c\/pre\u003e\u003c\/div\u003e\n\n\u003cp\u003eOr should we require extensions to modify their code for every new MW version?\u003c\/p\u003e\n\n\u003cp\u003eHow extensions are supposed to support multiple MW versions?\u003c\/p\u003e\u003c\/div\u003e\u003c\/span\u003e\u003c\/div\u003e\u003c\/div\u003e\u003c\/div\u003e\u003c\/div\u003e\u003c\/div\u003e\u003c\/div\u003e\u003cdiv class=\"phui-timeline-event-view phui-timeline-spacer\"\u003e\u003c\/div\u003e\u003cdiv class=\"phui-timeline-shell\" data-sigil=\"transaction anchor-container\" data-meta=\"0_385\"\u003e\u003cdiv class=\"phui-timeline-event-view phui-timeline-minor-event\"\u003e\u003cdiv class=\"phui-timeline-content\"\u003e\u003ca style=\"background-image: url(https:\/\/phab.wmfusercontent.org\/file\/data\/l2cg2zimvt2uq6xna6zg\/PHID-FILE-it2g7whiwxxkzdfzans5\/profile)\" class=\"visual-only phui-timeline-image\" href=\"\/p\/Lucas_Werkmeister_WMDE\/\" aria-hidden=\"true\"\u003e\u003c\/a\u003e\u003cdiv class=\"phui-timeline-wedge\" style=\"\"\u003e\u003c\/div\u003e\u003cdiv class=\"phui-timeline-group\"\u003e\u003ca name=\"5744269\" id=\"5744269\" class=\"phabricator-anchor-view\"\u003e\u003c\/a\u003e\u003cdiv class=\"phui-timeline-title phui-timeline-title-with-icon\"\u003e\u003cspan class=\"phui-timeline-icon-fill\"\u003e\u003cspan class=\"visual-only phui-icon-view phui-font-fa fa-user-plus phui-timeline-icon\" data-meta=\"0_384\" aria-hidden=\"true\"\u003e\u003c\/span\u003e\u003c\/span\u003e\u003ca href=\"\/p\/Lucas_Werkmeister_WMDE\/\" class=\"phui-handle phui-link-person\" data-sigil=\"hovercard\" data-meta=\"0_113\"\u003eLucas_Werkmeister_WMDE\u003c\/a\u003e subscribed.\u003cspan class=\"phui-timeline-extra\"\u003e\u003ca href=\"#5744269\" data-sigil=\"has-tooltip\" data-meta=\"0_383\"\u003e\u003cspan class=\"screen-only\"\u003eDec 16 2019, 12:58 PM\u003c\/span\u003e\u003cspan class=\"print-only\" aria-hidden=\"true\"\u003e2019-12-16 12:58:26 (UTC+0)\u003c\/span\u003e\u003c\/a\u003e\u003c\/span\u003e\u003c\/div\u003e\u003c\/div\u003e\u003c\/div\u003e\u003c\/div\u003e\u003c\/div\u003e\u003cdiv class=\"phui-timeline-event-view phui-timeline-spacer\"\u003e\u003c\/div\u003e\u003cdiv class=\"phui-timeline-shell\" data-sigil=\"transaction anchor-container\" data-meta=\"0_396\"\u003e\u003cdiv class=\"phui-timeline-event-view phui-timeline-major-event\"\u003e\u003cdiv class=\"phui-timeline-content\"\u003e\u003ca style=\"background-image: url(https:\/\/phab.wmfusercontent.org\/file\/data\/v5wmnfiaelrd6nztxd3a\/PHID-FILE-s57znldbv3qchtewuryd\/profile)\" class=\"visual-only phui-timeline-image\" href=\"\/p\/daniel\/\" aria-hidden=\"true\"\u003e\u003c\/a\u003e\u003cdiv class=\"phui-timeline-badges\"\u003e\u003cul class=\"phui-badge-flex-view grouped flex-view-collapsed \"\u003e\u003cli class=\"phui-badge-flex-item\"\u003e\u003ca class=\"phui-badge-mini phui-badge-mini-indigo \" href=\"\/badges\/view\/14\/\" data-sigil=\"has-tooltip\" data-meta=\"0_394\"\u003e\u003cspan class=\"visual-only phui-icon-view phui-font-fa fa-empire\" data-meta=\"0_395\" aria-hidden=\"true\"\u003e\u003c\/span\u003e\u003c\/a\u003e\u003c\/li\u003e\u003c\/ul\u003e\u003c\/div\u003e\u003cdiv class=\"phui-timeline-wedge\" style=\"\"\u003e\u003c\/div\u003e\u003cdiv class=\"phui-timeline-group\"\u003e\u003cdiv class=\"phui-timeline-inner-content\"\u003e\u003ca name=\"5744479\" id=\"5744479\" class=\"phabricator-anchor-view\"\u003e\u003c\/a\u003e\u003cdiv class=\"phui-timeline-title phui-timeline-title-with-icon phui-timeline-title-with-menu\"\u003e\u003cspan class=\"phui-timeline-icon-fill\"\u003e\u003cspan class=\"visual-only phui-icon-view phui-font-fa fa-comment phui-timeline-icon\" data-meta=\"0_393\" aria-hidden=\"true\"\u003e\u003c\/span\u003e\u003c\/span\u003e\u003ca href=\"\/p\/daniel\/\" class=\"phui-handle phui-link-person\" data-sigil=\"hovercard\" data-meta=\"0_114\"\u003edaniel\u003c\/a\u003e added a comment.\u003cspan class=\"phui-timeline-extra\"\u003e\u003ca href=\"#5744479\" data-sigil=\"has-tooltip\" data-meta=\"0_392\"\u003e\u003cspan class=\"screen-only\"\u003eDec 16 2019, 2:17 PM\u003c\/span\u003e\u003cspan class=\"print-only\" aria-hidden=\"true\"\u003e2019-12-16 14:17:35 (UTC+0)\u003c\/span\u003e\u003c\/a\u003e\u003c\/span\u003e\u003c\/div\u003e\u003ca href=\"#\" class=\"phui-timeline-menu\" aria-haspopup=\"true\" aria-expanded=\"false\" data-sigil=\"phui-dropdown-menu\" data-meta=\"0_390\"\u003e\u003cspan class=\"aural-only\"\u003eComment Actions\u003c\/span\u003e\u003cspan class=\"visual-only phui-icon-view phui-font-fa fa-caret-down\" data-meta=\"0_391\" aria-hidden=\"true\"\u003e\u003c\/span\u003e\u003c\/a\u003e\u003cdiv class=\"phui-timeline-core-content\"\u003e\u003cspan class=\"transaction-comment\" data-sigil=\"transaction-comment\" data-meta=\"0_115\"\u003e\u003cdiv class=\"phabricator-remarkup\"\u003e\u003cp\u003eI really like the proposal, especially using the same interface for handling and for triggering events.\u003c\/p\u003e\n\n\u003cp\u003eOne thing I don't quite see is why we still need hooks names, other than the names of the associated interfaces. This seems redundant and prone to inconsistencies. For legacy hook, there could be an aliasing mechanism by which extra names for a hook can be registered, which then get mapped to the name of an interface.\u003c\/p\u003e\n\n\u003cp\u003eTo mitigate inconvenience when a new version of a hook is introduced, we could support a mechanism to register adapters: When MyNewHook is introduced to replace MyOldHook, an adapter MyOldHookAdapter can written that implements MyNewHook and wraps an instance of MyOldHook. An instantiator callback (or object spec) for that adapter can then be registered with something like addAdapter( MyOldHook::class, MyNewHook::class, $instantiatorCallback ). When an eon registers a handler for MyOldHook, the instanstiator callback is used to create an instance of MyOldHookAdapter which gets registered as a MyNewHook instead of the original handler.\u003c\/p\u003e\u003c\/div\u003e\u003c\/span\u003e\u003c\/div\u003e\u003c\/div\u003e\u003c\/div\u003e\u003c\/div\u003e\u003c\/div\u003e\u003c\/div\u003e\u003cdiv class=\"phui-timeline-event-view phui-timeline-spacer\"\u003e\u003c\/div\u003e\u003cdiv class=\"phui-timeline-shell\" data-sigil=\"transaction anchor-container\" data-meta=\"0_405\"\u003e\u003cdiv class=\"phui-timeline-event-view phui-timeline-major-event\"\u003e\u003cdiv class=\"phui-timeline-content\"\u003e\u003ca style=\"background-image: url(https:\/\/phab.wmfusercontent.org\/file\/data\/pw54q7gozmlycx5be2ms\/PHID-FILE-4etzxu4xqrmq3e67kho6\/profile)\" class=\"visual-only phui-timeline-image\" href=\"\/p\/Slayful\/\" aria-hidden=\"true\"\u003e\u003c\/a\u003e\u003cdiv class=\"phui-timeline-wedge\" style=\"\"\u003e\u003c\/div\u003e\u003cdiv class=\"phui-timeline-group\"\u003e\u003cdiv class=\"phui-timeline-inner-content\"\u003e\u003ca name=\"5744685\" id=\"5744685\" class=\"phabricator-anchor-view\"\u003e\u003c\/a\u003e\u003cdiv class=\"phui-timeline-title phui-timeline-title-with-icon phui-timeline-title-with-menu\"\u003e\u003cspan class=\"phui-timeline-icon-fill\"\u003e\u003cspan class=\"visual-only phui-icon-view phui-font-fa fa-user-plus phui-timeline-icon\" data-meta=\"0_404\" aria-hidden=\"true\"\u003e\u003c\/span\u003e\u003c\/span\u003e\u003ca href=\"\/p\/Slayful\/\" class=\"phui-handle phui-link-person\" data-sigil=\"hovercard\" data-meta=\"0_117\"\u003eSlayful\u003c\/a\u003e subscribed.\u003cspan class=\"phui-timeline-extra\"\u003e\u003ca href=\"#5744685\" data-sigil=\"has-tooltip\" data-meta=\"0_403\"\u003e\u003cspan class=\"screen-only\"\u003eDec 16 2019, 3:12 PM\u003c\/span\u003e\u003cspan class=\"print-only\" aria-hidden=\"true\"\u003e2019-12-16 15:12:37 (UTC+0)\u003c\/span\u003e\u003c\/a\u003e\u003c\/span\u003e\u003c\/div\u003e\u003ca href=\"#\" class=\"phui-timeline-menu\" aria-haspopup=\"true\" aria-expanded=\"false\" data-sigil=\"phui-dropdown-menu\" data-meta=\"0_401\"\u003e\u003cspan class=\"aural-only\"\u003eComment Actions\u003c\/span\u003e\u003cspan class=\"visual-only phui-icon-view phui-font-fa fa-caret-down\" data-meta=\"0_402\" aria-hidden=\"true\"\u003e\u003c\/span\u003e\u003c\/a\u003e\u003cdiv class=\"phui-timeline-core-content\"\u003e\u003cspan class=\"transaction-comment\" data-sigil=\"transaction-comment\" data-meta=\"0_116\"\u003e\u003cdiv class=\"phabricator-remarkup\"\u003e\u003cp\u003eI *really* like the approach with using the interfaces and a service, like the proposed "HookContainer", to run the hooks.\u003c\/p\u003e\n\n\u003cp\u003eI'm wondering if the interfaces could be leveraged more for executing the hooks, for example:\u003c\/p\u003e\n\n\u003cdiv class=\"remarkup-code-block\" data-code-lang=\"text\" data-sigil=\"remarkup-code-block\"\u003e\u003cpre class=\"remarkup-code\"\u003e\/\/ hook container injected from MediaWikiServices\nhookContainer->getHook(UserLoginComplete::class)\n ->onUserLoginComplete( $user, $injected_html, $direct );\n}\u003c\/pre\u003e\u003c\/div\u003e\n\n\u003cp\u003eThe result of \u003ctt class=\"remarkup-monospaced\"\u003egetHook\u003c\/tt\u003e implements the hook's interface (in this case UserLoginComplete), so we get type safety. The implementation returned by the hookContainer would run all hooks that have been registered for this interface.\u003c\/p\u003e\u003c\/div\u003e\u003c\/span\u003e\u003c\/div\u003e\u003c\/div\u003e\u003c\/div\u003e\u003c\/div\u003e\u003c\/div\u003e\u003c\/div\u003e\u003cdiv class=\"phui-timeline-event-view phui-timeline-spacer\"\u003e\u003c\/div\u003e\u003cdiv class=\"phui-timeline-shell\" data-sigil=\"transaction anchor-container\" data-meta=\"0_417\"\u003e\u003cdiv class=\"phui-timeline-event-view phui-timeline-major-event\"\u003e\u003cdiv class=\"phui-timeline-content\"\u003e\u003ca style=\"background-image: url(https:\/\/phab.wmfusercontent.org\/file\/data\/ms665yc73j6nadjitytk\/PHID-FILE-mocohumlrcbe2lcuplml\/profile)\" class=\"visual-only phui-timeline-image\" href=\"\/p\/Anomie\/\" aria-hidden=\"true\"\u003e\u003c\/a\u003e\u003cdiv class=\"phui-timeline-badges\"\u003e\u003cul class=\"phui-badge-flex-view grouped flex-view-collapsed \"\u003e\u003cli class=\"phui-badge-flex-item\"\u003e\u003ca class=\"phui-badge-mini phui-badge-mini-orange \" href=\"\/badges\/view\/5\/\" data-sigil=\"has-tooltip\" data-meta=\"0_415\"\u003e\u003cspan class=\"visual-only phui-icon-view phui-font-fa fa-rocket\" data-meta=\"0_416\" aria-hidden=\"true\"\u003e\u003c\/span\u003e\u003c\/a\u003e\u003c\/li\u003e\u003c\/ul\u003e\u003c\/div\u003e\u003cdiv class=\"phui-timeline-wedge\" style=\"\"\u003e\u003c\/div\u003e\u003cdiv class=\"phui-timeline-group\"\u003e\u003cdiv class=\"phui-timeline-inner-content\"\u003e\u003ca name=\"5744732\" id=\"5744732\" class=\"phabricator-anchor-view\"\u003e\u003c\/a\u003e\u003cdiv class=\"phui-timeline-title phui-timeline-title-with-icon phui-timeline-title-with-menu\"\u003e\u003cspan class=\"phui-timeline-icon-fill\"\u003e\u003cspan class=\"visual-only phui-icon-view phui-font-fa fa-comment phui-timeline-icon\" data-meta=\"0_414\" aria-hidden=\"true\"\u003e\u003c\/span\u003e\u003c\/span\u003e\u003ca href=\"\/p\/Anomie\/\" class=\"phui-handle phui-link-person\" data-sigil=\"hovercard\" data-meta=\"0_118\"\u003eAnomie\u003c\/a\u003e added a comment.\u003cspan class=\"phui-timeline-extra\"\u003eEdited\u003cspan class=\"visual-only\" aria-hidden=\"true\"\u003e \u00b7 \u003c\/span\u003e\u003ca href=\"#5744732\" data-sigil=\"has-tooltip\" data-meta=\"0_413\"\u003e\u003cspan class=\"screen-only\"\u003eDec 16 2019, 3:27 PM\u003c\/span\u003e\u003cspan class=\"print-only\" aria-hidden=\"true\"\u003e2019-12-16 15:27:45 (UTC+0)\u003c\/span\u003e\u003c\/a\u003e\u003c\/span\u003e\u003c\/div\u003e\u003ca href=\"#\" class=\"phui-timeline-menu\" aria-haspopup=\"true\" aria-expanded=\"false\" data-sigil=\"phui-dropdown-menu\" data-meta=\"0_411\"\u003e\u003cspan class=\"aural-only\"\u003eComment Actions\u003c\/span\u003e\u003cspan class=\"visual-only phui-icon-view phui-font-fa fa-caret-down\" data-meta=\"0_412\" aria-hidden=\"true\"\u003e\u003c\/span\u003e\u003c\/a\u003e\u003cdiv class=\"phui-timeline-core-content\"\u003e\u003cspan class=\"transaction-comment\" data-sigil=\"transaction-comment\" data-meta=\"0_119\"\u003e\u003cdiv class=\"phabricator-remarkup\"\u003e\u003cblockquote class=\"remarkup-reply-block\"\u003e\n\u003cdiv class=\"remarkup-reply-head\"\u003eIn \u003ca href=\"\/T240307#5744479\" class=\"phui-tag-view phui-tag-type-object \" data-sigil=\"hovercard\" data-meta=\"0_16\"\u003e\u003cspan class=\"phui-tag-core-closed\"\u003e\u003cspan class=\"phui-tag-core phui-tag-color-object\"\u003eT240307#5744479\u003c\/span\u003e\u003c\/span\u003e\u003c\/a\u003e, \u003ca href=\"\/p\/daniel\/\" class=\"phui-tag-view phui-tag-type-person \" data-sigil=\"hovercard\" data-meta=\"0_17\"\u003e\u003cspan class=\"phui-tag-core phui-tag-color-person\"\u003e@daniel\u003c\/span\u003e\u003c\/a\u003e wrote:\u003c\/div\u003e\n\u003cdiv class=\"remarkup-reply-body\"\u003e\u003cp\u003eOne thing I don't quite see is why we still need hooks names, other than the names of the associated interfaces. This seems redundant and prone to inconsistencies.\u003c\/p\u003e\u003c\/div\u003e\n\u003c\/blockquote\u003e\n\n\u003cp\u003eThe convention here seems to be that the interface's "base" name always matches the hook name. Using just the "base" name avoids repeating namespace prefixes unnecessarily in places like extension.json, and avoids potential collisions between same-named hooks existing in different namespaces.\u003c\/p\u003e\n\n\u003cp\u003eAs some examples of the latter if we didn't use hook names:\u003c\/p\u003e\n\n\u003cul class=\"remarkup-list\"\u003e\n\u003cli class=\"remarkup-list-item\"\u003eIf MediaWiki\\Foo\\SomeName is an alias for MediaWiki\\Bar\\SomeName, we'd need extra logic to ensure that listeners registered for both names wind up being called. But at the same time not doing so for MediaWiki\\Foo\\SomeOtherName and MediaWiki\\Bar\\SomeOtherName which are actually different hooks that happen to have the same base name.\u003c\/li\u003e\n\u003cli class=\"remarkup-list-item\"\u003eIf MediaWiki\\Foo\\SomeName and MediaWiki\\Bar\\SomeName are different hooks, they can't be implemented by the same listener or runner because they'd both be defining "onSomeName" methods. Or else all the method names on all hook interfaces would be longer because they'd have to somehow incorporate the full namespace.\u003c\/li\u003e\n\u003c\/ul\u003e\n\n\n\n\u003cblockquote\u003e\u003cp\u003eTo mitigate inconvenience when a new version of a hook is introduced, we could support a mechanism to register adapters: When MyNewHook is introduced to replace MyOldHook, an adapter MyOldHookAdapter can written that implements MyNewHook and wraps an instance of MyOldHook. An instantiator callback (or object spec) for that adapter can then be registered with something like addAdapter( MyOldHook::class, MyNewHook::class, $instantiatorCallback ). When an eon registers a handler for MyOldHook, the instanstiator callback is used to create an instance of MyOldHookAdapter which gets registered as a MyNewHook instead of the original handler.\u003c\/p\u003e\u003c\/blockquote\u003e\n\n\u003cp\u003eIt seems to me that it would be simpler to just have the calling code call both ->onMyNewHook() and ->onMyOldHook(), with the latter following the usual deprecation process.\u003c\/p\u003e\n\n\u003cp\u003eExtensions that follow the "release branches" policy would just update interface usage, hook signature, and extension.json all at once to drop use of the old versions and begin using the new.\u003c\/p\u003e\n\n\u003cp\u003eExtensions using the "master" policy would probably[1] have to register multiple entries in HookListeners to deal with the relevant interfaces potentially not existing, and would probably have their onMyOldHook implementation look something like\u003c\/p\u003e\n\n\u003cdiv class=\"remarkup-code-block\" data-code-lang=\"php\" data-sigil=\"remarkup-code-block\"\u003e\u003cpre class=\"remarkup-code\"\u003e\u003cspan class=\"k\"\u003epublic\u003c\/span\u003e \u003cspan class=\"k\"\u003efunction\u003c\/span\u003e \u003cspan class=\"no\"\u003eonMyOldHook\u003c\/span\u003e\u003cspan class=\"o\"\u003e()\u003c\/span\u003e \u003cspan class=\"o\"\u003e{\u003c\/span\u003e\n \u003cspan class=\"k\"\u003eif\u003c\/span\u003e \u003cspan class=\"o\"\u003e(\u003c\/span\u003e \u003cspan class=\"nf\" data-symbol-name=\"interface_exists\"\u003einterface_exists\u003c\/span\u003e\u003cspan class=\"o\"\u003e(\u003c\/span\u003e \u003cspan class=\"nc\" data-symbol-name=\"MyNewHook\"\u003eMyNewHook\u003c\/span\u003e\u003cspan class=\"o\"\u003e::\u003c\/span\u003e\u003cspan class=\"na\" data-symbol-context=\"MyNewHook\" data-symbol-name=\"class\"\u003eclass\u003c\/span\u003e \u003cspan class=\"o\"\u003e)\u003c\/span\u003e \u003cspan class=\"o\"\u003e)\u003c\/span\u003e \u003cspan class=\"o\"\u003e{\u003c\/span\u003e\n \u003cspan class=\"k\"\u003ereturn\u003c\/span\u003e\u003cspan class=\"o\"\u003e;\u003c\/span\u003e \u003cspan class=\"c\"\u003e\/\/ new hook interface exists, assume it was\/will be called\u003c\/span\u003e\n \u003cspan class=\"o\"\u003e}\u003c\/span\u003e\n\n \u003cspan class=\"c\"\u003e\/\/ hook logic goes here\u003c\/span\u003e\n\u003cspan class=\"o\"\u003e}\u003c\/span\u003e\u003c\/pre\u003e\u003c\/div\u003e\n\n\u003cp\u003e[1]: Or not, if it's not actually checked that the listener actually implements the interface versus just providing the correctly-named method with a compatible signature. And if we don't start having the methods be like "MyHook_v1::onMyHook()" and "MyHook_v2::onMyHook()".\u003c\/p\u003e\u003c\/div\u003e\u003c\/span\u003e\u003c\/div\u003e\u003c\/div\u003e\u003c\/div\u003e\u003c\/div\u003e\u003c\/div\u003e\u003c\/div\u003e\u003cdiv class=\"phui-timeline-event-view phui-timeline-spacer\"\u003e\u003c\/div\u003e\u003cdiv class=\"phui-timeline-shell\" data-sigil=\"transaction anchor-container\" data-meta=\"0_428\"\u003e\u003cdiv class=\"phui-timeline-event-view phui-timeline-major-event\"\u003e\u003cdiv class=\"phui-timeline-content\"\u003e\u003ca style=\"background-image: url(https:\/\/phab.wmfusercontent.org\/file\/data\/ms665yc73j6nadjitytk\/PHID-FILE-mocohumlrcbe2lcuplml\/profile)\" class=\"visual-only phui-timeline-image\" href=\"\/p\/Anomie\/\" aria-hidden=\"true\"\u003e\u003c\/a\u003e\u003cdiv class=\"phui-timeline-badges\"\u003e\u003cul class=\"phui-badge-flex-view grouped flex-view-collapsed \"\u003e\u003cli class=\"phui-badge-flex-item\"\u003e\u003ca class=\"phui-badge-mini phui-badge-mini-orange \" href=\"\/badges\/view\/5\/\" data-sigil=\"has-tooltip\" data-meta=\"0_426\"\u003e\u003cspan class=\"visual-only phui-icon-view phui-font-fa fa-rocket\" data-meta=\"0_427\" aria-hidden=\"true\"\u003e\u003c\/span\u003e\u003c\/a\u003e\u003c\/li\u003e\u003c\/ul\u003e\u003c\/div\u003e\u003cdiv class=\"phui-timeline-wedge\" style=\"\"\u003e\u003c\/div\u003e\u003cdiv class=\"phui-timeline-group\"\u003e\u003cdiv class=\"phui-timeline-inner-content\"\u003e\u003ca name=\"5744742\" id=\"5744742\" class=\"phabricator-anchor-view\"\u003e\u003c\/a\u003e\u003cdiv class=\"phui-timeline-title phui-timeline-title-with-icon phui-timeline-title-with-menu\"\u003e\u003cspan class=\"phui-timeline-icon-fill\"\u003e\u003cspan class=\"visual-only phui-icon-view phui-font-fa fa-comment phui-timeline-icon\" data-meta=\"0_425\" aria-hidden=\"true\"\u003e\u003c\/span\u003e\u003c\/span\u003e\u003ca href=\"\/p\/Anomie\/\" class=\"phui-handle phui-link-person\" data-sigil=\"hovercard\" data-meta=\"0_120\"\u003eAnomie\u003c\/a\u003e added a comment.\u003cspan class=\"phui-timeline-extra\"\u003e\u003ca href=\"#5744742\" data-sigil=\"has-tooltip\" data-meta=\"0_424\"\u003e\u003cspan class=\"screen-only\"\u003eDec 16 2019, 3:31 PM\u003c\/span\u003e\u003cspan class=\"print-only\" aria-hidden=\"true\"\u003e2019-12-16 15:31:24 (UTC+0)\u003c\/span\u003e\u003c\/a\u003e\u003c\/span\u003e\u003c\/div\u003e\u003ca href=\"#\" class=\"phui-timeline-menu\" aria-haspopup=\"true\" aria-expanded=\"false\" data-sigil=\"phui-dropdown-menu\" data-meta=\"0_422\"\u003e\u003cspan class=\"aural-only\"\u003eComment Actions\u003c\/span\u003e\u003cspan class=\"visual-only phui-icon-view phui-font-fa fa-caret-down\" data-meta=\"0_423\" aria-hidden=\"true\"\u003e\u003c\/span\u003e\u003c\/a\u003e\u003cdiv class=\"phui-timeline-core-content\"\u003e\u003cspan class=\"transaction-comment\" data-sigil=\"transaction-comment\" data-meta=\"0_121\"\u003e\u003cdiv class=\"phabricator-remarkup\"\u003e\u003cblockquote class=\"remarkup-reply-block\"\u003e\n\u003cdiv class=\"remarkup-reply-head\"\u003eIn \u003ca href=\"\/T240307#5744685\" class=\"phui-tag-view phui-tag-type-object \" data-sigil=\"hovercard\" data-meta=\"0_18\"\u003e\u003cspan class=\"phui-tag-core-closed\"\u003e\u003cspan class=\"phui-tag-core phui-tag-color-object\"\u003eT240307#5744685\u003c\/span\u003e\u003c\/span\u003e\u003c\/a\u003e, \u003ca href=\"\/p\/Slayful\/\" class=\"phui-tag-view phui-tag-type-person \" data-sigil=\"hovercard\" data-meta=\"0_19\"\u003e\u003cspan class=\"phui-tag-core phui-tag-color-person\"\u003e@Slayful\u003c\/span\u003e\u003c\/a\u003e wrote:\u003c\/div\u003e\n\u003cdiv class=\"remarkup-reply-body\"\u003e\u003cp\u003eI'm wondering if the interfaces could be leveraged more for executing the hooks, for example:\u003c\/p\u003e\n\n\u003cdiv class=\"remarkup-code-block\" data-code-lang=\"text\" data-sigil=\"remarkup-code-block\"\u003e\u003cpre class=\"remarkup-code\"\u003e\/\/ hook container injected from MediaWikiServices\nhookContainer->getHook(UserLoginComplete::class)\n ->onUserLoginComplete( $user, $injected_html, $direct );\n}\u003c\/pre\u003e\u003c\/div\u003e\n\n\u003cp\u003eThe result of \u003ctt class=\"remarkup-monospaced\"\u003egetHook\u003c\/tt\u003e implements the hook's interface (in this case UserLoginComplete), so we get type safety. The implementation returned by the hookContainer would run all hooks that have been registered for this interface.\u003c\/p\u003e\u003c\/div\u003e\n\u003c\/blockquote\u003e\n\n\u003cp\u003eWhat's the difference between that and the HookRunner class(es) as proposed?\u003c\/p\u003e\u003c\/div\u003e\u003c\/span\u003e\u003c\/div\u003e\u003c\/div\u003e\u003c\/div\u003e\u003c\/div\u003e\u003c\/div\u003e\u003c\/div\u003e\u003cdiv class=\"phui-timeline-event-view phui-timeline-spacer\"\u003e\u003c\/div\u003e\u003cdiv class=\"phui-timeline-shell\" data-sigil=\"transaction anchor-container\" data-meta=\"0_431\"\u003e\u003cdiv class=\"phui-timeline-event-view phui-timeline-minor-event\"\u003e\u003cdiv class=\"phui-timeline-content\"\u003e\u003ca style=\"background-image: url(https:\/\/phab.wmfusercontent.org\/file\/data\/247abt7phqlbitgglyxa\/PHID-FILE-tx36db6dprvfuxu72bcj\/alphanumeric_aleo-white_D.png-_ec9da1-0%2C0%2C0%2C0.png)\" class=\"visual-only phui-timeline-image\" href=\"\/p\/Daimona\/\" aria-hidden=\"true\"\u003e\u003c\/a\u003e\u003cdiv class=\"phui-timeline-wedge\" style=\"\"\u003e\u003c\/div\u003e\u003cdiv class=\"phui-timeline-group\"\u003e\u003ca name=\"5745139\" id=\"5745139\" class=\"phabricator-anchor-view\"\u003e\u003c\/a\u003e\u003cdiv class=\"phui-timeline-title phui-timeline-title-with-icon\"\u003e\u003cspan class=\"phui-timeline-icon-fill\"\u003e\u003cspan class=\"visual-only phui-icon-view phui-font-fa fa-user-plus phui-timeline-icon\" data-meta=\"0_430\" aria-hidden=\"true\"\u003e\u003c\/span\u003e\u003c\/span\u003e\u003ca href=\"\/p\/Daimona\/\" class=\"phui-handle phui-link-person\" data-sigil=\"hovercard\" data-meta=\"0_122\"\u003eDaimona\u003c\/a\u003e subscribed.\u003cspan class=\"phui-timeline-extra\"\u003e\u003ca href=\"#5745139\" data-sigil=\"has-tooltip\" data-meta=\"0_429\"\u003e\u003cspan class=\"screen-only\"\u003eDec 16 2019, 5:29 PM\u003c\/span\u003e\u003cspan class=\"print-only\" aria-hidden=\"true\"\u003e2019-12-16 17:29:40 (UTC+0)\u003c\/span\u003e\u003c\/a\u003e\u003c\/span\u003e\u003c\/div\u003e\u003c\/div\u003e\u003c\/div\u003e\u003c\/div\u003e\u003c\/div\u003e\u003cdiv class=\"phui-timeline-event-view phui-timeline-spacer\"\u003e\u003c\/div\u003e\u003cdiv class=\"phui-timeline-shell\" data-sigil=\"transaction anchor-container\" data-meta=\"0_442\"\u003e\u003cdiv class=\"phui-timeline-event-view phui-timeline-major-event\"\u003e\u003cdiv class=\"phui-timeline-content\"\u003e\u003ca style=\"background-image: url(https:\/\/phab.wmfusercontent.org\/file\/data\/v5wmnfiaelrd6nztxd3a\/PHID-FILE-s57znldbv3qchtewuryd\/profile)\" class=\"visual-only phui-timeline-image\" href=\"\/p\/daniel\/\" aria-hidden=\"true\"\u003e\u003c\/a\u003e\u003cdiv class=\"phui-timeline-badges\"\u003e\u003cul class=\"phui-badge-flex-view grouped flex-view-collapsed \"\u003e\u003cli class=\"phui-badge-flex-item\"\u003e\u003ca class=\"phui-badge-mini phui-badge-mini-indigo \" href=\"\/badges\/view\/14\/\" data-sigil=\"has-tooltip\" data-meta=\"0_440\"\u003e\u003cspan class=\"visual-only phui-icon-view phui-font-fa fa-empire\" data-meta=\"0_441\" aria-hidden=\"true\"\u003e\u003c\/span\u003e\u003c\/a\u003e\u003c\/li\u003e\u003c\/ul\u003e\u003c\/div\u003e\u003cdiv class=\"phui-timeline-wedge\" style=\"\"\u003e\u003c\/div\u003e\u003cdiv class=\"phui-timeline-group\"\u003e\u003cdiv class=\"phui-timeline-inner-content\"\u003e\u003ca name=\"5745198\" id=\"5745198\" class=\"phabricator-anchor-view\"\u003e\u003c\/a\u003e\u003cdiv class=\"phui-timeline-title phui-timeline-title-with-icon phui-timeline-title-with-menu\"\u003e\u003cspan class=\"phui-timeline-icon-fill\"\u003e\u003cspan class=\"visual-only phui-icon-view phui-font-fa fa-comment phui-timeline-icon\" data-meta=\"0_439\" aria-hidden=\"true\"\u003e\u003c\/span\u003e\u003c\/span\u003e\u003ca href=\"\/p\/daniel\/\" class=\"phui-handle phui-link-person\" data-sigil=\"hovercard\" data-meta=\"0_123\"\u003edaniel\u003c\/a\u003e added a comment.\u003cspan class=\"phui-timeline-extra\"\u003e\u003ca href=\"#5745198\" data-sigil=\"has-tooltip\" data-meta=\"0_438\"\u003e\u003cspan class=\"screen-only\"\u003eDec 16 2019, 5:36 PM\u003c\/span\u003e\u003cspan class=\"print-only\" aria-hidden=\"true\"\u003e2019-12-16 17:36:53 (UTC+0)\u003c\/span\u003e\u003c\/a\u003e\u003c\/span\u003e\u003c\/div\u003e\u003ca href=\"#\" class=\"phui-timeline-menu\" aria-haspopup=\"true\" aria-expanded=\"false\" data-sigil=\"phui-dropdown-menu\" data-meta=\"0_436\"\u003e\u003cspan class=\"aural-only\"\u003eComment Actions\u003c\/span\u003e\u003cspan class=\"visual-only phui-icon-view phui-font-fa fa-caret-down\" data-meta=\"0_437\" aria-hidden=\"true\"\u003e\u003c\/span\u003e\u003c\/a\u003e\u003cdiv class=\"phui-timeline-core-content\"\u003e\u003cspan class=\"transaction-comment\" data-sigil=\"transaction-comment\" data-meta=\"0_124\"\u003e\u003cdiv class=\"phabricator-remarkup\"\u003e\u003cblockquote class=\"remarkup-reply-block\"\u003e\n\u003cdiv class=\"remarkup-reply-head\"\u003eIn \u003ca href=\"\/T240307#5744685\" class=\"phui-tag-view phui-tag-type-object \" data-sigil=\"hovercard\" data-meta=\"0_20\"\u003e\u003cspan class=\"phui-tag-core-closed\"\u003e\u003cspan class=\"phui-tag-core phui-tag-color-object\"\u003eT240307#5744685\u003c\/span\u003e\u003c\/span\u003e\u003c\/a\u003e, \u003ca href=\"\/p\/Slayful\/\" class=\"phui-tag-view phui-tag-type-person \" data-sigil=\"hovercard\" data-meta=\"0_21\"\u003e\u003cspan class=\"phui-tag-core phui-tag-color-person\"\u003e@Slayful\u003c\/span\u003e\u003c\/a\u003e wrote:\u003c\/div\u003e\n\u003cdiv class=\"remarkup-reply-body\"\u003e\u003cp\u003e\/\/ hook container injected from MediaWikiServices\u003cbr \/\u003e\nhookContainer->getHook(UserLoginComplete::class)\u003cbr \/\u003e\n ->onUserLoginComplete( $user, $injected_html, $direct );\u003cbr \/\u003e\n}\u003c\/p\u003e\u003c\/div\u003e\n\u003c\/blockquote\u003e\n\n\u003cp\u003eYes, except that the class that calls the hook shouldn't have the HookContainer injected -- it should have handlers for the individual hooks injected.\u003c\/p\u003e\n\n\u003cp\u003eThe wiring file would have:\u003c\/p\u003e\n\n\u003cdiv class=\"remarkup-code-block\" data-code-lang=\"php\" data-sigil=\"remarkup-code-block\"\u003e\u003cpre class=\"remarkup-code\"\u003e\u003cspan class=\"k\"\u003efunction\u003c\/span\u003e \u003cspan class=\"o\"\u003e(\u003c\/span\u003e \u003cspan class=\"no\"\u003eMediaWikiServices\u003c\/span\u003e \u003cspan class=\"nv\"\u003e$services\u003c\/span\u003e \u003cspan class=\"o\"\u003e)\u003c\/span\u003e \u003cspan class=\"o\"\u003e{\u003c\/span\u003e\n \u003cspan class=\"k\"\u003ereturn\u003c\/span\u003e \u003cspan class=\"k\"\u003enew\u003c\/span\u003e \u003cspan class=\"nc\" data-symbol-name=\"MyService\"\u003eMyService\u003c\/span\u003e\u003cspan class=\"o\"\u003e(\u003c\/span\u003e\n \u003cspan class=\"nv\"\u003e$services\u003c\/span\u003e\u003cspan class=\"o\"\u003e->\u003c\/span\u003e\u003cspan class=\"na\" data-symbol-name=\"getHookContainer\"\u003egetHookContainer\u003c\/span\u003e\u003cspan class=\"o\"\u003e()->\u003c\/span\u003e\u003cspan class=\"na\" data-symbol-name=\"getHook\"\u003egetHook\u003c\/span\u003e\u003cspan class=\"o\"\u003e(\u003c\/span\u003e\u003cspan class=\"nc\" data-symbol-name=\"OnFooHandler\"\u003eOnFooHandler\u003c\/span\u003e\u003cspan class=\"o\"\u003e::\u003c\/span\u003e\u003cspan class=\"na\" data-symbol-context=\"OnFooHandler\" data-symbol-name=\"class\"\u003eclass\u003c\/span\u003e\u003cspan class=\"o\"\u003e),\u003c\/span\u003e\n \u003cspan class=\"nv\"\u003e$services\u003c\/span\u003e\u003cspan class=\"o\"\u003e->\u003c\/span\u003e\u003cspan class=\"na\" data-symbol-name=\"getHookContainer\"\u003egetHookContainer\u003c\/span\u003e\u003cspan class=\"o\"\u003e()->\u003c\/span\u003e\u003cspan class=\"na\" data-symbol-name=\"getHook\"\u003egetHook\u003c\/span\u003e\u003cspan class=\"o\"\u003e(\u003c\/span\u003e\u003cspan class=\"nc\" data-symbol-name=\"FooBarFilter\"\u003eFooBarFilter\u003c\/span\u003e\u003cspan class=\"o\"\u003e::\u003c\/span\u003e\u003cspan class=\"na\" data-symbol-context=\"FooBarFilter\" data-symbol-name=\"class\"\u003eclass\u003c\/span\u003e\u003cspan class=\"o\"\u003e)\u003c\/span\u003e\n \u003cspan class=\"o\"\u003e);\u003c\/span\u003e\n\u003cspan class=\"o\"\u003e}\u003c\/span\u003e\u003c\/pre\u003e\u003c\/div\u003e\n\n\u003cp\u003eAnd the, in the service class:\u003c\/p\u003e\n\n\u003cdiv class=\"remarkup-code-block\" data-code-lang=\"php\" data-sigil=\"remarkup-code-block\"\u003e\u003cpre class=\"remarkup-code\"\u003e\u003cspan class=\"o\"\u003e...\u003c\/span\u003e\n \u003cspan class=\"nv\"\u003e$this\u003c\/span\u003e\u003cspan class=\"o\"\u003e->\u003c\/span\u003e\u003cspan class=\"na\" data-symbol-name=\"onFooHandler\"\u003eonFooHandler\u003c\/span\u003e\u003cspan class=\"o\"\u003e->\u003c\/span\u003e\u003cspan class=\"na\" data-symbol-name=\"onFoo\"\u003eonFoo\u003c\/span\u003e\u003cspan class=\"o\"\u003e(\u003c\/span\u003e \u003cspan class=\"nv\"\u003e$something\u003c\/span\u003e \u003cspan class=\"o\"\u003e);\u003c\/span\u003e\n\u003cspan class=\"o\"\u003e...\u003c\/span\u003e\n \u003cspan class=\"nv\"\u003e$this\u003c\/span\u003e\u003cspan class=\"o\"\u003e->\u003c\/span\u003e\u003cspan class=\"na\" data-symbol-name=\"fooBarFilter\"\u003efooBarFilter\u003c\/span\u003e\u003cspan class=\"o\"\u003e->\u003c\/span\u003e\u003cspan class=\"na\" data-symbol-name=\"filterFooBar\"\u003efilterFooBar\u003c\/span\u003e\u003cspan class=\"o\"\u003e(\u003c\/span\u003e \u003cspan class=\"nv\"\u003e$foo\u003c\/span\u003e\u003cspan class=\"o\"\u003e,\u003c\/span\u003e \u003cspan class=\"nv\"\u003e$bar\u003c\/span\u003e \u003cspan class=\"o\"\u003e);\u003c\/span\u003e\u003c\/pre\u003e\u003c\/div\u003e\u003c\/div\u003e\u003c\/span\u003e\u003c\/div\u003e\u003c\/div\u003e\u003c\/div\u003e\u003c\/div\u003e\u003c\/div\u003e\u003c\/div\u003e\u003cdiv class=\"phui-timeline-event-view phui-timeline-spacer\"\u003e\u003c\/div\u003e\u003cdiv class=\"phui-timeline-shell\" data-sigil=\"transaction anchor-container\" data-meta=\"0_454\"\u003e\u003cdiv class=\"phui-timeline-event-view phui-timeline-major-event\"\u003e\u003cdiv class=\"phui-timeline-content\"\u003e\u003ca style=\"background-image: url(https:\/\/phab.wmfusercontent.org\/file\/data\/v5wmnfiaelrd6nztxd3a\/PHID-FILE-s57znldbv3qchtewuryd\/profile)\" class=\"visual-only phui-timeline-image\" href=\"\/p\/daniel\/\" aria-hidden=\"true\"\u003e\u003c\/a\u003e\u003cdiv class=\"phui-timeline-badges\"\u003e\u003cul class=\"phui-badge-flex-view grouped flex-view-collapsed \"\u003e\u003cli class=\"phui-badge-flex-item\"\u003e\u003ca class=\"phui-badge-mini phui-badge-mini-indigo \" href=\"\/badges\/view\/14\/\" data-sigil=\"has-tooltip\" data-meta=\"0_452\"\u003e\u003cspan class=\"visual-only phui-icon-view phui-font-fa fa-empire\" data-meta=\"0_453\" aria-hidden=\"true\"\u003e\u003c\/span\u003e\u003c\/a\u003e\u003c\/li\u003e\u003c\/ul\u003e\u003c\/div\u003e\u003cdiv class=\"phui-timeline-wedge\" style=\"\"\u003e\u003c\/div\u003e\u003cdiv class=\"phui-timeline-group\"\u003e\u003cdiv class=\"phui-timeline-inner-content\"\u003e\u003ca name=\"5745267\" id=\"5745267\" class=\"phabricator-anchor-view\"\u003e\u003c\/a\u003e\u003cdiv class=\"phui-timeline-title phui-timeline-title-with-icon phui-timeline-title-with-menu\"\u003e\u003cspan class=\"phui-timeline-icon-fill\"\u003e\u003cspan class=\"visual-only phui-icon-view phui-font-fa fa-comment phui-timeline-icon\" data-meta=\"0_451\" aria-hidden=\"true\"\u003e\u003c\/span\u003e\u003c\/span\u003e\u003ca href=\"\/p\/daniel\/\" class=\"phui-handle phui-link-person\" data-sigil=\"hovercard\" data-meta=\"0_125\"\u003edaniel\u003c\/a\u003e added a comment.\u003cspan class=\"phui-timeline-extra\"\u003eEdited\u003cspan class=\"visual-only\" aria-hidden=\"true\"\u003e \u00b7 \u003c\/span\u003e\u003ca href=\"#5745267\" data-sigil=\"has-tooltip\" data-meta=\"0_450\"\u003e\u003cspan class=\"screen-only\"\u003eDec 16 2019, 5:48 PM\u003c\/span\u003e\u003cspan class=\"print-only\" aria-hidden=\"true\"\u003e2019-12-16 17:48:03 (UTC+0)\u003c\/span\u003e\u003c\/a\u003e\u003c\/span\u003e\u003c\/div\u003e\u003ca href=\"#\" class=\"phui-timeline-menu\" aria-haspopup=\"true\" aria-expanded=\"false\" data-sigil=\"phui-dropdown-menu\" data-meta=\"0_448\"\u003e\u003cspan class=\"aural-only\"\u003eComment Actions\u003c\/span\u003e\u003cspan class=\"visual-only phui-icon-view phui-font-fa fa-caret-down\" data-meta=\"0_449\" aria-hidden=\"true\"\u003e\u003c\/span\u003e\u003c\/a\u003e\u003cdiv class=\"phui-timeline-core-content\"\u003e\u003cspan class=\"transaction-comment\" data-sigil=\"transaction-comment\" data-meta=\"0_126\"\u003e\u003cdiv class=\"phabricator-remarkup\"\u003e\u003cblockquote class=\"remarkup-reply-block\"\u003e\n\u003cdiv class=\"remarkup-reply-head\"\u003eIn \u003ca href=\"\/T240307#5744732\" class=\"phui-tag-view phui-tag-type-object \" data-sigil=\"hovercard\" data-meta=\"0_22\"\u003e\u003cspan class=\"phui-tag-core-closed\"\u003e\u003cspan class=\"phui-tag-core phui-tag-color-object\"\u003eT240307#5744732\u003c\/span\u003e\u003c\/span\u003e\u003c\/a\u003e, \u003ca href=\"\/p\/Anomie\/\" class=\"phui-tag-view phui-tag-type-person \" data-sigil=\"hovercard\" data-meta=\"0_23\"\u003e\u003cspan class=\"phui-tag-core phui-tag-color-person\"\u003e@Anomie\u003c\/span\u003e\u003c\/a\u003e wrote:\u003c\/div\u003e\n\u003cdiv class=\"remarkup-reply-body\"\u003e\u003cp\u003eThe convention here seems to be that the interface's "base" name always matches the hook name. Using just the "base" name avoids repeating namespace prefixes unnecessarily in places like extension.json, and avoids potential collisions between same-named hooks existing in different namespaces.\u003c\/p\u003e\u003c\/div\u003e\n\u003c\/blockquote\u003e\n\n\u003cp\u003eHooks with the same name won't collide when they are namespaced. With "plain" hook names, prefixes have to be used by extensions to avoid that. Why not just namespaces as prefixes, then?\u003c\/p\u003e\n\n\u003cblockquote\u003e\u003cp\u003eAs some examples of the latter if we didn't use hook names:\u003c\/p\u003e\n\n\u003cul class=\"remarkup-list\"\u003e\n\u003cli class=\"remarkup-list-item\"\u003eIf MediaWiki\\Foo\\SomeName is an alias for MediaWiki\\Bar\\SomeName, we'd need extra logic to ensure that listeners registered for both names wind up being called.\u003c\/li\u003e\n\u003c\/ul\u003e\u003c\/blockquote\u003e\n\n\u003cp\u003eAliases would be resolved when hook handlers get registered. That's indeed the only time aliases would be resolved.\u003c\/p\u003e\n\n\u003cblockquote\u003e\u003cp\u003eBut at the same time not doing so for MediaWiki\\Foo\\SomeOtherName and MediaWiki\\Bar\\SomeOtherName which are actually different hooks that happen to have the same base name.\u003c\/p\u003e\u003c\/blockquote\u003e\n\n\u003cp\u003eI'd only resolve aliases explicitly defined as such. Not just cut away the prefix.\u003c\/p\u003e\n\n\u003cblockquote\u003e\u003cul class=\"remarkup-list\"\u003e\n\u003cli class=\"remarkup-list-item\"\u003eIf MediaWiki\\Foo\\SomeName and MediaWiki\\Bar\\SomeName are different hooks, they can't be implemented by the same listener or runner because they'd both be defining "onSomeName" methods. Or else all the method names on all hook interfaces would be longer because they'd have to somehow incorporate the full namespace.\u003c\/li\u003e\n\u003c\/ul\u003e\u003c\/blockquote\u003e\n\n\u003cp\u003eI agree that this is a potential problem, but I don't see how using "plain names" makes it any better. It just makes all names longer, the hook name and the method name.\u003c\/p\u003e\n\n\u003cblockquote\u003e\u003cp\u003eIt seems to me that it would be simpler to just have the calling code call both ->onMyNewHook() and ->onMyOldHook(), with the latter following the usual deprecation process.\u003c\/p\u003e\u003c\/blockquote\u003e\n\n\u003cp\u003eThat's indeed the simplest solution, but it has a downside that is already problematic in core code now: if the old signature requires an object that is not needed by the new hook, and would have to be constructed just to satisfy the legacy hook's signature, it's nicer to encapsulate that logic in an adapter class. Allows for automated deprecation warnings, and reduces boiler plate code in the application logic. This also ensures that the code is only run when actually needed - though it might cause such code to run once per handler, instead once per call...\u003c\/p\u003e\n\n\u003cblockquote\u003e\u003cp\u003eExtensions using the "master" policy would probably[1] have to register multiple entries in HookListeners to deal with the relevant interfaces potentially not existing, and would probably have their onMyOldHook implementation look\u003c\/p\u003e\u003c\/blockquote\u003e\n\n\u003cp\u003eThis actually raises a serious issue: making extensions forward-compatible. An extension cannot easily make use of the new interface unless it *requires* that new interface to be present. We'd have to make hook registration depend on what is available, perhaps by encoding a conditional in the object spec.\u003c\/p\u003e\u003c\/div\u003e\u003c\/span\u003e\u003c\/div\u003e\u003c\/div\u003e\u003c\/div\u003e\u003c\/div\u003e\u003c\/div\u003e\u003c\/div\u003e\u003cdiv class=\"phui-timeline-event-view phui-timeline-spacer\"\u003e\u003c\/div\u003e\u003cdiv class=\"phui-timeline-shell\" data-sigil=\"transaction anchor-container\" data-meta=\"0_465\"\u003e\u003cdiv class=\"phui-timeline-event-view phui-timeline-major-event\"\u003e\u003cdiv class=\"phui-timeline-content\"\u003e\u003ca style=\"background-image: url(https:\/\/phab.wmfusercontent.org\/file\/data\/ms665yc73j6nadjitytk\/PHID-FILE-mocohumlrcbe2lcuplml\/profile)\" class=\"visual-only phui-timeline-image\" href=\"\/p\/Anomie\/\" aria-hidden=\"true\"\u003e\u003c\/a\u003e\u003cdiv class=\"phui-timeline-badges\"\u003e\u003cul class=\"phui-badge-flex-view grouped flex-view-collapsed \"\u003e\u003cli class=\"phui-badge-flex-item\"\u003e\u003ca class=\"phui-badge-mini phui-badge-mini-orange \" href=\"\/badges\/view\/5\/\" data-sigil=\"has-tooltip\" data-meta=\"0_463\"\u003e\u003cspan class=\"visual-only phui-icon-view phui-font-fa fa-rocket\" data-meta=\"0_464\" aria-hidden=\"true\"\u003e\u003c\/span\u003e\u003c\/a\u003e\u003c\/li\u003e\u003c\/ul\u003e\u003c\/div\u003e\u003cdiv class=\"phui-timeline-wedge\" style=\"\"\u003e\u003c\/div\u003e\u003cdiv class=\"phui-timeline-group\"\u003e\u003cdiv class=\"phui-timeline-inner-content\"\u003e\u003ca name=\"5745428\" id=\"5745428\" class=\"phabricator-anchor-view\"\u003e\u003c\/a\u003e\u003cdiv class=\"phui-timeline-title phui-timeline-title-with-icon phui-timeline-title-with-menu\"\u003e\u003cspan class=\"phui-timeline-icon-fill\"\u003e\u003cspan class=\"visual-only phui-icon-view phui-font-fa fa-comment phui-timeline-icon\" data-meta=\"0_462\" aria-hidden=\"true\"\u003e\u003c\/span\u003e\u003c\/span\u003e\u003ca href=\"\/p\/Anomie\/\" class=\"phui-handle phui-link-person\" data-sigil=\"hovercard\" data-meta=\"0_127\"\u003eAnomie\u003c\/a\u003e added a comment.\u003cspan class=\"phui-timeline-extra\"\u003e\u003ca href=\"#5745428\" data-sigil=\"has-tooltip\" data-meta=\"0_461\"\u003e\u003cspan class=\"screen-only\"\u003eDec 16 2019, 6:30 PM\u003c\/span\u003e\u003cspan class=\"print-only\" aria-hidden=\"true\"\u003e2019-12-16 18:30:23 (UTC+0)\u003c\/span\u003e\u003c\/a\u003e\u003c\/span\u003e\u003c\/div\u003e\u003ca href=\"#\" class=\"phui-timeline-menu\" aria-haspopup=\"true\" aria-expanded=\"false\" data-sigil=\"phui-dropdown-menu\" data-meta=\"0_459\"\u003e\u003cspan class=\"aural-only\"\u003eComment Actions\u003c\/span\u003e\u003cspan class=\"visual-only phui-icon-view phui-font-fa fa-caret-down\" data-meta=\"0_460\" aria-hidden=\"true\"\u003e\u003c\/span\u003e\u003c\/a\u003e\u003cdiv class=\"phui-timeline-core-content\"\u003e\u003cspan class=\"transaction-comment\" data-sigil=\"transaction-comment\" data-meta=\"0_128\"\u003e\u003cdiv class=\"phabricator-remarkup\"\u003e\u003cblockquote class=\"remarkup-reply-block\"\u003e\n\u003cdiv class=\"remarkup-reply-head\"\u003eIn \u003ca href=\"\/T240307#5745267\" class=\"phui-tag-view phui-tag-type-object \" data-sigil=\"hovercard\" data-meta=\"0_24\"\u003e\u003cspan class=\"phui-tag-core-closed\"\u003e\u003cspan class=\"phui-tag-core phui-tag-color-object\"\u003eT240307#5745267\u003c\/span\u003e\u003c\/span\u003e\u003c\/a\u003e, \u003ca href=\"\/p\/daniel\/\" class=\"phui-tag-view phui-tag-type-person \" data-sigil=\"hovercard\" data-meta=\"0_27\"\u003e\u003cspan class=\"phui-tag-core phui-tag-color-person\"\u003e@daniel\u003c\/span\u003e\u003c\/a\u003e wrote:\u003c\/div\u003e\n\u003cdiv class=\"remarkup-reply-body\"\u003e\u003cblockquote\u003e\u003cp\u003eAs some examples of the latter if we didn't use hook names:\u003c\/p\u003e\n\n\u003cul class=\"remarkup-list\"\u003e\n\u003cli class=\"remarkup-list-item\"\u003eIf MediaWiki\\Foo\\SomeName is an alias for MediaWiki\\Bar\\SomeName, we'd need extra logic to ensure that listeners registered for both names wind up being called.\u003c\/li\u003e\n\u003c\/ul\u003e\u003c\/blockquote\u003e\n\n\u003cp\u003eAliases would be resolved when hook handlers get registered. That's indeed the only time aliases would be resolved.\u003c\/p\u003e\u003c\/div\u003e\n\u003c\/blockquote\u003e\n\n\u003cp\u003eDoing this as stated would require loading the PHP file for every hook registered, even if it's not going to be called. We generally try to avoid reading PHP files that aren't actually going to be used during the execution.\u003c\/p\u003e\n\n\u003cp\u003eIn some cases that might result in an undesired exception, if the hook isn't going to be called because it doesn't actually exist in the current version of MediaWiki (i.e. it's being registered for back-compat or forward-compat).\u003c\/p\u003e\n\n\u003cblockquote\u003e\u003cp\u003eI agree that this is a potential problem, but I don't see how using "plain names" makes it any better. It just makes all names longer, the hook name and the method name.\u003c\/p\u003e\u003c\/blockquote\u003e\n\n\u003cp\u003eBetter "onFooSomeName" than "onMediaWiki$Foo$SomeName" (or whatever mangling we choose for the backslashes).\u003c\/p\u003e\n\n\u003cblockquote\u003e\u003cp\u003eThat's indeed the simplest solution, but it has a downside that is already problematic in core code now: if the old signature requires an object that is not needed by the new hook, and would have to be constructed just to satisfy the legacy hook's signature, it's nicer to encapsulate that logic in an adapter class.\u003c\/p\u003e\u003c\/blockquote\u003e\n\n\u003cp\u003eIt seems to me that creating a whole adapter class and having to register it and so on is far more complicated than just doing\u003c\/p\u003e\n\n\u003cdiv class=\"remarkup-code-block\" data-code-lang=\"php\" data-sigil=\"remarkup-code-block\"\u003e\u003cpre class=\"remarkup-code\"\u003e\u003cspan class=\"c\"\u003e\/\/ OldHook needs an OldObj\u003c\/span\u003e\n\u003cspan class=\"nv\"\u003e$oldObj\u003c\/span\u003e \u003cspan class=\"o\"\u003e=\u003c\/span\u003e \u003cspan class=\"k\"\u003enew\u003c\/span\u003e \u003cspan class=\"nc\" data-symbol-name=\"OldObj\"\u003eOldObj\u003c\/span\u003e\u003cspan class=\"o\"\u003e(\u003c\/span\u003e \u003cspan class=\"o\"\u003e...\u003c\/span\u003e \u003cspan class=\"o\"\u003e);\u003c\/span\u003e\n\u003cspan class=\"nv\"\u003e$this\u003c\/span\u003e\u003cspan class=\"o\"\u003e->\u003c\/span\u003e\u003cspan class=\"na\" data-symbol-name=\"hookRunner\"\u003ehookRunner\u003c\/span\u003e\u003cspan class=\"o\"\u003e->\u003c\/span\u003e\u003cspan class=\"na\" data-symbol-name=\"onOldHook\"\u003eonOldHook\u003c\/span\u003e\u003cspan class=\"o\"\u003e(\u003c\/span\u003e \u003cspan class=\"nv\"\u003e$oldObj\u003c\/span\u003e \u003cspan class=\"o\"\u003e);\u003c\/span\u003e\u003c\/pre\u003e\u003c\/div\u003e\n\n\u003cp\u003ewhere it's needed.\u003c\/p\u003e\n\n\u003cp\u003eIf the equivalent of "new OldObj" is actually expensive enough to care, wrap the whole thing in \u003ctt class=\"remarkup-monospaced\"\u003eif ( $this->hookContainer->isRegistered( 'OldHook' ) ) {\u003c\/tt\u003e.\u003c\/p\u003e\n\n\u003cblockquote\u003e\u003cp\u003eAllows for automated deprecation warnings,\u003c\/p\u003e\u003c\/blockquote\u003e\n\n\u003cp\u003eAdapters aren't needed for this. The HookRunner's implementation of onSomeOldThing() could set \u003ctt class=\"remarkup-monospaced\"\u003e$options['deprecatedVersion']\u003c\/tt\u003e or the like regardless of any adapter.\u003c\/p\u003e\n\n\u003cblockquote\u003e\u003cp\u003eand reduces boiler plate code in the application logic.\u003c\/p\u003e\u003c\/blockquote\u003e\n\n\u003cp\u003eConsidering that most hooks have exactly one caller, this too seem unlikely to be much of a concern.\u003c\/p\u003e\n\n\u003cblockquote\u003e\u003cp\u003eThis also ensures that the code is only run when actually needed - though it might cause such code to run once per handler, instead once per call...\u003c\/p\u003e\u003c\/blockquote\u003e\n\n\u003cp\u003eIn the best case you're running a bunch of extra code to register the adapter just before the hook is called to try to avoid running a probably-similar amount of code for just creating the object. In the worst case you're running a bunch of code during setup to register all these adapters even if they're only rarely needed.\u003c\/p\u003e\n\n\u003cblockquote\u003e\u003cblockquote\u003e\u003cp\u003eExtensions using the "master" policy would probably[1] have to register multiple entries in HookListeners to deal with the relevant interfaces potentially not existing, and would probably have their onMyOldHook implementation look\u003c\/p\u003e\u003c\/blockquote\u003e\n\n\u003cp\u003eThis actually raises a serious issue: making extensions forward-compatible. An extension cannot easily make use of the new interface unless it *requires* that new interface to be present. We'd have to make hook registration depend on what is available, perhaps by encoding a conditional in the object spec.\u003c\/p\u003e\u003c\/blockquote\u003e\n\n\u003cp\u003eAs currently proposed, this isn't much of a problem. The listener class isn't loaded until a hook on it is actually called, so it doesn't matter if it would use an interface that doesn't exist when the hook is never called. So, as I said, the extension would merely have to split up its listeners across more than one class. Which is already proposed as a suggestion anyway for other reasons, see \u003ca href=\"\/T240307#5729964\" class=\"phui-tag-view phui-tag-type-object \" data-sigil=\"hovercard\" data-meta=\"0_25\"\u003e\u003cspan class=\"phui-tag-core-closed\"\u003e\u003cspan class=\"phui-tag-core phui-tag-color-object\"\u003eT240307#5729964\u003c\/span\u003e\u003c\/span\u003e\u003c\/a\u003e and \u003ca href=\"\/T240307#5733085\" class=\"phui-tag-view phui-tag-type-object \" data-sigil=\"hovercard\" data-meta=\"0_26\"\u003e\u003cspan class=\"phui-tag-core-closed\"\u003e\u003cspan class=\"phui-tag-core phui-tag-color-object\"\u003eT240307#5733085\u003c\/span\u003e\u003c\/span\u003e\u003c\/a\u003e.\u003c\/p\u003e\u003c\/div\u003e\u003c\/span\u003e\u003c\/div\u003e\u003c\/div\u003e\u003c\/div\u003e\u003c\/div\u003e\u003c\/div\u003e\u003c\/div\u003e\u003cdiv class=\"phui-timeline-event-view phui-timeline-spacer\"\u003e\u003c\/div\u003e\u003cdiv class=\"phui-timeline-shell\" data-sigil=\"transaction anchor-container\" data-meta=\"0_474\"\u003e\u003cdiv class=\"phui-timeline-event-view phui-timeline-major-event\"\u003e\u003cdiv class=\"phui-timeline-content\"\u003e\u003ca style=\"background-image: url(https:\/\/phab.wmfusercontent.org\/file\/data\/xgl3wy55ovinfnucvwhx\/PHID-FILE-zocnksypiqutzf5oubpi\/profile)\" class=\"visual-only phui-timeline-image\" href=\"\/p\/tstarling\/\" aria-hidden=\"true\"\u003e\u003c\/a\u003e\u003cdiv class=\"phui-timeline-wedge\" style=\"\"\u003e\u003c\/div\u003e\u003cdiv class=\"phui-timeline-group\"\u003e\u003cdiv class=\"phui-timeline-inner-content\"\u003e\u003ca name=\"5746862\" id=\"5746862\" class=\"phabricator-anchor-view\"\u003e\u003c\/a\u003e\u003cdiv class=\"phui-timeline-title phui-timeline-title-with-icon phui-timeline-title-with-menu\"\u003e\u003cspan class=\"phui-timeline-icon-fill\"\u003e\u003cspan class=\"visual-only phui-icon-view phui-font-fa fa-comment phui-timeline-icon\" data-meta=\"0_473\" aria-hidden=\"true\"\u003e\u003c\/span\u003e\u003c\/span\u003e\u003ca href=\"\/p\/tstarling\/\" class=\"phui-handle handle-availability-partial phui-link-person\" data-sigil=\"hovercard\" data-meta=\"0_129\"\u003e\u003cspan class=\"perfect-circle\"\u003e\u2022\u003c\/span\u003e tstarling\u003c\/a\u003e added a comment.\u003cspan class=\"phui-timeline-extra\"\u003e\u003ca href=\"#5746862\" data-sigil=\"has-tooltip\" data-meta=\"0_472\"\u003e\u003cspan class=\"screen-only\"\u003eDec 17 2019, 6:29 AM\u003c\/span\u003e\u003cspan class=\"print-only\" aria-hidden=\"true\"\u003e2019-12-17 06:29:12 (UTC+0)\u003c\/span\u003e\u003c\/a\u003e\u003c\/span\u003e\u003c\/div\u003e\u003ca href=\"#\" class=\"phui-timeline-menu\" aria-haspopup=\"true\" aria-expanded=\"false\" data-sigil=\"phui-dropdown-menu\" data-meta=\"0_470\"\u003e\u003cspan class=\"aural-only\"\u003eComment Actions\u003c\/span\u003e\u003cspan class=\"visual-only phui-icon-view phui-font-fa fa-caret-down\" data-meta=\"0_471\" aria-hidden=\"true\"\u003e\u003c\/span\u003e\u003c\/a\u003e\u003cdiv class=\"phui-timeline-core-content\"\u003e\u003cspan class=\"transaction-comment\" data-sigil=\"transaction-comment\" data-meta=\"0_130\"\u003e\u003cdiv class=\"phabricator-remarkup\"\u003e\u003cblockquote class=\"remarkup-reply-block\"\u003e\n\u003cdiv class=\"remarkup-reply-head\"\u003eIn \u003ca href=\"\/T240307#5744732\" class=\"phui-tag-view phui-tag-type-object \" data-sigil=\"hovercard\" data-meta=\"0_28\"\u003e\u003cspan class=\"phui-tag-core-closed\"\u003e\u003cspan class=\"phui-tag-core phui-tag-color-object\"\u003eT240307#5744732\u003c\/span\u003e\u003c\/span\u003e\u003c\/a\u003e, \u003ca href=\"\/p\/Anomie\/\" class=\"phui-tag-view phui-tag-type-person \" data-sigil=\"hovercard\" data-meta=\"0_29\"\u003e\u003cspan class=\"phui-tag-core phui-tag-color-person\"\u003e@Anomie\u003c\/span\u003e\u003c\/a\u003e wrote:\u003c\/div\u003e\n\u003cdiv class=\"remarkup-reply-body\"\u003e\u003cdiv class=\"remarkup-code-block\" data-code-lang=\"php\" data-sigil=\"remarkup-code-block\"\u003e\u003cpre class=\"remarkup-code\"\u003e\u003cspan class=\"k\"\u003epublic\u003c\/span\u003e \u003cspan class=\"k\"\u003efunction\u003c\/span\u003e \u003cspan class=\"no\"\u003eonMyOldHook\u003c\/span\u003e\u003cspan class=\"o\"\u003e()\u003c\/span\u003e \u003cspan class=\"o\"\u003e{\u003c\/span\u003e\n \u003cspan class=\"k\"\u003eif\u003c\/span\u003e \u003cspan class=\"o\"\u003e(\u003c\/span\u003e \u003cspan class=\"nf\" data-symbol-name=\"interface_exists\"\u003einterface_exists\u003c\/span\u003e\u003cspan class=\"o\"\u003e(\u003c\/span\u003e \u003cspan class=\"nc\" data-symbol-name=\"MyNewHook\"\u003eMyNewHook\u003c\/span\u003e\u003cspan class=\"o\"\u003e::\u003c\/span\u003e\u003cspan class=\"na\" data-symbol-context=\"MyNewHook\" data-symbol-name=\"class\"\u003eclass\u003c\/span\u003e \u003cspan class=\"o\"\u003e)\u003c\/span\u003e \u003cspan class=\"o\"\u003e)\u003c\/span\u003e \u003cspan class=\"o\"\u003e{\u003c\/span\u003e\n \u003cspan class=\"k\"\u003ereturn\u003c\/span\u003e\u003cspan class=\"o\"\u003e;\u003c\/span\u003e \u003cspan class=\"c\"\u003e\/\/ new hook interface exists, assume it was\/will be called\u003c\/span\u003e\n \u003cspan class=\"o\"\u003e}\u003c\/span\u003e\n\n \u003cspan class=\"c\"\u003e\/\/ hook logic goes here\u003c\/span\u003e\n\u003cspan class=\"o\"\u003e}\u003c\/span\u003e\u003c\/pre\u003e\u003c\/div\u003e\u003c\/div\u003e\n\u003c\/blockquote\u003e\n\n\u003cp\u003eThis seems awkward, and we do have a lot of extensions using the "master" compatibility policy. Let's move this logic to HookContainer.\u003c\/p\u003e\n\n\u003cp\u003eLet's have a concept of hook versions in core, and if an extension registers listeners for multiple versions of a hook, only the latest known one is called. HookContainer::getLegacyHandlers() and HookContainer::getListeners() can check for later versions of a hook within the same extension and filter out deprecated listeners.\u003c\/p\u003e\n\n\u003cp\u003eI considered just declaring the fallback sequence in extension.json, omitting the core registry of hook names. The problem with this is that HookContainer won't know what the latest version is. If MyHook1, MyHook2 and MyHook3 are registered in an extension, and the latest version in core is MyHook2, then the call to MyHook2 needs to be unfiltered. So it doesn't help if the extension is telling us that MyHook3 is the latest.\u003c\/p\u003e\n\n\u003cp\u003eWe could still have a "filterable" flag in extension.json enabling this filtering behaviour, allowing extensions to opt in and making it more obvious what is going on by reading the extension source code. We just can't omit the core hook version list altogether, since it's needed for forwards compatibility of core.\u003c\/p\u003e\u003c\/div\u003e\u003c\/span\u003e\u003c\/div\u003e\u003c\/div\u003e\u003c\/div\u003e\u003c\/div\u003e\u003c\/div\u003e\u003c\/div\u003e\u003cdiv class=\"phui-timeline-event-view phui-timeline-spacer\"\u003e\u003c\/div\u003e\u003cdiv class=\"phui-timeline-shell\" data-sigil=\"transaction anchor-container\" data-meta=\"0_477\"\u003e\u003cdiv class=\"phui-timeline-event-view phui-timeline-minor-event\"\u003e\u003cdiv class=\"phui-timeline-content\"\u003e\u003ca style=\"background-image: url(https:\/\/phab.wmfusercontent.org\/file\/data\/amjf7djel4bvkhlyq6pi\/PHID-FILE-47q2t645h5oachtffqbv\/alphanumeric_lato-dark_F.png-_607bc2-255%2C255%2C255%2C0.7.png)\" class=\"visual-only phui-timeline-image\" href=\"\/p\/Foxtrott\/\" aria-hidden=\"true\"\u003e\u003c\/a\u003e\u003cdiv class=\"phui-timeline-wedge\" style=\"\"\u003e\u003c\/div\u003e\u003cdiv class=\"phui-timeline-group\"\u003e\u003ca name=\"5747052\" id=\"5747052\" class=\"phabricator-anchor-view\"\u003e\u003c\/a\u003e\u003cdiv class=\"phui-timeline-title phui-timeline-title-with-icon\"\u003e\u003cspan class=\"phui-timeline-icon-fill\"\u003e\u003cspan class=\"visual-only phui-icon-view phui-font-fa fa-user-plus phui-timeline-icon\" data-meta=\"0_476\" aria-hidden=\"true\"\u003e\u003c\/span\u003e\u003c\/span\u003e\u003ca href=\"\/p\/Foxtrott\/\" class=\"phui-handle phui-link-person\" data-sigil=\"hovercard\" data-meta=\"0_131\"\u003eFoxtrott\u003c\/a\u003e subscribed.\u003cspan class=\"phui-timeline-extra\"\u003e\u003ca href=\"#5747052\" data-sigil=\"has-tooltip\" data-meta=\"0_475\"\u003e\u003cspan class=\"screen-only\"\u003eDec 17 2019, 9:33 AM\u003c\/span\u003e\u003cspan class=\"print-only\" aria-hidden=\"true\"\u003e2019-12-17 09:33:22 (UTC+0)\u003c\/span\u003e\u003c\/a\u003e\u003c\/span\u003e\u003c\/div\u003e\u003c\/div\u003e\u003c\/div\u003e\u003c\/div\u003e\u003c\/div\u003e\u003cdiv class=\"phui-timeline-event-view phui-timeline-spacer\"\u003e\u003c\/div\u003e\u003cdiv class=\"phui-timeline-shell\" data-sigil=\"transaction anchor-container\" data-meta=\"0_489\"\u003e\u003cdiv class=\"phui-timeline-event-view phui-timeline-major-event\"\u003e\u003cdiv class=\"phui-timeline-content\"\u003e\u003ca style=\"background-image: url(https:\/\/phab.wmfusercontent.org\/file\/data\/v5wmnfiaelrd6nztxd3a\/PHID-FILE-s57znldbv3qchtewuryd\/profile)\" class=\"visual-only phui-timeline-image\" href=\"\/p\/daniel\/\" aria-hidden=\"true\"\u003e\u003c\/a\u003e\u003cdiv class=\"phui-timeline-badges\"\u003e\u003cul class=\"phui-badge-flex-view grouped flex-view-collapsed \"\u003e\u003cli class=\"phui-badge-flex-item\"\u003e\u003ca class=\"phui-badge-mini phui-badge-mini-indigo \" href=\"\/badges\/view\/14\/\" data-sigil=\"has-tooltip\" data-meta=\"0_487\"\u003e\u003cspan class=\"visual-only phui-icon-view phui-font-fa fa-empire\" data-meta=\"0_488\" aria-hidden=\"true\"\u003e\u003c\/span\u003e\u003c\/a\u003e\u003c\/li\u003e\u003c\/ul\u003e\u003c\/div\u003e\u003cdiv class=\"phui-timeline-wedge\" style=\"\"\u003e\u003c\/div\u003e\u003cdiv class=\"phui-timeline-group\"\u003e\u003cdiv class=\"phui-timeline-inner-content\"\u003e\u003ca name=\"5747190\" id=\"5747190\" class=\"phabricator-anchor-view\"\u003e\u003c\/a\u003e\u003cdiv class=\"phui-timeline-title phui-timeline-title-with-icon phui-timeline-title-with-menu\"\u003e\u003cspan class=\"phui-timeline-icon-fill\"\u003e\u003cspan class=\"visual-only phui-icon-view phui-font-fa fa-comment phui-timeline-icon\" data-meta=\"0_486\" aria-hidden=\"true\"\u003e\u003c\/span\u003e\u003c\/span\u003e\u003ca href=\"\/p\/daniel\/\" class=\"phui-handle phui-link-person\" data-sigil=\"hovercard\" data-meta=\"0_132\"\u003edaniel\u003c\/a\u003e added a comment.\u003cspan class=\"phui-timeline-extra\"\u003eEdited\u003cspan class=\"visual-only\" aria-hidden=\"true\"\u003e \u00b7 \u003c\/span\u003e\u003ca href=\"#5747190\" data-sigil=\"has-tooltip\" data-meta=\"0_485\"\u003e\u003cspan class=\"screen-only\"\u003eDec 17 2019, 10:46 AM\u003c\/span\u003e\u003cspan class=\"print-only\" aria-hidden=\"true\"\u003e2019-12-17 10:46:46 (UTC+0)\u003c\/span\u003e\u003c\/a\u003e\u003c\/span\u003e\u003c\/div\u003e\u003ca href=\"#\" class=\"phui-timeline-menu\" aria-haspopup=\"true\" aria-expanded=\"false\" data-sigil=\"phui-dropdown-menu\" data-meta=\"0_483\"\u003e\u003cspan class=\"aural-only\"\u003eComment Actions\u003c\/span\u003e\u003cspan class=\"visual-only phui-icon-view phui-font-fa fa-caret-down\" data-meta=\"0_484\" aria-hidden=\"true\"\u003e\u003c\/span\u003e\u003c\/a\u003e\u003cdiv class=\"phui-timeline-core-content\"\u003e\u003cspan class=\"transaction-comment\" data-sigil=\"transaction-comment\" data-meta=\"0_133\"\u003e\u003cdiv class=\"phabricator-remarkup\"\u003e\u003cblockquote class=\"remarkup-reply-block\"\u003e\n\u003cdiv class=\"remarkup-reply-head\"\u003eIn \u003ca href=\"\/T240307#5745428\" class=\"phui-tag-view phui-tag-type-object \" data-sigil=\"hovercard\" data-meta=\"0_31\"\u003e\u003cspan class=\"phui-tag-core-closed\"\u003e\u003cspan class=\"phui-tag-core phui-tag-color-object\"\u003eT240307#5745428\u003c\/span\u003e\u003c\/span\u003e\u003c\/a\u003e, \u003ca href=\"\/p\/Anomie\/\" class=\"phui-tag-view phui-tag-type-person \" data-sigil=\"hovercard\" data-meta=\"0_35\"\u003e\u003cspan class=\"phui-tag-core phui-tag-color-person\"\u003e@Anomie\u003c\/span\u003e\u003c\/a\u003e wrote:\u003c\/div\u003e\n\u003cdiv class=\"remarkup-reply-body\"\u003e\u003cblockquote class=\"remarkup-reply-block\"\u003e\n\u003cdiv class=\"remarkup-reply-head\"\u003eIn \u003ca href=\"\/T240307#5745267\" class=\"phui-tag-view phui-tag-type-object \" data-sigil=\"hovercard\" data-meta=\"0_30\"\u003e\u003cspan class=\"phui-tag-core-closed\"\u003e\u003cspan class=\"phui-tag-core phui-tag-color-object\"\u003eT240307#5745267\u003c\/span\u003e\u003c\/span\u003e\u003c\/a\u003e, \u003ca href=\"\/p\/daniel\/\" class=\"phui-tag-view phui-tag-type-person \" data-sigil=\"hovercard\" data-meta=\"0_34\"\u003e\u003cspan class=\"phui-tag-core phui-tag-color-person\"\u003e@daniel\u003c\/span\u003e\u003c\/a\u003e wrote:\u003c\/div\u003e\n\u003cdiv class=\"remarkup-reply-body\"\u003e\u003cp\u003eAliases would be resolved when hook handlers get registered. That's indeed the only time aliases would be resolved.\u003c\/p\u003e\u003c\/div\u003e\n\u003c\/blockquote\u003e\n\n\u003cp\u003eDoing this as stated would require loading the PHP file for every hook registered, even if it's not going to be called. We generally try to avoid reading PHP files that aren't actually going to be used during the execution.\u003c\/p\u003e\u003c\/div\u003e\n\u003c\/blockquote\u003e\n\n\u003cp\u003eThe aliases would be a string to string map in HookContainer, with values for core hardcoded. I don't see how that would cause any classes to be loaded.\u003c\/p\u003e\n\n\u003cblockquote\u003e\u003cp\u003eBetter "onFooSomeName" than "onMediaWiki$Foo$SomeName" (or whatever mangling we choose for the backslashes).\u003c\/p\u003e\u003c\/blockquote\u003e\n\n\u003cp\u003eIf you already know onFooSomeName is unique, then how would the use of namespaces make the method name any longer?\u003c\/p\u003e\n\n\u003cblockquote\u003e\u003cp\u003eIt seems to me that creating a whole adapter class and having to register it and so on is far more complicated than just doing\u003c\/p\u003e\n\n\u003cdiv class=\"remarkup-code-block\" data-code-lang=\"php\" data-sigil=\"remarkup-code-block\"\u003e\u003cpre class=\"remarkup-code\"\u003e\u003cspan class=\"c\"\u003e\/\/ OldHook needs an OldObj\u003c\/span\u003e\n\u003cspan class=\"nv\"\u003e$oldObj\u003c\/span\u003e \u003cspan class=\"o\"\u003e=\u003c\/span\u003e \u003cspan class=\"k\"\u003enew\u003c\/span\u003e \u003cspan class=\"nc\" data-symbol-name=\"OldObj\"\u003eOldObj\u003c\/span\u003e\u003cspan class=\"o\"\u003e(\u003c\/span\u003e \u003cspan class=\"o\"\u003e...\u003c\/span\u003e \u003cspan class=\"o\"\u003e);\u003c\/span\u003e\n\u003cspan class=\"nv\"\u003e$this\u003c\/span\u003e\u003cspan class=\"o\"\u003e->\u003c\/span\u003e\u003cspan class=\"na\" data-symbol-name=\"hookRunner\"\u003ehookRunner\u003c\/span\u003e\u003cspan class=\"o\"\u003e->\u003c\/span\u003e\u003cspan class=\"na\" data-symbol-name=\"onOldHook\"\u003eonOldHook\u003c\/span\u003e\u003cspan class=\"o\"\u003e(\u003c\/span\u003e \u003cspan class=\"nv\"\u003e$oldObj\u003c\/span\u003e \u003cspan class=\"o\"\u003e);\u003c\/span\u003e\u003c\/pre\u003e\u003c\/div\u003e\n\n\u003cp\u003ewhere it's needed.\u003c\/p\u003e\n\n\u003cp\u003eIf the equivalent of "new OldObj" is actually expensive enough to care, wrap the whole thing in \u003ctt class=\"remarkup-monospaced\"\u003eif ( $this->hookContainer->isRegistered( 'OldHook' ) ) {\u003c\/tt\u003e.\u003c\/p\u003e\u003c\/blockquote\u003e\n\n\u003cp\u003eIt's not just about being expensive. Construction of legacy objects often relies on global state and\/or drags in unwanted dependencies on kitchen sink classes. The adapter approach would avoid that.\u003c\/p\u003e\n\n\u003cp\u003eHaving support for "automatic" adapters doesn't mean they always have to be used. You can of course still call both hooks, keeping simply cases simple. I just want a way out of the pain that this is currently causing.\u003c\/p\u003e\n\n\u003cblockquote\u003e\u003cp\u003eAdapters aren't needed for this. The HookRunner's implementation of onSomeOldThing() could set \u003ctt class=\"remarkup-monospaced\"\u003e$options['deprecatedVersion']\u003c\/tt\u003e or the like regardless of any adapter.\u003c\/p\u003e\u003c\/blockquote\u003e\n\n\u003cp\u003eTrue.\u003c\/p\u003e\n\n\u003cblockquote\u003e\u003cblockquote\u003e\u003cp\u003eand reduces boiler plate code in the application logic.\u003c\/p\u003e\u003c\/blockquote\u003e\n\n\u003cp\u003eConsidering that most hooks have exactly one caller, this too seem unlikely to be much of a concern.\u003c\/p\u003e\u003c\/blockquote\u003e\n\n\u003cp\u003eHow many places we have that currently construct a legacy Revision object from a RevisionRecord so it can be passed to a hook? With boilerplate code for checking whether the hook is actually used, and all that.\u003c\/p\u003e\n\n\u003cp\u003eWith adapters, we'd have one adapter class per hook - but that "mess" would be located with the listener interface; we would be able to keep it out of the actual logic, making the code more readable.\u003c\/p\u003e\n\n\u003cblockquote\u003e\u003cp\u003eIn the best case you're running a bunch of extra code to register the adapter just before the hook is called to try to avoid running a probably-similar amount of code for just creating the object.\u003c\/p\u003e\u003c\/blockquote\u003e\n\n\u003cp\u003eNo, the caller doesn't register the adapter. The caller doesn't know or care about the adapter. Knowledge about adapters and aliases is solely in the wiring code that creates the HookContainer.\u003c\/p\u003e\n\n\u003cblockquote\u003e\u003cp\u003eIn the worst case you're running a bunch of code during setup to register all these adapters even if they're only rarely needed.\u003c\/p\u003e\u003c\/blockquote\u003e\n\n\u003cp\u003eIt's a single array. Much better than having all the boiler plate code sprinkled across the code base for legacy hooks that are rarely needed. The mess would be in once place, outside "normal" code.\u003c\/p\u003e\n\n\u003cblockquote\u003e\u003cp\u003eAs currently proposed, this isn't much of a problem. The listener class isn't loaded until a hook on it is actually called, so it doesn't matter if it would use an interface that doesn't exist when the hook is never called. So, as I said, the extension would merely have to split up its listeners across more than one class. Which is already proposed as a suggestion anyway for other reasons, see \u003ca href=\"\/T240307#5729964\" class=\"phui-tag-view phui-tag-type-object \" data-sigil=\"hovercard\" data-meta=\"0_32\"\u003e\u003cspan class=\"phui-tag-core-closed\"\u003e\u003cspan class=\"phui-tag-core phui-tag-color-object\"\u003eT240307#5729964\u003c\/span\u003e\u003c\/span\u003e\u003c\/a\u003e and \u003ca href=\"\/T240307#5733085\" class=\"phui-tag-view phui-tag-type-object \" data-sigil=\"hovercard\" data-meta=\"0_33\"\u003e\u003cspan class=\"phui-tag-core-closed\"\u003e\u003cspan class=\"phui-tag-core phui-tag-color-object\"\u003eT240307#5733085\u003c\/span\u003e\u003c\/span\u003e\u003c\/a\u003e.\u003c\/p\u003e\u003c\/blockquote\u003e\n\n\u003cp\u003eThat need to split is what I was thinking of. I suppose the split can be per MW version, so not as problematic.\u003c\/p\u003e\u003c\/div\u003e\u003c\/span\u003e\u003c\/div\u003e\u003c\/div\u003e\u003c\/div\u003e\u003c\/div\u003e\u003c\/div\u003e\u003c\/div\u003e\u003cdiv class=\"phui-timeline-event-view phui-timeline-spacer\"\u003e\u003c\/div\u003e\u003cdiv class=\"phui-timeline-shell\" data-sigil=\"transaction anchor-container\" data-meta=\"0_500\"\u003e\u003cdiv class=\"phui-timeline-event-view phui-timeline-major-event\"\u003e\u003cdiv class=\"phui-timeline-content\"\u003e\u003ca style=\"background-image: url(https:\/\/phab.wmfusercontent.org\/file\/data\/v5wmnfiaelrd6nztxd3a\/PHID-FILE-s57znldbv3qchtewuryd\/profile)\" class=\"visual-only phui-timeline-image\" href=\"\/p\/daniel\/\" aria-hidden=\"true\"\u003e\u003c\/a\u003e\u003cdiv class=\"phui-timeline-badges\"\u003e\u003cul class=\"phui-badge-flex-view grouped flex-view-collapsed \"\u003e\u003cli class=\"phui-badge-flex-item\"\u003e\u003ca class=\"phui-badge-mini phui-badge-mini-indigo \" href=\"\/badges\/view\/14\/\" data-sigil=\"has-tooltip\" data-meta=\"0_498\"\u003e\u003cspan class=\"visual-only phui-icon-view phui-font-fa fa-empire\" data-meta=\"0_499\" aria-hidden=\"true\"\u003e\u003c\/span\u003e\u003c\/a\u003e\u003c\/li\u003e\u003c\/ul\u003e\u003c\/div\u003e\u003cdiv class=\"phui-timeline-wedge\" style=\"\"\u003e\u003c\/div\u003e\u003cdiv class=\"phui-timeline-group\"\u003e\u003cdiv class=\"phui-timeline-inner-content\"\u003e\u003ca name=\"5747196\" id=\"5747196\" class=\"phabricator-anchor-view\"\u003e\u003c\/a\u003e\u003cdiv class=\"phui-timeline-title phui-timeline-title-with-icon phui-timeline-title-with-menu\"\u003e\u003cspan class=\"phui-timeline-icon-fill\"\u003e\u003cspan class=\"visual-only phui-icon-view phui-font-fa fa-comment phui-timeline-icon\" data-meta=\"0_497\" aria-hidden=\"true\"\u003e\u003c\/span\u003e\u003c\/span\u003e\u003ca href=\"\/p\/daniel\/\" class=\"phui-handle phui-link-person\" data-sigil=\"hovercard\" data-meta=\"0_134\"\u003edaniel\u003c\/a\u003e added a comment.\u003cspan class=\"phui-timeline-extra\"\u003e\u003ca href=\"#5747196\" data-sigil=\"has-tooltip\" data-meta=\"0_496\"\u003e\u003cspan class=\"screen-only\"\u003eDec 17 2019, 10:51 AM\u003c\/span\u003e\u003cspan class=\"print-only\" aria-hidden=\"true\"\u003e2019-12-17 10:51:12 (UTC+0)\u003c\/span\u003e\u003c\/a\u003e\u003c\/span\u003e\u003c\/div\u003e\u003ca href=\"#\" class=\"phui-timeline-menu\" aria-haspopup=\"true\" aria-expanded=\"false\" data-sigil=\"phui-dropdown-menu\" data-meta=\"0_494\"\u003e\u003cspan class=\"aural-only\"\u003eComment Actions\u003c\/span\u003e\u003cspan class=\"visual-only phui-icon-view phui-font-fa fa-caret-down\" data-meta=\"0_495\" aria-hidden=\"true\"\u003e\u003c\/span\u003e\u003c\/a\u003e\u003cdiv class=\"phui-timeline-core-content\"\u003e\u003cspan class=\"transaction-comment\" data-sigil=\"transaction-comment\" data-meta=\"0_135\"\u003e\u003cdiv class=\"phabricator-remarkup\"\u003e\u003cblockquote\u003e\u003cp\u003eLet's have a concept of hook versions in core, and if an extension registers listeners for multiple versions of a hook, only the latest known one is called. HookContainer::getLegacyHandlers() and HookContainer::getListeners() can check for later versions of a hook within the same extension and filter out deprecated listeners.\u003c\/p\u003e\u003c\/blockquote\u003e\n\n\u003cp\u003eI like that idea, but it's not entirely clear to me what that would look like in practice. Is it actual numbered versions of an interface, e.g. UserLoginComplete2, UserLoginComplete3, etc? Or just one hook superseding another?\u003c\/p\u003e\n\n\u003cblockquote\u003e\u003cp\u003eWe could still have a "filterable" flag in extension.json enabling this filtering behavior, allowing extensions to opt in and making it more obvious what is going on by reading the extension source code.\u003c\/p\u003e\u003c\/blockquote\u003e\n\n\u003cp\u003eIf we want to give the extension control over the filtering, perhaps the registration mechanism could support some kind of "register only if some other hook X isn't defined" or "register as a fallback for X".\u003c\/p\u003e\u003c\/div\u003e\u003c\/span\u003e\u003c\/div\u003e\u003c\/div\u003e\u003c\/div\u003e\u003c\/div\u003e\u003c\/div\u003e\u003c\/div\u003e\u003cdiv class=\"phui-timeline-event-view phui-timeline-spacer\"\u003e\u003c\/div\u003e\u003cdiv class=\"phui-timeline-shell\" data-sigil=\"transaction anchor-container\" data-meta=\"0_511\"\u003e\u003cdiv class=\"phui-timeline-event-view phui-timeline-major-event\"\u003e\u003cdiv class=\"phui-timeline-content\"\u003e\u003ca style=\"background-image: url(https:\/\/phab.wmfusercontent.org\/file\/data\/v5wmnfiaelrd6nztxd3a\/PHID-FILE-s57znldbv3qchtewuryd\/profile)\" class=\"visual-only phui-timeline-image\" href=\"\/p\/daniel\/\" aria-hidden=\"true\"\u003e\u003c\/a\u003e\u003cdiv class=\"phui-timeline-badges\"\u003e\u003cul class=\"phui-badge-flex-view grouped flex-view-collapsed \"\u003e\u003cli class=\"phui-badge-flex-item\"\u003e\u003ca class=\"phui-badge-mini phui-badge-mini-indigo \" href=\"\/badges\/view\/14\/\" data-sigil=\"has-tooltip\" data-meta=\"0_509\"\u003e\u003cspan class=\"visual-only phui-icon-view phui-font-fa fa-empire\" data-meta=\"0_510\" aria-hidden=\"true\"\u003e\u003c\/span\u003e\u003c\/a\u003e\u003c\/li\u003e\u003c\/ul\u003e\u003c\/div\u003e\u003cdiv class=\"phui-timeline-wedge\" style=\"\"\u003e\u003c\/div\u003e\u003cdiv class=\"phui-timeline-group\"\u003e\u003cdiv class=\"phui-timeline-inner-content\"\u003e\u003ca name=\"5747418\" id=\"5747418\" class=\"phabricator-anchor-view\"\u003e\u003c\/a\u003e\u003cdiv class=\"phui-timeline-title phui-timeline-title-with-icon phui-timeline-title-with-menu\"\u003e\u003cspan class=\"phui-timeline-icon-fill\"\u003e\u003cspan class=\"visual-only phui-icon-view phui-font-fa fa-comment phui-timeline-icon\" data-meta=\"0_508\" aria-hidden=\"true\"\u003e\u003c\/span\u003e\u003c\/span\u003e\u003ca href=\"\/p\/daniel\/\" class=\"phui-handle phui-link-person\" data-sigil=\"hovercard\" data-meta=\"0_136\"\u003edaniel\u003c\/a\u003e added a comment.\u003cspan class=\"phui-timeline-extra\"\u003e\u003ca href=\"#5747418\" data-sigil=\"has-tooltip\" data-meta=\"0_507\"\u003e\u003cspan class=\"screen-only\"\u003eDec 17 2019, 12:26 PM\u003c\/span\u003e\u003cspan class=\"print-only\" aria-hidden=\"true\"\u003e2019-12-17 12:26:56 (UTC+0)\u003c\/span\u003e\u003c\/a\u003e\u003c\/span\u003e\u003c\/div\u003e\u003ca href=\"#\" class=\"phui-timeline-menu\" aria-haspopup=\"true\" aria-expanded=\"false\" data-sigil=\"phui-dropdown-menu\" data-meta=\"0_505\"\u003e\u003cspan class=\"aural-only\"\u003eComment Actions\u003c\/span\u003e\u003cspan class=\"visual-only phui-icon-view phui-font-fa fa-caret-down\" data-meta=\"0_506\" aria-hidden=\"true\"\u003e\u003c\/span\u003e\u003c\/a\u003e\u003cdiv class=\"phui-timeline-core-content\"\u003e\u003cspan class=\"transaction-comment\" data-sigil=\"transaction-comment\" data-meta=\"0_137\"\u003e\u003cdiv class=\"phabricator-remarkup\"\u003e\u003cp\u003eThe discussion above is mostly about handling legacy names hook versioning. While it's important to discuss these here so we don't paint ourselves into a corner, it seems to me like the proposal as stated is mostly good as it is. There are a few things I'd change:\u003c\/p\u003e\n\n\u003cul class=\"remarkup-list\"\u003e\n\u003cli class=\"remarkup-list-item\"\u003eReserve the term "listener" for purely passive hook handlers, like the "action" handlers in \u003ca href=\"\/T212482\" class=\"phui-tag-view phui-tag-type-object \" data-sigil=\"hovercard\" data-meta=\"0_36\"\u003e\u003cspan class=\"phui-tag-core phui-tag-color-object\"\u003eT212482\u003c\/span\u003e\u003c\/a\u003e. Callbacks that can affect the caller aren't listeners in my understanding.\u003c\/li\u003e\n\u003cli class=\"remarkup-list-item\"\u003eClarify the relationship between hook names, class names, and method names. All three should represent the exact same thing, but they are defined independently, making inconsistencies likely. Since all three are globally unique, it would make sense to define a strict mapping between them: the class name must be the hook name plus a suffix that indicates the hook type, and the method name must be the hook name plus a prefix that indicates the hook type. E.g. the "UserLoginComplete" would use the UserLoginCompleteListener interface which declares the onUserLoginComplete() method. And the "UserCan" hook uses the UserCanFilter interface which declares the filterUserCan() method. The namespace would be determined by where the hook is called (see next point).\u003c\/li\u003e\n\u003cli class=\"remarkup-list-item\"\u003eDefine hook interfaces in the same namespace as their caller. Centralizing the hook interfaces in a single namespace inevitable leads to cyclic dependencies between namespaces: hooks depend on concepts declared in namespace X, and namespace X depends on the hook namespace.\u003c\/li\u003e\n\u003cli class=\"remarkup-list-item\"\u003eRequire hooks to be explicitly declared in the HookContainer (or HookRunner). Registering a handler for an unknown hook should cause an exception. This protects against typos in the registration, and allows registration to be conditional on which hook points are supported. Since defining a hook already requires boiler pate code to be added to HookRunner, the registration should happen close to that. Alternatively, HookContainer could check on registration if HookRunner has a method (and\/or implements an interface) that matches the hook handler being registered. Might be expensive to do it this way, though.\u003c\/li\u003e\n\u003c\/ul\u003e\u003c\/div\u003e\u003c\/span\u003e\u003c\/div\u003e\u003c\/div\u003e\u003c\/div\u003e\u003c\/div\u003e\u003c\/div\u003e\u003c\/div\u003e\u003cdiv class=\"phui-timeline-event-view phui-timeline-spacer\"\u003e\u003c\/div\u003e\u003cdiv class=\"phui-timeline-shell\" data-sigil=\"transaction anchor-container\" data-meta=\"0_522\"\u003e\u003cdiv class=\"phui-timeline-event-view phui-timeline-major-event\"\u003e\u003cdiv class=\"phui-timeline-content\"\u003e\u003ca style=\"background-image: url(https:\/\/phab.wmfusercontent.org\/file\/data\/ms665yc73j6nadjitytk\/PHID-FILE-mocohumlrcbe2lcuplml\/profile)\" class=\"visual-only phui-timeline-image\" href=\"\/p\/Anomie\/\" aria-hidden=\"true\"\u003e\u003c\/a\u003e\u003cdiv class=\"phui-timeline-badges\"\u003e\u003cul class=\"phui-badge-flex-view grouped flex-view-collapsed \"\u003e\u003cli class=\"phui-badge-flex-item\"\u003e\u003ca class=\"phui-badge-mini phui-badge-mini-orange \" href=\"\/badges\/view\/5\/\" data-sigil=\"has-tooltip\" data-meta=\"0_520\"\u003e\u003cspan class=\"visual-only phui-icon-view phui-font-fa fa-rocket\" data-meta=\"0_521\" aria-hidden=\"true\"\u003e\u003c\/span\u003e\u003c\/a\u003e\u003c\/li\u003e\u003c\/ul\u003e\u003c\/div\u003e\u003cdiv class=\"phui-timeline-wedge\" style=\"\"\u003e\u003c\/div\u003e\u003cdiv class=\"phui-timeline-group\"\u003e\u003cdiv class=\"phui-timeline-inner-content\"\u003e\u003ca name=\"5748443\" id=\"5748443\" class=\"phabricator-anchor-view\"\u003e\u003c\/a\u003e\u003cdiv class=\"phui-timeline-title phui-timeline-title-with-icon phui-timeline-title-with-menu\"\u003e\u003cspan class=\"phui-timeline-icon-fill\"\u003e\u003cspan class=\"visual-only phui-icon-view phui-font-fa fa-comment phui-timeline-icon\" data-meta=\"0_519\" aria-hidden=\"true\"\u003e\u003c\/span\u003e\u003c\/span\u003e\u003ca href=\"\/p\/Anomie\/\" class=\"phui-handle phui-link-person\" data-sigil=\"hovercard\" data-meta=\"0_138\"\u003eAnomie\u003c\/a\u003e added a comment.\u003cspan class=\"phui-timeline-extra\"\u003e\u003ca href=\"#5748443\" data-sigil=\"has-tooltip\" data-meta=\"0_518\"\u003e\u003cspan class=\"screen-only\"\u003eDec 17 2019, 5:32 PM\u003c\/span\u003e\u003cspan class=\"print-only\" aria-hidden=\"true\"\u003e2019-12-17 17:32:32 (UTC+0)\u003c\/span\u003e\u003c\/a\u003e\u003c\/span\u003e\u003c\/div\u003e\u003ca href=\"#\" class=\"phui-timeline-menu\" aria-haspopup=\"true\" aria-expanded=\"false\" data-sigil=\"phui-dropdown-menu\" data-meta=\"0_516\"\u003e\u003cspan class=\"aural-only\"\u003eComment Actions\u003c\/span\u003e\u003cspan class=\"visual-only phui-icon-view phui-font-fa fa-caret-down\" data-meta=\"0_517\" aria-hidden=\"true\"\u003e\u003c\/span\u003e\u003c\/a\u003e\u003cdiv class=\"phui-timeline-core-content\"\u003e\u003cspan class=\"transaction-comment\" data-sigil=\"transaction-comment\" data-meta=\"0_139\"\u003e\u003cdiv class=\"phabricator-remarkup\"\u003e\u003cblockquote class=\"remarkup-reply-block\"\u003e\n\u003cdiv class=\"remarkup-reply-head\"\u003eIn \u003ca href=\"\/T240307#5746862\" class=\"phui-tag-view phui-tag-type-object \" data-sigil=\"hovercard\" data-meta=\"0_37\"\u003e\u003cspan class=\"phui-tag-core-closed\"\u003e\u003cspan class=\"phui-tag-core phui-tag-color-object\"\u003eT240307#5746862\u003c\/span\u003e\u003c\/span\u003e\u003c\/a\u003e, \u003ca href=\"\/p\/tstarling\/\" class=\"phui-tag-view phui-tag-type-person \" data-sigil=\"hovercard\" data-meta=\"0_40\"\u003e\u003cspan class=\"phui-tag-core phui-tag-color-person\"\u003e\u003cspan class=\"phui-tag-dot phui-tag-color-orange\"\u003e\u003c\/span\u003e@tstarling\u003c\/span\u003e\u003c\/a\u003e wrote:\u003c\/div\u003e\n\u003cdiv class=\"remarkup-reply-body\"\u003e\u003cp\u003eand we do have a lot of extensions using the "master" compatibility policy\u003c\/p\u003e\u003c\/div\u003e\n\u003c\/blockquote\u003e\n\n\u003cp\u003eI was curious, so I checked the policies in Wikimedia-deployed extensions.\u003c\/p\u003e\n\n\u003cul class=\"remarkup-list\"\u003e\n\u003cli class=\"remarkup-list-item\"\u003e15 are "master".\u003c\/li\u003e\n\u003cli class=\"remarkup-list-item\"\u003e53 are "release branches".\u003c\/li\u003e\n\u003cli class=\"remarkup-list-item\"\u003e118 don't specify a policy, including 4 which don't even have a page with {{Extension}} on mediawiki.org.\u003c\/li\u003e\n\u003c\/ul\u003e\n\n\u003cblockquote\u003e\u003cp\u003eLet's have a concept of hook versions in core, and if an extension registers listeners for multiple versions of a hook, only the latest known one is called. HookContainer::getLegacyHandlers() and HookContainer::getListeners() can check for later versions of a hook within the same extension and filter out deprecated listeners.\u003c\/p\u003e\u003c\/blockquote\u003e\n\n\u003cp\u003eI'll be interested to see more details as to how that's proposed to work. I'm a bit concerned it'll turn out to be a complex system trying to avoid a relatively rare problem. But if the solution is tightly scoped, maybe the complexity won't be as much as I fear.\u003c\/p\u003e\n\n\u003cblockquote class=\"remarkup-reply-block\"\u003e\n\u003cdiv class=\"remarkup-reply-head\"\u003eIn \u003ca href=\"\/T240307#5747190\" class=\"phui-tag-view phui-tag-type-object \" data-sigil=\"hovercard\" data-meta=\"0_38\"\u003e\u003cspan class=\"phui-tag-core-closed\"\u003e\u003cspan class=\"phui-tag-core phui-tag-color-object\"\u003eT240307#5747190\u003c\/span\u003e\u003c\/span\u003e\u003c\/a\u003e, \u003ca href=\"\/p\/daniel\/\" class=\"phui-tag-view phui-tag-type-person \" data-sigil=\"hovercard\" data-meta=\"0_41\"\u003e\u003cspan class=\"phui-tag-core phui-tag-color-person\"\u003e@daniel\u003c\/span\u003e\u003c\/a\u003e wrote:\u003c\/div\u003e\n\u003cdiv class=\"remarkup-reply-body\"\u003e\u003cp\u003eThe aliases would be a string to string map in HookContainer, with values for core hardcoded. I don't see how that would cause any classes to be loaded.\u003c\/p\u003e\u003c\/div\u003e\n\u003c\/blockquote\u003e\n\n\u003cp\u003eSure, if you maintain a list of hook data completely separate from the actual interfaces, you could avoid having to reflect on the interfaces to find the aliases. But then you're adding yet another thing that need maintaining.\u003c\/p\u003e\n\n\u003cblockquote\u003e\u003cblockquote\u003e\u003cp\u003eBetter "onFooSomeName" than "onMediaWiki$Foo$SomeName" (or whatever mangling we choose for the backslashes).\u003c\/p\u003e\u003c\/blockquote\u003e\n\n\u003cp\u003eIf you already know onFooSomeName is unique, then how would the use of namespaces make the method name any longer?\u003c\/p\u003e\u003c\/blockquote\u003e\n\n\u003cp\u003eIf we allow the namespace to be significant, then the code in HookContainer that's building the method name to call based has to take it into account.\u003c\/p\u003e\n\n\u003cp\u003eUnless you're proposing that instead of a cheap string manipulation to determine the method name, we have to use slow reflection to extract the method name from the interface? Or just adding more global data to your global list of every known hook, I suppose.\u003c\/p\u003e\n\n\u003cblockquote\u003e\u003cp\u003eIt's not just about being expensive. Construction of legacy objects often relies on global state and\/or drags in unwanted dependencies on kitchen sink classes. The adapter approach would avoid that.\u003c\/p\u003e\u003c\/blockquote\u003e\n\n\u003cp\u003eThe adapter approach wouldn't avoid it, it would just hide it inside the adapter.\u003c\/p\u003e\n\n\u003cblockquote\u003e\u003cp\u003eHaving support for "automatic" adapters doesn't mean they always have to be used. You can of course still call both hooks, keeping simply cases simple. I just want a way out of the pain that this is currently causing.\u003c\/p\u003e\u003c\/blockquote\u003e\n\n\u003cp\u003eSounds very much like you're getting to the point of YAGNI now.\u003c\/p\u003e\n\n\u003cblockquote\u003e\u003cp\u003eHow many places we have that currently construct a legacy Revision object from a RevisionRecord so it can be passed to a hook? With boilerplate code for checking whether the hook is actually used, and all that.\u003c\/p\u003e\n\n\u003cp\u003eWith adapters, we'd have one adapter class per hook - but that "mess" would be located with the listener interface; we would be able to keep it out of the actual logic, making the code more readable.\u003c\/p\u003e\u003c\/blockquote\u003e\n\n\u003cp\u003e"We have a dozen legacy hooks, each called from one place. Much better to have a dozen adapter classes instead!" All the same boilerplate, plus added infrastructure, and it's more work to find where the legacy hook is actually being called from too.\u003c\/p\u003e\n\n\u003cp\u003ePersonally, I find code more readable when it's not scattered all about the codebase with registrations of handlers elsewhere causing action at a distance.\u003c\/p\u003e\n\n\u003cblockquote\u003e\u003cblockquote\u003e\u003cp\u003eIn the best case you're running a bunch of extra code to register the adapter just before the hook is called to try to avoid running a probably-similar amount of code for just creating the object.\u003c\/p\u003e\u003c\/blockquote\u003e\n\n\u003cp\u003eNo, the caller doesn't register the adapter. The caller doesn't know or care about the adapter. Knowledge about adapters and aliases is solely in the wiring code that creates the HookContainer.\u003c\/p\u003e\u003c\/blockquote\u003e\n\n\u003cp\u003eI had expected you'd be proposing the worst case.\u003c\/p\u003e\n\n\u003cblockquote\u003e\u003cblockquote\u003e\u003cp\u003eIn the worst case you're running a bunch of code during setup to register all these adapters even if they're only rarely needed.\u003c\/p\u003e\u003c\/blockquote\u003e\n\n\u003cp\u003eIt's a single array. Much better than having all the boiler plate code sprinkled across the code base for legacy hooks that are rarely needed. The mess would be in once place, outside "normal" code.\u003c\/p\u003e\u003c\/blockquote\u003e\n\n\u003cp\u003eWe seem to differ on this point. I like the code affecting a thing to be proximate to the thing (where it can be easily found when looking at the thing), while you prefer action at a distance to try to hide the messiness.\u003c\/p\u003e\n\n\u003cblockquote class=\"remarkup-reply-block\"\u003e\n\u003cdiv class=\"remarkup-reply-head\"\u003eIn \u003ca href=\"\/T240307#5747418\" class=\"phui-tag-view phui-tag-type-object \" data-sigil=\"hovercard\" data-meta=\"0_39\"\u003e\u003cspan class=\"phui-tag-core-closed\"\u003e\u003cspan class=\"phui-tag-core phui-tag-color-object\"\u003eT240307#5747418\u003c\/span\u003e\u003c\/span\u003e\u003c\/a\u003e, \u003ca href=\"\/p\/daniel\/\" class=\"phui-tag-view phui-tag-type-person \" data-sigil=\"hovercard\" data-meta=\"0_42\"\u003e\u003cspan class=\"phui-tag-core phui-tag-color-person\"\u003e@daniel\u003c\/span\u003e\u003c\/a\u003e wrote:\u003c\/div\u003e\n\u003cdiv class=\"remarkup-reply-body\"\u003e\u003cp\u003eAnd the "UserCan" hook uses the UserCanFilter interface which declares the filterUserCan() method.\u003c\/p\u003e\u003c\/div\u003e\n\u003c\/blockquote\u003e\n\n\u003cp\u003eWhat's the advantage in having different naming conventions for different kinds of hooks? It seems extra complexity (specifying or determining the "kind" to determine which prefix to use) for no clear benefit.\u003c\/p\u003e\n\n\u003cblockquote\u003e\u003cul class=\"remarkup-list\"\u003e\n\u003cli class=\"remarkup-list-item\"\u003eDefine hook interfaces in the same namespace as their caller. Centralizing the hook interfaces in a single namespace inevitable leads to cyclic dependencies between namespaces: hooks depend on concepts declared in namespace X, and namespace X depends on the hook namespace.\u003c\/li\u003e\n\u003c\/ul\u003e\u003c\/blockquote\u003e\n\n\u003cp\u003ePersonally I'm more concerned with actual dependencies than with imagined dependencies between unrelated things that happen to be in the same namespace.\u003c\/p\u003e\n\n\u003cp\u003eOn the other hand, keeping the hook interfaces associated with the code that calls them (by placing them in the same directory, which in PSR-4 means the same namespace) has distinct benefits that may outweigh the benefits of having all the hook interfaces together for ease of reference. Particularly since we can't really do "together" anyway once extensions are involved. So I'm fine with the bullet, just not the reasoning used.\u003c\/p\u003e\n\n\u003cblockquote\u003e\u003cul class=\"remarkup-list\"\u003e\n\u003cli class=\"remarkup-list-item\"\u003eRequire hooks to be explicitly declared in the HookContainer (or HookRunner). Registering a handler for an unknown hook should cause an exception. This [...] allows registration to be conditional on which hook points are supported.\u003c\/li\u003e\n\u003c\/ul\u003e\u003c\/blockquote\u003e\n\n\u003cp\u003eIt doesn't \u003cstrong\u003eallow\u003c\/strong\u003e registration to be conditional, it \u003cstrong\u003edemands\u003c\/strong\u003e it. It requires using \u003ca href=\"https:\/\/www.mediawiki.org\/wiki\/Manual:Extension_registration#Customizing_registration\" class=\"remarkup-link\" target=\"_blank\" rel=\"noreferrer\"\u003eextension.json's "callback"\u003c\/a\u003e with tests for which hooks are actually available in the specific version of MW+extensions being run, or else requires a micro-language in extension.json to specify which hooks to register with which specific versions of MW and\/or other extensions.\u003c\/p\u003e\n\n\u003cblockquote\u003e\u003cp\u003eSince defining a hook already requires boiler pate code to be added to HookRunner, the registration should happen close to that.\u003c\/p\u003e\u003c\/blockquote\u003e\n\n\u003cp\u003eThis makes little sense to me.\u003c\/p\u003e\n\n\u003cul class=\"remarkup-list\"\u003e\n\u003cli class=\"remarkup-list-item\"\u003e"HookRunner" in this proposal isn't just one thing. Even if we have only one in core, each extension would still have its own. But if we're putting the hook interfaces in the namespace with their callers, it would probably make more sense to similarly have a HookRunner per namespace as well instead of one HookRunner trying to do everything.\u003c\/li\u003e\n\u003cli class=\"remarkup-list-item\"\u003eThe code in HookRunner is a method definition on a class. Nothing is actually \u003cem\u003erun\u003c\/em\u003e there during setup (ideally HookRunner.php isn't even loaded during setup).\u003c\/li\u003e\n\u003c\/ul\u003e\n\n\u003cp\u003eThe best you might do is have the "registration" be some static array on a HookRunner class, and then somehow register all the HookRunners with something else so setup can load them all to collect all their arrays.\u003c\/p\u003e\n\n\u003cblockquote\u003e\u003cp\u003eAlternatively, HookContainer could check on registration if HookRunner has a method (and\/or implements an interface) that matches the hook handler being registered. Might be expensive to do it this way, though.\u003c\/p\u003e\u003c\/blockquote\u003e\n\n\u003cp\u003eAgain, there's more than one HookRunner.\u003c\/p\u003e\n\n\u003cp\u003eThat probably would be expensive. We should avoid unnecessarily loading every hook-interface's PHP file or doing a bunch of reflection during setup.\u003c\/p\u003e\u003c\/div\u003e\u003c\/span\u003e\u003c\/div\u003e\u003c\/div\u003e\u003c\/div\u003e\u003c\/div\u003e\u003c\/div\u003e\u003c\/div\u003e\u003cdiv class=\"phui-timeline-event-view phui-timeline-spacer\"\u003e\u003c\/div\u003e\u003cdiv class=\"phui-timeline-shell\" data-sigil=\"transaction anchor-container\" data-meta=\"0_535\"\u003e\u003cdiv class=\"phui-timeline-event-view phui-timeline-major-event\"\u003e\u003cdiv class=\"phui-timeline-content\"\u003e\u003ca style=\"background-image: url(https:\/\/phab.wmfusercontent.org\/file\/data\/m25d4sm73mzvfxk7efxx\/PHID-FILE-zigk2s47ziyr7hqvpw7v\/profile)\" class=\"visual-only phui-timeline-image\" href=\"\/p\/Ladsgroup\/\" aria-hidden=\"true\"\u003e\u003c\/a\u003e\u003cdiv class=\"phui-timeline-badges\"\u003e\u003cul class=\"phui-badge-flex-view grouped flex-view-collapsed \"\u003e\u003cli class=\"phui-badge-flex-item\"\u003e\u003ca class=\"phui-badge-mini phui-badge-mini-orange \" href=\"\/badges\/view\/17\/\" data-sigil=\"has-tooltip\" data-meta=\"0_531\"\u003e\u003cspan class=\"visual-only phui-icon-view phui-font-fa fa-rocket\" data-meta=\"0_532\" aria-hidden=\"true\"\u003e\u003c\/span\u003e\u003c\/a\u003e\u003c\/li\u003e\u003cli class=\"phui-badge-flex-item\"\u003e\u003ca class=\"phui-badge-mini phui-badge-mini-indigo \" href=\"\/badges\/view\/15\/\" data-sigil=\"has-tooltip\" data-meta=\"0_533\"\u003e\u003cspan class=\"visual-only phui-icon-view phui-font-fa fa-eye\" data-meta=\"0_534\" aria-hidden=\"true\"\u003e\u003c\/span\u003e\u003c\/a\u003e\u003c\/li\u003e\u003c\/ul\u003e\u003c\/div\u003e\u003cdiv class=\"phui-timeline-wedge\" style=\"\"\u003e\u003c\/div\u003e\u003cdiv class=\"phui-timeline-group\"\u003e\u003cdiv class=\"phui-timeline-inner-content\"\u003e\u003ca name=\"5749236\" id=\"5749236\" class=\"phabricator-anchor-view\"\u003e\u003c\/a\u003e\u003cdiv class=\"phui-timeline-title phui-timeline-title-with-icon phui-timeline-title-with-menu\"\u003e\u003cspan class=\"phui-timeline-icon-fill\"\u003e\u003cspan class=\"visual-only phui-icon-view phui-font-fa fa-user-plus phui-timeline-icon\" data-meta=\"0_530\" aria-hidden=\"true\"\u003e\u003c\/span\u003e\u003c\/span\u003e\u003ca href=\"\/p\/Ladsgroup\/\" class=\"phui-handle phui-link-person\" data-sigil=\"hovercard\" data-meta=\"0_141\"\u003eLadsgroup\u003c\/a\u003e subscribed.\u003cspan class=\"phui-timeline-extra\"\u003e\u003ca href=\"#5749236\" data-sigil=\"has-tooltip\" data-meta=\"0_529\"\u003e\u003cspan class=\"screen-only\"\u003eDec 17 2019, 9:57 PM\u003c\/span\u003e\u003cspan class=\"print-only\" aria-hidden=\"true\"\u003e2019-12-17 21:57:31 (UTC+0)\u003c\/span\u003e\u003c\/a\u003e\u003c\/span\u003e\u003c\/div\u003e\u003ca href=\"#\" class=\"phui-timeline-menu\" aria-haspopup=\"true\" aria-expanded=\"false\" data-sigil=\"phui-dropdown-menu\" data-meta=\"0_527\"\u003e\u003cspan class=\"aural-only\"\u003eComment Actions\u003c\/span\u003e\u003cspan class=\"visual-only phui-icon-view phui-font-fa fa-caret-down\" data-meta=\"0_528\" aria-hidden=\"true\"\u003e\u003c\/span\u003e\u003c\/a\u003e\u003cdiv class=\"phui-timeline-core-content\"\u003e\u003cspan class=\"transaction-comment\" data-sigil=\"transaction-comment\" data-meta=\"0_140\"\u003e\u003cdiv class=\"phabricator-remarkup\"\u003e\u003cblockquote\u003e\u003cp\u003e\/\/ ... many interfaces would be added here ...\u003c\/p\u003e\u003c\/blockquote\u003e\n\n\u003cp\u003eThat would be maybe hundreds of interfaces, do we really should do it? I don't have a better solution though given that I like everything else about the proposal.\u003c\/p\u003e\u003c\/div\u003e\u003c\/span\u003e\u003c\/div\u003e\u003c\/div\u003e\u003c\/div\u003e\u003c\/div\u003e\u003c\/div\u003e\u003c\/div\u003e\u003cdiv class=\"phui-timeline-event-view phui-timeline-spacer\"\u003e\u003c\/div\u003e\u003cdiv class=\"phui-timeline-shell\" data-sigil=\"transaction anchor-container\" data-meta=\"0_548\"\u003e\u003cdiv class=\"phui-timeline-event-view phui-timeline-major-event\"\u003e\u003cdiv class=\"phui-timeline-content\"\u003e\u003ca style=\"background-image: url(https:\/\/phab.wmfusercontent.org\/file\/data\/bxdymb7zqtipuiytbor5\/PHID-FILE-hh7qwoflwjmrunovgr5a\/profile)\" class=\"visual-only phui-timeline-image\" href=\"\/p\/Jdforrester-WMF\/\" aria-hidden=\"true\"\u003e\u003c\/a\u003e\u003cdiv class=\"phui-timeline-badges\"\u003e\u003cul class=\"phui-badge-flex-view grouped flex-view-collapsed \"\u003e\u003cli class=\"phui-badge-flex-item\"\u003e\u003ca class=\"phui-badge-mini phui-badge-mini-blue \" href=\"\/badges\/view\/18\/\" data-sigil=\"has-tooltip\" data-meta=\"0_544\"\u003e\u003cspan class=\"visual-only phui-icon-view phui-font-fa fa-star\" data-meta=\"0_545\" aria-hidden=\"true\"\u003e\u003c\/span\u003e\u003c\/a\u003e\u003c\/li\u003e\u003cli class=\"phui-badge-flex-item\"\u003e\u003ca class=\"phui-badge-mini phui-badge-mini-indigo \" href=\"\/badges\/view\/12\/\" data-sigil=\"has-tooltip\" data-meta=\"0_546\"\u003e\u003cspan class=\"visual-only phui-icon-view phui-font-fa fa-space-shuttle\" data-meta=\"0_547\" aria-hidden=\"true\"\u003e\u003c\/span\u003e\u003c\/a\u003e\u003c\/li\u003e\u003c\/ul\u003e\u003c\/div\u003e\u003cdiv class=\"phui-timeline-wedge\" style=\"\"\u003e\u003c\/div\u003e\u003cdiv class=\"phui-timeline-group\"\u003e\u003cdiv class=\"phui-timeline-inner-content\"\u003e\u003ca name=\"5750645\" id=\"5750645\" class=\"phabricator-anchor-view\"\u003e\u003c\/a\u003e\u003cdiv class=\"phui-timeline-title phui-timeline-title-with-icon phui-timeline-title-with-menu\"\u003e\u003cspan class=\"phui-timeline-icon-fill\"\u003e\u003cspan class=\"visual-only phui-icon-view phui-font-fa fa-user-plus phui-timeline-icon\" data-meta=\"0_543\" aria-hidden=\"true\"\u003e\u003c\/span\u003e\u003c\/span\u003e\u003ca href=\"\/p\/Jdforrester-WMF\/\" class=\"phui-handle phui-link-person\" data-sigil=\"hovercard\" data-meta=\"0_143\"\u003eJdforrester-WMF\u003c\/a\u003e subscribed.\u003cspan class=\"phui-timeline-extra\"\u003e\u003ca href=\"#5750645\" data-sigil=\"has-tooltip\" data-meta=\"0_542\"\u003e\u003cspan class=\"screen-only\"\u003eDec 18 2019, 10:45 AM\u003c\/span\u003e\u003cspan class=\"print-only\" aria-hidden=\"true\"\u003e2019-12-18 10:45:02 (UTC+0)\u003c\/span\u003e\u003c\/a\u003e\u003c\/span\u003e\u003c\/div\u003e\u003ca href=\"#\" class=\"phui-timeline-menu\" aria-haspopup=\"true\" aria-expanded=\"false\" data-sigil=\"phui-dropdown-menu\" data-meta=\"0_540\"\u003e\u003cspan class=\"aural-only\"\u003eComment Actions\u003c\/span\u003e\u003cspan class=\"visual-only phui-icon-view phui-font-fa fa-caret-down\" data-meta=\"0_541\" aria-hidden=\"true\"\u003e\u003c\/span\u003e\u003c\/a\u003e\u003cdiv class=\"phui-timeline-core-content\"\u003e\u003cspan class=\"transaction-comment\" data-sigil=\"transaction-comment\" data-meta=\"0_142\"\u003e\u003cdiv class=\"phabricator-remarkup\"\u003e\u003cblockquote class=\"remarkup-reply-block\"\u003e\n\u003cdiv class=\"remarkup-reply-head\"\u003eIn \u003ca href=\"\/T240307#5748443\" class=\"phui-tag-view phui-tag-type-object \" data-sigil=\"hovercard\" data-meta=\"0_44\"\u003e\u003cspan class=\"phui-tag-core-closed\"\u003e\u003cspan class=\"phui-tag-core phui-tag-color-object\"\u003eT240307#5748443\u003c\/span\u003e\u003c\/span\u003e\u003c\/a\u003e, \u003ca href=\"\/p\/Anomie\/\" class=\"phui-tag-view phui-tag-type-person \" data-sigil=\"hovercard\" data-meta=\"0_46\"\u003e\u003cspan class=\"phui-tag-core phui-tag-color-person\"\u003e@Anomie\u003c\/span\u003e\u003c\/a\u003e wrote:\u003c\/div\u003e\n\u003cdiv class=\"remarkup-reply-body\"\u003e\u003cblockquote class=\"remarkup-reply-block\"\u003e\n\u003cdiv class=\"remarkup-reply-head\"\u003eIn \u003ca href=\"\/T240307#5746862\" class=\"phui-tag-view phui-tag-type-object \" data-sigil=\"hovercard\" data-meta=\"0_43\"\u003e\u003cspan class=\"phui-tag-core-closed\"\u003e\u003cspan class=\"phui-tag-core phui-tag-color-object\"\u003eT240307#5746862\u003c\/span\u003e\u003c\/span\u003e\u003c\/a\u003e, \u003ca href=\"\/p\/tstarling\/\" class=\"phui-tag-view phui-tag-type-person \" data-sigil=\"hovercard\" data-meta=\"0_45\"\u003e\u003cspan class=\"phui-tag-core phui-tag-color-person\"\u003e\u003cspan class=\"phui-tag-dot phui-tag-color-orange\"\u003e\u003c\/span\u003e@tstarling\u003c\/span\u003e\u003c\/a\u003e wrote:\u003c\/div\u003e\n\u003cdiv class=\"remarkup-reply-body\"\u003e\u003cp\u003eand we do have a lot of extensions using the "master" compatibility policy\u003c\/p\u003e\u003c\/div\u003e\n\u003c\/blockquote\u003e\n\n\u003cp\u003eI was curious, so I checked the policies in Wikimedia-deployed extensions.\u003c\/p\u003e\n\n\u003cul class=\"remarkup-list\"\u003e\n\u003cli class=\"remarkup-list-item\"\u003e15 are "master".\u003c\/li\u003e\n\u003cli class=\"remarkup-list-item\"\u003e53 are "release branches".\u003c\/li\u003e\n\u003cli class=\"remarkup-list-item\"\u003e118 don't specify a policy, including 4 which don't even have a page with {{Extension}} on mediawiki.org.\u003c\/li\u003e\n\u003c\/ul\u003e\u003c\/div\u003e\n\u003c\/blockquote\u003e\n\n\u003cp\u003eI'll go fix those 118 to "release branches" if you sling me the list. ;-)\u003c\/p\u003e\n\n\u003cp\u003eMore generally, however, Tim is right; many of the hundreds of extensions not deployed on Wikimedia seem to (at least attempt to) operate on a "master" compatibility basis, however much we try to discourage it. Not sure how much TechCom\/etc. would like to use this opportunity to more seriously discourage this practice.\u003c\/p\u003e\u003c\/div\u003e\u003c\/span\u003e\u003c\/div\u003e\u003c\/div\u003e\u003c\/div\u003e\u003c\/div\u003e\u003c\/div\u003e\u003c\/div\u003e\u003cdiv class=\"phui-timeline-event-view phui-timeline-spacer\"\u003e\u003c\/div\u003e\u003cdiv class=\"phui-timeline-shell\" data-sigil=\"transaction anchor-container\" data-meta=\"0_559\"\u003e\u003cdiv class=\"phui-timeline-event-view phui-timeline-major-event\"\u003e\u003cdiv class=\"phui-timeline-content\"\u003e\u003ca style=\"background-image: url(https:\/\/phab.wmfusercontent.org\/file\/data\/v5wmnfiaelrd6nztxd3a\/PHID-FILE-s57znldbv3qchtewuryd\/profile)\" class=\"visual-only phui-timeline-image\" href=\"\/p\/daniel\/\" aria-hidden=\"true\"\u003e\u003c\/a\u003e\u003cdiv class=\"phui-timeline-badges\"\u003e\u003cul class=\"phui-badge-flex-view grouped flex-view-collapsed \"\u003e\u003cli class=\"phui-badge-flex-item\"\u003e\u003ca class=\"phui-badge-mini phui-badge-mini-indigo \" href=\"\/badges\/view\/14\/\" data-sigil=\"has-tooltip\" data-meta=\"0_557\"\u003e\u003cspan class=\"visual-only phui-icon-view phui-font-fa fa-empire\" data-meta=\"0_558\" aria-hidden=\"true\"\u003e\u003c\/span\u003e\u003c\/a\u003e\u003c\/li\u003e\u003c\/ul\u003e\u003c\/div\u003e\u003cdiv class=\"phui-timeline-wedge\" style=\"\"\u003e\u003c\/div\u003e\u003cdiv class=\"phui-timeline-group\"\u003e\u003cdiv class=\"phui-timeline-inner-content\"\u003e\u003ca name=\"5750750\" id=\"5750750\" class=\"phabricator-anchor-view\"\u003e\u003c\/a\u003e\u003cdiv class=\"phui-timeline-title phui-timeline-title-with-icon phui-timeline-title-with-menu\"\u003e\u003cspan class=\"phui-timeline-icon-fill\"\u003e\u003cspan class=\"visual-only phui-icon-view phui-font-fa fa-comment phui-timeline-icon\" data-meta=\"0_556\" aria-hidden=\"true\"\u003e\u003c\/span\u003e\u003c\/span\u003e\u003ca href=\"\/p\/daniel\/\" class=\"phui-handle phui-link-person\" data-sigil=\"hovercard\" data-meta=\"0_144\"\u003edaniel\u003c\/a\u003e added a comment.\u003cspan class=\"phui-timeline-extra\"\u003e\u003ca href=\"#5750750\" data-sigil=\"has-tooltip\" data-meta=\"0_555\"\u003e\u003cspan class=\"screen-only\"\u003eDec 18 2019, 11:40 AM\u003c\/span\u003e\u003cspan class=\"print-only\" aria-hidden=\"true\"\u003e2019-12-18 11:40:53 (UTC+0)\u003c\/span\u003e\u003c\/a\u003e\u003c\/span\u003e\u003c\/div\u003e\u003ca href=\"#\" class=\"phui-timeline-menu\" aria-haspopup=\"true\" aria-expanded=\"false\" data-sigil=\"phui-dropdown-menu\" data-meta=\"0_553\"\u003e\u003cspan class=\"aural-only\"\u003eComment Actions\u003c\/span\u003e\u003cspan class=\"visual-only phui-icon-view phui-font-fa fa-caret-down\" data-meta=\"0_554\" aria-hidden=\"true\"\u003e\u003c\/span\u003e\u003c\/a\u003e\u003cdiv class=\"phui-timeline-core-content\"\u003e\u003cspan class=\"transaction-comment\" data-sigil=\"transaction-comment\" data-meta=\"0_145\"\u003e\u003cdiv class=\"phabricator-remarkup\"\u003e\u003cblockquote class=\"remarkup-reply-block\"\u003e\n\u003cdiv class=\"remarkup-reply-head\"\u003eIn \u003ca href=\"\/T240307#5749236\" class=\"phui-tag-view phui-tag-type-object \" data-sigil=\"hovercard\" data-meta=\"0_47\"\u003e\u003cspan class=\"phui-tag-core-closed\"\u003e\u003cspan class=\"phui-tag-core phui-tag-color-object\"\u003eT240307#5749236\u003c\/span\u003e\u003c\/span\u003e\u003c\/a\u003e, \u003ca href=\"\/p\/Ladsgroup\/\" class=\"phui-tag-view phui-tag-type-person \" data-sigil=\"hovercard\" data-meta=\"0_48\"\u003e\u003cspan class=\"phui-tag-core phui-tag-color-person\"\u003e@Ladsgroup\u003c\/span\u003e\u003c\/a\u003e wrote:\u003c\/div\u003e\n\u003cdiv class=\"remarkup-reply-body\"\u003e\u003cp\u003eThat would be maybe hundreds of interfaces, do we really should do it? I don't have a better solution though given that I like everything else about the proposal.\u003c\/p\u003e\u003c\/div\u003e\n\u003c\/blockquote\u003e\n\n\u003cp\u003eI think it's worth it. While the number of files may look big, but we are basically adding 5 lines of declaration and 5 lines of documentation for each hook, which was previously missing. Also, you'd get a nice overview of hooks used in a module just by looking at the files in the corresponding directory (if we put the interfaces with the callers).\u003c\/p\u003e\n\n\u003cp\u003eThe boilerplate in the HookRunner is a bit annoying, but no worse than MediaWikiServies.\u003c\/p\u003e\u003c\/div\u003e\u003c\/span\u003e\u003c\/div\u003e\u003c\/div\u003e\u003c\/div\u003e\u003c\/div\u003e\u003c\/div\u003e\u003c\/div\u003e\u003cdiv class=\"phui-timeline-event-view phui-timeline-spacer\"\u003e\u003c\/div\u003e\u003cdiv class=\"phui-timeline-shell\" data-sigil=\"transaction anchor-container\" data-meta=\"0_570\"\u003e\u003cdiv class=\"phui-timeline-event-view phui-timeline-major-event\"\u003e\u003cdiv class=\"phui-timeline-content\"\u003e\u003ca style=\"background-image: url(https:\/\/phab.wmfusercontent.org\/file\/data\/ms665yc73j6nadjitytk\/PHID-FILE-mocohumlrcbe2lcuplml\/profile)\" class=\"visual-only phui-timeline-image\" href=\"\/p\/Anomie\/\" aria-hidden=\"true\"\u003e\u003c\/a\u003e\u003cdiv class=\"phui-timeline-badges\"\u003e\u003cul class=\"phui-badge-flex-view grouped flex-view-collapsed \"\u003e\u003cli class=\"phui-badge-flex-item\"\u003e\u003ca class=\"phui-badge-mini phui-badge-mini-orange \" href=\"\/badges\/view\/5\/\" data-sigil=\"has-tooltip\" data-meta=\"0_568\"\u003e\u003cspan class=\"visual-only phui-icon-view phui-font-fa fa-rocket\" data-meta=\"0_569\" aria-hidden=\"true\"\u003e\u003c\/span\u003e\u003c\/a\u003e\u003c\/li\u003e\u003c\/ul\u003e\u003c\/div\u003e\u003cdiv class=\"phui-timeline-wedge\" style=\"\"\u003e\u003c\/div\u003e\u003cdiv class=\"phui-timeline-group\"\u003e\u003cdiv class=\"phui-timeline-inner-content\"\u003e\u003ca name=\"5752156\" id=\"5752156\" class=\"phabricator-anchor-view\"\u003e\u003c\/a\u003e\u003cdiv class=\"phui-timeline-title phui-timeline-title-with-icon phui-timeline-title-with-menu\"\u003e\u003cspan class=\"phui-timeline-icon-fill\"\u003e\u003cspan class=\"visual-only phui-icon-view phui-font-fa fa-comment phui-timeline-icon\" data-meta=\"0_567\" aria-hidden=\"true\"\u003e\u003c\/span\u003e\u003c\/span\u003e\u003ca href=\"\/p\/Anomie\/\" class=\"phui-handle phui-link-person\" data-sigil=\"hovercard\" data-meta=\"0_146\"\u003eAnomie\u003c\/a\u003e added a comment.\u003cspan class=\"phui-timeline-extra\"\u003e\u003ca href=\"#5752156\" data-sigil=\"has-tooltip\" data-meta=\"0_566\"\u003e\u003cspan class=\"screen-only\"\u003eDec 18 2019, 7:23 PM\u003c\/span\u003e\u003cspan class=\"print-only\" aria-hidden=\"true\"\u003e2019-12-18 19:23:35 (UTC+0)\u003c\/span\u003e\u003c\/a\u003e\u003c\/span\u003e\u003c\/div\u003e\u003ca href=\"#\" class=\"phui-timeline-menu\" aria-haspopup=\"true\" aria-expanded=\"false\" data-sigil=\"phui-dropdown-menu\" data-meta=\"0_564\"\u003e\u003cspan class=\"aural-only\"\u003eComment Actions\u003c\/span\u003e\u003cspan class=\"visual-only phui-icon-view phui-font-fa fa-caret-down\" data-meta=\"0_565\" aria-hidden=\"true\"\u003e\u003c\/span\u003e\u003c\/a\u003e\u003cdiv class=\"phui-timeline-core-content\"\u003e\u003cspan class=\"transaction-comment\" data-sigil=\"transaction-comment\" data-meta=\"0_147\"\u003e\u003cdiv class=\"phabricator-remarkup\"\u003e\u003cblockquote class=\"remarkup-reply-block\"\u003e\n\u003cdiv class=\"remarkup-reply-head\"\u003eIn \u003ca href=\"\/T240307#5750645\" class=\"phui-tag-view phui-tag-type-object \" data-sigil=\"hovercard\" data-meta=\"0_49\"\u003e\u003cspan class=\"phui-tag-core-closed\"\u003e\u003cspan class=\"phui-tag-core phui-tag-color-object\"\u003eT240307#5750645\u003c\/span\u003e\u003c\/span\u003e\u003c\/a\u003e, \u003ca href=\"\/p\/Jdforrester-WMF\/\" class=\"phui-tag-view phui-tag-type-person \" data-sigil=\"hovercard\" data-meta=\"0_52\"\u003e\u003cspan class=\"phui-tag-core phui-tag-color-person\"\u003e@Jdforrester-WMF\u003c\/span\u003e\u003c\/a\u003e wrote:\u003c\/div\u003e\n\u003cdiv class=\"remarkup-reply-body\"\u003e\u003cp\u003eI'll go fix those 118 to "release branches" if you sling me the list. ;-)\u003c\/p\u003e\u003c\/div\u003e\n\u003c\/blockquote\u003e\n\n\u003cp\u003eI recreated it just for you. \u003ca href=\"\/P9944\" class=\"phui-tag-view phui-tag-type-object \" data-sigil=\"hovercard\" data-meta=\"0_51\"\u003e\u003cspan class=\"phui-tag-core phui-tag-color-object\"\u003eP9944\u003c\/span\u003e\u003c\/a\u003e\u003c\/p\u003e\n\n\u003cblockquote\u003e\u003cp\u003eMore generally, however, Tim is right; many of the hundreds of extensions not deployed on Wikimedia seem to (at least attempt to) operate on a "master" compatibility basis, however much we try to discourage it. Not sure how much TechCom\/etc. would like to use this opportunity to more seriously discourage this practice.\u003c\/p\u003e\u003c\/blockquote\u003e\n\n\u003cp\u003eThe extra boilerplate in \u003ca href=\"\/T240307#5746862\" class=\"phui-tag-view phui-tag-type-object \" data-sigil=\"hovercard\" data-meta=\"0_50\"\u003e\u003cspan class=\"phui-tag-core-closed\"\u003e\u003cspan class=\"phui-tag-core phui-tag-color-object\"\u003eT240307#5746862\u003c\/span\u003e\u003c\/span\u003e\u003c\/a\u003e for extensions wanting to use "master" doesn't seem like much to me. They already need similar code for detecting added methods and such to classes.\u003c\/p\u003e\u003c\/div\u003e\u003c\/span\u003e\u003c\/div\u003e\u003c\/div\u003e\u003c\/div\u003e\u003c\/div\u003e\u003c\/div\u003e\u003c\/div\u003e\u003cdiv class=\"phui-timeline-event-view phui-timeline-spacer\"\u003e\u003c\/div\u003e\u003cdiv class=\"phui-timeline-shell\" data-sigil=\"transaction anchor-container\" data-meta=\"0_579\"\u003e\u003cdiv class=\"phui-timeline-event-view phui-timeline-major-event\"\u003e\u003cdiv class=\"phui-timeline-content\"\u003e\u003ca style=\"background-image: url(https:\/\/phab.wmfusercontent.org\/file\/data\/7lqct4xp34rumpqkxymb\/PHID-FILE-7yq2n2z3fpbyyfcqlhwu\/profile)\" class=\"visual-only phui-timeline-image\" href=\"\/p\/dbarratt\/\" aria-hidden=\"true\"\u003e\u003c\/a\u003e\u003cdiv class=\"phui-timeline-wedge\" style=\"\"\u003e\u003c\/div\u003e\u003cdiv class=\"phui-timeline-group\"\u003e\u003cdiv class=\"phui-timeline-inner-content\"\u003e\u003ca name=\"5771802\" id=\"5771802\" class=\"phabricator-anchor-view\"\u003e\u003c\/a\u003e\u003cdiv class=\"phui-timeline-title phui-timeline-title-with-icon phui-timeline-title-with-menu\"\u003e\u003cspan class=\"phui-timeline-icon-fill\"\u003e\u003cspan class=\"visual-only phui-icon-view phui-font-fa fa-user-plus phui-timeline-icon\" data-meta=\"0_578\" aria-hidden=\"true\"\u003e\u003c\/span\u003e\u003c\/span\u003e\u003ca href=\"\/p\/dbarratt\/\" class=\"phui-handle phui-link-person\" data-sigil=\"hovercard\" data-meta=\"0_149\"\u003edbarratt\u003c\/a\u003e subscribed.\u003cspan class=\"phui-timeline-extra\"\u003e\u003ca href=\"#5771802\" data-sigil=\"has-tooltip\" data-meta=\"0_577\"\u003e\u003cspan class=\"screen-only\"\u003eJan 2 2020, 6:37 PM\u003c\/span\u003e\u003cspan class=\"print-only\" aria-hidden=\"true\"\u003e2020-01-02 18:37:33 (UTC+0)\u003c\/span\u003e\u003c\/a\u003e\u003c\/span\u003e\u003c\/div\u003e\u003ca href=\"#\" class=\"phui-timeline-menu\" aria-haspopup=\"true\" aria-expanded=\"false\" data-sigil=\"phui-dropdown-menu\" data-meta=\"0_575\"\u003e\u003cspan class=\"aural-only\"\u003eComment Actions\u003c\/span\u003e\u003cspan class=\"visual-only phui-icon-view phui-font-fa fa-caret-down\" data-meta=\"0_576\" aria-hidden=\"true\"\u003e\u003c\/span\u003e\u003c\/a\u003e\u003cdiv class=\"phui-timeline-core-content\"\u003e\u003cspan class=\"transaction-comment\" data-sigil=\"transaction-comment\" data-meta=\"0_148\"\u003e\u003cdiv class=\"phabricator-remarkup\"\u003e\u003cp\u003eThis reminds me a lot of \u003ca href=\"https:\/\/packagist.org\/packages\/drupal\/core-plugin\" class=\"remarkup-link\" target=\"_blank\" rel=\"noreferrer\"\u003edrupal\/core-plugin\u003c\/a\u003e and their \u003ca href=\"https:\/\/www.drupal.org\/docs\/8\/api\/plugin-api\/plugin-api-overview\" class=\"remarkup-link\" target=\"_blank\" rel=\"noreferrer\"\u003ePlugin API\u003c\/a\u003e which was implemented for many of the same reasons.\u003c\/p\u003e\n\n\u003cp\u003eSounds like a good idea to me! :)\u003c\/p\u003e\u003c\/div\u003e\u003c\/span\u003e\u003c\/div\u003e\u003c\/div\u003e\u003c\/div\u003e\u003c\/div\u003e\u003c\/div\u003e\u003c\/div\u003e\u003cdiv class=\"phui-timeline-event-view phui-timeline-spacer\"\u003e\u003c\/div\u003e\u003cdiv class=\"phui-timeline-shell\" data-sigil=\"transaction anchor-container\" data-meta=\"0_588\"\u003e\u003cdiv class=\"phui-timeline-event-view phui-timeline-major-event\"\u003e\u003cdiv class=\"phui-timeline-content\"\u003e\u003ca style=\"background-image: url(https:\/\/phab.wmfusercontent.org\/file\/data\/xgl3wy55ovinfnucvwhx\/PHID-FILE-zocnksypiqutzf5oubpi\/profile)\" class=\"visual-only phui-timeline-image\" href=\"\/p\/tstarling\/\" aria-hidden=\"true\"\u003e\u003c\/a\u003e\u003cdiv class=\"phui-timeline-wedge\" style=\"\"\u003e\u003c\/div\u003e\u003cdiv class=\"phui-timeline-group\"\u003e\u003cdiv class=\"phui-timeline-inner-content\"\u003e\u003ca name=\"5780427\" id=\"5780427\" class=\"phabricator-anchor-view\"\u003e\u003c\/a\u003e\u003cdiv class=\"phui-timeline-title phui-timeline-title-with-icon phui-timeline-title-with-menu\"\u003e\u003cspan class=\"phui-timeline-icon-fill\"\u003e\u003cspan class=\"visual-only phui-icon-view phui-font-fa fa-comment phui-timeline-icon\" data-meta=\"0_587\" aria-hidden=\"true\"\u003e\u003c\/span\u003e\u003c\/span\u003e\u003ca href=\"\/p\/tstarling\/\" class=\"phui-handle handle-availability-partial phui-link-person\" data-sigil=\"hovercard\" data-meta=\"0_150\"\u003e\u003cspan class=\"perfect-circle\"\u003e\u2022\u003c\/span\u003e tstarling\u003c\/a\u003e added a comment.\u003cspan class=\"phui-timeline-extra\"\u003e\u003ca href=\"#5780427\" data-sigil=\"has-tooltip\" data-meta=\"0_586\"\u003e\u003cspan class=\"screen-only\"\u003eJan 7 2020, 4:18 AM\u003c\/span\u003e\u003cspan class=\"print-only\" aria-hidden=\"true\"\u003e2020-01-07 04:18:05 (UTC+0)\u003c\/span\u003e\u003c\/a\u003e\u003c\/span\u003e\u003c\/div\u003e\u003ca href=\"#\" class=\"phui-timeline-menu\" aria-haspopup=\"true\" aria-expanded=\"false\" data-sigil=\"phui-dropdown-menu\" data-meta=\"0_584\"\u003e\u003cspan class=\"aural-only\"\u003eComment Actions\u003c\/span\u003e\u003cspan class=\"visual-only phui-icon-view phui-font-fa fa-caret-down\" data-meta=\"0_585\" aria-hidden=\"true\"\u003e\u003c\/span\u003e\u003c\/a\u003e\u003cdiv class=\"phui-timeline-core-content\"\u003e\u003cspan class=\"transaction-comment\" data-sigil=\"transaction-comment\" data-meta=\"0_151\"\u003e\u003cdiv class=\"phabricator-remarkup\"\u003e\u003cblockquote class=\"remarkup-reply-block\"\u003e\n\u003cdiv class=\"remarkup-reply-head\"\u003eIn \u003ca href=\"\/T240307#5744479\" class=\"phui-tag-view phui-tag-type-object \" data-sigil=\"hovercard\" data-meta=\"0_53\"\u003e\u003cspan class=\"phui-tag-core-closed\"\u003e\u003cspan class=\"phui-tag-core phui-tag-color-object\"\u003eT240307#5744479\u003c\/span\u003e\u003c\/span\u003e\u003c\/a\u003e, \u003ca href=\"\/p\/daniel\/\" class=\"phui-tag-view phui-tag-type-person \" data-sigil=\"hovercard\" data-meta=\"0_59\"\u003e\u003cspan class=\"phui-tag-core phui-tag-color-person\"\u003e@daniel\u003c\/span\u003e\u003c\/a\u003e wrote:\u003c\/div\u003e\n\u003cdiv class=\"remarkup-reply-body\"\u003e\u003cp\u003eOne thing I don't quite see is why we still need hooks names, other than the names of the associated interfaces. This seems redundant and prone to inconsistencies. For legacy hook, there could be an aliasing mechanism by which extra names for a hook can be registered, which then get mapped to the name of an interface.\u003c\/p\u003e\u003c\/div\u003e\n\u003c\/blockquote\u003e\n\n\u003cp\u003eThis has basically already been said, but: the method name is the hook name with "on" prepended. HookContainer only needs the method name, it does not need to know the interface name. The reason for passing the hook name to HookContainer is so that it is able to figure out the right method to call.\u003c\/p\u003e\n\n\u003cp\u003eMaybe I missed it, but I have not seen a positive reason from Daniel as to why we should use interface names instead of method names, except that retaining hook names "seems redundant and prone to inconsistencies", which I don't agree with. The discussion seems to consist of Daniel telling Anomie why it is not quite as bad as we might think, rather than why it is a good idea.\u003c\/p\u003e\n\n\u003cblockquote class=\"remarkup-reply-block\"\u003e\n\u003cdiv class=\"remarkup-reply-head\"\u003eIn \u003ca href=\"\/T240307#5747196\" class=\"phui-tag-view phui-tag-type-object \" data-sigil=\"hovercard\" data-meta=\"0_54\"\u003e\u003cspan class=\"phui-tag-core-closed\"\u003e\u003cspan class=\"phui-tag-core phui-tag-color-object\"\u003eT240307#5747196\u003c\/span\u003e\u003c\/span\u003e\u003c\/a\u003e, \u003ca href=\"\/p\/daniel\/\" class=\"phui-tag-view phui-tag-type-person \" data-sigil=\"hovercard\" data-meta=\"0_60\"\u003e\u003cspan class=\"phui-tag-core phui-tag-color-person\"\u003e@daniel\u003c\/span\u003e\u003c\/a\u003e wrote:\u003c\/div\u003e\n\u003cdiv class=\"remarkup-reply-body\"\u003e\u003cp\u003eI like that idea, but it's not entirely clear to me what that would look like in practice. Is it actual numbered versions of an interface, e.g. UserLoginComplete2, UserLoginComplete3, etc? Or just one hook superseding another?\u003c\/p\u003e\u003c\/div\u003e\n\u003c\/blockquote\u003e\n\n\u003cp\u003eThese are not mutually exclusive, but the latter is closer to the truth. The idea is that core would know the complete deprecation chain. That might be UserLoginComplete -> UserLoginComplete2 -> UserLoginComplete3, or it might be ArticleSaveComplete -> PageContentSaveComplete. The important thing is that every deprecation is supported by core, to avoid the need for interface_exists() etc. It's not important that the hooks be exactly equivalent.\u003c\/p\u003e\n\n\u003cp\u003eLet's call it a hook deprecation system rather than a hook versioning system.\u003c\/p\u003e\n\n\u003cblockquote\u003e\u003cp\u003eIf we want to give the extension control over the filtering, perhaps the registration mechanism could support some kind of "register only if some other hook X isn't defined" or "register as a fallback for X".\u003c\/p\u003e\u003c\/blockquote\u003e\n\n\u003cp\u003eThere's no concept of a hook being defined, so to introduce such conditional syntax, we would have to introduce a system for registering hooks. I see you're proposing that below, but in my proposal, only deprecated hooks need to be registered.\u003c\/p\u003e\n\n\u003cblockquote class=\"remarkup-reply-block\"\u003e\n\u003cdiv class=\"remarkup-reply-head\"\u003eIn \u003ca href=\"\/T240307#5747418\" class=\"phui-tag-view phui-tag-type-object \" data-sigil=\"hovercard\" data-meta=\"0_55\"\u003e\u003cspan class=\"phui-tag-core-closed\"\u003e\u003cspan class=\"phui-tag-core phui-tag-color-object\"\u003eT240307#5747418\u003c\/span\u003e\u003c\/span\u003e\u003c\/a\u003e, \u003ca href=\"\/p\/daniel\/\" class=\"phui-tag-view phui-tag-type-person \" data-sigil=\"hovercard\" data-meta=\"0_61\"\u003e\u003cspan class=\"phui-tag-core phui-tag-color-person\"\u003e@daniel\u003c\/span\u003e\u003c\/a\u003e wrote:\u003c\/div\u003e\n\u003cdiv class=\"remarkup-reply-body\"\u003e\u003cul class=\"remarkup-list\"\u003e\n\u003cli class=\"remarkup-list-item\"\u003eRequire hooks to be explicitly declared in the HookContainer (or HookRunner). Registering a handler for an unknown hook should cause an exception.\u003c\/li\u003e\n\u003c\/ul\u003e\u003c\/div\u003e\n\u003c\/blockquote\u003e\n\n\u003cp\u003eThis lacks forwards compatibility. Registering a handler for an unknown hook should be allowed, for forwards compatibility.\u003c\/p\u003e\n\n\u003cblockquote\u003e\u003cul class=\"remarkup-list\"\u003e\n\u003cli class=\"remarkup-list-item\"\u003eReserve the term "listener" for purely passive hook handlers, like the "action" handlers in \u003ca href=\"\/T212482\" class=\"phui-tag-view phui-tag-type-object \" data-sigil=\"hovercard\" data-meta=\"0_56\"\u003e\u003cspan class=\"phui-tag-core phui-tag-color-object\"\u003eT212482\u003c\/span\u003e\u003c\/a\u003e. Callbacks that can affect the caller aren't listeners in my understanding.\u003c\/li\u003e\n\u003c\/ul\u003e\u003c\/blockquote\u003e\n\n\u003cp\u003eThey can just be called hook interfaces. This project will not include reviewing the code of all ~680 hooks and judging how passive they are.\u003c\/p\u003e\n\n\u003cblockquote\u003e\u003cul class=\"remarkup-list\"\u003e\n\u003cli class=\"remarkup-list-item\"\u003eDefine hook interfaces in the same namespace as their caller. Centralizing the hook interfaces in a single namespace inevitable leads to cyclic dependencies between namespaces: hooks depend on concepts declared in namespace X, and namespace X depends on the hook namespace.\u003c\/li\u003e\n\u003c\/ul\u003e\u003c\/blockquote\u003e\n\n\u003cp\u003eI think this is possible. Note that out of 203 files in includes\/ with Hooks::run() in them, only 25 of them are in a namespace. You're talking about adding maybe 500 interfaces to the root namespace. Your complaint about cyclic dependencies between namespaces is theoretical at this point.\u003c\/p\u003e\n\n\u003cp\u003eThe namespaces will all move when \u003ca href=\"\/T166010\" class=\"phui-tag-view phui-tag-type-object \" data-sigil=\"hovercard\" data-meta=\"0_57\"\u003e\u003cspan class=\"phui-tag-core phui-tag-color-object\"\u003eT166010\u003c\/span\u003e\u003c\/a\u003e is implemented. We could do \u003ca href=\"\/T166010\" class=\"phui-tag-view phui-tag-type-object \" data-sigil=\"hovercard\" data-meta=\"0_58\"\u003e\u003cspan class=\"phui-tag-core phui-tag-color-object\"\u003eT166010\u003c\/span\u003e\u003c\/a\u003e first, I guess.\u003c\/p\u003e\n\n\u003cblockquote\u003e\u003cul class=\"remarkup-list\"\u003e\n\u003cli class=\"remarkup-list-item\"\u003eClarify the relationship between hook names, class names, and method names. All three should represent the exact same thing, but they are defined independently, making inconsistencies likely. Since all three are globally unique, it would make sense to define a strict mapping between them: the class name must be the hook name plus a suffix that indicates the hook type, and the method name must be the hook name plus a prefix that indicates the hook type. E.g. the "UserLoginComplete" would use the UserLoginCompleteListener interface which declares the onUserLoginComplete() method. And the "UserCan" hook uses the UserCanFilter interface which declares the filterUserCan() method. The namespace would be determined by where the hook is called (see next point).\u003c\/li\u003e\n\u003c\/ul\u003e\u003c\/blockquote\u003e\n\n\u003cp\u003eI will clarify the current proposal. I don't agree with having a strict mapping between the interface name and the hook name. In this proposal, interface names can freely change, say to support renamespacing, as long as a b\/c alias remains. There will need to be a clear and simple policy to derive the interface name from the hook name, because this work will be completed by juniors or contractors. As a compromise, I would suggest: take the hook name, prepend the caller namespace, and append "Hook". So the interface for UserLoginComplete becomes UserLoginCompleteHook (in the root namespace). PageContentSave by the same rules will have the interface MediaWiki\\Storage\\PageContentSaveHook.\u003c\/p\u003e\u003c\/div\u003e\u003c\/span\u003e\u003c\/div\u003e\u003c\/div\u003e\u003c\/div\u003e\u003c\/div\u003e\u003c\/div\u003e\u003c\/div\u003e\u003cdiv class=\"phui-timeline-event-view phui-timeline-spacer\"\u003e\u003c\/div\u003e\u003cdiv class=\"phui-timeline-shell\" data-sigil=\"transaction anchor-container\" data-meta=\"0_597\"\u003e\u003cdiv class=\"phui-timeline-event-view phui-timeline-major-event\"\u003e\u003cdiv class=\"phui-timeline-content\"\u003e\u003ca style=\"background-image: url(https:\/\/phab.wmfusercontent.org\/file\/data\/xgl3wy55ovinfnucvwhx\/PHID-FILE-zocnksypiqutzf5oubpi\/profile)\" class=\"visual-only phui-timeline-image\" href=\"\/p\/tstarling\/\" aria-hidden=\"true\"\u003e\u003c\/a\u003e\u003cdiv class=\"phui-timeline-wedge\" style=\"\"\u003e\u003c\/div\u003e\u003cdiv class=\"phui-timeline-group\"\u003e\u003cdiv class=\"phui-timeline-inner-content\"\u003e\u003ca name=\"5784843\" id=\"5784843\" class=\"phabricator-anchor-view\"\u003e\u003c\/a\u003e\u003cdiv class=\"phui-timeline-title phui-timeline-title-with-icon phui-timeline-title-with-menu\"\u003e\u003cspan class=\"phui-timeline-icon-fill\"\u003e\u003cspan class=\"visual-only phui-icon-view phui-font-fa fa-pencil phui-timeline-icon\" data-meta=\"0_596\" aria-hidden=\"true\"\u003e\u003c\/span\u003e\u003c\/span\u003e\u003ca href=\"\/p\/tstarling\/\" class=\"phui-handle handle-availability-partial phui-link-person\" data-sigil=\"hovercard\" data-meta=\"0_152\"\u003e\u003cspan class=\"perfect-circle\"\u003e\u2022\u003c\/span\u003e tstarling\u003c\/a\u003e updated the task description. \u003ca href=\"\/transactions\/detail\/PHID-XACT-TASK-5qzldtm434g3rb3\/\" data-sigil=\"workflow\"\u003e(Show Details)\u003c\/a\u003e\u003cspan class=\"phui-timeline-extra\"\u003e\u003ca href=\"#5784843\" data-sigil=\"has-tooltip\" data-meta=\"0_595\"\u003e\u003cspan class=\"screen-only\"\u003eJan 8 2020, 4:49 AM\u003c\/span\u003e\u003cspan class=\"print-only\" aria-hidden=\"true\"\u003e2020-01-08 04:49:06 (UTC+0)\u003c\/span\u003e\u003c\/a\u003e\u003c\/span\u003e\u003c\/div\u003e\u003ca href=\"#\" class=\"phui-timeline-menu\" aria-haspopup=\"true\" aria-expanded=\"false\" data-sigil=\"phui-dropdown-menu\" data-meta=\"0_593\"\u003e\u003cspan class=\"aural-only\"\u003eComment Actions\u003c\/span\u003e\u003cspan class=\"visual-only phui-icon-view phui-font-fa fa-caret-down\" data-meta=\"0_594\" aria-hidden=\"true\"\u003e\u003c\/span\u003e\u003c\/a\u003e\u003cdiv class=\"phui-timeline-core-content\"\u003e\u003cspan class=\"transaction-comment\" data-sigil=\"transaction-comment\" data-meta=\"0_153\"\u003e\u003cdiv class=\"phabricator-remarkup\"\u003e\u003cp\u003eTask description edit: remove the term "listener" and move hook interfaces into the namespace of the caller.\u003c\/p\u003e\u003c\/div\u003e\u003c\/span\u003e\u003c\/div\u003e\u003c\/div\u003e\u003c\/div\u003e\u003c\/div\u003e\u003c\/div\u003e\u003c\/div\u003e\u003cdiv class=\"phui-timeline-event-view phui-timeline-spacer\"\u003e\u003c\/div\u003e\u003cdiv class=\"phui-timeline-shell\" data-sigil=\"transaction anchor-container\" data-meta=\"0_600\"\u003e\u003cdiv class=\"phui-timeline-event-view phui-timeline-minor-event\"\u003e\u003cdiv class=\"phui-timeline-content\"\u003e\u003ca style=\"background-image: url(https:\/\/phab.wmfusercontent.org\/file\/data\/xgl3wy55ovinfnucvwhx\/PHID-FILE-zocnksypiqutzf5oubpi\/profile)\" class=\"visual-only phui-timeline-image\" href=\"\/p\/tstarling\/\" aria-hidden=\"true\"\u003e\u003c\/a\u003e\u003cdiv class=\"phui-timeline-wedge\" style=\"\"\u003e\u003c\/div\u003e\u003cdiv class=\"phui-timeline-group\"\u003e\u003ca name=\"5784855\" id=\"5784855\" class=\"phabricator-anchor-view\"\u003e\u003c\/a\u003e\u003cdiv class=\"phui-timeline-title phui-timeline-title-with-icon\"\u003e\u003cspan class=\"phui-timeline-icon-fill\"\u003e\u003cspan class=\"visual-only phui-icon-view phui-font-fa fa-pencil phui-timeline-icon\" data-meta=\"0_599\" aria-hidden=\"true\"\u003e\u003c\/span\u003e\u003c\/span\u003e\u003ca href=\"\/p\/tstarling\/\" class=\"phui-handle handle-availability-partial phui-link-person\" data-sigil=\"hovercard\" data-meta=\"0_154\"\u003e\u003cspan class=\"perfect-circle\"\u003e\u2022\u003c\/span\u003e tstarling\u003c\/a\u003e updated the task description. \u003ca href=\"\/transactions\/detail\/PHID-XACT-TASK-olhipq7fyeypexg\/\" data-sigil=\"workflow\"\u003e(Show Details)\u003c\/a\u003e\u003cspan class=\"phui-timeline-extra\"\u003e\u003ca href=\"#5784855\" data-sigil=\"has-tooltip\" data-meta=\"0_598\"\u003e\u003cspan class=\"screen-only\"\u003eJan 8 2020, 5:07 AM\u003c\/span\u003e\u003cspan class=\"print-only\" aria-hidden=\"true\"\u003e2020-01-08 05:07:28 (UTC+0)\u003c\/span\u003e\u003c\/a\u003e\u003c\/span\u003e\u003c\/div\u003e\u003c\/div\u003e\u003c\/div\u003e\u003c\/div\u003e\u003c\/div\u003e\u003cdiv class=\"phui-timeline-event-view phui-timeline-spacer\"\u003e\u003c\/div\u003e\u003cdiv class=\"phui-timeline-shell\" data-sigil=\"transaction anchor-container\" data-meta=\"0_609\"\u003e\u003cdiv class=\"phui-timeline-event-view phui-timeline-major-event\"\u003e\u003cdiv class=\"phui-timeline-content\"\u003e\u003ca style=\"background-image: url(https:\/\/phab.wmfusercontent.org\/file\/data\/xgl3wy55ovinfnucvwhx\/PHID-FILE-zocnksypiqutzf5oubpi\/profile)\" class=\"visual-only phui-timeline-image\" href=\"\/p\/tstarling\/\" aria-hidden=\"true\"\u003e\u003c\/a\u003e\u003cdiv class=\"phui-timeline-wedge\" style=\"\"\u003e\u003c\/div\u003e\u003cdiv class=\"phui-timeline-group\"\u003e\u003cdiv class=\"phui-timeline-inner-content\"\u003e\u003ca name=\"5784856\" id=\"5784856\" class=\"phabricator-anchor-view\"\u003e\u003c\/a\u003e\u003cdiv class=\"phui-timeline-title phui-timeline-title-with-icon phui-timeline-title-with-menu\"\u003e\u003cspan class=\"phui-timeline-icon-fill\"\u003e\u003cspan class=\"visual-only phui-icon-view phui-font-fa fa-comment phui-timeline-icon\" data-meta=\"0_608\" aria-hidden=\"true\"\u003e\u003c\/span\u003e\u003c\/span\u003e\u003ca href=\"\/p\/tstarling\/\" class=\"phui-handle handle-availability-partial phui-link-person\" data-sigil=\"hovercard\" data-meta=\"0_155\"\u003e\u003cspan class=\"perfect-circle\"\u003e\u2022\u003c\/span\u003e tstarling\u003c\/a\u003e added a comment.\u003cspan class=\"phui-timeline-extra\"\u003e\u003ca href=\"#5784856\" data-sigil=\"has-tooltip\" data-meta=\"0_607\"\u003e\u003cspan class=\"screen-only\"\u003eJan 8 2020, 5:09 AM\u003c\/span\u003e\u003cspan class=\"print-only\" aria-hidden=\"true\"\u003e2020-01-08 05:09:35 (UTC+0)\u003c\/span\u003e\u003c\/a\u003e\u003c\/span\u003e\u003c\/div\u003e\u003ca href=\"#\" class=\"phui-timeline-menu\" aria-haspopup=\"true\" aria-expanded=\"false\" data-sigil=\"phui-dropdown-menu\" data-meta=\"0_605\"\u003e\u003cspan class=\"aural-only\"\u003eComment Actions\u003c\/span\u003e\u003cspan class=\"visual-only phui-icon-view phui-font-fa fa-caret-down\" data-meta=\"0_606\" aria-hidden=\"true\"\u003e\u003c\/span\u003e\u003c\/a\u003e\u003cdiv class=\"phui-timeline-core-content\"\u003e\u003cspan class=\"transaction-comment\" data-sigil=\"transaction-comment\" data-meta=\"0_156\"\u003e\u003cdiv class=\"phabricator-remarkup\"\u003e\u003cp\u003eTask description edit: I came up with a pretty neat and simple hook deprecation system, slightly different to what I proposed in the comment above. See what you think. It doesn't need core to be aware of the deprecation chain, it just needs a list of deprecated hooks.\u003c\/p\u003e\u003c\/div\u003e\u003c\/span\u003e\u003c\/div\u003e\u003c\/div\u003e\u003c\/div\u003e\u003c\/div\u003e\u003c\/div\u003e\u003c\/div\u003e\u003cdiv class=\"phui-timeline-event-view phui-timeline-spacer\"\u003e\u003c\/div\u003e\u003cdiv class=\"phui-timeline-shell\" data-sigil=\"transaction anchor-container\" data-meta=\"0_620\"\u003e\u003cdiv class=\"phui-timeline-event-view phui-timeline-major-event\"\u003e\u003cdiv class=\"phui-timeline-content\"\u003e\u003ca style=\"background-image: url(https:\/\/phab.wmfusercontent.org\/file\/data\/ms665yc73j6nadjitytk\/PHID-FILE-mocohumlrcbe2lcuplml\/profile)\" class=\"visual-only phui-timeline-image\" href=\"\/p\/Anomie\/\" aria-hidden=\"true\"\u003e\u003c\/a\u003e\u003cdiv class=\"phui-timeline-badges\"\u003e\u003cul class=\"phui-badge-flex-view grouped flex-view-collapsed \"\u003e\u003cli class=\"phui-badge-flex-item\"\u003e\u003ca class=\"phui-badge-mini phui-badge-mini-orange \" href=\"\/badges\/view\/5\/\" data-sigil=\"has-tooltip\" data-meta=\"0_618\"\u003e\u003cspan class=\"visual-only phui-icon-view phui-font-fa fa-rocket\" data-meta=\"0_619\" aria-hidden=\"true\"\u003e\u003c\/span\u003e\u003c\/a\u003e\u003c\/li\u003e\u003c\/ul\u003e\u003c\/div\u003e\u003cdiv class=\"phui-timeline-wedge\" style=\"\"\u003e\u003c\/div\u003e\u003cdiv class=\"phui-timeline-group\"\u003e\u003cdiv class=\"phui-timeline-inner-content\"\u003e\u003ca name=\"5786336\" id=\"5786336\" class=\"phabricator-anchor-view\"\u003e\u003c\/a\u003e\u003cdiv class=\"phui-timeline-title phui-timeline-title-with-icon phui-timeline-title-with-menu\"\u003e\u003cspan class=\"phui-timeline-icon-fill\"\u003e\u003cspan class=\"visual-only phui-icon-view phui-font-fa fa-comment phui-timeline-icon\" data-meta=\"0_617\" aria-hidden=\"true\"\u003e\u003c\/span\u003e\u003c\/span\u003e\u003ca href=\"\/p\/Anomie\/\" class=\"phui-handle phui-link-person\" data-sigil=\"hovercard\" data-meta=\"0_157\"\u003eAnomie\u003c\/a\u003e added a comment.\u003cspan class=\"phui-timeline-extra\"\u003e\u003ca href=\"#5786336\" data-sigil=\"has-tooltip\" data-meta=\"0_616\"\u003e\u003cspan class=\"screen-only\"\u003eJan 8 2020, 4:31 PM\u003c\/span\u003e\u003cspan class=\"print-only\" aria-hidden=\"true\"\u003e2020-01-08 16:31:14 (UTC+0)\u003c\/span\u003e\u003c\/a\u003e\u003c\/span\u003e\u003c\/div\u003e\u003ca href=\"#\" class=\"phui-timeline-menu\" aria-haspopup=\"true\" aria-expanded=\"false\" data-sigil=\"phui-dropdown-menu\" data-meta=\"0_614\"\u003e\u003cspan class=\"aural-only\"\u003eComment Actions\u003c\/span\u003e\u003cspan class=\"visual-only phui-icon-view phui-font-fa fa-caret-down\" data-meta=\"0_615\" aria-hidden=\"true\"\u003e\u003c\/span\u003e\u003c\/a\u003e\u003cdiv class=\"phui-timeline-core-content\"\u003e\u003cspan class=\"transaction-comment\" data-sigil=\"transaction-comment\" data-meta=\"0_158\"\u003e\u003cdiv class=\"phabricator-remarkup\"\u003e\u003cblockquote class=\"remarkup-reply-block\"\u003e\n\u003cdiv class=\"remarkup-reply-head\"\u003eIn \u003ca href=\"\/T240307#5784856\" class=\"phui-tag-view phui-tag-type-object \" data-sigil=\"hovercard\" data-meta=\"0_62\"\u003e\u003cspan class=\"phui-tag-core-closed\"\u003e\u003cspan class=\"phui-tag-core phui-tag-color-object\"\u003eT240307#5784856\u003c\/span\u003e\u003c\/span\u003e\u003c\/a\u003e, \u003ca href=\"\/p\/tstarling\/\" class=\"phui-tag-view phui-tag-type-person \" data-sigil=\"hovercard\" data-meta=\"0_63\"\u003e\u003cspan class=\"phui-tag-core phui-tag-color-person\"\u003e\u003cspan class=\"phui-tag-dot phui-tag-color-orange\"\u003e\u003c\/span\u003e@tstarling\u003c\/span\u003e\u003c\/a\u003e wrote:\u003c\/div\u003e\n\u003cdiv class=\"remarkup-reply-body\"\u003e\u003cp\u003eTask description edit: I came up with a pretty neat and simple hook deprecation system, slightly different to what I proposed in the comment above. See what you think. It doesn't need core to be aware of the deprecation chain, it just needs a list of deprecated hooks.\u003c\/p\u003e\u003c\/div\u003e\n\u003c\/blockquote\u003e\n\n\u003cp\u003eI like it. Simple and straightforward while still covering the necessary use cases.\u003c\/p\u003e\u003c\/div\u003e\u003c\/span\u003e\u003c\/div\u003e\u003c\/div\u003e\u003c\/div\u003e\u003c\/div\u003e\u003c\/div\u003e\u003c\/div\u003e\u003cdiv class=\"phui-timeline-event-view phui-timeline-spacer\"\u003e\u003c\/div\u003e\u003cdiv class=\"phui-timeline-shell\" data-sigil=\"transaction anchor-container\" data-meta=\"0_631\"\u003e\u003cdiv class=\"phui-timeline-event-view phui-timeline-major-event\"\u003e\u003cdiv class=\"phui-timeline-content\"\u003e\u003ca style=\"background-image: url(https:\/\/phab.wmfusercontent.org\/file\/data\/v5wmnfiaelrd6nztxd3a\/PHID-FILE-s57znldbv3qchtewuryd\/profile)\" class=\"visual-only phui-timeline-image\" href=\"\/p\/daniel\/\" aria-hidden=\"true\"\u003e\u003c\/a\u003e\u003cdiv class=\"phui-timeline-badges\"\u003e\u003cul class=\"phui-badge-flex-view grouped flex-view-collapsed \"\u003e\u003cli class=\"phui-badge-flex-item\"\u003e\u003ca class=\"phui-badge-mini phui-badge-mini-indigo \" href=\"\/badges\/view\/14\/\" data-sigil=\"has-tooltip\" data-meta=\"0_629\"\u003e\u003cspan class=\"visual-only phui-icon-view phui-font-fa fa-empire\" data-meta=\"0_630\" aria-hidden=\"true\"\u003e\u003c\/span\u003e\u003c\/a\u003e\u003c\/li\u003e\u003c\/ul\u003e\u003c\/div\u003e\u003cdiv class=\"phui-timeline-wedge\" style=\"\"\u003e\u003c\/div\u003e\u003cdiv class=\"phui-timeline-group\"\u003e\u003cdiv class=\"phui-timeline-inner-content\"\u003e\u003ca name=\"5786976\" id=\"5786976\" class=\"phabricator-anchor-view\"\u003e\u003c\/a\u003e\u003cdiv class=\"phui-timeline-title phui-timeline-title-with-icon phui-timeline-title-with-menu\"\u003e\u003cspan class=\"phui-timeline-icon-fill\"\u003e\u003cspan class=\"visual-only phui-icon-view phui-font-fa fa-comment phui-timeline-icon\" data-meta=\"0_628\" aria-hidden=\"true\"\u003e\u003c\/span\u003e\u003c\/span\u003e\u003ca href=\"\/p\/daniel\/\" class=\"phui-handle phui-link-person\" data-sigil=\"hovercard\" data-meta=\"0_159\"\u003edaniel\u003c\/a\u003e added a comment.\u003cspan class=\"phui-timeline-extra\"\u003e\u003ca href=\"#5786976\" data-sigil=\"has-tooltip\" data-meta=\"0_627\"\u003e\u003cspan class=\"screen-only\"\u003eJan 8 2020, 5:55 PM\u003c\/span\u003e\u003cspan class=\"print-only\" aria-hidden=\"true\"\u003e2020-01-08 17:55:52 (UTC+0)\u003c\/span\u003e\u003c\/a\u003e\u003c\/span\u003e\u003c\/div\u003e\u003ca href=\"#\" class=\"phui-timeline-menu\" aria-haspopup=\"true\" aria-expanded=\"false\" data-sigil=\"phui-dropdown-menu\" data-meta=\"0_625\"\u003e\u003cspan class=\"aural-only\"\u003eComment Actions\u003c\/span\u003e\u003cspan class=\"visual-only phui-icon-view phui-font-fa fa-caret-down\" data-meta=\"0_626\" aria-hidden=\"true\"\u003e\u003c\/span\u003e\u003c\/a\u003e\u003cdiv class=\"phui-timeline-core-content\"\u003e\u003cspan class=\"transaction-comment\" data-sigil=\"transaction-comment\" data-meta=\"0_160\"\u003e\u003cdiv class=\"phabricator-remarkup\"\u003e\u003cblockquote class=\"remarkup-reply-block\"\u003e\n\u003cdiv class=\"remarkup-reply-head\"\u003eIn \u003ca href=\"\/T240307#5784843\" class=\"phui-tag-view phui-tag-type-object \" data-sigil=\"hovercard\" data-meta=\"0_64\"\u003e\u003cspan class=\"phui-tag-core-closed\"\u003e\u003cspan class=\"phui-tag-core phui-tag-color-object\"\u003eT240307#5784843\u003c\/span\u003e\u003c\/span\u003e\u003c\/a\u003e, \u003ca href=\"\/p\/tstarling\/\" class=\"phui-tag-view phui-tag-type-person \" data-sigil=\"hovercard\" data-meta=\"0_65\"\u003e\u003cspan class=\"phui-tag-core phui-tag-color-person\"\u003e\u003cspan class=\"phui-tag-dot phui-tag-color-orange\"\u003e\u003c\/span\u003e@tstarling\u003c\/span\u003e\u003c\/a\u003e wrote:\u003c\/div\u003e\n\u003cdiv class=\"remarkup-reply-body\"\u003e\u003cp\u003eTask description edit: remove the term "listener" and move hook interfaces into the namespace of the caller.\u003c\/p\u003e\u003c\/div\u003e\n\u003c\/blockquote\u003e\n\n\u003cp\u003eThanks. My intention was to keep the hook's definition close to the caller - that primarily means in the same directory, the namespace is really secondary.\u003c\/p\u003e\n\n\u003cp\u003eI don't consider the definition of the hook interface to be bolierplate code, by the way. All hook interfaces are different, there is nothing there that could be auto-generated or copied.\u003c\/p\u003e\u003c\/div\u003e\u003c\/span\u003e\u003c\/div\u003e\u003c\/div\u003e\u003c\/div\u003e\u003c\/div\u003e\u003c\/div\u003e\u003c\/div\u003e\u003cdiv class=\"phui-timeline-event-view phui-timeline-spacer\"\u003e\u003c\/div\u003e\u003cdiv class=\"phui-timeline-shell\" data-sigil=\"transaction anchor-container\" data-meta=\"0_643\"\u003e\u003cdiv class=\"phui-timeline-event-view phui-timeline-major-event\"\u003e\u003cdiv class=\"phui-timeline-content\"\u003e\u003ca style=\"background-image: url(https:\/\/phab.wmfusercontent.org\/file\/data\/v5wmnfiaelrd6nztxd3a\/PHID-FILE-s57znldbv3qchtewuryd\/profile)\" class=\"visual-only phui-timeline-image\" href=\"\/p\/daniel\/\" aria-hidden=\"true\"\u003e\u003c\/a\u003e\u003cdiv class=\"phui-timeline-badges\"\u003e\u003cul class=\"phui-badge-flex-view grouped flex-view-collapsed \"\u003e\u003cli class=\"phui-badge-flex-item\"\u003e\u003ca class=\"phui-badge-mini phui-badge-mini-indigo \" href=\"\/badges\/view\/14\/\" data-sigil=\"has-tooltip\" data-meta=\"0_641\"\u003e\u003cspan class=\"visual-only phui-icon-view phui-font-fa fa-empire\" data-meta=\"0_642\" aria-hidden=\"true\"\u003e\u003c\/span\u003e\u003c\/a\u003e\u003c\/li\u003e\u003c\/ul\u003e\u003c\/div\u003e\u003cdiv class=\"phui-timeline-wedge\" style=\"\"\u003e\u003c\/div\u003e\u003cdiv class=\"phui-timeline-group\"\u003e\u003cdiv class=\"phui-timeline-inner-content\"\u003e\u003ca name=\"5786978\" id=\"5786978\" class=\"phabricator-anchor-view\"\u003e\u003c\/a\u003e\u003cdiv class=\"phui-timeline-title phui-timeline-title-with-icon phui-timeline-title-with-menu\"\u003e\u003cspan class=\"phui-timeline-icon-fill\"\u003e\u003cspan class=\"visual-only phui-icon-view phui-font-fa fa-comment phui-timeline-icon\" data-meta=\"0_640\" aria-hidden=\"true\"\u003e\u003c\/span\u003e\u003c\/span\u003e\u003ca href=\"\/p\/daniel\/\" class=\"phui-handle phui-link-person\" data-sigil=\"hovercard\" data-meta=\"0_161\"\u003edaniel\u003c\/a\u003e added a comment.\u003cspan class=\"phui-timeline-extra\"\u003eEdited\u003cspan class=\"visual-only\" aria-hidden=\"true\"\u003e \u00b7 \u003c\/span\u003e\u003ca href=\"#5786978\" data-sigil=\"has-tooltip\" data-meta=\"0_639\"\u003e\u003cspan class=\"screen-only\"\u003eJan 8 2020, 5:56 PM\u003c\/span\u003e\u003cspan class=\"print-only\" aria-hidden=\"true\"\u003e2020-01-08 17:56:26 (UTC+0)\u003c\/span\u003e\u003c\/a\u003e\u003c\/span\u003e\u003c\/div\u003e\u003ca href=\"#\" class=\"phui-timeline-menu\" aria-haspopup=\"true\" aria-expanded=\"false\" data-sigil=\"phui-dropdown-menu\" data-meta=\"0_637\"\u003e\u003cspan class=\"aural-only\"\u003eComment Actions\u003c\/span\u003e\u003cspan class=\"visual-only phui-icon-view phui-font-fa fa-caret-down\" data-meta=\"0_638\" aria-hidden=\"true\"\u003e\u003c\/span\u003e\u003c\/a\u003e\u003cdiv class=\"phui-timeline-core-content\"\u003e\u003cspan class=\"transaction-comment\" data-sigil=\"transaction-comment\" data-meta=\"0_162\"\u003e\u003cdiv class=\"phabricator-remarkup\"\u003e\u003cblockquote class=\"remarkup-reply-block\"\u003e\n\u003cdiv class=\"remarkup-reply-head\"\u003eIn \u003ca href=\"\/T240307#5786336\" class=\"phui-tag-view phui-tag-type-object \" data-sigil=\"hovercard\" data-meta=\"0_66\"\u003e\u003cspan class=\"phui-tag-core-closed\"\u003e\u003cspan class=\"phui-tag-core phui-tag-color-object\"\u003eT240307#5786336\u003c\/span\u003e\u003c\/span\u003e\u003c\/a\u003e, \u003ca href=\"\/p\/Anomie\/\" class=\"phui-tag-view phui-tag-type-person \" data-sigil=\"hovercard\" data-meta=\"0_67\"\u003e\u003cspan class=\"phui-tag-core phui-tag-color-person\"\u003e@Anomie\u003c\/span\u003e\u003c\/a\u003e wrote:\u003c\/div\u003e\n\u003cdiv class=\"remarkup-reply-body\"\u003e\u003cp\u003eI like it. Simple and straightforward while still covering the necessary use cases.\u003c\/p\u003e\u003c\/div\u003e\n\u003c\/blockquote\u003e\n\n\u003cp\u003e+1\u003c\/p\u003e\u003c\/div\u003e\u003c\/span\u003e\u003c\/div\u003e\u003c\/div\u003e\u003c\/div\u003e\u003c\/div\u003e\u003c\/div\u003e\u003c\/div\u003e\u003cdiv class=\"phui-timeline-event-view phui-timeline-spacer\"\u003e\u003c\/div\u003e\u003cdiv class=\"phui-timeline-shell\" data-sigil=\"transaction anchor-container\" data-meta=\"0_654\"\u003e\u003cdiv class=\"phui-timeline-event-view phui-timeline-major-event\"\u003e\u003cdiv class=\"phui-timeline-content\"\u003e\u003ca style=\"background-image: url(https:\/\/phab.wmfusercontent.org\/file\/data\/ms665yc73j6nadjitytk\/PHID-FILE-mocohumlrcbe2lcuplml\/profile)\" class=\"visual-only phui-timeline-image\" href=\"\/p\/Anomie\/\" aria-hidden=\"true\"\u003e\u003c\/a\u003e\u003cdiv class=\"phui-timeline-badges\"\u003e\u003cul class=\"phui-badge-flex-view grouped flex-view-collapsed \"\u003e\u003cli class=\"phui-badge-flex-item\"\u003e\u003ca class=\"phui-badge-mini phui-badge-mini-orange \" href=\"\/badges\/view\/5\/\" data-sigil=\"has-tooltip\" data-meta=\"0_652\"\u003e\u003cspan class=\"visual-only phui-icon-view phui-font-fa fa-rocket\" data-meta=\"0_653\" aria-hidden=\"true\"\u003e\u003c\/span\u003e\u003c\/a\u003e\u003c\/li\u003e\u003c\/ul\u003e\u003c\/div\u003e\u003cdiv class=\"phui-timeline-wedge\" style=\"\"\u003e\u003c\/div\u003e\u003cdiv class=\"phui-timeline-group\"\u003e\u003cdiv class=\"phui-timeline-inner-content\"\u003e\u003ca name=\"5787292\" id=\"5787292\" class=\"phabricator-anchor-view\"\u003e\u003c\/a\u003e\u003cdiv class=\"phui-timeline-title phui-timeline-title-with-icon phui-timeline-title-with-menu\"\u003e\u003cspan class=\"phui-timeline-icon-fill\"\u003e\u003cspan class=\"visual-only phui-icon-view phui-font-fa fa-comment phui-timeline-icon\" data-meta=\"0_651\" aria-hidden=\"true\"\u003e\u003c\/span\u003e\u003c\/span\u003e\u003ca href=\"\/p\/Anomie\/\" class=\"phui-handle phui-link-person\" data-sigil=\"hovercard\" data-meta=\"0_163\"\u003eAnomie\u003c\/a\u003e added a comment.\u003cspan class=\"phui-timeline-extra\"\u003e\u003ca href=\"#5787292\" data-sigil=\"has-tooltip\" data-meta=\"0_650\"\u003e\u003cspan class=\"screen-only\"\u003eJan 8 2020, 6:35 PM\u003c\/span\u003e\u003cspan class=\"print-only\" aria-hidden=\"true\"\u003e2020-01-08 18:35:38 (UTC+0)\u003c\/span\u003e\u003c\/a\u003e\u003c\/span\u003e\u003c\/div\u003e\u003ca href=\"#\" class=\"phui-timeline-menu\" aria-haspopup=\"true\" aria-expanded=\"false\" data-sigil=\"phui-dropdown-menu\" data-meta=\"0_648\"\u003e\u003cspan class=\"aural-only\"\u003eComment Actions\u003c\/span\u003e\u003cspan class=\"visual-only phui-icon-view phui-font-fa fa-caret-down\" data-meta=\"0_649\" aria-hidden=\"true\"\u003e\u003c\/span\u003e\u003c\/a\u003e\u003cdiv class=\"phui-timeline-core-content\"\u003e\u003cspan class=\"transaction-comment\" data-sigil=\"transaction-comment\" data-meta=\"0_164\"\u003e\u003cdiv class=\"phabricator-remarkup\"\u003e\u003cblockquote class=\"remarkup-reply-block\"\u003e\n\u003cdiv class=\"remarkup-reply-head\"\u003eIn \u003ca href=\"\/T240307#5786976\" class=\"phui-tag-view phui-tag-type-object \" data-sigil=\"hovercard\" data-meta=\"0_68\"\u003e\u003cspan class=\"phui-tag-core-closed\"\u003e\u003cspan class=\"phui-tag-core phui-tag-color-object\"\u003eT240307#5786976\u003c\/span\u003e\u003c\/span\u003e\u003c\/a\u003e, \u003ca href=\"\/p\/daniel\/\" class=\"phui-tag-view phui-tag-type-person \" data-sigil=\"hovercard\" data-meta=\"0_69\"\u003e\u003cspan class=\"phui-tag-core phui-tag-color-person\"\u003e@daniel\u003c\/span\u003e\u003c\/a\u003e wrote:\u003c\/div\u003e\n\u003cdiv class=\"remarkup-reply-body\"\u003e\u003cp\u003eI don't consider the definition of the hook interface to be bolierplate code, by the way. All hook interfaces are different, there is nothing there that could be auto-generated or copied.\u003c\/p\u003e\u003c\/div\u003e\n\u003c\/blockquote\u003e\n\n\u003cp\u003eMy impression was that "boilerplate code" referred to the contents of HookRunner.php, not the interface definitions. The majority would look like\u003c\/p\u003e\n\n\u003cdiv class=\"remarkup-code-block\" data-code-lang=\"php\" data-sigil=\"remarkup-code-block\"\u003e\u003cpre class=\"remarkup-code\"\u003e\u003cspan class=\"sd\"\u003e\/** @inheritDoc *\/\u003c\/span\u003e\n\u003cspan class=\"k\"\u003efunction\u003c\/span\u003e \u003cspan class=\"no\"\u003eonSomething\u003c\/span\u003e\u003cspan class=\"o\"\u003e(\u003c\/span\u003e \u003cspan class=\"nv\"\u003e$some\u003c\/span\u003e\u003cspan class=\"o\"\u003e,\u003c\/span\u003e \u003cspan class=\"nv\"\u003e$args\u003c\/span\u003e\u003cspan class=\"o\"\u003e,\u003c\/span\u003e \u003cspan class=\"nv\"\u003e$here\u003c\/span\u003e \u003cspan class=\"o\"\u003e)\u003c\/span\u003e \u003cspan class=\"o\"\u003e{\u003c\/span\u003e\n \u003cspan class=\"k\"\u003ereturn\u003c\/span\u003e \u003cspan class=\"nv\"\u003e$this\u003c\/span\u003e\u003cspan class=\"o\"\u003e->\u003c\/span\u003e\u003cspan class=\"na\" data-symbol-name=\"hookContainer\"\u003ehookContainer\u003c\/span\u003e\u003cspan class=\"o\"\u003e->\u003c\/span\u003e\u003cspan class=\"na\" data-symbol-name=\"run\"\u003erun\u003c\/span\u003e\u003cspan class=\"o\"\u003e(\u003c\/span\u003e \u003cspan class=\"s1\"\u003e'Something'\u003c\/span\u003e\u003cspan class=\"o\"\u003e,\u003c\/span\u003e \u003cspan class=\"o\"\u003e[\u003c\/span\u003e \u003cspan class=\"nv\"\u003e$some\u003c\/span\u003e\u003cspan class=\"o\"\u003e,\u003c\/span\u003e \u003cspan class=\"nv\"\u003e$args\u003c\/span\u003e\u003cspan class=\"o\"\u003e,\u003c\/span\u003e \u003cspan class=\"nv\"\u003e$here\u003c\/span\u003e \u003cspan class=\"o\"\u003e]\u003c\/span\u003e \u003cspan class=\"o\"\u003e);\u003c\/span\u003e\n\u003cspan class=\"o\"\u003e}\u003c\/span\u003e\u003c\/pre\u003e\u003c\/div\u003e\n\n\u003cp\u003eSome would also pass a value for $options.\u003c\/p\u003e\u003c\/div\u003e\u003c\/span\u003e\u003c\/div\u003e\u003c\/div\u003e\u003c\/div\u003e\u003c\/div\u003e\u003c\/div\u003e\u003c\/div\u003e\u003cdiv class=\"phui-timeline-event-view phui-timeline-spacer\"\u003e\u003c\/div\u003e\u003cdiv class=\"phui-timeline-shell\" data-sigil=\"transaction anchor-container\" data-meta=\"0_665\"\u003e\u003cdiv class=\"phui-timeline-event-view phui-timeline-major-event\"\u003e\u003cdiv class=\"phui-timeline-content\"\u003e\u003ca style=\"background-image: url(https:\/\/phab.wmfusercontent.org\/file\/data\/v5wmnfiaelrd6nztxd3a\/PHID-FILE-s57znldbv3qchtewuryd\/profile)\" class=\"visual-only phui-timeline-image\" href=\"\/p\/daniel\/\" aria-hidden=\"true\"\u003e\u003c\/a\u003e\u003cdiv class=\"phui-timeline-badges\"\u003e\u003cul class=\"phui-badge-flex-view grouped flex-view-collapsed \"\u003e\u003cli class=\"phui-badge-flex-item\"\u003e\u003ca class=\"phui-badge-mini phui-badge-mini-indigo \" href=\"\/badges\/view\/14\/\" data-sigil=\"has-tooltip\" data-meta=\"0_663\"\u003e\u003cspan class=\"visual-only phui-icon-view phui-font-fa fa-empire\" data-meta=\"0_664\" aria-hidden=\"true\"\u003e\u003c\/span\u003e\u003c\/a\u003e\u003c\/li\u003e\u003c\/ul\u003e\u003c\/div\u003e\u003cdiv class=\"phui-timeline-wedge\" style=\"\"\u003e\u003c\/div\u003e\u003cdiv class=\"phui-timeline-group\"\u003e\u003cdiv class=\"phui-timeline-inner-content\"\u003e\u003ca name=\"5791394\" id=\"5791394\" class=\"phabricator-anchor-view\"\u003e\u003c\/a\u003e\u003cdiv class=\"phui-timeline-title phui-timeline-title-with-icon phui-timeline-title-with-menu\"\u003e\u003cspan class=\"phui-timeline-icon-fill\"\u003e\u003cspan class=\"visual-only phui-icon-view phui-font-fa fa-columns phui-timeline-icon\" data-meta=\"0_662\" aria-hidden=\"true\"\u003e\u003c\/span\u003e\u003c\/span\u003e\u003ca href=\"\/p\/daniel\/\" class=\"phui-handle phui-link-person\" data-sigil=\"hovercard\" data-meta=\"0_165\"\u003edaniel\u003c\/a\u003e moved this task from \u003ca href=\"\/project\/board\/52\/\" class=\"phui-handle handle-status-closed\" data-sigil=\"hovercard\" data-meta=\"0_166\"\u003eUnder discussion\u003c\/a\u003e to \u003ca href=\"\/project\/board\/52\/\" class=\"phui-handle\" data-sigil=\"hovercard\" data-meta=\"0_167\"\u003eP5: Last Call\u003c\/a\u003e on the \u003ca href=\"\/tag\/techcom-rfc\/\" class=\"phui-handle handle-status-closed\" data-sigil=\"hovercard\" data-meta=\"0_168\"\u003eTechCom-RFC\u003c\/a\u003e board.\u003cspan class=\"phui-timeline-extra\"\u003e\u003ca href=\"#5791394\" data-sigil=\"has-tooltip\" data-meta=\"0_661\"\u003e\u003cspan class=\"screen-only\"\u003eJan 9 2020, 10:53 PM\u003c\/span\u003e\u003cspan class=\"print-only\" aria-hidden=\"true\"\u003e2020-01-09 22:53:34 (UTC+0)\u003c\/span\u003e\u003c\/a\u003e\u003c\/span\u003e\u003c\/div\u003e\u003ca href=\"#\" class=\"phui-timeline-menu\" aria-haspopup=\"true\" aria-expanded=\"false\" data-sigil=\"phui-dropdown-menu\" data-meta=\"0_659\"\u003e\u003cspan class=\"aural-only\"\u003eComment Actions\u003c\/span\u003e\u003cspan class=\"visual-only phui-icon-view phui-font-fa fa-caret-down\" data-meta=\"0_660\" aria-hidden=\"true\"\u003e\u003c\/span\u003e\u003c\/a\u003e\u003cdiv class=\"phui-timeline-core-content\"\u003e\u003cspan class=\"transaction-comment\" data-sigil=\"transaction-comment\" data-meta=\"0_169\"\u003e\u003cdiv class=\"phabricator-remarkup\"\u003e\u003cp\u003eThis RFC has been put on Last Call per the TechCom meeting on January 8. If there are no issues left unresolved by January 22, this RFC will be approved as proposed.\u003c\/p\u003e\u003c\/div\u003e\u003c\/span\u003e\u003c\/div\u003e\u003c\/div\u003e\u003c\/div\u003e\u003c\/div\u003e\u003c\/div\u003e\u003c\/div\u003e\u003cdiv class=\"phui-timeline-event-view phui-timeline-spacer\"\u003e\u003c\/div\u003e\u003cdiv class=\"phui-timeline-shell phui-timeline-green\" data-sigil=\"transaction anchor-container\" data-meta=\"0_668\"\u003e\u003cdiv class=\"phui-timeline-event-view phui-timeline-minor-event\"\u003e\u003cdiv class=\"phui-timeline-content\"\u003e\u003ca style=\"background-image: url(https:\/\/phab.wmfusercontent.org\/file\/data\/ckuog6lpgvwxciyg5wab\/PHID-FILE-sfqnl3dgxxdvoa527rb4\/profile)\" class=\"visual-only phui-timeline-image\" href=\"\/p\/Eevans\/\" aria-hidden=\"true\"\u003e\u003c\/a\u003e\u003cdiv class=\"phui-timeline-wedge\" style=\"\"\u003e\u003c\/div\u003e\u003cdiv class=\"phui-timeline-group\"\u003e\u003ca name=\"5793087\" id=\"5793087\" class=\"phabricator-anchor-view\"\u003e\u003c\/a\u003e\u003cdiv class=\"phui-timeline-title phui-timeline-title-with-icon\"\u003e\u003cspan class=\"phui-timeline-icon-fill fill-has-color phui-timeline-icon-fill-green\"\u003e\u003cspan class=\"visual-only phui-icon-view phui-font-fa fa-arrow-right phui-timeline-icon\" data-meta=\"0_667\" aria-hidden=\"true\"\u003e\u003c\/span\u003e\u003c\/span\u003e\u003ca href=\"\/p\/Eevans\/\" class=\"phui-handle phui-link-person\" data-sigil=\"hovercard\" data-meta=\"0_170\"\u003eEevans\u003c\/a\u003e triaged this task as \u003cspan class=\"phui-timeline-value\"\u003eMedium\u003c\/span\u003e priority.\u003cspan class=\"phui-timeline-extra\"\u003e\u003ca href=\"#5793087\" data-sigil=\"has-tooltip\" data-meta=\"0_666\"\u003e\u003cspan class=\"screen-only\"\u003eJan 10 2020, 5:34 PM\u003c\/span\u003e\u003cspan class=\"print-only\" aria-hidden=\"true\"\u003e2020-01-10 17:34:30 (UTC+0)\u003c\/span\u003e\u003c\/a\u003e\u003c\/span\u003e\u003c\/div\u003e\u003c\/div\u003e\u003c\/div\u003e\u003c\/div\u003e\u003c\/div\u003e\u003cdiv class=\"phui-timeline-event-view phui-timeline-spacer\"\u003e\u003c\/div\u003e\u003cdiv class=\"phui-timeline-shell\" data-sigil=\"transaction anchor-container\" data-meta=\"0_671\"\u003e\u003cdiv class=\"phui-timeline-event-view phui-timeline-minor-event\"\u003e\u003cdiv class=\"phui-timeline-content\"\u003e\u003ca style=\"background-image: url(https:\/\/phab.wmfusercontent.org\/file\/data\/4nt2ycoh46nyuzaihcns\/PHID-FILE-jeovvhuuekt3wtjx53if\/profile)\" class=\"visual-only phui-timeline-image\" href=\"\/p\/CCicalese_WMF\/\" aria-hidden=\"true\"\u003e\u003c\/a\u003e\u003cdiv class=\"phui-timeline-wedge\" style=\"\"\u003e\u003c\/div\u003e\u003cdiv class=\"phui-timeline-group\"\u003e\u003ca name=\"5810420\" id=\"5810420\" class=\"phabricator-anchor-view\"\u003e\u003c\/a\u003e\u003cdiv class=\"phui-timeline-title phui-timeline-title-with-icon\"\u003e\u003cspan class=\"phui-timeline-icon-fill\"\u003e\u003cspan class=\"visual-only phui-icon-view phui-font-fa fa-columns phui-timeline-icon\" data-meta=\"0_670\" aria-hidden=\"true\"\u003e\u003c\/span\u003e\u003c\/span\u003e\u003ca href=\"\/p\/CCicalese_WMF\/\" class=\"phui-handle phui-link-person\" data-sigil=\"hovercard\" data-meta=\"0_171\"\u003eCCicalese_WMF\u003c\/a\u003e moved this task from \u003ca href=\"\/project\/board\/3654\/\" class=\"phui-handle\" data-sigil=\"hovercard\" data-meta=\"0_172\"\u003eInbox\u003c\/a\u003e to \u003ca href=\"\/project\/board\/3654\/\" class=\"phui-handle handle-status-closed\" data-sigil=\"hovercard\" data-meta=\"0_173\"\u003eFuture Initiatives\/Small Projects\u003c\/a\u003e on the \u003ca href=\"\/tag\/platform_engineering\/\" class=\"phui-handle handle-status-closed\" data-sigil=\"hovercard\" data-meta=\"0_174\"\u003ePlatform Engineering\u003c\/a\u003e board.\u003cspan class=\"phui-timeline-extra\"\u003e\u003ca href=\"#5810420\" data-sigil=\"has-tooltip\" data-meta=\"0_669\"\u003e\u003cspan class=\"screen-only\"\u003eJan 16 2020, 6:52 PM\u003c\/span\u003e\u003cspan class=\"print-only\" aria-hidden=\"true\"\u003e2020-01-16 18:52:25 (UTC+0)\u003c\/span\u003e\u003c\/a\u003e\u003c\/span\u003e\u003c\/div\u003e\u003c\/div\u003e\u003c\/div\u003e\u003c\/div\u003e\u003c\/div\u003e\u003cdiv class=\"phui-timeline-event-view phui-timeline-spacer\"\u003e\u003c\/div\u003e\u003cdiv class=\"phui-timeline-shell\" data-sigil=\"transaction anchor-container\" data-meta=\"0_682\"\u003e\u003cdiv class=\"phui-timeline-event-view phui-timeline-major-event\"\u003e\u003cdiv class=\"phui-timeline-content\"\u003e\u003ca style=\"background-image: url(https:\/\/phab.wmfusercontent.org\/file\/data\/v5wmnfiaelrd6nztxd3a\/PHID-FILE-s57znldbv3qchtewuryd\/profile)\" class=\"visual-only phui-timeline-image\" href=\"\/p\/daniel\/\" aria-hidden=\"true\"\u003e\u003c\/a\u003e\u003cdiv class=\"phui-timeline-badges\"\u003e\u003cul class=\"phui-badge-flex-view grouped flex-view-collapsed \"\u003e\u003cli class=\"phui-badge-flex-item\"\u003e\u003ca class=\"phui-badge-mini phui-badge-mini-indigo \" href=\"\/badges\/view\/14\/\" data-sigil=\"has-tooltip\" data-meta=\"0_680\"\u003e\u003cspan class=\"visual-only phui-icon-view phui-font-fa fa-empire\" data-meta=\"0_681\" aria-hidden=\"true\"\u003e\u003c\/span\u003e\u003c\/a\u003e\u003c\/li\u003e\u003c\/ul\u003e\u003c\/div\u003e\u003cdiv class=\"phui-timeline-wedge\" style=\"\"\u003e\u003c\/div\u003e\u003cdiv class=\"phui-timeline-group\"\u003e\u003cdiv class=\"phui-timeline-inner-content\"\u003e\u003ca name=\"5824638\" id=\"5824638\" class=\"phabricator-anchor-view\"\u003e\u003c\/a\u003e\u003cdiv class=\"phui-timeline-title phui-timeline-title-with-icon phui-timeline-title-with-menu\"\u003e\u003cspan class=\"phui-timeline-icon-fill\"\u003e\u003cspan class=\"visual-only phui-icon-view phui-font-fa fa-link phui-timeline-icon\" data-meta=\"0_679\" aria-hidden=\"true\"\u003e\u003c\/span\u003e\u003c\/span\u003e\u003ca href=\"\/p\/daniel\/\" class=\"phui-handle phui-link-person\" data-sigil=\"hovercard\" data-meta=\"0_175\"\u003edaniel\u003c\/a\u003e edited projects, added \u003ca href=\"\/project\/view\/2002\/\" class=\"phui-handle handle-status-closed\" data-sigil=\"hovercard\" data-meta=\"0_176\"\u003eTechCom-RFC (TechCom-RFC-Closed)\u003c\/a\u003e; removed \u003ca href=\"\/tag\/techcom-rfc\/\" class=\"phui-handle handle-status-closed\" data-sigil=\"hovercard\" data-meta=\"0_177\"\u003eTechCom-RFC\u003c\/a\u003e.\u003cspan class=\"phui-timeline-extra\"\u003e\u003ca href=\"#5824638\" data-sigil=\"has-tooltip\" data-meta=\"0_678\"\u003e\u003cspan class=\"screen-only\"\u003eJan 22 2020, 9:36 PM\u003c\/span\u003e\u003cspan class=\"print-only\" aria-hidden=\"true\"\u003e2020-01-22 21:36:22 (UTC+0)\u003c\/span\u003e\u003c\/a\u003e\u003c\/span\u003e\u003c\/div\u003e\u003ca href=\"#\" class=\"phui-timeline-menu\" aria-haspopup=\"true\" aria-expanded=\"false\" data-sigil=\"phui-dropdown-menu\" data-meta=\"0_676\"\u003e\u003cspan class=\"aural-only\"\u003eComment Actions\u003c\/span\u003e\u003cspan class=\"visual-only phui-icon-view phui-font-fa fa-caret-down\" data-meta=\"0_677\" aria-hidden=\"true\"\u003e\u003c\/span\u003e\u003c\/a\u003e\u003cdiv class=\"phui-timeline-core-content\"\u003e\u003cspan class=\"transaction-comment\" data-sigil=\"transaction-comment\" data-meta=\"0_178\"\u003e\u003cdiv class=\"phabricator-remarkup\"\u003e\u003cp\u003eThis RFC has been approved as proposed per today's TechCom meeting\u003c\/p\u003e\u003c\/div\u003e\u003c\/span\u003e\u003c\/div\u003e\u003c\/div\u003e\u003c\/div\u003e\u003c\/div\u003e\u003c\/div\u003e\u003c\/div\u003e\u003cdiv class=\"phui-timeline-event-view phui-timeline-spacer\"\u003e\u003c\/div\u003e\u003cdiv class=\"phui-timeline-shell\" data-sigil=\"transaction anchor-container\" data-meta=\"0_685\"\u003e\u003cdiv class=\"phui-timeline-event-view phui-timeline-minor-event\"\u003e\u003cdiv class=\"phui-timeline-content\"\u003e\u003ca style=\"background-image: url(https:\/\/phab.wmfusercontent.org\/file\/data\/zirzntnbnbimsxdels47\/PHID-FILE-tu3ola3spvpugy5kzs6b\/profile)\" class=\"visual-only phui-timeline-image\" href=\"\/p\/Mholloway\/\" aria-hidden=\"true\"\u003e\u003c\/a\u003e\u003cdiv class=\"phui-timeline-wedge\" style=\"\"\u003e\u003c\/div\u003e\u003cdiv class=\"phui-timeline-group\"\u003e\u003ca name=\"5836721\" id=\"5836721\" class=\"phabricator-anchor-view\"\u003e\u003c\/a\u003e\u003cdiv class=\"phui-timeline-title phui-timeline-title-with-icon\"\u003e\u003cspan class=\"phui-timeline-icon-fill\"\u003e\u003cspan class=\"visual-only phui-icon-view phui-font-fa fa-user-plus phui-timeline-icon\" data-meta=\"0_684\" aria-hidden=\"true\"\u003e\u003c\/span\u003e\u003c\/span\u003e\u003ca href=\"\/p\/Mholloway\/\" class=\"phui-handle handle-availability-disabled phui-link-person\" data-sigil=\"hovercard\" data-meta=\"0_179\"\u003e\u003cspan class=\"perfect-circle\"\u003e\u2022\u003c\/span\u003e Mholloway\u003c\/a\u003e subscribed.\u003cspan class=\"phui-timeline-extra\"\u003e\u003ca href=\"#5836721\" data-sigil=\"has-tooltip\" data-meta=\"0_683\"\u003e\u003cspan class=\"screen-only\"\u003eJan 28 2020, 4:36 PM\u003c\/span\u003e\u003cspan class=\"print-only\" aria-hidden=\"true\"\u003e2020-01-28 16:36:03 (UTC+0)\u003c\/span\u003e\u003c\/a\u003e\u003c\/span\u003e\u003c\/div\u003e\u003c\/div\u003e\u003c\/div\u003e\u003c\/div\u003e\u003c\/div\u003e\u003cdiv class=\"phui-timeline-event-view phui-timeline-spacer\"\u003e\u003c\/div\u003e\u003cdiv class=\"phui-timeline-shell\" data-sigil=\"transaction anchor-container\" data-meta=\"0_694\"\u003e\u003cdiv class=\"phui-timeline-event-view phui-timeline-major-event\"\u003e\u003cdiv class=\"phui-timeline-content\"\u003e\u003ca style=\"background-image: url(https:\/\/phab.wmfusercontent.org\/file\/data\/6vn6slgby7ia62ouikut\/PHID-FILE-ay56qvafgaxajuctgtw3\/profile)\" class=\"visual-only phui-timeline-image\" href=\"\/p\/gerritbot\/\" aria-hidden=\"true\"\u003e\u003c\/a\u003e\u003cdiv class=\"phui-timeline-wedge\" style=\"\"\u003e\u003c\/div\u003e\u003cdiv class=\"phui-timeline-group\"\u003e\u003cdiv class=\"phui-timeline-inner-content\"\u003e\u003ca name=\"5865067\" id=\"5865067\" class=\"phabricator-anchor-view\"\u003e\u003c\/a\u003e\u003cdiv class=\"phui-timeline-title phui-timeline-title-with-icon phui-timeline-title-with-menu\"\u003e\u003cspan class=\"phui-timeline-icon-fill\"\u003e\u003cspan class=\"visual-only phui-icon-view phui-font-fa fa-comment phui-timeline-icon\" data-meta=\"0_693\" aria-hidden=\"true\"\u003e\u003c\/span\u003e\u003c\/span\u003e\u003ca href=\"\/p\/gerritbot\/\" class=\"phui-handle phui-link-person\" data-sigil=\"hovercard\" data-meta=\"0_180\"\u003egerritbot\u003c\/a\u003e added a comment.\u003cspan class=\"phui-timeline-extra\"\u003e\u003ca href=\"#5865067\" data-sigil=\"has-tooltip\" data-meta=\"0_692\"\u003e\u003cspan class=\"screen-only\"\u003eFeb 10 2020, 2:48 PM\u003c\/span\u003e\u003cspan class=\"print-only\" aria-hidden=\"true\"\u003e2020-02-10 14:48:57 (UTC+0)\u003c\/span\u003e\u003c\/a\u003e\u003c\/span\u003e\u003c\/div\u003e\u003ca href=\"#\" class=\"phui-timeline-menu\" aria-haspopup=\"true\" aria-expanded=\"false\" data-sigil=\"phui-dropdown-menu\" data-meta=\"0_690\"\u003e\u003cspan class=\"aural-only\"\u003eComment Actions\u003c\/span\u003e\u003cspan class=\"visual-only phui-icon-view phui-font-fa fa-caret-down\" data-meta=\"0_691\" aria-hidden=\"true\"\u003e\u003c\/span\u003e\u003c\/a\u003e\u003cdiv class=\"phui-timeline-core-content\"\u003e\u003cspan class=\"transaction-comment\" data-sigil=\"transaction-comment\" data-meta=\"0_181\"\u003e\u003cdiv class=\"phabricator-remarkup\"\u003e\u003cp\u003eChange 571297 had a related patch set uploaded (by Nikki Nikkhoui; owner: Nikki Nikkhoui):\u003cbr \/\u003e\n[mediawiki\/core@master] Hook Container\u003c\/p\u003e\n\n\u003cp\u003e\u003ca href=\"https:\/\/gerrit.wikimedia.org\/r\/571297\" class=\"remarkup-link\" target=\"_blank\" rel=\"noreferrer\"\u003ehttps:\/\/gerrit.wikimedia.org\/r\/571297\u003c\/a\u003e\u003c\/p\u003e\u003c\/div\u003e\u003c\/span\u003e\u003c\/div\u003e\u003c\/div\u003e\u003c\/div\u003e\u003c\/div\u003e\u003c\/div\u003e\u003c\/div\u003e\u003cdiv class=\"phui-timeline-event-view phui-timeline-spacer\"\u003e\u003c\/div\u003e\u003cdiv class=\"phui-timeline-shell\" data-sigil=\"transaction anchor-container\" data-meta=\"0_697\"\u003e\u003cdiv class=\"phui-timeline-event-view phui-timeline-minor-event\"\u003e\u003cdiv class=\"phui-timeline-content\"\u003e\u003ca style=\"background-image: url(https:\/\/phab.wmfusercontent.org\/file\/data\/6vn6slgby7ia62ouikut\/PHID-FILE-ay56qvafgaxajuctgtw3\/profile)\" class=\"visual-only phui-timeline-image\" href=\"\/p\/gerritbot\/\" aria-hidden=\"true\"\u003e\u003c\/a\u003e\u003cdiv class=\"phui-timeline-wedge\" style=\"\"\u003e\u003c\/div\u003e\u003cdiv class=\"phui-timeline-group\"\u003e\u003ca name=\"5865068\" id=\"5865068\" class=\"phabricator-anchor-view\"\u003e\u003c\/a\u003e\u003cdiv class=\"phui-timeline-title phui-timeline-title-with-icon\"\u003e\u003cspan class=\"phui-timeline-icon-fill\"\u003e\u003cspan class=\"visual-only phui-icon-view phui-font-fa fa-link phui-timeline-icon\" data-meta=\"0_696\" aria-hidden=\"true\"\u003e\u003c\/span\u003e\u003c\/span\u003e\u003ca href=\"\/p\/gerritbot\/\" class=\"phui-handle phui-link-person\" data-sigil=\"hovercard\" data-meta=\"0_182\"\u003egerritbot\u003c\/a\u003e added a project: \u003ca href=\"\/tag\/patch-for-review\/\" class=\"phui-handle\" data-sigil=\"hovercard\" data-meta=\"0_183\"\u003ePatch-For-Review\u003c\/a\u003e.\u003cspan class=\"phui-timeline-extra\"\u003e\u003ca href=\"#5865068\" data-sigil=\"has-tooltip\" data-meta=\"0_695\"\u003e\u003cspan class=\"screen-only\"\u003eFeb 10 2020, 2:48 PM\u003c\/span\u003e\u003cspan class=\"print-only\" aria-hidden=\"true\"\u003e2020-02-10 14:48:58 (UTC+0)\u003c\/span\u003e\u003c\/a\u003e\u003c\/span\u003e\u003c\/div\u003e\u003c\/div\u003e\u003c\/div\u003e\u003c\/div\u003e\u003c\/div\u003e\u003cdiv class=\"phui-timeline-event-view phui-timeline-spacer\"\u003e\u003c\/div\u003e\u003cdiv class=\"phui-timeline-shell\" data-sigil=\"transaction anchor-container\" data-meta=\"0_700\"\u003e\u003cdiv class=\"phui-timeline-event-view phui-timeline-minor-event\"\u003e\u003cdiv class=\"phui-timeline-content\"\u003e\u003ca style=\"background-image: url(https:\/\/phab.wmfusercontent.org\/file\/data\/q4xtskw4ul5dvrupkmqs\/PHID-FILE-ezxrezgeehrb4vjobxgz\/profile)\" class=\"visual-only phui-timeline-image\" href=\"\/p\/Krinkle\/\" aria-hidden=\"true\"\u003e\u003c\/a\u003e\u003cdiv class=\"phui-timeline-wedge\" style=\"\"\u003e\u003c\/div\u003e\u003cdiv class=\"phui-timeline-group\"\u003e\u003ca name=\"5899330\" id=\"5899330\" class=\"phabricator-anchor-view\"\u003e\u003c\/a\u003e\u003cdiv class=\"phui-timeline-title phui-timeline-title-with-icon\"\u003e\u003cspan class=\"phui-timeline-icon-fill\"\u003e\u003cspan class=\"visual-only phui-icon-view phui-font-fa fa-columns phui-timeline-icon\" data-meta=\"0_699\" aria-hidden=\"true\"\u003e\u003c\/span\u003e\u003c\/span\u003e\u003ca href=\"\/p\/Krinkle\/\" class=\"phui-handle phui-link-person\" data-sigil=\"hovercard\" data-meta=\"0_184\"\u003eKrinkle\u003c\/a\u003e moved this task from \u003ca href=\"\/project\/board\/2002\/\" class=\"phui-handle\" data-sigil=\"hovercard\" data-meta=\"0_185\"\u003eUntriaged\u003c\/a\u003e to \u003ca href=\"\/project\/board\/2002\/\" class=\"phui-handle\" data-sigil=\"hovercard\" data-meta=\"0_186\"\u003eApproved\u003c\/a\u003e on the \u003ca href=\"\/project\/view\/2002\/\" class=\"phui-handle handle-status-closed\" data-sigil=\"hovercard\" data-meta=\"0_187\"\u003eTechCom-RFC (TechCom-RFC-Closed)\u003c\/a\u003e board.\u003cspan class=\"phui-timeline-extra\"\u003e\u003ca href=\"#5899330\" data-sigil=\"has-tooltip\" data-meta=\"0_698\"\u003e\u003cspan class=\"screen-only\"\u003eFeb 19 2020, 11:04 PM\u003c\/span\u003e\u003cspan class=\"print-only\" aria-hidden=\"true\"\u003e2020-02-19 23:04:48 (UTC+0)\u003c\/span\u003e\u003c\/a\u003e\u003c\/span\u003e\u003c\/div\u003e\u003c\/div\u003e\u003c\/div\u003e\u003c\/div\u003e\u003c\/div\u003e\u003cdiv class=\"phui-timeline-event-view phui-timeline-spacer\"\u003e\u003c\/div\u003e\u003cdiv class=\"phui-timeline-shell\" data-sigil=\"transaction anchor-container\" data-meta=\"0_709\"\u003e\u003cdiv class=\"phui-timeline-event-view phui-timeline-major-event\"\u003e\u003cdiv class=\"phui-timeline-content\"\u003e\u003ca style=\"background-image: url(https:\/\/phab.wmfusercontent.org\/file\/data\/6vn6slgby7ia62ouikut\/PHID-FILE-ay56qvafgaxajuctgtw3\/profile)\" class=\"visual-only phui-timeline-image\" href=\"\/p\/gerritbot\/\" aria-hidden=\"true\"\u003e\u003c\/a\u003e\u003cdiv class=\"phui-timeline-wedge\" style=\"\"\u003e\u003c\/div\u003e\u003cdiv class=\"phui-timeline-group\"\u003e\u003cdiv class=\"phui-timeline-inner-content\"\u003e\u003ca name=\"5910913\" id=\"5910913\" class=\"phabricator-anchor-view\"\u003e\u003c\/a\u003e\u003cdiv class=\"phui-timeline-title phui-timeline-title-with-icon phui-timeline-title-with-menu\"\u003e\u003cspan class=\"phui-timeline-icon-fill\"\u003e\u003cspan class=\"visual-only phui-icon-view phui-font-fa fa-comment phui-timeline-icon\" data-meta=\"0_708\" aria-hidden=\"true\"\u003e\u003c\/span\u003e\u003c\/span\u003e\u003ca href=\"\/p\/gerritbot\/\" class=\"phui-handle phui-link-person\" data-sigil=\"hovercard\" data-meta=\"0_188\"\u003egerritbot\u003c\/a\u003e added a comment.\u003cspan class=\"phui-timeline-extra\"\u003e\u003ca href=\"#5910913\" data-sigil=\"has-tooltip\" data-meta=\"0_707\"\u003e\u003cspan class=\"screen-only\"\u003eFeb 24 2020, 5:44 AM\u003c\/span\u003e\u003cspan class=\"print-only\" aria-hidden=\"true\"\u003e2020-02-24 05:44:58 (UTC+0)\u003c\/span\u003e\u003c\/a\u003e\u003c\/span\u003e\u003c\/div\u003e\u003ca href=\"#\" class=\"phui-timeline-menu\" aria-haspopup=\"true\" aria-expanded=\"false\" data-sigil=\"phui-dropdown-menu\" data-meta=\"0_705\"\u003e\u003cspan class=\"aural-only\"\u003eComment Actions\u003c\/span\u003e\u003cspan class=\"visual-only phui-icon-view phui-font-fa fa-caret-down\" data-meta=\"0_706\" aria-hidden=\"true\"\u003e\u003c\/span\u003e\u003c\/a\u003e\u003cdiv class=\"phui-timeline-core-content\"\u003e\u003cspan class=\"transaction-comment\" data-sigil=\"transaction-comment\" data-meta=\"0_189\"\u003e\u003cdiv class=\"phabricator-remarkup\"\u003e\u003cp\u003eChange 574266 had a related patch set uploaded (by Tim Starling; owner: Tim Starling):\u003cbr \/\u003e\n[mediawiki\/core@master] [WIP] Automatically generated hook interfaces\u003c\/p\u003e\n\n\u003cp\u003e\u003ca href=\"https:\/\/gerrit.wikimedia.org\/r\/574266\" class=\"remarkup-link\" target=\"_blank\" rel=\"noreferrer\"\u003ehttps:\/\/gerrit.wikimedia.org\/r\/574266\u003c\/a\u003e\u003c\/p\u003e\u003c\/div\u003e\u003c\/span\u003e\u003c\/div\u003e\u003c\/div\u003e\u003c\/div\u003e\u003c\/div\u003e\u003c\/div\u003e\u003c\/div\u003e\u003cdiv class=\"phui-timeline-event-view phui-timeline-spacer\"\u003e\u003c\/div\u003e\u003cdiv class=\"phui-timeline-shell\" data-sigil=\"transaction anchor-container\" data-meta=\"0_718\"\u003e\u003cdiv class=\"phui-timeline-event-view phui-timeline-major-event\"\u003e\u003cdiv class=\"phui-timeline-content\"\u003e\u003ca style=\"background-image: url(https:\/\/phab.wmfusercontent.org\/file\/data\/6vn6slgby7ia62ouikut\/PHID-FILE-ay56qvafgaxajuctgtw3\/profile)\" class=\"visual-only phui-timeline-image\" href=\"\/p\/gerritbot\/\" aria-hidden=\"true\"\u003e\u003c\/a\u003e\u003cdiv class=\"phui-timeline-wedge\" style=\"\"\u003e\u003c\/div\u003e\u003cdiv class=\"phui-timeline-group\"\u003e\u003cdiv class=\"phui-timeline-inner-content\"\u003e\u003ca name=\"5918671\" id=\"5918671\" class=\"phabricator-anchor-view\"\u003e\u003c\/a\u003e\u003cdiv class=\"phui-timeline-title phui-timeline-title-with-icon phui-timeline-title-with-menu\"\u003e\u003cspan class=\"phui-timeline-icon-fill\"\u003e\u003cspan class=\"visual-only phui-icon-view phui-font-fa fa-comment phui-timeline-icon\" data-meta=\"0_717\" aria-hidden=\"true\"\u003e\u003c\/span\u003e\u003c\/span\u003e\u003ca href=\"\/p\/gerritbot\/\" class=\"phui-handle phui-link-person\" data-sigil=\"hovercard\" data-meta=\"0_190\"\u003egerritbot\u003c\/a\u003e added a comment.\u003cspan class=\"phui-timeline-extra\"\u003e\u003ca href=\"#5918671\" data-sigil=\"has-tooltip\" data-meta=\"0_716\"\u003e\u003cspan class=\"screen-only\"\u003eFeb 26 2020, 4:11 AM\u003c\/span\u003e\u003cspan class=\"print-only\" aria-hidden=\"true\"\u003e2020-02-26 04:11:08 (UTC+0)\u003c\/span\u003e\u003c\/a\u003e\u003c\/span\u003e\u003c\/div\u003e\u003ca href=\"#\" class=\"phui-timeline-menu\" aria-haspopup=\"true\" aria-expanded=\"false\" data-sigil=\"phui-dropdown-menu\" data-meta=\"0_714\"\u003e\u003cspan class=\"aural-only\"\u003eComment Actions\u003c\/span\u003e\u003cspan class=\"visual-only phui-icon-view phui-font-fa fa-caret-down\" data-meta=\"0_715\" aria-hidden=\"true\"\u003e\u003c\/span\u003e\u003c\/a\u003e\u003cdiv class=\"phui-timeline-core-content\"\u003e\u003cspan class=\"transaction-comment\" data-sigil=\"transaction-comment\" data-meta=\"0_191\"\u003e\u003cdiv class=\"phabricator-remarkup\"\u003e\u003cp\u003eChange 574915 had a related patch set uploaded (by Tim Starling; owner: Tim Starling):\u003cbr \/\u003e\n[mediawiki\/tools\/generateHookInterfaces@master] A script for generating hook interfaces per \u003ca href=\"\/T240307\" class=\"phui-tag-view phui-tag-type-object \" data-sigil=\"hovercard\" data-meta=\"0_70\"\u003e\u003cspan class=\"phui-tag-core-closed\"\u003e\u003cspan class=\"phui-tag-core phui-tag-color-object\"\u003eT240307\u003c\/span\u003e\u003c\/span\u003e\u003c\/a\u003e (initial commit)\u003c\/p\u003e\n\n\u003cp\u003e\u003ca href=\"https:\/\/gerrit.wikimedia.org\/r\/574915\" class=\"remarkup-link\" target=\"_blank\" rel=\"noreferrer\"\u003ehttps:\/\/gerrit.wikimedia.org\/r\/574915\u003c\/a\u003e\u003c\/p\u003e\u003c\/div\u003e\u003c\/span\u003e\u003c\/div\u003e\u003c\/div\u003e\u003c\/div\u003e\u003c\/div\u003e\u003c\/div\u003e\u003c\/div\u003e\u003cdiv class=\"phui-timeline-event-view phui-timeline-spacer\"\u003e\u003c\/div\u003e\u003cdiv class=\"phui-timeline-shell\" data-sigil=\"transaction anchor-container\" data-meta=\"0_721\"\u003e\u003cdiv class=\"phui-timeline-event-view phui-timeline-minor-event\"\u003e\u003cdiv class=\"phui-timeline-content\"\u003e\u003ca style=\"background-image: url(https:\/\/phab.wmfusercontent.org\/file\/data\/xgl3wy55ovinfnucvwhx\/PHID-FILE-zocnksypiqutzf5oubpi\/profile)\" class=\"visual-only phui-timeline-image\" href=\"\/p\/tstarling\/\" aria-hidden=\"true\"\u003e\u003c\/a\u003e\u003cdiv class=\"phui-timeline-wedge\" style=\"\"\u003e\u003c\/div\u003e\u003cdiv class=\"phui-timeline-group\"\u003e\u003ca name=\"5918688\" id=\"5918688\" class=\"phabricator-anchor-view\"\u003e\u003c\/a\u003e\u003cdiv class=\"phui-timeline-title phui-timeline-title-with-icon\"\u003e\u003cspan class=\"phui-timeline-icon-fill\"\u003e\u003cspan class=\"visual-only phui-icon-view phui-font-fa fa-link phui-timeline-icon\" data-meta=\"0_720\" aria-hidden=\"true\"\u003e\u003c\/span\u003e\u003c\/span\u003e\u003ca href=\"\/p\/tstarling\/\" class=\"phui-handle handle-availability-partial phui-link-person\" data-sigil=\"hovercard\" data-meta=\"0_192\"\u003e\u003cspan class=\"perfect-circle\"\u003e\u2022\u003c\/span\u003e tstarling\u003c\/a\u003e mentioned this in \u003ca href=\"\/T193950\" class=\"phui-handle\" data-sigil=\"hovercard\" data-meta=\"0_193\"\u003eT193950: Hook parameters should not be passed by reference unless the parameter is documented to be replaceable\u003c\/a\u003e.\u003cspan class=\"phui-timeline-extra\"\u003e\u003ca href=\"#5918688\" data-sigil=\"has-tooltip\" data-meta=\"0_719\"\u003e\u003cspan class=\"screen-only\"\u003eFeb 26 2020, 4:49 AM\u003c\/span\u003e\u003cspan class=\"print-only\" aria-hidden=\"true\"\u003e2020-02-26 04:49:48 (UTC+0)\u003c\/span\u003e\u003c\/a\u003e\u003c\/span\u003e\u003c\/div\u003e\u003c\/div\u003e\u003c\/div\u003e\u003c\/div\u003e\u003c\/div\u003e\u003cdiv class=\"phui-timeline-event-view phui-timeline-spacer\"\u003e\u003c\/div\u003e\u003cdiv class=\"phui-timeline-shell\" data-sigil=\"transaction anchor-container\" data-meta=\"0_730\"\u003e\u003cdiv class=\"phui-timeline-event-view phui-timeline-major-event\"\u003e\u003cdiv class=\"phui-timeline-content\"\u003e\u003ca style=\"background-image: url(https:\/\/phab.wmfusercontent.org\/file\/data\/6vn6slgby7ia62ouikut\/PHID-FILE-ay56qvafgaxajuctgtw3\/profile)\" class=\"visual-only phui-timeline-image\" href=\"\/p\/gerritbot\/\" aria-hidden=\"true\"\u003e\u003c\/a\u003e\u003cdiv class=\"phui-timeline-wedge\" style=\"\"\u003e\u003c\/div\u003e\u003cdiv class=\"phui-timeline-group\"\u003e\u003cdiv class=\"phui-timeline-inner-content\"\u003e\u003ca name=\"5925594\" id=\"5925594\" class=\"phabricator-anchor-view\"\u003e\u003c\/a\u003e\u003cdiv class=\"phui-timeline-title phui-timeline-title-with-icon phui-timeline-title-with-menu\"\u003e\u003cspan class=\"phui-timeline-icon-fill\"\u003e\u003cspan class=\"visual-only phui-icon-view phui-font-fa fa-comment phui-timeline-icon\" data-meta=\"0_729\" aria-hidden=\"true\"\u003e\u003c\/span\u003e\u003c\/span\u003e\u003ca href=\"\/p\/gerritbot\/\" class=\"phui-handle phui-link-person\" data-sigil=\"hovercard\" data-meta=\"0_194\"\u003egerritbot\u003c\/a\u003e added a comment.\u003cspan class=\"phui-timeline-extra\"\u003e\u003ca href=\"#5925594\" data-sigil=\"has-tooltip\" data-meta=\"0_728\"\u003e\u003cspan class=\"screen-only\"\u003eFeb 28 2020, 6:26 AM\u003c\/span\u003e\u003cspan class=\"print-only\" aria-hidden=\"true\"\u003e2020-02-28 06:26:46 (UTC+0)\u003c\/span\u003e\u003c\/a\u003e\u003c\/span\u003e\u003c\/div\u003e\u003ca href=\"#\" class=\"phui-timeline-menu\" aria-haspopup=\"true\" aria-expanded=\"false\" data-sigil=\"phui-dropdown-menu\" data-meta=\"0_726\"\u003e\u003cspan class=\"aural-only\"\u003eComment Actions\u003c\/span\u003e\u003cspan class=\"visual-only phui-icon-view phui-font-fa fa-caret-down\" data-meta=\"0_727\" aria-hidden=\"true\"\u003e\u003c\/span\u003e\u003c\/a\u003e\u003cdiv class=\"phui-timeline-core-content\"\u003e\u003cspan class=\"transaction-comment\" data-sigil=\"transaction-comment\" data-meta=\"0_195\"\u003e\u003cdiv class=\"phabricator-remarkup\"\u003e\u003cp\u003eChange 575408 had a related patch set uploaded (by Tim Starling; owner: Tim Starling):\u003cbr \/\u003e\n[mediawiki\/core@master] Use array literals when calling Hooks::run()\u003c\/p\u003e\n\n\u003cp\u003e\u003ca href=\"https:\/\/gerrit.wikimedia.org\/r\/575408\" class=\"remarkup-link\" target=\"_blank\" rel=\"noreferrer\"\u003ehttps:\/\/gerrit.wikimedia.org\/r\/575408\u003c\/a\u003e\u003c\/p\u003e\u003c\/div\u003e\u003c\/span\u003e\u003c\/div\u003e\u003c\/div\u003e\u003c\/div\u003e\u003c\/div\u003e\u003c\/div\u003e\u003c\/div\u003e\u003cdiv class=\"phui-timeline-event-view phui-timeline-spacer\"\u003e\u003c\/div\u003e\u003cdiv class=\"phui-timeline-shell\" data-sigil=\"transaction anchor-container\" data-meta=\"0_739\"\u003e\u003cdiv class=\"phui-timeline-event-view phui-timeline-major-event\"\u003e\u003cdiv class=\"phui-timeline-content\"\u003e\u003ca style=\"background-image: url(https:\/\/phab.wmfusercontent.org\/file\/data\/6vn6slgby7ia62ouikut\/PHID-FILE-ay56qvafgaxajuctgtw3\/profile)\" class=\"visual-only phui-timeline-image\" href=\"\/p\/gerritbot\/\" aria-hidden=\"true\"\u003e\u003c\/a\u003e\u003cdiv class=\"phui-timeline-wedge\" style=\"\"\u003e\u003c\/div\u003e\u003cdiv class=\"phui-timeline-group\"\u003e\u003cdiv class=\"phui-timeline-inner-content\"\u003e\u003ca name=\"5945400\" id=\"5945400\" class=\"phabricator-anchor-view\"\u003e\u003c\/a\u003e\u003cdiv class=\"phui-timeline-title phui-timeline-title-with-icon phui-timeline-title-with-menu\"\u003e\u003cspan class=\"phui-timeline-icon-fill\"\u003e\u003cspan class=\"visual-only phui-icon-view phui-font-fa fa-comment phui-timeline-icon\" data-meta=\"0_738\" aria-hidden=\"true\"\u003e\u003c\/span\u003e\u003c\/span\u003e\u003ca href=\"\/p\/gerritbot\/\" class=\"phui-handle phui-link-person\" data-sigil=\"hovercard\" data-meta=\"0_196\"\u003egerritbot\u003c\/a\u003e added a comment.\u003cspan class=\"phui-timeline-extra\"\u003e\u003ca href=\"#5945400\" data-sigil=\"has-tooltip\" data-meta=\"0_737\"\u003e\u003cspan class=\"screen-only\"\u003eMar 5 2020, 4:49 PM\u003c\/span\u003e\u003cspan class=\"print-only\" aria-hidden=\"true\"\u003e2020-03-05 16:49:43 (UTC+0)\u003c\/span\u003e\u003c\/a\u003e\u003c\/span\u003e\u003c\/div\u003e\u003ca href=\"#\" class=\"phui-timeline-menu\" aria-haspopup=\"true\" aria-expanded=\"false\" data-sigil=\"phui-dropdown-menu\" data-meta=\"0_735\"\u003e\u003cspan class=\"aural-only\"\u003eComment Actions\u003c\/span\u003e\u003cspan class=\"visual-only phui-icon-view phui-font-fa fa-caret-down\" data-meta=\"0_736\" aria-hidden=\"true\"\u003e\u003c\/span\u003e\u003c\/a\u003e\u003cdiv class=\"phui-timeline-core-content\"\u003e\u003cspan class=\"transaction-comment\" data-sigil=\"transaction-comment\" data-meta=\"0_197\"\u003e\u003cdiv class=\"phabricator-remarkup\"\u003e\u003cp\u003eChange 575408 \u003cstrong\u003emerged\u003c\/strong\u003e by jenkins-bot:\u003cbr \/\u003e\n[mediawiki\/core@master] Use array literals when calling Hooks::run()\u003c\/p\u003e\n\n\u003cp\u003e\u003ca href=\"https:\/\/gerrit.wikimedia.org\/r\/575408\" class=\"remarkup-link\" target=\"_blank\" rel=\"noreferrer\"\u003ehttps:\/\/gerrit.wikimedia.org\/r\/575408\u003c\/a\u003e\u003c\/p\u003e\u003c\/div\u003e\u003c\/span\u003e\u003c\/div\u003e\u003c\/div\u003e\u003c\/div\u003e\u003c\/div\u003e\u003c\/div\u003e\u003c\/div\u003e\u003cdiv class=\"phui-timeline-event-view phui-timeline-spacer\"\u003e\u003c\/div\u003e\u003cdiv class=\"phui-timeline-shell\" data-sigil=\"transaction anchor-container\" data-meta=\"0_742\"\u003e\u003cdiv class=\"phui-timeline-event-view phui-timeline-minor-event\"\u003e\u003cdiv class=\"phui-timeline-content\"\u003e\u003ca style=\"background-image: url(https:\/\/phab.wmfusercontent.org\/file\/data\/4n4bfuo6qhvlmne4smgd\/PHID-FILE-n44cjn5x2ltqvfawn6ks\/alphanumeric_aleo-white_R.png-_7f4c7f-255%2C255%2C255%2C0.7.png)\" class=\"visual-only phui-timeline-image\" href=\"\/p\/ReleaseTaggerBot\/\" aria-hidden=\"true\"\u003e\u003c\/a\u003e\u003cdiv class=\"phui-timeline-wedge\" style=\"\"\u003e\u003c\/div\u003e\u003cdiv class=\"phui-timeline-group\"\u003e\u003ca name=\"5945430\" id=\"5945430\" class=\"phabricator-anchor-view\"\u003e\u003c\/a\u003e\u003cdiv class=\"phui-timeline-title phui-timeline-title-with-icon\"\u003e\u003cspan class=\"phui-timeline-icon-fill\"\u003e\u003cspan class=\"visual-only phui-icon-view phui-font-fa fa-link phui-timeline-icon\" data-meta=\"0_741\" aria-hidden=\"true\"\u003e\u003c\/span\u003e\u003c\/span\u003e\u003ca href=\"\/p\/ReleaseTaggerBot\/\" class=\"phui-handle phui-link-person\" data-sigil=\"hovercard\" data-meta=\"0_198\"\u003eReleaseTaggerBot\u003c\/a\u003e added a project: \u003ca href=\"\/project\/view\/4474\/\" class=\"phui-handle handle-status-closed\" data-sigil=\"hovercard\" data-meta=\"0_199\"\u003eMW-1.35-notes (1.35.0-wmf.23; 2020-03-10)\u003c\/a\u003e.\u003cspan class=\"phui-timeline-extra\"\u003e\u003ca href=\"#5945430\" data-sigil=\"has-tooltip\" data-meta=\"0_740\"\u003e\u003cspan class=\"screen-only\"\u003eMar 5 2020, 5:00 PM\u003c\/span\u003e\u003cspan class=\"print-only\" aria-hidden=\"true\"\u003e2020-03-05 17:00:43 (UTC+0)\u003c\/span\u003e\u003c\/a\u003e\u003c\/span\u003e\u003c\/div\u003e\u003c\/div\u003e\u003c\/div\u003e\u003c\/div\u003e\u003c\/div\u003e\u003cdiv class=\"phui-timeline-event-view phui-timeline-spacer\"\u003e\u003c\/div\u003e\u003cdiv class=\"phui-timeline-shell\" data-sigil=\"transaction anchor-container\" data-meta=\"0_751\"\u003e\u003cdiv class=\"phui-timeline-event-view phui-timeline-major-event\"\u003e\u003cdiv class=\"phui-timeline-content\"\u003e\u003ca style=\"background-image: url(https:\/\/phab.wmfusercontent.org\/file\/data\/6vn6slgby7ia62ouikut\/PHID-FILE-ay56qvafgaxajuctgtw3\/profile)\" class=\"visual-only phui-timeline-image\" href=\"\/p\/gerritbot\/\" aria-hidden=\"true\"\u003e\u003c\/a\u003e\u003cdiv class=\"phui-timeline-wedge\" style=\"\"\u003e\u003c\/div\u003e\u003cdiv class=\"phui-timeline-group\"\u003e\u003cdiv class=\"phui-timeline-inner-content\"\u003e\u003ca name=\"5947174\" id=\"5947174\" class=\"phabricator-anchor-view\"\u003e\u003c\/a\u003e\u003cdiv class=\"phui-timeline-title phui-timeline-title-with-icon phui-timeline-title-with-menu\"\u003e\u003cspan class=\"phui-timeline-icon-fill\"\u003e\u003cspan class=\"visual-only phui-icon-view phui-font-fa fa-comment phui-timeline-icon\" data-meta=\"0_750\" aria-hidden=\"true\"\u003e\u003c\/span\u003e\u003c\/span\u003e\u003ca href=\"\/p\/gerritbot\/\" class=\"phui-handle phui-link-person\" data-sigil=\"hovercard\" data-meta=\"0_200\"\u003egerritbot\u003c\/a\u003e added a comment.\u003cspan class=\"phui-timeline-extra\"\u003e\u003ca href=\"#5947174\" data-sigil=\"has-tooltip\" data-meta=\"0_749\"\u003e\u003cspan class=\"screen-only\"\u003eMar 6 2020, 5:26 AM\u003c\/span\u003e\u003cspan class=\"print-only\" aria-hidden=\"true\"\u003e2020-03-06 05:26:48 (UTC+0)\u003c\/span\u003e\u003c\/a\u003e\u003c\/span\u003e\u003c\/div\u003e\u003ca href=\"#\" class=\"phui-timeline-menu\" aria-haspopup=\"true\" aria-expanded=\"false\" data-sigil=\"phui-dropdown-menu\" data-meta=\"0_747\"\u003e\u003cspan class=\"aural-only\"\u003eComment Actions\u003c\/span\u003e\u003cspan class=\"visual-only phui-icon-view phui-font-fa fa-caret-down\" data-meta=\"0_748\" aria-hidden=\"true\"\u003e\u003c\/span\u003e\u003c\/a\u003e\u003cdiv class=\"phui-timeline-core-content\"\u003e\u003cspan class=\"transaction-comment\" data-sigil=\"transaction-comment\" data-meta=\"0_201\"\u003e\u003cdiv class=\"phabricator-remarkup\"\u003e\u003cp\u003eChange 577414 had a related patch set uploaded (by Tim Starling; owner: Tim Starling):\u003cbr \/\u003e\n[mediawiki\/core@master] [WIP] Automatically generated HookRunner\u003c\/p\u003e\n\n\u003cp\u003e\u003ca href=\"https:\/\/gerrit.wikimedia.org\/r\/577414\" class=\"remarkup-link\" target=\"_blank\" rel=\"noreferrer\"\u003ehttps:\/\/gerrit.wikimedia.org\/r\/577414\u003c\/a\u003e\u003c\/p\u003e\u003c\/div\u003e\u003c\/span\u003e\u003c\/div\u003e\u003c\/div\u003e\u003c\/div\u003e\u003c\/div\u003e\u003c\/div\u003e\u003c\/div\u003e\u003cdiv class=\"phui-timeline-event-view phui-timeline-spacer\"\u003e\u003c\/div\u003e\u003cdiv class=\"phui-timeline-shell\" data-sigil=\"transaction anchor-container\" data-meta=\"0_754\"\u003e\u003cdiv class=\"phui-timeline-event-view phui-timeline-minor-event\"\u003e\u003cdiv class=\"phui-timeline-content\"\u003e\u003ca style=\"background-image: url(https:\/\/phab.wmfusercontent.org\/file\/data\/247abt7phqlbitgglyxa\/PHID-FILE-tx36db6dprvfuxu72bcj\/alphanumeric_aleo-white_D.png-_ec9da1-0%2C0%2C0%2C0.png)\" class=\"visual-only phui-timeline-image\" href=\"\/p\/Daimona\/\" aria-hidden=\"true\"\u003e\u003c\/a\u003e\u003cdiv class=\"phui-timeline-wedge\" style=\"\"\u003e\u003c\/div\u003e\u003cdiv class=\"phui-timeline-group\"\u003e\u003ca name=\"5953282\" id=\"5953282\" class=\"phabricator-anchor-view\"\u003e\u003c\/a\u003e\u003cdiv class=\"phui-timeline-title phui-timeline-title-with-icon\"\u003e\u003cspan class=\"phui-timeline-icon-fill\"\u003e\u003cspan class=\"visual-only phui-icon-view phui-font-fa fa-link phui-timeline-icon\" data-meta=\"0_753\" aria-hidden=\"true\"\u003e\u003c\/span\u003e\u003c\/span\u003e\u003ca href=\"\/p\/Daimona\/\" class=\"phui-handle phui-link-person\" data-sigil=\"hovercard\" data-meta=\"0_202\"\u003eDaimona\u003c\/a\u003e mentioned this in \u003ca href=\"\/T154677\" class=\"phui-handle handle-status-closed\" data-sigil=\"hovercard\" data-meta=\"0_203\"\u003eT154677: Turn static Hooks class into HookManager service\u003c\/a\u003e.\u003cspan class=\"phui-timeline-extra\"\u003e\u003ca href=\"#5953282\" data-sigil=\"has-tooltip\" data-meta=\"0_752\"\u003e\u003cspan class=\"screen-only\"\u003eMar 9 2020, 11:12 AM\u003c\/span\u003e\u003cspan class=\"print-only\" aria-hidden=\"true\"\u003e2020-03-09 11:12:41 (UTC+0)\u003c\/span\u003e\u003c\/a\u003e\u003c\/span\u003e\u003c\/div\u003e\u003c\/div\u003e\u003c\/div\u003e\u003c\/div\u003e\u003c\/div\u003e\u003cdiv class=\"phui-timeline-event-view phui-timeline-spacer\"\u003e\u003c\/div\u003e\u003cdiv class=\"phui-timeline-shell\" data-sigil=\"transaction anchor-container\" data-meta=\"0_757\"\u003e\u003cdiv class=\"phui-timeline-event-view phui-timeline-minor-event\"\u003e\u003cdiv class=\"phui-timeline-content\"\u003e\u003ca style=\"background-image: url(https:\/\/phab.wmfusercontent.org\/file\/data\/uozy27tmumvtidur53cx\/PHID-FILE-hkxqy4vstbohkujqlcoc\/profile)\" class=\"visual-only phui-timeline-image\" href=\"\/p\/ItamarWMDE\/\" aria-hidden=\"true\"\u003e\u003c\/a\u003e\u003cdiv class=\"phui-timeline-wedge\" style=\"\"\u003e\u003c\/div\u003e\u003cdiv class=\"phui-timeline-group\"\u003e\u003ca name=\"5960502\" id=\"5960502\" class=\"phabricator-anchor-view\"\u003e\u003c\/a\u003e\u003cdiv class=\"phui-timeline-title phui-timeline-title-with-icon\"\u003e\u003cspan class=\"phui-timeline-icon-fill\"\u003e\u003cspan class=\"visual-only phui-icon-view phui-font-fa fa-user-plus phui-timeline-icon\" data-meta=\"0_756\" aria-hidden=\"true\"\u003e\u003c\/span\u003e\u003c\/span\u003e\u003ca href=\"\/p\/ItamarWMDE\/\" class=\"phui-handle phui-link-person\" data-sigil=\"hovercard\" data-meta=\"0_204\"\u003eItamarWMDE\u003c\/a\u003e subscribed.\u003cspan class=\"phui-timeline-extra\"\u003e\u003ca href=\"#5960502\" data-sigil=\"has-tooltip\" data-meta=\"0_755\"\u003e\u003cspan class=\"screen-only\"\u003eMar 11 2020, 3:29 PM\u003c\/span\u003e\u003cspan class=\"print-only\" aria-hidden=\"true\"\u003e2020-03-11 15:29:29 (UTC+0)\u003c\/span\u003e\u003c\/a\u003e\u003c\/span\u003e\u003c\/div\u003e\u003c\/div\u003e\u003c\/div\u003e\u003c\/div\u003e\u003c\/div\u003e\u003cdiv class=\"phui-timeline-event-view phui-timeline-spacer\"\u003e\u003c\/div\u003e\u003cdiv class=\"phui-timeline-shell\" data-sigil=\"transaction anchor-container\" data-meta=\"0_761\"\u003e\u003cdiv class=\"phui-timeline-event-view phui-timeline-minor-event\"\u003e\u003cdiv class=\"phui-timeline-content\"\u003e\u003ca style=\"background-image: url(https:\/\/phab.wmfusercontent.org\/file\/data\/ms665yc73j6nadjitytk\/PHID-FILE-mocohumlrcbe2lcuplml\/profile)\" class=\"visual-only phui-timeline-image\" href=\"\/p\/Anomie\/\" aria-hidden=\"true\"\u003e\u003c\/a\u003e\u003cdiv class=\"phui-timeline-wedge\" style=\"\"\u003e\u003c\/div\u003e\u003cdiv class=\"phui-timeline-group\"\u003e\u003ca name=\"5980694\" id=\"5980694\" class=\"phabricator-anchor-view\"\u003e\u003c\/a\u003e\u003cdiv class=\"phui-timeline-title phui-timeline-title-with-icon\"\u003e\u003cspan class=\"phui-timeline-icon-fill\"\u003e\u003cspan class=\"visual-only phui-icon-view phui-font-fa fa-link phui-timeline-icon\" data-meta=\"0_759\" aria-hidden=\"true\"\u003e\u003c\/span\u003e\u003c\/span\u003e\u003ca href=\"\/p\/Anomie\/\" class=\"phui-handle phui-link-person\" data-sigil=\"hovercard\" data-meta=\"0_205\"\u003eAnomie\u003c\/a\u003e added a project: \u003ca href=\"\/project\/view\/4149\/\" class=\"phui-handle handle-status-closed\" data-sigil=\"hovercard\" data-meta=\"0_206\"\u003ePlatform Team Workboards (Clinic Duty Team)\u003c\/a\u003e.\u003cspan class=\"phui-timeline-extra\"\u003e\u003ca href=\"#5980694\" data-sigil=\"has-tooltip\" data-meta=\"0_758\"\u003e\u003cspan class=\"screen-only\"\u003eMar 18 2020, 5:12 PM\u003c\/span\u003e\u003cspan class=\"print-only\" aria-hidden=\"true\"\u003e2020-03-18 17:12:54 (UTC+0)\u003c\/span\u003e\u003c\/a\u003e\u003c\/span\u003e\u003c\/div\u003e\u003cdiv class=\"phui-timeline-title phui-timeline-title-with-icon\"\u003e\u003cspan class=\"phui-timeline-icon-fill\"\u003e\u003cspan class=\"visual-only phui-icon-view phui-font-fa fa-columns phui-timeline-icon\" data-meta=\"0_760\" aria-hidden=\"true\"\u003e\u003c\/span\u003e\u003c\/span\u003e\u003ca href=\"\/p\/Anomie\/\" class=\"phui-handle phui-link-person\" data-sigil=\"hovercard\" data-meta=\"0_207\"\u003eAnomie\u003c\/a\u003e moved this task from \u003ca href=\"\/project\/board\/4149\/\" class=\"phui-handle\" data-sigil=\"hovercard\" data-meta=\"0_208\"\u003eInbox\u003c\/a\u003e to \u003ca href=\"\/project\/board\/4149\/\" class=\"phui-handle\" data-sigil=\"hovercard\" data-meta=\"0_209\"\u003eWaiting for Review\u003c\/a\u003e on the \u003ca href=\"\/project\/view\/4149\/\" class=\"phui-handle handle-status-closed\" data-sigil=\"hovercard\" data-meta=\"0_210\"\u003ePlatform Team Workboards (Clinic Duty Team)\u003c\/a\u003e board.\u003c\/div\u003e\u003c\/div\u003e\u003c\/div\u003e\u003c\/div\u003e\u003c\/div\u003e\u003cdiv class=\"phui-timeline-event-view phui-timeline-spacer\"\u003e\u003c\/div\u003e\u003cdiv class=\"phui-timeline-shell\" data-sigil=\"transaction anchor-container\" data-meta=\"0_764\"\u003e\u003cdiv class=\"phui-timeline-event-view phui-timeline-minor-event\"\u003e\u003cdiv class=\"phui-timeline-content\"\u003e\u003ca style=\"background-image: url(https:\/\/phab.wmfusercontent.org\/file\/data\/vujzl5hgii6pty7gvjgn\/PHID-FILE-dyybnatmpguzojq462gd\/92b8c4-alphanumeric_lato-white_D.png-0%2C0%2C0%2C0.3.png)\" class=\"visual-only phui-timeline-image\" href=\"\/p\/DannyS712\/\" aria-hidden=\"true\"\u003e\u003c\/a\u003e\u003cdiv class=\"phui-timeline-wedge\" style=\"\"\u003e\u003c\/div\u003e\u003cdiv class=\"phui-timeline-group\"\u003e\u003ca name=\"5987573\" id=\"5987573\" class=\"phabricator-anchor-view\"\u003e\u003c\/a\u003e\u003cdiv class=\"phui-timeline-title phui-timeline-title-with-icon\"\u003e\u003cspan class=\"phui-timeline-icon-fill\"\u003e\u003cspan class=\"visual-only phui-icon-view phui-font-fa fa-link phui-timeline-icon\" data-meta=\"0_763\" aria-hidden=\"true\"\u003e\u003c\/span\u003e\u003c\/span\u003e\u003ca href=\"\/p\/DannyS712\/\" class=\"phui-handle phui-link-person\" data-sigil=\"hovercard\" data-meta=\"0_211\"\u003eDannyS712\u003c\/a\u003e added a project: \u003ca href=\"\/tag\/dependency_injection\/\" class=\"phui-handle\" data-sigil=\"hovercard\" data-meta=\"0_212\"\u003eDependency injection\u003c\/a\u003e.\u003cspan class=\"phui-timeline-extra\"\u003e\u003ca href=\"#5987573\" data-sigil=\"has-tooltip\" data-meta=\"0_762\"\u003e\u003cspan class=\"screen-only\"\u003eMar 20 2020, 5:12 PM\u003c\/span\u003e\u003cspan class=\"print-only\" aria-hidden=\"true\"\u003e2020-03-20 17:12:59 (UTC+0)\u003c\/span\u003e\u003c\/a\u003e\u003c\/span\u003e\u003c\/div\u003e\u003c\/div\u003e\u003c\/div\u003e\u003c\/div\u003e\u003c\/div\u003e\u003cdiv class=\"phui-timeline-event-view phui-timeline-spacer\"\u003e\u003c\/div\u003e\u003cdiv class=\"phui-timeline-shell\" data-sigil=\"transaction anchor-container\" data-meta=\"0_767\"\u003e\u003cdiv class=\"phui-timeline-event-view phui-timeline-minor-event\"\u003e\u003cdiv class=\"phui-timeline-content\"\u003e\u003ca style=\"background-image: url(https:\/\/phab.wmfusercontent.org\/file\/data\/mnn6n3d4yj6rt5gzndq5\/PHID-FILE-6zzeafreuspccjbzdvmj\/profile)\" class=\"visual-only phui-timeline-image\" href=\"\/p\/edwardspec\/\" aria-hidden=\"true\"\u003e\u003c\/a\u003e\u003cdiv class=\"phui-timeline-wedge\" style=\"\"\u003e\u003c\/div\u003e\u003cdiv class=\"phui-timeline-group\"\u003e\u003ca name=\"6021288\" id=\"6021288\" class=\"phabricator-anchor-view\"\u003e\u003c\/a\u003e\u003cdiv class=\"phui-timeline-title phui-timeline-title-with-icon\"\u003e\u003cspan class=\"phui-timeline-icon-fill\"\u003e\u003cspan class=\"visual-only phui-icon-view phui-font-fa fa-user-plus phui-timeline-icon\" data-meta=\"0_766\" aria-hidden=\"true\"\u003e\u003c\/span\u003e\u003c\/span\u003e\u003ca href=\"\/p\/edwardspec\/\" class=\"phui-handle phui-link-person\" data-sigil=\"hovercard\" data-meta=\"0_213\"\u003eedwardspec\u003c\/a\u003e subscribed.\u003cspan class=\"phui-timeline-extra\"\u003e\u003ca href=\"#6021288\" data-sigil=\"has-tooltip\" data-meta=\"0_765\"\u003e\u003cspan class=\"screen-only\"\u003eApr 2 2020, 2:57 AM\u003c\/span\u003e\u003cspan class=\"print-only\" aria-hidden=\"true\"\u003e2020-04-02 02:57:03 (UTC+0)\u003c\/span\u003e\u003c\/a\u003e\u003c\/span\u003e\u003c\/div\u003e\u003c\/div\u003e\u003c\/div\u003e\u003c\/div\u003e\u003c\/div\u003e\u003cdiv class=\"phui-timeline-event-view phui-timeline-spacer\"\u003e\u003c\/div\u003e\u003cdiv class=\"phui-timeline-shell\" data-sigil=\"transaction anchor-container\" data-meta=\"0_770\"\u003e\u003cdiv class=\"phui-timeline-event-view phui-timeline-minor-event\"\u003e\u003cdiv class=\"phui-timeline-content\"\u003e\u003ca style=\"background-image: url(https:\/\/phab.wmfusercontent.org\/file\/data\/q4xtskw4ul5dvrupkmqs\/PHID-FILE-ezxrezgeehrb4vjobxgz\/profile)\" class=\"visual-only phui-timeline-image\" href=\"\/p\/Krinkle\/\" aria-hidden=\"true\"\u003e\u003c\/a\u003e\u003cdiv class=\"phui-timeline-wedge\" style=\"\"\u003e\u003c\/div\u003e\u003cdiv class=\"phui-timeline-group\"\u003e\u003ca name=\"6028455\" id=\"6028455\" class=\"phabricator-anchor-view\"\u003e\u003c\/a\u003e\u003cdiv class=\"phui-timeline-title phui-timeline-title-with-icon\"\u003e\u003cspan class=\"phui-timeline-icon-fill\"\u003e\u003cspan class=\"visual-only phui-icon-view phui-font-fa fa-link phui-timeline-icon\" data-meta=\"0_769\" aria-hidden=\"true\"\u003e\u003c\/span\u003e\u003c\/span\u003e\u003ca href=\"\/p\/Krinkle\/\" class=\"phui-handle phui-link-person\" data-sigil=\"hovercard\" data-meta=\"0_214\"\u003eKrinkle\u003c\/a\u003e mentioned this in \u003ca href=\"\/T154674\" class=\"phui-handle handle-status-closed\" data-sigil=\"hovercard\" data-meta=\"0_215\"\u003eT154674: Introduce HookRunner, a wrapper for hook handlers for a specific event.\u003c\/a\u003e.\u003cspan class=\"phui-timeline-extra\"\u003e\u003ca href=\"#6028455\" data-sigil=\"has-tooltip\" data-meta=\"0_768\"\u003e\u003cspan class=\"screen-only\"\u003eApr 4 2020, 1:11 AM\u003c\/span\u003e\u003cspan class=\"print-only\" aria-hidden=\"true\"\u003e2020-04-04 01:11:21 (UTC+0)\u003c\/span\u003e\u003c\/a\u003e\u003c\/span\u003e\u003c\/div\u003e\u003c\/div\u003e\u003c\/div\u003e\u003c\/div\u003e\u003c\/div\u003e\u003cdiv class=\"phui-timeline-event-view phui-timeline-spacer\"\u003e\u003c\/div\u003e\u003cdiv class=\"phui-timeline-shell\" data-sigil=\"transaction anchor-container\" data-meta=\"0_773\"\u003e\u003cdiv class=\"phui-timeline-event-view phui-timeline-minor-event\"\u003e\u003cdiv class=\"phui-timeline-content\"\u003e\u003ca style=\"background-image: url(https:\/\/phab.wmfusercontent.org\/file\/data\/vujzl5hgii6pty7gvjgn\/PHID-FILE-dyybnatmpguzojq462gd\/92b8c4-alphanumeric_lato-white_D.png-0%2C0%2C0%2C0.3.png)\" class=\"visual-only phui-timeline-image\" href=\"\/p\/DannyS712\/\" aria-hidden=\"true\"\u003e\u003c\/a\u003e\u003cdiv class=\"phui-timeline-wedge\" style=\"\"\u003e\u003c\/div\u003e\u003cdiv class=\"phui-timeline-group\"\u003e\u003ca name=\"6048624\" id=\"6048624\" class=\"phabricator-anchor-view\"\u003e\u003c\/a\u003e\u003cdiv class=\"phui-timeline-title phui-timeline-title-with-icon\"\u003e\u003cspan class=\"phui-timeline-icon-fill\"\u003e\u003cspan class=\"visual-only phui-icon-view phui-font-fa fa-link phui-timeline-icon\" data-meta=\"0_772\" aria-hidden=\"true\"\u003e\u003c\/span\u003e\u003c\/span\u003e\u003ca href=\"\/p\/DannyS712\/\" class=\"phui-handle phui-link-person\" data-sigil=\"hovercard\" data-meta=\"0_216\"\u003eDannyS712\u003c\/a\u003e added a project: \u003ca href=\"\/tag\/mediawiki-core-hooks\/\" class=\"phui-handle\" data-sigil=\"hovercard\" data-meta=\"0_217\"\u003eMediaWiki-Core-Hooks\u003c\/a\u003e.\u003cspan class=\"phui-timeline-extra\"\u003e\u003ca href=\"#6048624\" data-sigil=\"has-tooltip\" data-meta=\"0_771\"\u003e\u003cspan class=\"screen-only\"\u003eApr 11 2020, 10:39 AM\u003c\/span\u003e\u003cspan class=\"print-only\" aria-hidden=\"true\"\u003e2020-04-11 10:39:32 (UTC+0)\u003c\/span\u003e\u003c\/a\u003e\u003c\/span\u003e\u003c\/div\u003e\u003c\/div\u003e\u003c\/div\u003e\u003c\/div\u003e\u003c\/div\u003e\u003cdiv class=\"phui-timeline-event-view phui-timeline-spacer\"\u003e\u003c\/div\u003e\u003cdiv class=\"phui-timeline-shell\" data-sigil=\"transaction anchor-container\" data-meta=\"0_782\"\u003e\u003cdiv class=\"phui-timeline-event-view phui-timeline-major-event\"\u003e\u003cdiv class=\"phui-timeline-content\"\u003e\u003ca style=\"background-image: url(https:\/\/phab.wmfusercontent.org\/file\/data\/6vn6slgby7ia62ouikut\/PHID-FILE-ay56qvafgaxajuctgtw3\/profile)\" class=\"visual-only phui-timeline-image\" href=\"\/p\/gerritbot\/\" aria-hidden=\"true\"\u003e\u003c\/a\u003e\u003cdiv class=\"phui-timeline-wedge\" style=\"\"\u003e\u003c\/div\u003e\u003cdiv class=\"phui-timeline-group\"\u003e\u003cdiv class=\"phui-timeline-inner-content\"\u003e\u003ca name=\"6064776\" id=\"6064776\" class=\"phabricator-anchor-view\"\u003e\u003c\/a\u003e\u003cdiv class=\"phui-timeline-title phui-timeline-title-with-icon phui-timeline-title-with-menu\"\u003e\u003cspan class=\"phui-timeline-icon-fill\"\u003e\u003cspan class=\"visual-only phui-icon-view phui-font-fa fa-comment phui-timeline-icon\" data-meta=\"0_781\" aria-hidden=\"true\"\u003e\u003c\/span\u003e\u003c\/span\u003e\u003ca href=\"\/p\/gerritbot\/\" class=\"phui-handle phui-link-person\" data-sigil=\"hovercard\" data-meta=\"0_218\"\u003egerritbot\u003c\/a\u003e added a comment.\u003cspan class=\"phui-timeline-extra\"\u003e\u003ca href=\"#6064776\" data-sigil=\"has-tooltip\" data-meta=\"0_780\"\u003e\u003cspan class=\"screen-only\"\u003eApr 17 2020, 6:04 AM\u003c\/span\u003e\u003cspan class=\"print-only\" aria-hidden=\"true\"\u003e2020-04-17 06:04:35 (UTC+0)\u003c\/span\u003e\u003c\/a\u003e\u003c\/span\u003e\u003c\/div\u003e\u003ca href=\"#\" class=\"phui-timeline-menu\" aria-haspopup=\"true\" aria-expanded=\"false\" data-sigil=\"phui-dropdown-menu\" data-meta=\"0_778\"\u003e\u003cspan class=\"aural-only\"\u003eComment Actions\u003c\/span\u003e\u003cspan class=\"visual-only phui-icon-view phui-font-fa fa-caret-down\" data-meta=\"0_779\" aria-hidden=\"true\"\u003e\u003c\/span\u003e\u003c\/a\u003e\u003cdiv class=\"phui-timeline-core-content\"\u003e\u003cspan class=\"transaction-comment\" data-sigil=\"transaction-comment\" data-meta=\"0_219\"\u003e\u003cdiv class=\"phabricator-remarkup\"\u003e\u003cp\u003eChange 571297 \u003cstrong\u003emerged\u003c\/strong\u003e by jenkins-bot:\u003cbr \/\u003e\n[mediawiki\/core@master] Hook Container\u003c\/p\u003e\n\n\u003cp\u003e\u003ca href=\"https:\/\/gerrit.wikimedia.org\/r\/571297\" class=\"remarkup-link\" target=\"_blank\" rel=\"noreferrer\"\u003ehttps:\/\/gerrit.wikimedia.org\/r\/571297\u003c\/a\u003e\u003c\/p\u003e\u003c\/div\u003e\u003c\/span\u003e\u003c\/div\u003e\u003c\/div\u003e\u003c\/div\u003e\u003c\/div\u003e\u003c\/div\u003e\u003c\/div\u003e\u003cdiv class=\"phui-timeline-event-view phui-timeline-spacer\"\u003e\u003c\/div\u003e\u003cdiv class=\"phui-timeline-shell\" data-sigil=\"transaction anchor-container\" data-meta=\"0_785\"\u003e\u003cdiv class=\"phui-timeline-event-view phui-timeline-minor-event\"\u003e\u003cdiv class=\"phui-timeline-content\"\u003e\u003ca style=\"background-image: url(https:\/\/phab.wmfusercontent.org\/file\/data\/l2cg2zimvt2uq6xna6zg\/PHID-FILE-it2g7whiwxxkzdfzans5\/profile)\" class=\"visual-only phui-timeline-image\" href=\"\/p\/Lucas_Werkmeister_WMDE\/\" aria-hidden=\"true\"\u003e\u003c\/a\u003e\u003cdiv class=\"phui-timeline-wedge\" style=\"\"\u003e\u003c\/div\u003e\u003cdiv class=\"phui-timeline-group\"\u003e\u003ca name=\"6065433\" id=\"6065433\" class=\"phabricator-anchor-view\"\u003e\u003c\/a\u003e\u003cdiv class=\"phui-timeline-title phui-timeline-title-with-icon\"\u003e\u003cspan class=\"phui-timeline-icon-fill\"\u003e\u003cspan class=\"visual-only phui-icon-view phui-font-fa fa-link phui-timeline-icon\" data-meta=\"0_784\" aria-hidden=\"true\"\u003e\u003c\/span\u003e\u003c\/span\u003e\u003ca href=\"\/p\/Lucas_Werkmeister_WMDE\/\" class=\"phui-handle phui-link-person\" data-sigil=\"hovercard\" data-meta=\"0_220\"\u003eLucas_Werkmeister_WMDE\u003c\/a\u003e mentioned this in \u003ca href=\"\/T250480\" class=\"phui-handle handle-status-closed\" data-sigil=\"hovercard\" data-meta=\"0_221\"\u003eT250480: Wikibase CI fails with \u201cReflectionException: Property handlers does not exist\u201d in LexemeDiffVisualizerIntegrationTest\u003c\/a\u003e.\u003cspan class=\"phui-timeline-extra\"\u003e\u003ca href=\"#6065433\" data-sigil=\"has-tooltip\" data-meta=\"0_783\"\u003e\u003cspan class=\"screen-only\"\u003eApr 17 2020, 12:24 PM\u003c\/span\u003e\u003cspan class=\"print-only\" aria-hidden=\"true\"\u003e2020-04-17 12:24:16 (UTC+0)\u003c\/span\u003e\u003c\/a\u003e\u003c\/span\u003e\u003c\/div\u003e\u003c\/div\u003e\u003c\/div\u003e\u003c\/div\u003e\u003c\/div\u003e\u003cdiv class=\"phui-timeline-event-view phui-timeline-spacer\"\u003e\u003c\/div\u003e\u003cdiv class=\"phui-timeline-shell-removed phui-timeline-shell phui-timeline-grey\" data-sigil=\"transaction anchor-container\" data-meta=\"0_790\"\u003e\u003cdiv class=\"phui-timeline-event-view phui-timeline-major-event\"\u003e\u003cdiv class=\"phui-timeline-content\"\u003e\u003ca style=\"background-image: url(https:\/\/phab.wmfusercontent.org\/file\/data\/gmb3bohtvy22zzvlaje7\/PHID-FILE-zcwqxhkprdlj5oadwhav\/profile)\" class=\"visual-only phui-timeline-image\" href=\"\/p\/Reedy\/\" aria-hidden=\"true\"\u003e\u003c\/a\u003e\u003cdiv class=\"phui-timeline-badges\"\u003e\u003cul class=\"phui-badge-flex-view grouped flex-view-collapsed \"\u003e\u003cli class=\"phui-badge-flex-item\"\u003e\u003ca class=\"phui-badge-mini phui-badge-mini-indigo \" href=\"\/badges\/view\/6\/\" data-sigil=\"has-tooltip\" data-meta=\"0_788\"\u003e\u003cspan class=\"visual-only phui-icon-view phui-font-fa fa-rebel\" data-meta=\"0_789\" aria-hidden=\"true\"\u003e\u003c\/span\u003e\u003c\/a\u003e\u003c\/li\u003e\u003c\/ul\u003e\u003c\/div\u003e\u003cdiv class=\"phui-timeline-wedge\" style=\"\"\u003e\u003c\/div\u003e\u003cdiv class=\"phui-timeline-group\"\u003e\u003cdiv class=\"phui-timeline-inner-content\"\u003e\u003ca name=\"6065997\" id=\"6065997\" class=\"phabricator-anchor-view\"\u003e\u003c\/a\u003e\u003cdiv class=\"phui-timeline-title phui-timeline-title-with-icon\"\u003e\u003cspan class=\"phui-timeline-icon-fill\"\u003e\u003cspan class=\"visual-only phui-icon-view phui-font-fa fa-user-plus phui-timeline-icon\" data-meta=\"0_787\" aria-hidden=\"true\"\u003e\u003c\/span\u003e\u003c\/span\u003e\u003ca href=\"\/p\/Reedy\/\" class=\"phui-handle phui-link-person\" data-sigil=\"hovercard\" data-meta=\"0_223\"\u003eReedy\u003c\/a\u003e subscribed.\u003cspan class=\"phui-timeline-extra\"\u003e\u003ca href=\"#6065997\" data-sigil=\"has-tooltip\" data-meta=\"0_786\"\u003e\u003cspan class=\"screen-only\"\u003eApr 17 2020, 4:06 PM\u003c\/span\u003e\u003cspan class=\"print-only\" aria-hidden=\"true\"\u003e2020-04-17 16:06:17 (UTC+0)\u003c\/span\u003e\u003c\/a\u003e\u003c\/span\u003e\u003c\/div\u003e\u003cdiv class=\"phui-timeline-core-content\"\u003e\u003cspan class=\"comment-deleted\" data-sigil=\"transaction-comment\" data-meta=\"0_222\"\u003eThis comment was removed by \u003ca href=\"\/p\/Reedy\/\" class=\"phui-handle phui-link-person\"\u003eReedy\u003c\/a\u003e.\u003c\/span\u003e\u003c\/div\u003e\u003c\/div\u003e\u003c\/div\u003e\u003c\/div\u003e\u003c\/div\u003e\u003c\/div\u003e\u003cdiv class=\"phui-timeline-event-view phui-timeline-spacer\"\u003e\u003c\/div\u003e\u003cdiv class=\"phui-timeline-shell\" data-sigil=\"transaction anchor-container\" data-meta=\"0_793\"\u003e\u003cdiv class=\"phui-timeline-event-view phui-timeline-minor-event\"\u003e\u003cdiv class=\"phui-timeline-content\"\u003e\u003ca style=\"background-image: url(https:\/\/phab.wmfusercontent.org\/file\/data\/247abt7phqlbitgglyxa\/PHID-FILE-tx36db6dprvfuxu72bcj\/alphanumeric_aleo-white_D.png-_ec9da1-0%2C0%2C0%2C0.png)\" class=\"visual-only phui-timeline-image\" href=\"\/p\/Daimona\/\" aria-hidden=\"true\"\u003e\u003c\/a\u003e\u003cdiv class=\"phui-timeline-wedge\" style=\"\"\u003e\u003c\/div\u003e\u003cdiv class=\"phui-timeline-group\"\u003e\u003ca name=\"6066032\" id=\"6066032\" class=\"phabricator-anchor-view\"\u003e\u003c\/a\u003e\u003cdiv class=\"phui-timeline-title phui-timeline-title-with-icon\"\u003e\u003cspan class=\"phui-timeline-icon-fill\"\u003e\u003cspan class=\"visual-only phui-icon-view phui-font-fa fa-link phui-timeline-icon\" data-meta=\"0_792\" aria-hidden=\"true\"\u003e\u003c\/span\u003e\u003c\/span\u003e\u003ca href=\"\/p\/Daimona\/\" class=\"phui-handle phui-link-person\" data-sigil=\"hovercard\" data-meta=\"0_224\"\u003eDaimona\u003c\/a\u003e mentioned this in \u003ca href=\"\/T250499\" class=\"phui-handle\" data-sigil=\"hovercard\" data-meta=\"0_225\"\u003eT250499: Make taint-check understand HookContainer\u003c\/a\u003e.\u003cspan class=\"phui-timeline-extra\"\u003e\u003ca href=\"#6066032\" data-sigil=\"has-tooltip\" data-meta=\"0_791\"\u003e\u003cspan class=\"screen-only\"\u003eApr 17 2020, 4:11 PM\u003c\/span\u003e\u003cspan class=\"print-only\" aria-hidden=\"true\"\u003e2020-04-17 16:11:08 (UTC+0)\u003c\/span\u003e\u003c\/a\u003e\u003c\/span\u003e\u003c\/div\u003e\u003c\/div\u003e\u003c\/div\u003e\u003c\/div\u003e\u003c\/div\u003e\u003cdiv class=\"phui-timeline-event-view phui-timeline-spacer\"\u003e\u003c\/div\u003e\u003cdiv class=\"phui-timeline-shell\" data-sigil=\"transaction anchor-container\" data-meta=\"0_802\"\u003e\u003cdiv class=\"phui-timeline-event-view phui-timeline-major-event\"\u003e\u003cdiv class=\"phui-timeline-content\"\u003e\u003ca style=\"background-image: url(https:\/\/phab.wmfusercontent.org\/file\/data\/z67mikd4lwdetm774u5v\/PHID-FILE-wzypambajaxwezctdezx\/profile-livejournal.jpg)\" class=\"visual-only phui-timeline-image\" href=\"\/p\/cscott\/\" aria-hidden=\"true\"\u003e\u003c\/a\u003e\u003cdiv class=\"phui-timeline-wedge\" style=\"\"\u003e\u003c\/div\u003e\u003cdiv class=\"phui-timeline-group\"\u003e\u003cdiv class=\"phui-timeline-inner-content\"\u003e\u003ca name=\"6066217\" id=\"6066217\" class=\"phabricator-anchor-view\"\u003e\u003c\/a\u003e\u003cdiv class=\"phui-timeline-title phui-timeline-title-with-icon phui-timeline-title-with-menu\"\u003e\u003cspan class=\"phui-timeline-icon-fill\"\u003e\u003cspan class=\"visual-only phui-icon-view phui-font-fa fa-user-plus phui-timeline-icon\" data-meta=\"0_801\" aria-hidden=\"true\"\u003e\u003c\/span\u003e\u003c\/span\u003e\u003ca href=\"\/p\/cscott\/\" class=\"phui-handle phui-link-person\" data-sigil=\"hovercard\" data-meta=\"0_227\"\u003ecscott\u003c\/a\u003e subscribed.\u003cspan class=\"phui-timeline-extra\"\u003e\u003ca href=\"#6066217\" data-sigil=\"has-tooltip\" data-meta=\"0_800\"\u003e\u003cspan class=\"screen-only\"\u003eApr 17 2020, 4:46 PM\u003c\/span\u003e\u003cspan class=\"print-only\" aria-hidden=\"true\"\u003e2020-04-17 16:46:23 (UTC+0)\u003c\/span\u003e\u003c\/a\u003e\u003c\/span\u003e\u003c\/div\u003e\u003ca href=\"#\" class=\"phui-timeline-menu\" aria-haspopup=\"true\" aria-expanded=\"false\" data-sigil=\"phui-dropdown-menu\" data-meta=\"0_798\"\u003e\u003cspan class=\"aural-only\"\u003eComment Actions\u003c\/span\u003e\u003cspan class=\"visual-only phui-icon-view phui-font-fa fa-caret-down\" data-meta=\"0_799\" aria-hidden=\"true\"\u003e\u003c\/span\u003e\u003c\/a\u003e\u003cdiv class=\"phui-timeline-core-content\"\u003e\u003cspan class=\"transaction-comment\" data-sigil=\"transaction-comment\" data-meta=\"0_226\"\u003e\u003cdiv class=\"phabricator-remarkup\"\u003e\u003cp\u003eI found another minor regression:\u003cbr \/\u003e\n\u003ca href=\"https:\/\/gerrit.wikimedia.org\/r\/#\/c\/mediawiki\/extensions\/WikiArticleFeeds\/+\/589629\/1..2\/WikiArticleFeeds.php\" class=\"remarkup-link\" target=\"_blank\" rel=\"noreferrer\"\u003ehttps:\/\/gerrit.wikimedia.org\/r\/#\/c\/mediawiki\/extensions\/WikiArticleFeeds\/+\/589629\/1..2\/WikiArticleFeeds.php\u003c\/a\u003e\u003c\/p\u003e\n\n\u003cp\u003eIt appears that prior to \u003ca href=\"\/rMW0adc5f342888740e1b611f95f1474be329eae817\" class=\"phui-tag-view phui-tag-type-object \" data-sigil=\"hovercard\" data-meta=\"0_71\"\u003e\u003cspan class=\"phui-tag-core phui-tag-color-object\"\u003e0adc5f342888740e1b611f95f1474be329eae817\u003c\/span\u003e\u003c\/a\u003e landing, the Hook system would accept a hook of the form \u003ctt class=\"remarkup-monospaced\"\u003e[ $object, 'ClassName::methodName' ]\u003c\/tt\u003e for virtual methods, but afterwards (as show in the jenkins logs for PS1 of the above patch) this leads to an error trying to resolve \u003ctt class=\"remarkup-monospaced\"\u003eClassName::ClassName::methodName\u003c\/tt\u003e.\u003c\/p\u003e\n\n\u003cp\u003eSeems straightforward to fix by using \u003ctt class=\"remarkup-monospaced\"\u003e[ $object, 'methodName' ]\u003c\/tt\u003e as the hook, which ought to work for both the old hook system and the new one, but I figured it was worth mentioning in case it makes sense to add a little bit of backwards-compat code to handle this case.\u003c\/p\u003e\u003c\/div\u003e\u003c\/span\u003e\u003c\/div\u003e\u003c\/div\u003e\u003c\/div\u003e\u003c\/div\u003e\u003c\/div\u003e\u003c\/div\u003e\u003cdiv class=\"phui-timeline-event-view phui-timeline-spacer\"\u003e\u003c\/div\u003e\u003cdiv class=\"phui-timeline-shell\" data-sigil=\"transaction anchor-container\" data-meta=\"0_811\"\u003e\u003cdiv class=\"phui-timeline-event-view phui-timeline-major-event\"\u003e\u003cdiv class=\"phui-timeline-content\"\u003e\u003ca style=\"background-image: url(https:\/\/phab.wmfusercontent.org\/file\/data\/6vn6slgby7ia62ouikut\/PHID-FILE-ay56qvafgaxajuctgtw3\/profile)\" class=\"visual-only phui-timeline-image\" href=\"\/p\/gerritbot\/\" aria-hidden=\"true\"\u003e\u003c\/a\u003e\u003cdiv class=\"phui-timeline-wedge\" style=\"\"\u003e\u003c\/div\u003e\u003cdiv class=\"phui-timeline-group\"\u003e\u003cdiv class=\"phui-timeline-inner-content\"\u003e\u003ca name=\"6073896\" id=\"6073896\" class=\"phabricator-anchor-view\"\u003e\u003c\/a\u003e\u003cdiv class=\"phui-timeline-title phui-timeline-title-with-icon phui-timeline-title-with-menu\"\u003e\u003cspan class=\"phui-timeline-icon-fill\"\u003e\u003cspan class=\"visual-only phui-icon-view phui-font-fa fa-comment phui-timeline-icon\" data-meta=\"0_810\" aria-hidden=\"true\"\u003e\u003c\/span\u003e\u003c\/span\u003e\u003ca href=\"\/p\/gerritbot\/\" class=\"phui-handle phui-link-person\" data-sigil=\"hovercard\" data-meta=\"0_228\"\u003egerritbot\u003c\/a\u003e added a comment.\u003cspan class=\"phui-timeline-extra\"\u003e\u003ca href=\"#6073896\" data-sigil=\"has-tooltip\" data-meta=\"0_809\"\u003e\u003cspan class=\"screen-only\"\u003eApr 21 2020, 12:07 AM\u003c\/span\u003e\u003cspan class=\"print-only\" aria-hidden=\"true\"\u003e2020-04-21 00:07:45 (UTC+0)\u003c\/span\u003e\u003c\/a\u003e\u003c\/span\u003e\u003c\/div\u003e\u003ca href=\"#\" class=\"phui-timeline-menu\" aria-haspopup=\"true\" aria-expanded=\"false\" data-sigil=\"phui-dropdown-menu\" data-meta=\"0_807\"\u003e\u003cspan class=\"aural-only\"\u003eComment Actions\u003c\/span\u003e\u003cspan class=\"visual-only phui-icon-view phui-font-fa fa-caret-down\" data-meta=\"0_808\" aria-hidden=\"true\"\u003e\u003c\/span\u003e\u003c\/a\u003e\u003cdiv class=\"phui-timeline-core-content\"\u003e\u003cspan class=\"transaction-comment\" data-sigil=\"transaction-comment\" data-meta=\"0_229\"\u003e\u003cdiv class=\"phabricator-remarkup\"\u003e\u003cp\u003eChange 574266 \u003cstrong\u003emerged\u003c\/strong\u003e by jenkins-bot:\u003cbr \/\u003e\n[mediawiki\/core@master] Automatically generated hook interfaces\u003c\/p\u003e\n\n\u003cp\u003e\u003ca href=\"https:\/\/gerrit.wikimedia.org\/r\/574266\" class=\"remarkup-link\" target=\"_blank\" rel=\"noreferrer\"\u003ehttps:\/\/gerrit.wikimedia.org\/r\/574266\u003c\/a\u003e\u003c\/p\u003e\u003c\/div\u003e\u003c\/span\u003e\u003c\/div\u003e\u003c\/div\u003e\u003c\/div\u003e\u003c\/div\u003e\u003c\/div\u003e\u003c\/div\u003e\u003cdiv class=\"phui-timeline-event-view phui-timeline-spacer\"\u003e\u003c\/div\u003e\u003cdiv class=\"phui-timeline-shell\" data-sigil=\"transaction anchor-container\" data-meta=\"0_820\"\u003e\u003cdiv class=\"phui-timeline-event-view phui-timeline-major-event\"\u003e\u003cdiv class=\"phui-timeline-content\"\u003e\u003ca style=\"background-image: url(https:\/\/phab.wmfusercontent.org\/file\/data\/6vn6slgby7ia62ouikut\/PHID-FILE-ay56qvafgaxajuctgtw3\/profile)\" class=\"visual-only phui-timeline-image\" href=\"\/p\/gerritbot\/\" aria-hidden=\"true\"\u003e\u003c\/a\u003e\u003cdiv class=\"phui-timeline-wedge\" style=\"\"\u003e\u003c\/div\u003e\u003cdiv class=\"phui-timeline-group\"\u003e\u003cdiv class=\"phui-timeline-inner-content\"\u003e\u003ca name=\"6073901\" id=\"6073901\" class=\"phabricator-anchor-view\"\u003e\u003c\/a\u003e\u003cdiv class=\"phui-timeline-title phui-timeline-title-with-icon phui-timeline-title-with-menu\"\u003e\u003cspan class=\"phui-timeline-icon-fill\"\u003e\u003cspan class=\"visual-only phui-icon-view phui-font-fa fa-comment phui-timeline-icon\" data-meta=\"0_819\" aria-hidden=\"true\"\u003e\u003c\/span\u003e\u003c\/span\u003e\u003ca href=\"\/p\/gerritbot\/\" class=\"phui-handle phui-link-person\" data-sigil=\"hovercard\" data-meta=\"0_230\"\u003egerritbot\u003c\/a\u003e added a comment.\u003cspan class=\"phui-timeline-extra\"\u003e\u003ca href=\"#6073901\" data-sigil=\"has-tooltip\" data-meta=\"0_818\"\u003e\u003cspan class=\"screen-only\"\u003eApr 21 2020, 12:09 AM\u003c\/span\u003e\u003cspan class=\"print-only\" aria-hidden=\"true\"\u003e2020-04-21 00:09:10 (UTC+0)\u003c\/span\u003e\u003c\/a\u003e\u003c\/span\u003e\u003c\/div\u003e\u003ca href=\"#\" class=\"phui-timeline-menu\" aria-haspopup=\"true\" aria-expanded=\"false\" data-sigil=\"phui-dropdown-menu\" data-meta=\"0_816\"\u003e\u003cspan class=\"aural-only\"\u003eComment Actions\u003c\/span\u003e\u003cspan class=\"visual-only phui-icon-view phui-font-fa fa-caret-down\" data-meta=\"0_817\" aria-hidden=\"true\"\u003e\u003c\/span\u003e\u003c\/a\u003e\u003cdiv class=\"phui-timeline-core-content\"\u003e\u003cspan class=\"transaction-comment\" data-sigil=\"transaction-comment\" data-meta=\"0_231\"\u003e\u003cdiv class=\"phabricator-remarkup\"\u003e\u003cp\u003eChange 588936 had a related patch set uploaded (by DannyS712; owner: DannyS712):\u003cbr \/\u003e\n[mediawiki\/core@master] Update hook interfaces for recent additions and deprecations\u003c\/p\u003e\n\n\u003cp\u003e\u003ca href=\"https:\/\/gerrit.wikimedia.org\/r\/588936\" class=\"remarkup-link\" target=\"_blank\" rel=\"noreferrer\"\u003ehttps:\/\/gerrit.wikimedia.org\/r\/588936\u003c\/a\u003e\u003c\/p\u003e\u003c\/div\u003e\u003c\/span\u003e\u003c\/div\u003e\u003c\/div\u003e\u003c\/div\u003e\u003c\/div\u003e\u003c\/div\u003e\u003c\/div\u003e"},"javelin_metadata":[{"hovercardSpec":{"objectPHID":"PHID-USER-k6tmz5ylx4rzfl3bitse"}},{"hovercardSpec":{"objectPHID":"PHID-TASK-gdzyw267wfavjfuqhmus"}},{"hovercardSpec":{"objectPHID":"PHID-USER-uqcn2l4ng4murmyfnvyp","contextPHID":"PHID-TASK-gdzyw267wfavjfuqhmus"}},{"hovercardSpec":{"objectPHID":"PHID-TASK-ern2josb5jwgl3a3kup3"}},{"hovercardSpec":{"objectPHID":"PHID-TASK-rorb4cpnc6lgzis55wa5"}},{"hovercardSpec":{"objectPHID":"PHID-TASK-ptxgtgkei6ywg6lkvi3g"}},{"hovercardSpec":{"objectPHID":"PHID-TASK-jwekstoldkzc7w7krj2p"}},{"hovercardSpec":{"objectPHID":"PHID-TASK-gdzyw267wfavjfuqhmus"}},{"hovercardSpec":{"objectPHID":"PHID-TASK-jwekstoldkzc7w7krj2p"}},{"hovercardSpec":{"objectPHID":"PHID-TASK-jwekstoldkzc7w7krj2p"}},{"hovercardSpec":{"objectPHID":"PHID-TASK-jwekstoldkzc7w7krj2p"}},{"hovercardSpec":{"objectPHID":"PHID-USER-sai77mtxmpqnm6pycyvz","contextPHID":"PHID-TASK-gdzyw267wfavjfuqhmus"}},{"hovercardSpec":{"objectPHID":"PHID-TASK-rorb4cpnc6lgzis55wa5"}},{"hovercardSpec":{"objectPHID":"PHID-TASK-ptxgtgkei6ywg6lkvi3g"}},{"hovercardSpec":{"objectPHID":"PHID-TASK-gdzyw267wfavjfuqhmus"}},{"hovercardSpec":{"objectPHID":"PHID-USER-sai77mtxmpqnm6pycyvz","contextPHID":"PHID-TASK-gdzyw267wfavjfuqhmus"}},{"hovercardSpec":{"objectPHID":"PHID-TASK-gdzyw267wfavjfuqhmus"}},{"hovercardSpec":{"objectPHID":"PHID-USER-5dqihbanu3caaj7pigif","contextPHID":"PHID-TASK-gdzyw267wfavjfuqhmus"}},{"hovercardSpec":{"objectPHID":"PHID-TASK-gdzyw267wfavjfuqhmus"}},{"hovercardSpec":{"objectPHID":"PHID-USER-t5nk47f4lpp4uyefscqp","contextPHID":"PHID-TASK-gdzyw267wfavjfuqhmus"}},{"hovercardSpec":{"objectPHID":"PHID-TASK-gdzyw267wfavjfuqhmus"}},{"hovercardSpec":{"objectPHID":"PHID-USER-t5nk47f4lpp4uyefscqp","contextPHID":"PHID-TASK-gdzyw267wfavjfuqhmus"}},{"hovercardSpec":{"objectPHID":"PHID-TASK-gdzyw267wfavjfuqhmus"}},{"hovercardSpec":{"objectPHID":"PHID-USER-uqcn2l4ng4murmyfnvyp","contextPHID":"PHID-TASK-gdzyw267wfavjfuqhmus"}},{"hovercardSpec":{"objectPHID":"PHID-TASK-gdzyw267wfavjfuqhmus"}},{"hovercardSpec":{"objectPHID":"PHID-TASK-gdzyw267wfavjfuqhmus"}},{"hovercardSpec":{"objectPHID":"PHID-TASK-gdzyw267wfavjfuqhmus"}},{"hovercardSpec":{"objectPHID":"PHID-USER-5dqihbanu3caaj7pigif","contextPHID":"PHID-TASK-gdzyw267wfavjfuqhmus"}},{"hovercardSpec":{"objectPHID":"PHID-TASK-gdzyw267wfavjfuqhmus"}},{"hovercardSpec":{"objectPHID":"PHID-USER-uqcn2l4ng4murmyfnvyp","contextPHID":"PHID-TASK-gdzyw267wfavjfuqhmus"}},{"hovercardSpec":{"objectPHID":"PHID-TASK-gdzyw267wfavjfuqhmus"}},{"hovercardSpec":{"objectPHID":"PHID-TASK-gdzyw267wfavjfuqhmus"}},{"hovercardSpec":{"objectPHID":"PHID-TASK-gdzyw267wfavjfuqhmus"}},{"hovercardSpec":{"objectPHID":"PHID-TASK-gdzyw267wfavjfuqhmus"}},{"hovercardSpec":{"objectPHID":"PHID-USER-5dqihbanu3caaj7pigif","contextPHID":"PHID-TASK-gdzyw267wfavjfuqhmus"}},{"hovercardSpec":{"objectPHID":"PHID-USER-uqcn2l4ng4murmyfnvyp","contextPHID":"PHID-TASK-gdzyw267wfavjfuqhmus"}},{"hovercardSpec":{"objectPHID":"PHID-TASK-jwekstoldkzc7w7krj2p"}},{"hovercardSpec":{"objectPHID":"PHID-TASK-gdzyw267wfavjfuqhmus"}},{"hovercardSpec":{"objectPHID":"PHID-TASK-gdzyw267wfavjfuqhmus"}},{"hovercardSpec":{"objectPHID":"PHID-TASK-gdzyw267wfavjfuqhmus"}},{"hovercardSpec":{"objectPHID":"PHID-USER-k6tmz5ylx4rzfl3bitse","contextPHID":"PHID-TASK-gdzyw267wfavjfuqhmus"}},{"hovercardSpec":{"objectPHID":"PHID-USER-5dqihbanu3caaj7pigif","contextPHID":"PHID-TASK-gdzyw267wfavjfuqhmus"}},{"hovercardSpec":{"objectPHID":"PHID-USER-5dqihbanu3caaj7pigif","contextPHID":"PHID-TASK-gdzyw267wfavjfuqhmus"}},{"hovercardSpec":{"objectPHID":"PHID-TASK-gdzyw267wfavjfuqhmus"}},{"hovercardSpec":{"objectPHID":"PHID-TASK-gdzyw267wfavjfuqhmus"}},{"hovercardSpec":{"objectPHID":"PHID-USER-k6tmz5ylx4rzfl3bitse","contextPHID":"PHID-TASK-gdzyw267wfavjfuqhmus"}},{"hovercardSpec":{"objectPHID":"PHID-USER-uqcn2l4ng4murmyfnvyp","contextPHID":"PHID-TASK-gdzyw267wfavjfuqhmus"}},{"hovercardSpec":{"objectPHID":"PHID-TASK-gdzyw267wfavjfuqhmus"}},{"hovercardSpec":{"objectPHID":"PHID-USER-ctchvhisqfvk4rz7nt7d","contextPHID":"PHID-TASK-gdzyw267wfavjfuqhmus"}},{"hovercardSpec":{"objectPHID":"PHID-TASK-gdzyw267wfavjfuqhmus"}},{"hovercardSpec":{"objectPHID":"PHID-TASK-gdzyw267wfavjfuqhmus"}},{"hovercardSpec":{"objectPHID":"PHID-PSTE-p6efneichixsxsh7d2gy"}},{"hovercardSpec":{"objectPHID":"PHID-USER-ydswvwhh5pm4lshahjje","contextPHID":"PHID-TASK-gdzyw267wfavjfuqhmus"}},{"hovercardSpec":{"objectPHID":"PHID-TASK-gdzyw267wfavjfuqhmus"}},{"hovercardSpec":{"objectPHID":"PHID-TASK-gdzyw267wfavjfuqhmus"}},{"hovercardSpec":{"objectPHID":"PHID-TASK-gdzyw267wfavjfuqhmus"}},{"hovercardSpec":{"objectPHID":"PHID-TASK-jwekstoldkzc7w7krj2p"}},{"hovercardSpec":{"objectPHID":"PHID-TASK-ern2josb5jwgl3a3kup3"}},{"hovercardSpec":{"objectPHID":"PHID-TASK-ern2josb5jwgl3a3kup3"}},{"hovercardSpec":{"objectPHID":"PHID-USER-5dqihbanu3caaj7pigif","contextPHID":"PHID-TASK-gdzyw267wfavjfuqhmus"}},{"hovercardSpec":{"objectPHID":"PHID-USER-5dqihbanu3caaj7pigif","contextPHID":"PHID-TASK-gdzyw267wfavjfuqhmus"}},{"hovercardSpec":{"objectPHID":"PHID-USER-5dqihbanu3caaj7pigif","contextPHID":"PHID-TASK-gdzyw267wfavjfuqhmus"}},{"hovercardSpec":{"objectPHID":"PHID-TASK-gdzyw267wfavjfuqhmus"}},{"hovercardSpec":{"objectPHID":"PHID-USER-k6tmz5ylx4rzfl3bitse","contextPHID":"PHID-TASK-gdzyw267wfavjfuqhmus"}},{"hovercardSpec":{"objectPHID":"PHID-TASK-gdzyw267wfavjfuqhmus"}},{"hovercardSpec":{"objectPHID":"PHID-USER-k6tmz5ylx4rzfl3bitse","contextPHID":"PHID-TASK-gdzyw267wfavjfuqhmus"}},{"hovercardSpec":{"objectPHID":"PHID-TASK-gdzyw267wfavjfuqhmus"}},{"hovercardSpec":{"objectPHID":"PHID-USER-uqcn2l4ng4murmyfnvyp","contextPHID":"PHID-TASK-gdzyw267wfavjfuqhmus"}},{"hovercardSpec":{"objectPHID":"PHID-TASK-gdzyw267wfavjfuqhmus"}},{"hovercardSpec":{"objectPHID":"PHID-USER-5dqihbanu3caaj7pigif","contextPHID":"PHID-TASK-gdzyw267wfavjfuqhmus"}},{"hovercardSpec":{"objectPHID":"PHID-TASK-gdzyw267wfavjfuqhmus"}},{"hovercardSpec":{"objectPHID":"PHID-CMIT-kzd4ccbl7ufyqgxbducj"}},{"hovercardSpec":{"objectPHID":"PHID-USER-k6tmz5ylx4rzfl3bitse"}},{"hovercardSpec":{"objectPHID":"PHID-USER-dpu5hmqvprhycqlkdzrk"}},{"hovercardSpec":{"objectPHID":"PHID-USER-c4xszutxtrvtj73h3rns"}},{"hovercardSpec":{"objectPHID":"PHID-USER-uqcn2l4ng4murmyfnvyp"}},{"phid":"PHID-XACT-TASK-hnssrwsb5q5kpz4"},{"hovercardSpec":{"objectPHID":"PHID-USER-k6tmz5ylx4rzfl3bitse"}},{"phid":"PHID-XACT-TASK-hayndf7q62kzfwv"},{"hovercardSpec":{"objectPHID":"PHID-USER-k6tmz5ylx4rzfl3bitse"}},{"hovercardSpec":{"objectPHID":"PHID-USER-k6tmz5ylx4rzfl3bitse"}},{"phid":"PHID-XACT-TASK-gmmug6z3n2hogwq"},{"hovercardSpec":{"objectPHID":"PHID-USER-uqcn2l4ng4murmyfnvyp"}},{"phid":"PHID-XACT-TASK-cwnkbggrnbiculo"},{"hovercardSpec":{"objectPHID":"PHID-USER-sai77mtxmpqnm6pycyvz"}},{"phid":"PHID-XACT-TASK-l6exy33mmdr2gjx"},{"hovercardSpec":{"objectPHID":"PHID-USER-uqcn2l4ng4murmyfnvyp"}},{"phid":"PHID-XACT-TASK-xyakswzwwyhctfu"},{"hovercardSpec":{"objectPHID":"PHID-USER-k6tmz5ylx4rzfl3bitse"}},{"phid":"PHID-XACT-TASK-ch7xae4kgeq3tua"},{"hovercardSpec":{"objectPHID":"PHID-USER-k6tmz5ylx4rzfl3bitse"}},{"phid":"PHID-XACT-TASK-hffwrr55ce3jnz6"},{"hovercardSpec":{"objectPHID":"PHID-USER-c4xszutxtrvtj73h3rns"}},{"hovercardSpec":{"objectPHID":"PHID-USER-hvywcttgalazbjxfl3tq"}},{"hovercardSpec":{"objectPHID":"PHID-USER-5dqihbanu3caaj7pigif"}},{"hovercardSpec":{"objectPHID":"PHID-USER-5dqihbanu3caaj7pigif"}},{"hovercardSpec":{"objectPHID":"PHID-PROJ-3ddkmewjlbj5m5n7mx5d"}},{"hovercardSpec":{"objectPHID":"PHID-USER-732lqsmz4v6bss3kln2v"}},{"hovercardSpec":{"objectPHID":"PHID-USER-5dqihbanu3caaj7pigif"}},{"hovercardSpec":{"objectPHID":"PHID-PCOL-gdnvii2tziibym5uf7pi"}},{"hovercardSpec":{"objectPHID":"PHID-PCOL-oa6xrkbjkdkxrcft3gwx"}},{"hovercardSpec":{"objectPHID":"PHID-PROJ-fc6tzpgo4uo33xqvhtdj"}},{"hovercardSpec":{"objectPHID":"PHID-USER-7y47cqz6jjpm4y22t4z6"}},{"hovercardSpec":{"objectPHID":"PHID-USER-7y47cqz6jjpm4y22t4z6"}},{"hovercardSpec":{"objectPHID":"PHID-USER-sscimmfqgfuh4pe2kfyw"}},{"hovercardSpec":{"objectPHID":"PHID-USER-k6tmz5ylx4rzfl3bitse"}},{"hovercardSpec":{"objectPHID":"PHID-USER-ilk3nopl66nufkd26tee"}},{"hovercardSpec":{"objectPHID":"PHID-USER-4z6eerx3m7iocsrcpku5"}},{"hovercardSpec":{"objectPHID":"PHID-USER-4z6eerx3m7iocsrcpku5"}},{"hovercardSpec":{"objectPHID":"PHID-USER-khiuzivvgcimpgvedbzf"}},{"hovercardSpec":{"objectPHID":"PHID-USER-kxyuujnpfeyuo2w2bw3s"}},{"phid":"PHID-XACT-TASK-dc7ofrz2eiluy7x"},{"hovercardSpec":{"objectPHID":"PHID-USER-aasrweh54ew7py3agvg2"}},{"hovercardSpec":{"objectPHID":"PHID-USER-hrcsuxxosiyjqpef64tc"}},{"hovercardSpec":{"objectPHID":"PHID-USER-5dqihbanu3caaj7pigif"}},{"phid":"PHID-XACT-TASK-jbewom6yeqoeqtl"},{"phid":"PHID-XACT-TASK-d25ci2aljnzspzg"},{"hovercardSpec":{"objectPHID":"PHID-USER-t5nk47f4lpp4uyefscqp"}},{"hovercardSpec":{"objectPHID":"PHID-USER-uqcn2l4ng4murmyfnvyp"}},{"phid":"PHID-XACT-TASK-ms27e5cx2jtdmd4"},{"hovercardSpec":{"objectPHID":"PHID-USER-uqcn2l4ng4murmyfnvyp"}},{"phid":"PHID-XACT-TASK-i22dgqlstmhzjsu"},{"hovercardSpec":{"objectPHID":"PHID-USER-hvywcttgalazbjxfl3tq"}},{"hovercardSpec":{"objectPHID":"PHID-USER-5dqihbanu3caaj7pigif"}},{"phid":"PHID-XACT-TASK-54l22ozd4tjdvce"},{"hovercardSpec":{"objectPHID":"PHID-USER-5dqihbanu3caaj7pigif"}},{"phid":"PHID-XACT-TASK-3vi4ktzgqyinffu"},{"hovercardSpec":{"objectPHID":"PHID-USER-uqcn2l4ng4murmyfnvyp"}},{"phid":"PHID-XACT-TASK-2xniixwwjqab76c"},{"hovercardSpec":{"objectPHID":"PHID-USER-k6tmz5ylx4rzfl3bitse"}},{"phid":"PHID-XACT-TASK-fomdoufqnp637mu"},{"hovercardSpec":{"objectPHID":"PHID-USER-cc6dswbtmstfsb4ldmit"}},{"hovercardSpec":{"objectPHID":"PHID-USER-5dqihbanu3caaj7pigif"}},{"phid":"PHID-XACT-TASK-lkitswdvtaq2rkp"},{"hovercardSpec":{"objectPHID":"PHID-USER-5dqihbanu3caaj7pigif"}},{"phid":"PHID-XACT-TASK-kzfjdd5x44mg4pw"},{"hovercardSpec":{"objectPHID":"PHID-USER-5dqihbanu3caaj7pigif"}},{"phid":"PHID-XACT-TASK-a4bpmlw5vnndcd3"},{"hovercardSpec":{"objectPHID":"PHID-USER-uqcn2l4ng4murmyfnvyp"}},{"phid":"PHID-XACT-TASK-f4w34cvv3mrmhvt"},{"phid":"PHID-XACT-TASK-2x7oyvzzgncznu3"},{"hovercardSpec":{"objectPHID":"PHID-USER-ctchvhisqfvk4rz7nt7d"}},{"phid":"PHID-XACT-TASK-xlzpiuks3afl5yo"},{"hovercardSpec":{"objectPHID":"PHID-USER-ydswvwhh5pm4lshahjje"}},{"hovercardSpec":{"objectPHID":"PHID-USER-5dqihbanu3caaj7pigif"}},{"phid":"PHID-XACT-TASK-247dlhkzogi2c5q"},{"hovercardSpec":{"objectPHID":"PHID-USER-uqcn2l4ng4murmyfnvyp"}},{"phid":"PHID-XACT-TASK-4fhbywfo66hwchs"},{"phid":"PHID-XACT-TASK-oxy22xximh3osg4"},{"hovercardSpec":{"objectPHID":"PHID-USER-g5rqg2k7irztdonlursm"}},{"hovercardSpec":{"objectPHID":"PHID-USER-k6tmz5ylx4rzfl3bitse"}},{"phid":"PHID-XACT-TASK-nz5wpkyqgz3aace"},{"hovercardSpec":{"objectPHID":"PHID-USER-k6tmz5ylx4rzfl3bitse"}},{"phid":"PHID-XACT-TASK-ccyjxks4qxc4eeu"},{"hovercardSpec":{"objectPHID":"PHID-USER-k6tmz5ylx4rzfl3bitse"}},{"hovercardSpec":{"objectPHID":"PHID-USER-k6tmz5ylx4rzfl3bitse"}},{"phid":"PHID-XACT-TASK-qppfhbejsch7ypf"},{"hovercardSpec":{"objectPHID":"PHID-USER-uqcn2l4ng4murmyfnvyp"}},{"phid":"PHID-XACT-TASK-qfla3plcvij3g72"},{"hovercardSpec":{"objectPHID":"PHID-USER-5dqihbanu3caaj7pigif"}},{"phid":"PHID-XACT-TASK-a3u74gyuv5rhvb4"},{"hovercardSpec":{"objectPHID":"PHID-USER-5dqihbanu3caaj7pigif"}},{"phid":"PHID-XACT-TASK-drpq3rvufrzcmxf"},{"hovercardSpec":{"objectPHID":"PHID-USER-uqcn2l4ng4murmyfnvyp"}},{"phid":"PHID-XACT-TASK-zzsgulitvrzchr2"},{"hovercardSpec":{"objectPHID":"PHID-USER-5dqihbanu3caaj7pigif"}},{"hovercardSpec":{"objectPHID":"PHID-PCOL-oa6xrkbjkdkxrcft3gwx"}},{"hovercardSpec":{"objectPHID":"PHID-PCOL-ayjnomqtp2tpio3lkqtd"}},{"hovercardSpec":{"objectPHID":"PHID-PROJ-fc6tzpgo4uo33xqvhtdj"}},{"phid":"PHID-XACT-TASK-sv6d6udoevvcula"},{"hovercardSpec":{"objectPHID":"PHID-USER-7mtggupugbd5i55vuvdc"}},{"hovercardSpec":{"objectPHID":"PHID-USER-rizrvu26ar4azamanlp7"}},{"hovercardSpec":{"objectPHID":"PHID-PCOL-y7k6c7zwrcb62hzgiulu"}},{"hovercardSpec":{"objectPHID":"PHID-PCOL-fjtzkojpha6ln5jm56oc"}},{"hovercardSpec":{"objectPHID":"PHID-PROJ-2b7oz62ylk3jk4aus262"}},{"hovercardSpec":{"objectPHID":"PHID-USER-5dqihbanu3caaj7pigif"}},{"hovercardSpec":{"objectPHID":"PHID-PROJ-gtmqksu2xtagmbjn2htz"}},{"hovercardSpec":{"objectPHID":"PHID-PROJ-fc6tzpgo4uo33xqvhtdj"}},{"phid":"PHID-XACT-TASK-i5un6su5bv4wlyg"},{"hovercardSpec":{"objectPHID":"PHID-USER-d2tiurktk2jgxzcpd2jw"}},{"hovercardSpec":{"objectPHID":"PHID-USER-idceizaw6elwiwm5xshb"}},{"phid":"PHID-XACT-TASK-ebemnv3sogxwrah"},{"hovercardSpec":{"objectPHID":"PHID-USER-idceizaw6elwiwm5xshb"}},{"hovercardSpec":{"objectPHID":"PHID-PROJ-onnxucoedheq3jevknyr"}},{"hovercardSpec":{"objectPHID":"PHID-USER-sai77mtxmpqnm6pycyvz"}},{"hovercardSpec":{"objectPHID":"PHID-PCOL-4xkx7rkmbqwvrhbxdrls"}},{"hovercardSpec":{"objectPHID":"PHID-PCOL-42czafapn3lggegongpj"}},{"hovercardSpec":{"objectPHID":"PHID-PROJ-gtmqksu2xtagmbjn2htz"}},{"hovercardSpec":{"objectPHID":"PHID-USER-idceizaw6elwiwm5xshb"}},{"phid":"PHID-XACT-TASK-px3taxs4y7x354h"},{"hovercardSpec":{"objectPHID":"PHID-USER-idceizaw6elwiwm5xshb"}},{"phid":"PHID-XACT-TASK-oztplda4a3u5bcw"},{"hovercardSpec":{"objectPHID":"PHID-USER-k6tmz5ylx4rzfl3bitse"}},{"hovercardSpec":{"objectPHID":"PHID-TASK-5dl2ye3o2uoh2owgf6y4"}},{"hovercardSpec":{"objectPHID":"PHID-USER-idceizaw6elwiwm5xshb"}},{"phid":"PHID-XACT-TASK-3dppwm4f3sp2ulr"},{"hovercardSpec":{"objectPHID":"PHID-USER-idceizaw6elwiwm5xshb"}},{"phid":"PHID-XACT-TASK-prnqfzqdnvfzb6r"},{"hovercardSpec":{"objectPHID":"PHID-USER-d4t4pqg6bbnh6kksz5ox"}},{"hovercardSpec":{"objectPHID":"PHID-PROJ-277qef67dlcfi5e7rhzm"}},{"hovercardSpec":{"objectPHID":"PHID-USER-idceizaw6elwiwm5xshb"}},{"phid":"PHID-XACT-TASK-erwozga5nyyimzd"},{"hovercardSpec":{"objectPHID":"PHID-USER-hvywcttgalazbjxfl3tq"}},{"hovercardSpec":{"objectPHID":"PHID-TASK-fqspwuowkuu2sqv5mdza"}},{"hovercardSpec":{"objectPHID":"PHID-USER-bjejtnxhzwcrlgcqh3gc"}},{"hovercardSpec":{"objectPHID":"PHID-USER-uqcn2l4ng4murmyfnvyp"}},{"hovercardSpec":{"objectPHID":"PHID-PROJ-va37kiwzbgywahiczwjk"}},{"hovercardSpec":{"objectPHID":"PHID-USER-uqcn2l4ng4murmyfnvyp"}},{"hovercardSpec":{"objectPHID":"PHID-PCOL-r5kuf624ie7dcnsf4ri6"}},{"hovercardSpec":{"objectPHID":"PHID-PCOL-d3hiinonfukpvs7rujmf"}},{"hovercardSpec":{"objectPHID":"PHID-PROJ-va37kiwzbgywahiczwjk"}},{"hovercardSpec":{"objectPHID":"PHID-USER-ilk3nopl66nufkd26tee"}},{"hovercardSpec":{"objectPHID":"PHID-PROJ-n4t5uw4v7qvdiide4irg"}},{"hovercardSpec":{"objectPHID":"PHID-USER-u2crzeo55u66lyf3gvor"}},{"hovercardSpec":{"objectPHID":"PHID-USER-sai77mtxmpqnm6pycyvz"}},{"hovercardSpec":{"objectPHID":"PHID-TASK-tbrivdnhoiekg3nqdwvw"}},{"hovercardSpec":{"objectPHID":"PHID-USER-ilk3nopl66nufkd26tee"}},{"hovercardSpec":{"objectPHID":"PHID-PROJ-7lr5gnt5ime652zehp37"}},{"hovercardSpec":{"objectPHID":"PHID-USER-idceizaw6elwiwm5xshb"}},{"phid":"PHID-XACT-TASK-75h2nsgemflivpl"},{"hovercardSpec":{"objectPHID":"PHID-USER-hrcsuxxosiyjqpef64tc"}},{"hovercardSpec":{"objectPHID":"PHID-TASK-un5at7jsnesgynaepbkn"}},{"phid":"PHID-XACT-TASK-djjrrpcqspjuuxi"},{"hovercardSpec":{"objectPHID":"PHID-USER-6vzzsmi22zem6yttr6vp"}},{"hovercardSpec":{"objectPHID":"PHID-USER-hvywcttgalazbjxfl3tq"}},{"hovercardSpec":{"objectPHID":"PHID-TASK-22iluo5emwh6npmjy2uc"}},{"phid":"PHID-XACT-TASK-sret55wl4ycbsd2"},{"hovercardSpec":{"objectPHID":"PHID-USER-m2ezqyeb4uz67zq6bats"}},{"hovercardSpec":{"objectPHID":"PHID-USER-idceizaw6elwiwm5xshb"}},{"phid":"PHID-XACT-TASK-4x7ywnuiybduiw7"},{"hovercardSpec":{"objectPHID":"PHID-USER-idceizaw6elwiwm5xshb"}},{"phid":"PHID-XACT-TASK-4xpm4tt73bn34gs"},{"tip":"Via Web"},[],[],{"phid":"PHID-XACT-TASK-spy5am7lhzybpmb","anchor":"5726875"},{"tip":"Via Web"},[],[],{"phid":"PHID-XACT-TASK-iq3wnf3eik3p5l2","anchor":"5726890"},{"tip":"Via Web"},[],{"phid":"PHID-XACT-TASK-2ekmsnhgqks2tbu","anchor":"5728302"},{"targetID":"UQ0_5","uri":"\/transactions\/quote\/PHID-XACT-TASK-hnssrwsb5q5kpz4\/","ref":"T240307#5728354"},[],{"anchor":"5728354"},[],{"items":"\u003cul class=\"phabricator-action-list-view \"\u003e\u003cli id=\"UQ0_1\" class=\"phabricator-action-view phabricator-action-view-href action-has-icon\" style=\"\"\u003e\u003ca href=\"#\" class=\"phabricator-action-view-item\" data-sigil=\"transaction-quote\" data-meta=\"0_243\"\u003e\u003cspan class=\"visual-only phui-icon-view phui-font-fa fa-quote-left phabricator-action-view-icon\" data-meta=\"0_244\" aria-hidden=\"true\"\u003e\u003c\/span\u003eQuote Comment\u003c\/a\u003e\u003c\/li\u003e\u003cli id=\"UQ0_3\" class=\"phabricator-action-view phabricator-action-view-href action-has-icon\" style=\"\"\u003e\u003ca href=\"\/transactions\/raw\/PHID-XACT-TASK-hnssrwsb5q5kpz4\/\" class=\"phabricator-action-view-item\" data-sigil=\"transaction-raw\" data-meta=\"0_245\"\u003e\u003cspan class=\"visual-only phui-icon-view phui-font-fa fa-code phabricator-action-view-icon\" data-meta=\"0_246\" aria-hidden=\"true\"\u003e\u003c\/span\u003eView Raw Remarkup\u003c\/a\u003e\u003c\/li\u003e\u003c\/ul\u003e"},[],{"tip":"Via Web"},[],{"tip":"Backport Deployer","align":"E","size":300},[],{"phid":"PHID-XACT-TASK-hnssrwsb5q5kpz4","anchor":"5728354"},{"targetID":"UQ0_5","uri":"\/transactions\/quote\/PHID-XACT-TASK-hayndf7q62kzfwv\/","ref":"T240307#5728815"},[],{"anchor":"5728815"},[],{"items":"\u003cul class=\"phabricator-action-list-view \"\u003e\u003cli id=\"UQ0_5\" class=\"phabricator-action-view phabricator-action-view-href action-has-icon\" style=\"\"\u003e\u003ca href=\"#\" class=\"phabricator-action-view-item\" data-sigil=\"transaction-quote\" data-meta=\"0_254\"\u003e\u003cspan class=\"visual-only phui-icon-view phui-font-fa fa-quote-left phabricator-action-view-icon\" data-meta=\"0_255\" aria-hidden=\"true\"\u003e\u003c\/span\u003eQuote Comment\u003c\/a\u003e\u003c\/li\u003e\u003cli id=\"UQ0_7\" class=\"phabricator-action-view phabricator-action-view-href action-has-icon\" style=\"\"\u003e\u003ca href=\"\/transactions\/raw\/PHID-XACT-TASK-hayndf7q62kzfwv\/\" class=\"phabricator-action-view-item\" data-sigil=\"transaction-raw\" data-meta=\"0_256\"\u003e\u003cspan class=\"visual-only phui-icon-view phui-font-fa fa-code phabricator-action-view-icon\" data-meta=\"0_257\" aria-hidden=\"true\"\u003e\u003c\/span\u003eView Raw Remarkup\u003c\/a\u003e\u003c\/li\u003e\u003c\/ul\u003e"},[],{"tip":"Via Web"},[],{"phid":"PHID-XACT-TASK-hayndf7q62kzfwv","anchor":"5728815"},{"tip":"Via Web"},[],{"phid":"PHID-XACT-TASK-u5du7sww2flgkqz","anchor":"5728816"},{"targetID":"UQ0_5","uri":"\/transactions\/quote\/PHID-XACT-TASK-gmmug6z3n2hogwq\/","ref":"T240307#5728830"},[],{"anchor":"5728830"},[],{"items":"\u003cul class=\"phabricator-action-list-view \"\u003e\u003cli id=\"UQ0_9\" class=\"phabricator-action-view phabricator-action-view-href action-has-icon\" style=\"\"\u003e\u003ca href=\"#\" class=\"phabricator-action-view-item\" data-sigil=\"transaction-quote\" data-meta=\"0_266\"\u003e\u003cspan class=\"visual-only phui-icon-view phui-font-fa fa-quote-left phabricator-action-view-icon\" data-meta=\"0_267\" aria-hidden=\"true\"\u003e\u003c\/span\u003eQuote Comment\u003c\/a\u003e\u003c\/li\u003e\u003cli id=\"UQ0_11\" class=\"phabricator-action-view phabricator-action-view-href action-has-icon\" style=\"\"\u003e\u003ca href=\"\/transactions\/raw\/PHID-XACT-TASK-gmmug6z3n2hogwq\/\" class=\"phabricator-action-view-item\" data-sigil=\"transaction-raw\" data-meta=\"0_268\"\u003e\u003cspan class=\"visual-only phui-icon-view phui-font-fa fa-code phabricator-action-view-icon\" data-meta=\"0_269\" aria-hidden=\"true\"\u003e\u003c\/span\u003eView Raw Remarkup\u003c\/a\u003e\u003c\/li\u003e\u003c\/ul\u003e"},[],{"tip":"Via Web"},[],{"phid":"PHID-XACT-TASK-gmmug6z3n2hogwq","anchor":"5728830"},{"targetID":"UQ0_5","uri":"\/transactions\/quote\/PHID-XACT-TASK-cwnkbggrnbiculo\/","ref":"T240307#5728876"},[],{"anchor":"5728876"},[],{"items":"\u003cul class=\"phabricator-action-list-view \"\u003e\u003cli id=\"UQ0_13\" class=\"phabricator-action-view phabricator-action-view-href action-has-icon\" style=\"\"\u003e\u003ca href=\"#\" class=\"phabricator-action-view-item\" data-sigil=\"transaction-quote\" data-meta=\"0_275\"\u003e\u003cspan class=\"visual-only phui-icon-view phui-font-fa fa-quote-left phabricator-action-view-icon\" data-meta=\"0_276\" aria-hidden=\"true\"\u003e\u003c\/span\u003eQuote Comment\u003c\/a\u003e\u003c\/li\u003e\u003cli id=\"UQ0_15\" class=\"phabricator-action-view phabricator-action-view-href action-has-icon\" style=\"\"\u003e\u003ca href=\"\/transactions\/raw\/PHID-XACT-TASK-cwnkbggrnbiculo\/\" class=\"phabricator-action-view-item\" data-sigil=\"transaction-raw\" data-meta=\"0_277\"\u003e\u003cspan class=\"visual-only phui-icon-view phui-font-fa fa-code phabricator-action-view-icon\" data-meta=\"0_278\" aria-hidden=\"true\"\u003e\u003c\/span\u003eView Raw Remarkup\u003c\/a\u003e\u003c\/li\u003e\u003c\/ul\u003e"},[],{"tip":"Via Web"},[],{"tip":"Backport Deployer","align":"E","size":300},[],{"phid":"PHID-XACT-TASK-cwnkbggrnbiculo","anchor":"5728876"},{"targetID":"UQ0_5","uri":"\/transactions\/quote\/PHID-XACT-TASK-l6exy33mmdr2gjx\/","ref":"T240307#5728938"},[],{"anchor":"5728938"},[],{"items":"\u003cul class=\"phabricator-action-list-view \"\u003e\u003cli id=\"UQ0_17\" class=\"phabricator-action-view phabricator-action-view-href action-has-icon\" style=\"\"\u003e\u003ca href=\"#\" class=\"phabricator-action-view-item\" data-sigil=\"transaction-quote\" data-meta=\"0_286\"\u003e\u003cspan class=\"visual-only phui-icon-view phui-font-fa fa-quote-left phabricator-action-view-icon\" data-meta=\"0_287\" aria-hidden=\"true\"\u003e\u003c\/span\u003eQuote Comment\u003c\/a\u003e\u003c\/li\u003e\u003cli id=\"UQ0_19\" class=\"phabricator-action-view phabricator-action-view-href action-has-icon\" style=\"\"\u003e\u003ca href=\"\/transactions\/raw\/PHID-XACT-TASK-l6exy33mmdr2gjx\/\" class=\"phabricator-action-view-item\" data-sigil=\"transaction-raw\" data-meta=\"0_288\"\u003e\u003cspan class=\"visual-only phui-icon-view phui-font-fa fa-code phabricator-action-view-icon\" data-meta=\"0_289\" aria-hidden=\"true\"\u003e\u003c\/span\u003eView Raw Remarkup\u003c\/a\u003e\u003c\/li\u003e\u003c\/ul\u003e"},[],{"tip":"Via Web"},[],{"tip":"Continuous Integrator","align":"E","size":300},[],{"phid":"PHID-XACT-TASK-l6exy33mmdr2gjx","anchor":"5728938"},{"targetID":"UQ0_5","uri":"\/transactions\/quote\/PHID-XACT-TASK-xyakswzwwyhctfu\/","ref":"T240307#5729089"},[],{"anchor":"5729089"},[],{"items":"\u003cul class=\"phabricator-action-list-view \"\u003e\u003cli id=\"UQ0_21\" class=\"phabricator-action-view phabricator-action-view-href action-has-icon\" style=\"\"\u003e\u003ca href=\"#\" class=\"phabricator-action-view-item\" data-sigil=\"transaction-quote\" data-meta=\"0_297\"\u003e\u003cspan class=\"visual-only phui-icon-view phui-font-fa fa-quote-left phabricator-action-view-icon\" data-meta=\"0_298\" aria-hidden=\"true\"\u003e\u003c\/span\u003eQuote Comment\u003c\/a\u003e\u003c\/li\u003e\u003cli id=\"UQ0_23\" class=\"phabricator-action-view phabricator-action-view-href action-has-icon\" style=\"\"\u003e\u003ca href=\"\/transactions\/raw\/PHID-XACT-TASK-xyakswzwwyhctfu\/\" class=\"phabricator-action-view-item\" data-sigil=\"transaction-raw\" data-meta=\"0_299\"\u003e\u003cspan class=\"visual-only phui-icon-view phui-font-fa fa-code phabricator-action-view-icon\" data-meta=\"0_300\" aria-hidden=\"true\"\u003e\u003c\/span\u003eView Raw Remarkup\u003c\/a\u003e\u003c\/li\u003e\u003c\/ul\u003e"},[],{"tip":"Via Web"},[],{"tip":"Backport Deployer","align":"E","size":300},[],{"phid":"PHID-XACT-TASK-xyakswzwwyhctfu","anchor":"5729089"},{"targetID":"UQ0_5","uri":"\/transactions\/quote\/PHID-XACT-TASK-ch7xae4kgeq3tua\/","ref":"T240307#5729964"},[],{"anchor":"5729964"},[],{"items":"\u003cul class=\"phabricator-action-list-view \"\u003e\u003cli id=\"UQ0_25\" class=\"phabricator-action-view phabricator-action-view-href action-has-icon\" style=\"\"\u003e\u003ca href=\"#\" class=\"phabricator-action-view-item\" data-sigil=\"transaction-quote\" data-meta=\"0_308\"\u003e\u003cspan class=\"visual-only phui-icon-view phui-font-fa fa-quote-left phabricator-action-view-icon\" data-meta=\"0_309\" aria-hidden=\"true\"\u003e\u003c\/span\u003eQuote Comment\u003c\/a\u003e\u003c\/li\u003e\u003cli id=\"UQ0_27\" class=\"phabricator-action-view phabricator-action-view-href action-has-icon\" style=\"\"\u003e\u003ca href=\"\/transactions\/raw\/PHID-XACT-TASK-ch7xae4kgeq3tua\/\" class=\"phabricator-action-view-item\" data-sigil=\"transaction-raw\" data-meta=\"0_310\"\u003e\u003cspan class=\"visual-only phui-icon-view phui-font-fa fa-code phabricator-action-view-icon\" data-meta=\"0_311\" aria-hidden=\"true\"\u003e\u003c\/span\u003eView Raw Remarkup\u003c\/a\u003e\u003c\/li\u003e\u003c\/ul\u003e"},[],{"tip":"Via Web"},[],{"phid":"PHID-XACT-TASK-ch7xae4kgeq3tua","anchor":"5729964"},{"targetID":"UQ0_5","uri":"\/transactions\/quote\/PHID-XACT-TASK-hffwrr55ce3jnz6\/","ref":"T240307#5733085"},[],{"anchor":"5733085"},[],{"items":"\u003cul class=\"phabricator-action-list-view \"\u003e\u003cli id=\"UQ0_29\" class=\"phabricator-action-view phabricator-action-view-href action-has-icon\" style=\"\"\u003e\u003ca href=\"#\" class=\"phabricator-action-view-item\" data-sigil=\"transaction-quote\" data-meta=\"0_317\"\u003e\u003cspan class=\"visual-only phui-icon-view phui-font-fa fa-quote-left phabricator-action-view-icon\" data-meta=\"0_318\" aria-hidden=\"true\"\u003e\u003c\/span\u003eQuote Comment\u003c\/a\u003e\u003c\/li\u003e\u003cli id=\"UQ0_31\" class=\"phabricator-action-view phabricator-action-view-href action-has-icon\" style=\"\"\u003e\u003ca href=\"\/transactions\/raw\/PHID-XACT-TASK-hffwrr55ce3jnz6\/\" class=\"phabricator-action-view-item\" data-sigil=\"transaction-raw\" data-meta=\"0_319\"\u003e\u003cspan class=\"visual-only phui-icon-view phui-font-fa fa-code phabricator-action-view-icon\" data-meta=\"0_320\" aria-hidden=\"true\"\u003e\u003c\/span\u003eView Raw Remarkup\u003c\/a\u003e\u003c\/li\u003e\u003c\/ul\u003e"},[],{"tip":"Via Web"},[],{"phid":"PHID-XACT-TASK-hffwrr55ce3jnz6","anchor":"5733085"},{"tip":"Via Web"},[],[],{"phid":"PHID-XACT-TASK-lqzpenfp3xuz5d6","anchor":"5733092"},{"tip":"Via Web"},[],[],{"phid":"PHID-XACT-TASK-trmwhdk4ndaherw","anchor":"5733143"},{"tip":"Via Web"},[],[],[],{"phid":"PHID-XACT-TASK-dicrmmzlfxidfza","anchor":"5733280"},{"tip":"Via Web"},[],{"phid":"PHID-XACT-TASK-x6x4efm3opwo7c2","anchor":"5733428"},{"tip":"Via Web"},[],{"phid":"PHID-XACT-TASK-rtlq45m32d5hdm5","anchor":"5733815"},{"tip":"Via Web"},[],[],[],{"phid":"PHID-XACT-TASK-uil3koyjkpxffuu","anchor":"5734277"},{"tip":"Via Web"},[],{"phid":"PHID-XACT-TASK-lqxx4xqxsisyrvx","anchor":"5742139"},{"tip":"Via Web"},[],{"phid":"PHID-XACT-TASK-5wac346uk4tr2co","anchor":"5742953"},{"tip":"Via Web"},[],{"phid":"PHID-XACT-TASK-smfdu4rtmxjlrpb","anchor":"5742960"},{"tip":"Via Web"},[],{"phid":"PHID-XACT-TASK-fhjhf7wt4wdny23","anchor":"5743025"},{"tip":"Via Web"},[],[],{"phid":"PHID-XACT-TASK-j5macva4ehjt4mz","anchor":"5743028"},{"tip":"Via Web"},[],{"phid":"PHID-XACT-TASK-hfhy5bcmfxid66x","anchor":"5743366"},{"tip":"Via Web"},[],{"phid":"PHID-XACT-TASK-rgvlsmgnbyszkmv","anchor":"5743564"},{"targetID":"UQ0_5","uri":"\/transactions\/quote\/PHID-XACT-TASK-dc7ofrz2eiluy7x\/","ref":"T240307#5743953"},[],{"anchor":"5743953"},[],{"items":"\u003cul class=\"phabricator-action-list-view \"\u003e\u003cli id=\"UQ0_33\" class=\"phabricator-action-view phabricator-action-view-href action-has-icon\" style=\"\"\u003e\u003ca href=\"#\" class=\"phabricator-action-view-item\" data-sigil=\"transaction-quote\" data-meta=\"0_372\"\u003e\u003cspan class=\"visual-only phui-icon-view phui-font-fa fa-quote-left phabricator-action-view-icon\" data-meta=\"0_373\" aria-hidden=\"true\"\u003e\u003c\/span\u003eQuote Comment\u003c\/a\u003e\u003c\/li\u003e\u003cli id=\"UQ0_35\" class=\"phabricator-action-view phabricator-action-view-href action-has-icon\" style=\"\"\u003e\u003ca href=\"\/transactions\/raw\/PHID-XACT-TASK-dc7ofrz2eiluy7x\/\" class=\"phabricator-action-view-item\" data-sigil=\"transaction-raw\" data-meta=\"0_374\"\u003e\u003cspan class=\"visual-only phui-icon-view phui-font-fa fa-code phabricator-action-view-icon\" data-meta=\"0_375\" aria-hidden=\"true\"\u003e\u003c\/span\u003eView Raw Remarkup\u003c\/a\u003e\u003c\/li\u003e\u003c\/ul\u003e"},[],{"tip":"Via Web"},[],{"tip":"Backport Deployer","align":"E","size":300},[],{"phid":"PHID-XACT-TASK-dc7ofrz2eiluy7x","anchor":"5743953"},{"tip":"Via Web"},[],{"phid":"PHID-XACT-TASK-wnw7d3nbqhkiqhe","anchor":"5744269"},{"targetID":"UQ0_5","uri":"\/transactions\/quote\/PHID-XACT-TASK-jbewom6yeqoeqtl\/","ref":"T240307#5744479"},[],{"anchor":"5744479"},[],{"items":"\u003cul class=\"phabricator-action-list-view \"\u003e\u003cli id=\"UQ0_37\" class=\"phabricator-action-view phabricator-action-view-href action-has-icon\" style=\"\"\u003e\u003ca href=\"#\" class=\"phabricator-action-view-item\" data-sigil=\"transaction-quote\" data-meta=\"0_386\"\u003e\u003cspan class=\"visual-only phui-icon-view phui-font-fa fa-quote-left phabricator-action-view-icon\" data-meta=\"0_387\" aria-hidden=\"true\"\u003e\u003c\/span\u003eQuote Comment\u003c\/a\u003e\u003c\/li\u003e\u003cli id=\"UQ0_39\" class=\"phabricator-action-view phabricator-action-view-href action-has-icon\" style=\"\"\u003e\u003ca href=\"\/transactions\/raw\/PHID-XACT-TASK-jbewom6yeqoeqtl\/\" class=\"phabricator-action-view-item\" data-sigil=\"transaction-raw\" data-meta=\"0_388\"\u003e\u003cspan class=\"visual-only phui-icon-view phui-font-fa fa-code phabricator-action-view-icon\" data-meta=\"0_389\" aria-hidden=\"true\"\u003e\u003c\/span\u003eView Raw Remarkup\u003c\/a\u003e\u003c\/li\u003e\u003c\/ul\u003e"},[],{"tip":"Via Web"},[],{"tip":"Nerd Sniper","align":"E","size":300},[],{"phid":"PHID-XACT-TASK-jbewom6yeqoeqtl","anchor":"5744479"},{"targetID":"UQ0_5","uri":"\/transactions\/quote\/PHID-XACT-TASK-d25ci2aljnzspzg\/","ref":"T240307#5744685"},[],{"anchor":"5744685"},[],{"items":"\u003cul class=\"phabricator-action-list-view \"\u003e\u003cli id=\"UQ0_41\" class=\"phabricator-action-view phabricator-action-view-href action-has-icon\" style=\"\"\u003e\u003ca href=\"#\" class=\"phabricator-action-view-item\" data-sigil=\"transaction-quote\" data-meta=\"0_397\"\u003e\u003cspan class=\"visual-only phui-icon-view phui-font-fa fa-quote-left phabricator-action-view-icon\" data-meta=\"0_398\" aria-hidden=\"true\"\u003e\u003c\/span\u003eQuote Comment\u003c\/a\u003e\u003c\/li\u003e\u003cli id=\"UQ0_43\" class=\"phabricator-action-view phabricator-action-view-href action-has-icon\" style=\"\"\u003e\u003ca href=\"\/transactions\/raw\/PHID-XACT-TASK-d25ci2aljnzspzg\/\" class=\"phabricator-action-view-item\" data-sigil=\"transaction-raw\" data-meta=\"0_399\"\u003e\u003cspan class=\"visual-only phui-icon-view phui-font-fa fa-code phabricator-action-view-icon\" data-meta=\"0_400\" aria-hidden=\"true\"\u003e\u003c\/span\u003eView Raw Remarkup\u003c\/a\u003e\u003c\/li\u003e\u003c\/ul\u003e"},[],{"tip":"Via Web"},[],{"phid":"PHID-XACT-TASK-d25ci2aljnzspzg","anchor":"5744685"},{"targetID":"UQ0_5","uri":"\/transactions\/quote\/PHID-XACT-TASK-ms27e5cx2jtdmd4\/","ref":"T240307#5744732"},[],{"anchor":"5744732"},[],[],{"items":"\u003cul class=\"phabricator-action-list-view \"\u003e\u003cli id=\"UQ0_45\" class=\"phabricator-action-view phabricator-action-view-href action-has-icon\" style=\"\"\u003e\u003ca href=\"#\" class=\"phabricator-action-view-item\" data-sigil=\"transaction-quote\" data-meta=\"0_406\"\u003e\u003cspan class=\"visual-only phui-icon-view phui-font-fa fa-quote-left phabricator-action-view-icon\" data-meta=\"0_407\" aria-hidden=\"true\"\u003e\u003c\/span\u003eQuote Comment\u003c\/a\u003e\u003c\/li\u003e\u003cli id=\"UQ0_47\" class=\"phabricator-action-view phabricator-action-view-href action-has-icon\" style=\"\"\u003e\u003ca href=\"\/transactions\/raw\/PHID-XACT-TASK-ms27e5cx2jtdmd4\/\" class=\"phabricator-action-view-item\" data-sigil=\"transaction-raw\" data-meta=\"0_408\"\u003e\u003cspan class=\"visual-only phui-icon-view phui-font-fa fa-code phabricator-action-view-icon\" data-meta=\"0_409\" aria-hidden=\"true\"\u003e\u003c\/span\u003eView Raw Remarkup\u003c\/a\u003e\u003c\/li\u003e\u003cli id=\"UQ0_49\" class=\"phabricator-action-view phabricator-action-view-href action-has-icon\" style=\"\"\u003e\u003ca href=\"\/transactions\/history\/PHID-XACT-TASK-ms27e5cx2jtdmd4\/\" class=\"phabricator-action-view-item\" data-sigil=\"workflow\"\u003e\u003cspan class=\"visual-only phui-icon-view phui-font-fa fa-list phabricator-action-view-icon\" data-meta=\"0_410\" aria-hidden=\"true\"\u003e\u003c\/span\u003eView Edit History\u003c\/a\u003e\u003c\/li\u003e\u003c\/ul\u003e"},[],{"tip":"Via Web"},[],{"tip":"Backport Deployer","align":"E","size":300},[],{"phid":"PHID-XACT-TASK-ms27e5cx2jtdmd4","anchor":"5744732"},{"targetID":"UQ0_5","uri":"\/transactions\/quote\/PHID-XACT-TASK-i22dgqlstmhzjsu\/","ref":"T240307#5744742"},[],{"anchor":"5744742"},[],{"items":"\u003cul class=\"phabricator-action-list-view \"\u003e\u003cli id=\"UQ0_51\" class=\"phabricator-action-view phabricator-action-view-href action-has-icon\" style=\"\"\u003e\u003ca href=\"#\" class=\"phabricator-action-view-item\" data-sigil=\"transaction-quote\" data-meta=\"0_418\"\u003e\u003cspan class=\"visual-only phui-icon-view phui-font-fa fa-quote-left phabricator-action-view-icon\" data-meta=\"0_419\" aria-hidden=\"true\"\u003e\u003c\/span\u003eQuote Comment\u003c\/a\u003e\u003c\/li\u003e\u003cli id=\"UQ0_53\" class=\"phabricator-action-view phabricator-action-view-href action-has-icon\" style=\"\"\u003e\u003ca href=\"\/transactions\/raw\/PHID-XACT-TASK-i22dgqlstmhzjsu\/\" class=\"phabricator-action-view-item\" data-sigil=\"transaction-raw\" data-meta=\"0_420\"\u003e\u003cspan class=\"visual-only phui-icon-view phui-font-fa fa-code phabricator-action-view-icon\" data-meta=\"0_421\" aria-hidden=\"true\"\u003e\u003c\/span\u003eView Raw Remarkup\u003c\/a\u003e\u003c\/li\u003e\u003c\/ul\u003e"},[],{"tip":"Via Web"},[],{"tip":"Backport Deployer","align":"E","size":300},[],{"phid":"PHID-XACT-TASK-i22dgqlstmhzjsu","anchor":"5744742"},{"tip":"Via Web"},[],{"phid":"PHID-XACT-TASK-7ur5q7uitssj5s2","anchor":"5745139"},{"targetID":"UQ0_5","uri":"\/transactions\/quote\/PHID-XACT-TASK-54l22ozd4tjdvce\/","ref":"T240307#5745198"},[],{"anchor":"5745198"},[],{"items":"\u003cul class=\"phabricator-action-list-view \"\u003e\u003cli id=\"UQ0_55\" class=\"phabricator-action-view phabricator-action-view-href action-has-icon\" style=\"\"\u003e\u003ca href=\"#\" class=\"phabricator-action-view-item\" data-sigil=\"transaction-quote\" data-meta=\"0_432\"\u003e\u003cspan class=\"visual-only phui-icon-view phui-font-fa fa-quote-left phabricator-action-view-icon\" data-meta=\"0_433\" aria-hidden=\"true\"\u003e\u003c\/span\u003eQuote Comment\u003c\/a\u003e\u003c\/li\u003e\u003cli id=\"UQ0_57\" class=\"phabricator-action-view phabricator-action-view-href action-has-icon\" style=\"\"\u003e\u003ca href=\"\/transactions\/raw\/PHID-XACT-TASK-54l22ozd4tjdvce\/\" class=\"phabricator-action-view-item\" data-sigil=\"transaction-raw\" data-meta=\"0_434\"\u003e\u003cspan class=\"visual-only phui-icon-view phui-font-fa fa-code phabricator-action-view-icon\" data-meta=\"0_435\" aria-hidden=\"true\"\u003e\u003c\/span\u003eView Raw Remarkup\u003c\/a\u003e\u003c\/li\u003e\u003c\/ul\u003e"},[],{"tip":"Via Web"},[],{"tip":"Nerd Sniper","align":"E","size":300},[],{"phid":"PHID-XACT-TASK-54l22ozd4tjdvce","anchor":"5745198"},{"targetID":"UQ0_5","uri":"\/transactions\/quote\/PHID-XACT-TASK-3vi4ktzgqyinffu\/","ref":"T240307#5745267"},[],{"anchor":"5745267"},[],[],{"items":"\u003cul class=\"phabricator-action-list-view \"\u003e\u003cli id=\"UQ0_59\" class=\"phabricator-action-view phabricator-action-view-href action-has-icon\" style=\"\"\u003e\u003ca href=\"#\" class=\"phabricator-action-view-item\" data-sigil=\"transaction-quote\" data-meta=\"0_443\"\u003e\u003cspan class=\"visual-only phui-icon-view phui-font-fa fa-quote-left phabricator-action-view-icon\" data-meta=\"0_444\" aria-hidden=\"true\"\u003e\u003c\/span\u003eQuote Comment\u003c\/a\u003e\u003c\/li\u003e\u003cli id=\"UQ0_61\" class=\"phabricator-action-view phabricator-action-view-href action-has-icon\" style=\"\"\u003e\u003ca href=\"\/transactions\/raw\/PHID-XACT-TASK-3vi4ktzgqyinffu\/\" class=\"phabricator-action-view-item\" data-sigil=\"transaction-raw\" data-meta=\"0_445\"\u003e\u003cspan class=\"visual-only phui-icon-view phui-font-fa fa-code phabricator-action-view-icon\" data-meta=\"0_446\" aria-hidden=\"true\"\u003e\u003c\/span\u003eView Raw Remarkup\u003c\/a\u003e\u003c\/li\u003e\u003cli id=\"UQ0_63\" class=\"phabricator-action-view phabricator-action-view-href action-has-icon\" style=\"\"\u003e\u003ca href=\"\/transactions\/history\/PHID-XACT-TASK-3vi4ktzgqyinffu\/\" class=\"phabricator-action-view-item\" data-sigil=\"workflow\"\u003e\u003cspan class=\"visual-only phui-icon-view phui-font-fa fa-list phabricator-action-view-icon\" data-meta=\"0_447\" aria-hidden=\"true\"\u003e\u003c\/span\u003eView Edit History\u003c\/a\u003e\u003c\/li\u003e\u003c\/ul\u003e"},[],{"tip":"Via Web"},[],{"tip":"Nerd Sniper","align":"E","size":300},[],{"phid":"PHID-XACT-TASK-3vi4ktzgqyinffu","anchor":"5745267"},{"targetID":"UQ0_5","uri":"\/transactions\/quote\/PHID-XACT-TASK-2xniixwwjqab76c\/","ref":"T240307#5745428"},[],{"anchor":"5745428"},[],{"items":"\u003cul class=\"phabricator-action-list-view \"\u003e\u003cli id=\"UQ0_65\" class=\"phabricator-action-view phabricator-action-view-href action-has-icon\" style=\"\"\u003e\u003ca href=\"#\" class=\"phabricator-action-view-item\" data-sigil=\"transaction-quote\" data-meta=\"0_455\"\u003e\u003cspan class=\"visual-only phui-icon-view phui-font-fa fa-quote-left phabricator-action-view-icon\" data-meta=\"0_456\" aria-hidden=\"true\"\u003e\u003c\/span\u003eQuote Comment\u003c\/a\u003e\u003c\/li\u003e\u003cli id=\"UQ0_67\" class=\"phabricator-action-view phabricator-action-view-href action-has-icon\" style=\"\"\u003e\u003ca href=\"\/transactions\/raw\/PHID-XACT-TASK-2xniixwwjqab76c\/\" class=\"phabricator-action-view-item\" data-sigil=\"transaction-raw\" data-meta=\"0_457\"\u003e\u003cspan class=\"visual-only phui-icon-view phui-font-fa fa-code phabricator-action-view-icon\" data-meta=\"0_458\" aria-hidden=\"true\"\u003e\u003c\/span\u003eView Raw Remarkup\u003c\/a\u003e\u003c\/li\u003e\u003c\/ul\u003e"},[],{"tip":"Via Web"},[],{"tip":"Backport Deployer","align":"E","size":300},[],{"phid":"PHID-XACT-TASK-2xniixwwjqab76c","anchor":"5745428"},{"targetID":"UQ0_5","uri":"\/transactions\/quote\/PHID-XACT-TASK-fomdoufqnp637mu\/","ref":"T240307#5746862"},[],{"anchor":"5746862"},[],{"items":"\u003cul class=\"phabricator-action-list-view \"\u003e\u003cli id=\"UQ0_69\" class=\"phabricator-action-view phabricator-action-view-href action-has-icon\" style=\"\"\u003e\u003ca href=\"#\" class=\"phabricator-action-view-item\" data-sigil=\"transaction-quote\" data-meta=\"0_466\"\u003e\u003cspan class=\"visual-only phui-icon-view phui-font-fa fa-quote-left phabricator-action-view-icon\" data-meta=\"0_467\" aria-hidden=\"true\"\u003e\u003c\/span\u003eQuote Comment\u003c\/a\u003e\u003c\/li\u003e\u003cli id=\"UQ0_71\" class=\"phabricator-action-view phabricator-action-view-href action-has-icon\" style=\"\"\u003e\u003ca href=\"\/transactions\/raw\/PHID-XACT-TASK-fomdoufqnp637mu\/\" class=\"phabricator-action-view-item\" data-sigil=\"transaction-raw\" data-meta=\"0_468\"\u003e\u003cspan class=\"visual-only phui-icon-view phui-font-fa fa-code phabricator-action-view-icon\" data-meta=\"0_469\" aria-hidden=\"true\"\u003e\u003c\/span\u003eView Raw Remarkup\u003c\/a\u003e\u003c\/li\u003e\u003c\/ul\u003e"},[],{"tip":"Via Web"},[],{"phid":"PHID-XACT-TASK-fomdoufqnp637mu","anchor":"5746862"},{"tip":"Via Web"},[],{"phid":"PHID-XACT-TASK-lsubjrqpxmfkgde","anchor":"5747052"},{"targetID":"UQ0_5","uri":"\/transactions\/quote\/PHID-XACT-TASK-lkitswdvtaq2rkp\/","ref":"T240307#5747190"},[],{"anchor":"5747190"},[],[],{"items":"\u003cul class=\"phabricator-action-list-view \"\u003e\u003cli id=\"UQ0_73\" class=\"phabricator-action-view phabricator-action-view-href action-has-icon\" style=\"\"\u003e\u003ca href=\"#\" class=\"phabricator-action-view-item\" data-sigil=\"transaction-quote\" data-meta=\"0_478\"\u003e\u003cspan class=\"visual-only phui-icon-view phui-font-fa fa-quote-left phabricator-action-view-icon\" data-meta=\"0_479\" aria-hidden=\"true\"\u003e\u003c\/span\u003eQuote Comment\u003c\/a\u003e\u003c\/li\u003e\u003cli id=\"UQ0_75\" class=\"phabricator-action-view phabricator-action-view-href action-has-icon\" style=\"\"\u003e\u003ca href=\"\/transactions\/raw\/PHID-XACT-TASK-lkitswdvtaq2rkp\/\" class=\"phabricator-action-view-item\" data-sigil=\"transaction-raw\" data-meta=\"0_480\"\u003e\u003cspan class=\"visual-only phui-icon-view phui-font-fa fa-code phabricator-action-view-icon\" data-meta=\"0_481\" aria-hidden=\"true\"\u003e\u003c\/span\u003eView Raw Remarkup\u003c\/a\u003e\u003c\/li\u003e\u003cli id=\"UQ0_77\" class=\"phabricator-action-view phabricator-action-view-href action-has-icon\" style=\"\"\u003e\u003ca href=\"\/transactions\/history\/PHID-XACT-TASK-lkitswdvtaq2rkp\/\" class=\"phabricator-action-view-item\" data-sigil=\"workflow\"\u003e\u003cspan class=\"visual-only phui-icon-view phui-font-fa fa-list phabricator-action-view-icon\" data-meta=\"0_482\" aria-hidden=\"true\"\u003e\u003c\/span\u003eView Edit History\u003c\/a\u003e\u003c\/li\u003e\u003c\/ul\u003e"},[],{"tip":"Via Web"},[],{"tip":"Nerd Sniper","align":"E","size":300},[],{"phid":"PHID-XACT-TASK-lkitswdvtaq2rkp","anchor":"5747190"},{"targetID":"UQ0_5","uri":"\/transactions\/quote\/PHID-XACT-TASK-kzfjdd5x44mg4pw\/","ref":"T240307#5747196"},[],{"anchor":"5747196"},[],{"items":"\u003cul class=\"phabricator-action-list-view \"\u003e\u003cli id=\"UQ0_79\" class=\"phabricator-action-view phabricator-action-view-href action-has-icon\" style=\"\"\u003e\u003ca href=\"#\" class=\"phabricator-action-view-item\" data-sigil=\"transaction-quote\" data-meta=\"0_490\"\u003e\u003cspan class=\"visual-only phui-icon-view phui-font-fa fa-quote-left phabricator-action-view-icon\" data-meta=\"0_491\" aria-hidden=\"true\"\u003e\u003c\/span\u003eQuote Comment\u003c\/a\u003e\u003c\/li\u003e\u003cli id=\"UQ0_81\" class=\"phabricator-action-view phabricator-action-view-href action-has-icon\" style=\"\"\u003e\u003ca href=\"\/transactions\/raw\/PHID-XACT-TASK-kzfjdd5x44mg4pw\/\" class=\"phabricator-action-view-item\" data-sigil=\"transaction-raw\" data-meta=\"0_492\"\u003e\u003cspan class=\"visual-only phui-icon-view phui-font-fa fa-code phabricator-action-view-icon\" data-meta=\"0_493\" aria-hidden=\"true\"\u003e\u003c\/span\u003eView Raw Remarkup\u003c\/a\u003e\u003c\/li\u003e\u003c\/ul\u003e"},[],{"tip":"Via Web"},[],{"tip":"Nerd Sniper","align":"E","size":300},[],{"phid":"PHID-XACT-TASK-kzfjdd5x44mg4pw","anchor":"5747196"},{"targetID":"UQ0_5","uri":"\/transactions\/quote\/PHID-XACT-TASK-a4bpmlw5vnndcd3\/","ref":"T240307#5747418"},[],{"anchor":"5747418"},[],{"items":"\u003cul class=\"phabricator-action-list-view \"\u003e\u003cli id=\"UQ0_83\" class=\"phabricator-action-view phabricator-action-view-href action-has-icon\" style=\"\"\u003e\u003ca href=\"#\" class=\"phabricator-action-view-item\" data-sigil=\"transaction-quote\" data-meta=\"0_501\"\u003e\u003cspan class=\"visual-only phui-icon-view phui-font-fa fa-quote-left phabricator-action-view-icon\" data-meta=\"0_502\" aria-hidden=\"true\"\u003e\u003c\/span\u003eQuote Comment\u003c\/a\u003e\u003c\/li\u003e\u003cli id=\"UQ0_85\" class=\"phabricator-action-view phabricator-action-view-href action-has-icon\" style=\"\"\u003e\u003ca href=\"\/transactions\/raw\/PHID-XACT-TASK-a4bpmlw5vnndcd3\/\" class=\"phabricator-action-view-item\" data-sigil=\"transaction-raw\" data-meta=\"0_503\"\u003e\u003cspan class=\"visual-only phui-icon-view phui-font-fa fa-code phabricator-action-view-icon\" data-meta=\"0_504\" aria-hidden=\"true\"\u003e\u003c\/span\u003eView Raw Remarkup\u003c\/a\u003e\u003c\/li\u003e\u003c\/ul\u003e"},[],{"tip":"Via Web"},[],{"tip":"Nerd Sniper","align":"E","size":300},[],{"phid":"PHID-XACT-TASK-a4bpmlw5vnndcd3","anchor":"5747418"},{"targetID":"UQ0_5","uri":"\/transactions\/quote\/PHID-XACT-TASK-f4w34cvv3mrmhvt\/","ref":"T240307#5748443"},[],{"anchor":"5748443"},[],{"items":"\u003cul class=\"phabricator-action-list-view \"\u003e\u003cli id=\"UQ0_87\" class=\"phabricator-action-view phabricator-action-view-href action-has-icon\" style=\"\"\u003e\u003ca href=\"#\" class=\"phabricator-action-view-item\" data-sigil=\"transaction-quote\" data-meta=\"0_512\"\u003e\u003cspan class=\"visual-only phui-icon-view phui-font-fa fa-quote-left phabricator-action-view-icon\" data-meta=\"0_513\" aria-hidden=\"true\"\u003e\u003c\/span\u003eQuote Comment\u003c\/a\u003e\u003c\/li\u003e\u003cli id=\"UQ0_89\" class=\"phabricator-action-view phabricator-action-view-href action-has-icon\" style=\"\"\u003e\u003ca href=\"\/transactions\/raw\/PHID-XACT-TASK-f4w34cvv3mrmhvt\/\" class=\"phabricator-action-view-item\" data-sigil=\"transaction-raw\" data-meta=\"0_514\"\u003e\u003cspan class=\"visual-only phui-icon-view phui-font-fa fa-code phabricator-action-view-icon\" data-meta=\"0_515\" aria-hidden=\"true\"\u003e\u003c\/span\u003eView Raw Remarkup\u003c\/a\u003e\u003c\/li\u003e\u003c\/ul\u003e"},[],{"tip":"Via Web"},[],{"tip":"Backport Deployer","align":"E","size":300},[],{"phid":"PHID-XACT-TASK-f4w34cvv3mrmhvt","anchor":"5748443"},{"targetID":"UQ0_5","uri":"\/transactions\/quote\/PHID-XACT-TASK-2x7oyvzzgncznu3\/","ref":"T240307#5749236"},[],{"anchor":"5749236"},[],{"items":"\u003cul class=\"phabricator-action-list-view \"\u003e\u003cli id=\"UQ0_91\" class=\"phabricator-action-view phabricator-action-view-href action-has-icon\" style=\"\"\u003e\u003ca href=\"#\" class=\"phabricator-action-view-item\" data-sigil=\"transaction-quote\" data-meta=\"0_523\"\u003e\u003cspan class=\"visual-only phui-icon-view phui-font-fa fa-quote-left phabricator-action-view-icon\" data-meta=\"0_524\" aria-hidden=\"true\"\u003e\u003c\/span\u003eQuote Comment\u003c\/a\u003e\u003c\/li\u003e\u003cli id=\"UQ0_93\" class=\"phabricator-action-view phabricator-action-view-href action-has-icon\" style=\"\"\u003e\u003ca href=\"\/transactions\/raw\/PHID-XACT-TASK-2x7oyvzzgncznu3\/\" class=\"phabricator-action-view-item\" data-sigil=\"transaction-raw\" data-meta=\"0_525\"\u003e\u003cspan class=\"visual-only phui-icon-view phui-font-fa fa-code phabricator-action-view-icon\" data-meta=\"0_526\" aria-hidden=\"true\"\u003e\u003c\/span\u003eView Raw Remarkup\u003c\/a\u003e\u003c\/li\u003e\u003c\/ul\u003e"},[],{"tip":"Via Web"},[],{"tip":"Web Perf Hero","align":"E","size":300},[],{"tip":"Rat Catcher","align":"E","size":300},[],{"phid":"PHID-XACT-TASK-2x7oyvzzgncznu3","anchor":"5749236"},{"targetID":"UQ0_5","uri":"\/transactions\/quote\/PHID-XACT-TASK-xlzpiuks3afl5yo\/","ref":"T240307#5750645"},[],{"anchor":"5750645"},[],{"items":"\u003cul class=\"phabricator-action-list-view \"\u003e\u003cli id=\"UQ0_95\" class=\"phabricator-action-view phabricator-action-view-href action-has-icon\" style=\"\"\u003e\u003ca href=\"#\" class=\"phabricator-action-view-item\" data-sigil=\"transaction-quote\" data-meta=\"0_536\"\u003e\u003cspan class=\"visual-only phui-icon-view phui-font-fa fa-quote-left phabricator-action-view-icon\" data-meta=\"0_537\" aria-hidden=\"true\"\u003e\u003c\/span\u003eQuote Comment\u003c\/a\u003e\u003c\/li\u003e\u003cli id=\"UQ0_97\" class=\"phabricator-action-view phabricator-action-view-href action-has-icon\" style=\"\"\u003e\u003ca href=\"\/transactions\/raw\/PHID-XACT-TASK-xlzpiuks3afl5yo\/\" class=\"phabricator-action-view-item\" data-sigil=\"transaction-raw\" data-meta=\"0_538\"\u003e\u003cspan class=\"visual-only phui-icon-view phui-font-fa fa-code phabricator-action-view-icon\" data-meta=\"0_539\" aria-hidden=\"true\"\u003e\u003c\/span\u003eView Raw Remarkup\u003c\/a\u003e\u003c\/li\u003e\u003c\/ul\u003e"},[],{"tip":"Via Web"},[],{"tip":"Mentor","align":"E","size":300},[],{"tip":"ResourceLoader module terminator ","align":"E","size":300},[],{"phid":"PHID-XACT-TASK-xlzpiuks3afl5yo","anchor":"5750645"},{"targetID":"UQ0_5","uri":"\/transactions\/quote\/PHID-XACT-TASK-247dlhkzogi2c5q\/","ref":"T240307#5750750"},[],{"anchor":"5750750"},[],{"items":"\u003cul class=\"phabricator-action-list-view \"\u003e\u003cli id=\"UQ0_99\" class=\"phabricator-action-view phabricator-action-view-href action-has-icon\" style=\"\"\u003e\u003ca href=\"#\" class=\"phabricator-action-view-item\" data-sigil=\"transaction-quote\" data-meta=\"0_549\"\u003e\u003cspan class=\"visual-only phui-icon-view phui-font-fa fa-quote-left phabricator-action-view-icon\" data-meta=\"0_550\" aria-hidden=\"true\"\u003e\u003c\/span\u003eQuote Comment\u003c\/a\u003e\u003c\/li\u003e\u003cli id=\"UQ0_101\" class=\"phabricator-action-view phabricator-action-view-href action-has-icon\" style=\"\"\u003e\u003ca href=\"\/transactions\/raw\/PHID-XACT-TASK-247dlhkzogi2c5q\/\" class=\"phabricator-action-view-item\" data-sigil=\"transaction-raw\" data-meta=\"0_551\"\u003e\u003cspan class=\"visual-only phui-icon-view phui-font-fa fa-code phabricator-action-view-icon\" data-meta=\"0_552\" aria-hidden=\"true\"\u003e\u003c\/span\u003eView Raw Remarkup\u003c\/a\u003e\u003c\/li\u003e\u003c\/ul\u003e"},[],{"tip":"Via Web"},[],{"tip":"Nerd Sniper","align":"E","size":300},[],{"phid":"PHID-XACT-TASK-247dlhkzogi2c5q","anchor":"5750750"},{"targetID":"UQ0_5","uri":"\/transactions\/quote\/PHID-XACT-TASK-4fhbywfo66hwchs\/","ref":"T240307#5752156"},[],{"anchor":"5752156"},[],{"items":"\u003cul class=\"phabricator-action-list-view \"\u003e\u003cli id=\"UQ0_103\" class=\"phabricator-action-view phabricator-action-view-href action-has-icon\" style=\"\"\u003e\u003ca href=\"#\" class=\"phabricator-action-view-item\" data-sigil=\"transaction-quote\" data-meta=\"0_560\"\u003e\u003cspan class=\"visual-only phui-icon-view phui-font-fa fa-quote-left phabricator-action-view-icon\" data-meta=\"0_561\" aria-hidden=\"true\"\u003e\u003c\/span\u003eQuote Comment\u003c\/a\u003e\u003c\/li\u003e\u003cli id=\"UQ0_105\" class=\"phabricator-action-view phabricator-action-view-href action-has-icon\" style=\"\"\u003e\u003ca href=\"\/transactions\/raw\/PHID-XACT-TASK-4fhbywfo66hwchs\/\" class=\"phabricator-action-view-item\" data-sigil=\"transaction-raw\" data-meta=\"0_562\"\u003e\u003cspan class=\"visual-only phui-icon-view phui-font-fa fa-code phabricator-action-view-icon\" data-meta=\"0_563\" aria-hidden=\"true\"\u003e\u003c\/span\u003eView Raw Remarkup\u003c\/a\u003e\u003c\/li\u003e\u003c\/ul\u003e"},[],{"tip":"Via Web"},[],{"tip":"Backport Deployer","align":"E","size":300},[],{"phid":"PHID-XACT-TASK-4fhbywfo66hwchs","anchor":"5752156"},{"targetID":"UQ0_5","uri":"\/transactions\/quote\/PHID-XACT-TASK-oxy22xximh3osg4\/","ref":"T240307#5771802"},[],{"anchor":"5771802"},[],{"items":"\u003cul class=\"phabricator-action-list-view \"\u003e\u003cli id=\"UQ0_107\" class=\"phabricator-action-view phabricator-action-view-href action-has-icon\" style=\"\"\u003e\u003ca href=\"#\" class=\"phabricator-action-view-item\" data-sigil=\"transaction-quote\" data-meta=\"0_571\"\u003e\u003cspan class=\"visual-only phui-icon-view phui-font-fa fa-quote-left phabricator-action-view-icon\" data-meta=\"0_572\" aria-hidden=\"true\"\u003e\u003c\/span\u003eQuote Comment\u003c\/a\u003e\u003c\/li\u003e\u003cli id=\"UQ0_109\" class=\"phabricator-action-view phabricator-action-view-href action-has-icon\" style=\"\"\u003e\u003ca href=\"\/transactions\/raw\/PHID-XACT-TASK-oxy22xximh3osg4\/\" class=\"phabricator-action-view-item\" data-sigil=\"transaction-raw\" data-meta=\"0_573\"\u003e\u003cspan class=\"visual-only phui-icon-view phui-font-fa fa-code phabricator-action-view-icon\" data-meta=\"0_574\" aria-hidden=\"true\"\u003e\u003c\/span\u003eView Raw Remarkup\u003c\/a\u003e\u003c\/li\u003e\u003c\/ul\u003e"},[],{"tip":"Via Web"},[],{"phid":"PHID-XACT-TASK-oxy22xximh3osg4","anchor":"5771802"},{"targetID":"UQ0_5","uri":"\/transactions\/quote\/PHID-XACT-TASK-nz5wpkyqgz3aace\/","ref":"T240307#5780427"},[],{"anchor":"5780427"},[],{"items":"\u003cul class=\"phabricator-action-list-view \"\u003e\u003cli id=\"UQ0_111\" class=\"phabricator-action-view phabricator-action-view-href action-has-icon\" style=\"\"\u003e\u003ca href=\"#\" class=\"phabricator-action-view-item\" data-sigil=\"transaction-quote\" data-meta=\"0_580\"\u003e\u003cspan class=\"visual-only phui-icon-view phui-font-fa fa-quote-left phabricator-action-view-icon\" data-meta=\"0_581\" aria-hidden=\"true\"\u003e\u003c\/span\u003eQuote Comment\u003c\/a\u003e\u003c\/li\u003e\u003cli id=\"UQ0_113\" class=\"phabricator-action-view phabricator-action-view-href action-has-icon\" style=\"\"\u003e\u003ca href=\"\/transactions\/raw\/PHID-XACT-TASK-nz5wpkyqgz3aace\/\" class=\"phabricator-action-view-item\" data-sigil=\"transaction-raw\" data-meta=\"0_582\"\u003e\u003cspan class=\"visual-only phui-icon-view phui-font-fa fa-code phabricator-action-view-icon\" data-meta=\"0_583\" aria-hidden=\"true\"\u003e\u003c\/span\u003eView Raw Remarkup\u003c\/a\u003e\u003c\/li\u003e\u003c\/ul\u003e"},[],{"tip":"Via Web"},[],{"phid":"PHID-XACT-TASK-nz5wpkyqgz3aace","anchor":"5780427"},{"targetID":"UQ0_5","uri":"\/transactions\/quote\/PHID-XACT-TASK-ccyjxks4qxc4eeu\/","ref":"T240307#5784843"},[],{"anchor":"5784843"},[],{"items":"\u003cul class=\"phabricator-action-list-view \"\u003e\u003cli id=\"UQ0_115\" class=\"phabricator-action-view phabricator-action-view-href action-has-icon\" style=\"\"\u003e\u003ca href=\"#\" class=\"phabricator-action-view-item\" data-sigil=\"transaction-quote\" data-meta=\"0_589\"\u003e\u003cspan class=\"visual-only phui-icon-view phui-font-fa fa-quote-left phabricator-action-view-icon\" data-meta=\"0_590\" aria-hidden=\"true\"\u003e\u003c\/span\u003eQuote Comment\u003c\/a\u003e\u003c\/li\u003e\u003cli id=\"UQ0_117\" class=\"phabricator-action-view phabricator-action-view-href action-has-icon\" style=\"\"\u003e\u003ca href=\"\/transactions\/raw\/PHID-XACT-TASK-ccyjxks4qxc4eeu\/\" class=\"phabricator-action-view-item\" data-sigil=\"transaction-raw\" data-meta=\"0_591\"\u003e\u003cspan class=\"visual-only phui-icon-view phui-font-fa fa-code phabricator-action-view-icon\" data-meta=\"0_592\" aria-hidden=\"true\"\u003e\u003c\/span\u003eView Raw Remarkup\u003c\/a\u003e\u003c\/li\u003e\u003c\/ul\u003e"},[],{"tip":"Via Web"},[],{"phid":"PHID-XACT-TASK-5qzldtm434g3rb3","anchor":"5784843"},{"tip":"Via Web"},[],{"phid":"PHID-XACT-TASK-olhipq7fyeypexg","anchor":"5784855"},{"targetID":"UQ0_5","uri":"\/transactions\/quote\/PHID-XACT-TASK-qppfhbejsch7ypf\/","ref":"T240307#5784856"},[],{"anchor":"5784856"},[],{"items":"\u003cul class=\"phabricator-action-list-view \"\u003e\u003cli id=\"UQ0_119\" class=\"phabricator-action-view phabricator-action-view-href action-has-icon\" style=\"\"\u003e\u003ca href=\"#\" class=\"phabricator-action-view-item\" data-sigil=\"transaction-quote\" data-meta=\"0_601\"\u003e\u003cspan class=\"visual-only phui-icon-view phui-font-fa fa-quote-left phabricator-action-view-icon\" data-meta=\"0_602\" aria-hidden=\"true\"\u003e\u003c\/span\u003eQuote Comment\u003c\/a\u003e\u003c\/li\u003e\u003cli id=\"UQ0_121\" class=\"phabricator-action-view phabricator-action-view-href action-has-icon\" style=\"\"\u003e\u003ca href=\"\/transactions\/raw\/PHID-XACT-TASK-qppfhbejsch7ypf\/\" class=\"phabricator-action-view-item\" data-sigil=\"transaction-raw\" data-meta=\"0_603\"\u003e\u003cspan class=\"visual-only phui-icon-view phui-font-fa fa-code phabricator-action-view-icon\" data-meta=\"0_604\" aria-hidden=\"true\"\u003e\u003c\/span\u003eView Raw Remarkup\u003c\/a\u003e\u003c\/li\u003e\u003c\/ul\u003e"},[],{"tip":"Via Web"},[],{"phid":"PHID-XACT-TASK-qppfhbejsch7ypf","anchor":"5784856"},{"targetID":"UQ0_5","uri":"\/transactions\/quote\/PHID-XACT-TASK-qfla3plcvij3g72\/","ref":"T240307#5786336"},[],{"anchor":"5786336"},[],{"items":"\u003cul class=\"phabricator-action-list-view \"\u003e\u003cli id=\"UQ0_123\" class=\"phabricator-action-view phabricator-action-view-href action-has-icon\" style=\"\"\u003e\u003ca href=\"#\" class=\"phabricator-action-view-item\" data-sigil=\"transaction-quote\" data-meta=\"0_610\"\u003e\u003cspan class=\"visual-only phui-icon-view phui-font-fa fa-quote-left phabricator-action-view-icon\" data-meta=\"0_611\" aria-hidden=\"true\"\u003e\u003c\/span\u003eQuote Comment\u003c\/a\u003e\u003c\/li\u003e\u003cli id=\"UQ0_125\" class=\"phabricator-action-view phabricator-action-view-href action-has-icon\" style=\"\"\u003e\u003ca href=\"\/transactions\/raw\/PHID-XACT-TASK-qfla3plcvij3g72\/\" class=\"phabricator-action-view-item\" data-sigil=\"transaction-raw\" data-meta=\"0_612\"\u003e\u003cspan class=\"visual-only phui-icon-view phui-font-fa fa-code phabricator-action-view-icon\" data-meta=\"0_613\" aria-hidden=\"true\"\u003e\u003c\/span\u003eView Raw Remarkup\u003c\/a\u003e\u003c\/li\u003e\u003c\/ul\u003e"},[],{"tip":"Via Web"},[],{"tip":"Backport Deployer","align":"E","size":300},[],{"phid":"PHID-XACT-TASK-qfla3plcvij3g72","anchor":"5786336"},{"targetID":"UQ0_5","uri":"\/transactions\/quote\/PHID-XACT-TASK-a3u74gyuv5rhvb4\/","ref":"T240307#5786976"},[],{"anchor":"5786976"},[],{"items":"\u003cul class=\"phabricator-action-list-view \"\u003e\u003cli id=\"UQ0_127\" class=\"phabricator-action-view phabricator-action-view-href action-has-icon\" style=\"\"\u003e\u003ca href=\"#\" class=\"phabricator-action-view-item\" data-sigil=\"transaction-quote\" data-meta=\"0_621\"\u003e\u003cspan class=\"visual-only phui-icon-view phui-font-fa fa-quote-left phabricator-action-view-icon\" data-meta=\"0_622\" aria-hidden=\"true\"\u003e\u003c\/span\u003eQuote Comment\u003c\/a\u003e\u003c\/li\u003e\u003cli id=\"UQ0_129\" class=\"phabricator-action-view phabricator-action-view-href action-has-icon\" style=\"\"\u003e\u003ca href=\"\/transactions\/raw\/PHID-XACT-TASK-a3u74gyuv5rhvb4\/\" class=\"phabricator-action-view-item\" data-sigil=\"transaction-raw\" data-meta=\"0_623\"\u003e\u003cspan class=\"visual-only phui-icon-view phui-font-fa fa-code phabricator-action-view-icon\" data-meta=\"0_624\" aria-hidden=\"true\"\u003e\u003c\/span\u003eView Raw Remarkup\u003c\/a\u003e\u003c\/li\u003e\u003c\/ul\u003e"},[],{"tip":"Via Web"},[],{"tip":"Nerd Sniper","align":"E","size":300},[],{"phid":"PHID-XACT-TASK-a3u74gyuv5rhvb4","anchor":"5786976"},{"targetID":"UQ0_5","uri":"\/transactions\/quote\/PHID-XACT-TASK-drpq3rvufrzcmxf\/","ref":"T240307#5786978"},[],{"anchor":"5786978"},[],[],{"items":"\u003cul class=\"phabricator-action-list-view \"\u003e\u003cli id=\"UQ0_131\" class=\"phabricator-action-view phabricator-action-view-href action-has-icon\" style=\"\"\u003e\u003ca href=\"#\" class=\"phabricator-action-view-item\" data-sigil=\"transaction-quote\" data-meta=\"0_632\"\u003e\u003cspan class=\"visual-only phui-icon-view phui-font-fa fa-quote-left phabricator-action-view-icon\" data-meta=\"0_633\" aria-hidden=\"true\"\u003e\u003c\/span\u003eQuote Comment\u003c\/a\u003e\u003c\/li\u003e\u003cli id=\"UQ0_133\" class=\"phabricator-action-view phabricator-action-view-href action-has-icon\" style=\"\"\u003e\u003ca href=\"\/transactions\/raw\/PHID-XACT-TASK-drpq3rvufrzcmxf\/\" class=\"phabricator-action-view-item\" data-sigil=\"transaction-raw\" data-meta=\"0_634\"\u003e\u003cspan class=\"visual-only phui-icon-view phui-font-fa fa-code phabricator-action-view-icon\" data-meta=\"0_635\" aria-hidden=\"true\"\u003e\u003c\/span\u003eView Raw Remarkup\u003c\/a\u003e\u003c\/li\u003e\u003cli id=\"UQ0_135\" class=\"phabricator-action-view phabricator-action-view-href action-has-icon\" style=\"\"\u003e\u003ca href=\"\/transactions\/history\/PHID-XACT-TASK-drpq3rvufrzcmxf\/\" class=\"phabricator-action-view-item\" data-sigil=\"workflow\"\u003e\u003cspan class=\"visual-only phui-icon-view phui-font-fa fa-list phabricator-action-view-icon\" data-meta=\"0_636\" aria-hidden=\"true\"\u003e\u003c\/span\u003eView Edit History\u003c\/a\u003e\u003c\/li\u003e\u003c\/ul\u003e"},[],{"tip":"Via Web"},[],{"tip":"Nerd Sniper","align":"E","size":300},[],{"phid":"PHID-XACT-TASK-drpq3rvufrzcmxf","anchor":"5786978"},{"targetID":"UQ0_5","uri":"\/transactions\/quote\/PHID-XACT-TASK-zzsgulitvrzchr2\/","ref":"T240307#5787292"},[],{"anchor":"5787292"},[],{"items":"\u003cul class=\"phabricator-action-list-view \"\u003e\u003cli id=\"UQ0_137\" class=\"phabricator-action-view phabricator-action-view-href action-has-icon\" style=\"\"\u003e\u003ca href=\"#\" class=\"phabricator-action-view-item\" data-sigil=\"transaction-quote\" data-meta=\"0_644\"\u003e\u003cspan class=\"visual-only phui-icon-view phui-font-fa fa-quote-left phabricator-action-view-icon\" data-meta=\"0_645\" aria-hidden=\"true\"\u003e\u003c\/span\u003eQuote Comment\u003c\/a\u003e\u003c\/li\u003e\u003cli id=\"UQ0_139\" class=\"phabricator-action-view phabricator-action-view-href action-has-icon\" style=\"\"\u003e\u003ca href=\"\/transactions\/raw\/PHID-XACT-TASK-zzsgulitvrzchr2\/\" class=\"phabricator-action-view-item\" data-sigil=\"transaction-raw\" data-meta=\"0_646\"\u003e\u003cspan class=\"visual-only phui-icon-view phui-font-fa fa-code phabricator-action-view-icon\" data-meta=\"0_647\" aria-hidden=\"true\"\u003e\u003c\/span\u003eView Raw Remarkup\u003c\/a\u003e\u003c\/li\u003e\u003c\/ul\u003e"},[],{"tip":"Via Web"},[],{"tip":"Backport Deployer","align":"E","size":300},[],{"phid":"PHID-XACT-TASK-zzsgulitvrzchr2","anchor":"5787292"},{"targetID":"UQ0_5","uri":"\/transactions\/quote\/PHID-XACT-TASK-sv6d6udoevvcula\/","ref":"T240307#5791394"},[],{"anchor":"5791394"},[],{"items":"\u003cul class=\"phabricator-action-list-view \"\u003e\u003cli id=\"UQ0_141\" class=\"phabricator-action-view phabricator-action-view-href action-has-icon\" style=\"\"\u003e\u003ca href=\"#\" class=\"phabricator-action-view-item\" data-sigil=\"transaction-quote\" data-meta=\"0_655\"\u003e\u003cspan class=\"visual-only phui-icon-view phui-font-fa fa-quote-left phabricator-action-view-icon\" data-meta=\"0_656\" aria-hidden=\"true\"\u003e\u003c\/span\u003eQuote Comment\u003c\/a\u003e\u003c\/li\u003e\u003cli id=\"UQ0_143\" class=\"phabricator-action-view phabricator-action-view-href action-has-icon\" style=\"\"\u003e\u003ca href=\"\/transactions\/raw\/PHID-XACT-TASK-sv6d6udoevvcula\/\" class=\"phabricator-action-view-item\" data-sigil=\"transaction-raw\" data-meta=\"0_657\"\u003e\u003cspan class=\"visual-only phui-icon-view phui-font-fa fa-code phabricator-action-view-icon\" data-meta=\"0_658\" aria-hidden=\"true\"\u003e\u003c\/span\u003eView Raw Remarkup\u003c\/a\u003e\u003c\/li\u003e\u003c\/ul\u003e"},[],{"tip":"Via Web"},[],{"tip":"Nerd Sniper","align":"E","size":300},[],{"phid":"PHID-XACT-TASK-pcgw5uzvhxdbykw","anchor":"5791394"},{"tip":"Via Web"},[],{"phid":"PHID-XACT-TASK-pjxmf36yop25eu7","anchor":"5793087"},{"tip":"Via Web"},[],{"phid":"PHID-XACT-TASK-xav3dgmk3xcdbwk","anchor":"5810420"},{"targetID":"UQ0_5","uri":"\/transactions\/quote\/PHID-XACT-TASK-i5un6su5bv4wlyg\/","ref":"T240307#5824638"},[],{"anchor":"5824638"},[],{"items":"\u003cul class=\"phabricator-action-list-view \"\u003e\u003cli id=\"UQ0_145\" class=\"phabricator-action-view phabricator-action-view-href action-has-icon\" style=\"\"\u003e\u003ca href=\"#\" class=\"phabricator-action-view-item\" data-sigil=\"transaction-quote\" data-meta=\"0_672\"\u003e\u003cspan class=\"visual-only phui-icon-view phui-font-fa fa-quote-left phabricator-action-view-icon\" data-meta=\"0_673\" aria-hidden=\"true\"\u003e\u003c\/span\u003eQuote Comment\u003c\/a\u003e\u003c\/li\u003e\u003cli id=\"UQ0_147\" class=\"phabricator-action-view phabricator-action-view-href action-has-icon\" style=\"\"\u003e\u003ca href=\"\/transactions\/raw\/PHID-XACT-TASK-i5un6su5bv4wlyg\/\" class=\"phabricator-action-view-item\" data-sigil=\"transaction-raw\" data-meta=\"0_674\"\u003e\u003cspan class=\"visual-only phui-icon-view phui-font-fa fa-code phabricator-action-view-icon\" data-meta=\"0_675\" aria-hidden=\"true\"\u003e\u003c\/span\u003eView Raw Remarkup\u003c\/a\u003e\u003c\/li\u003e\u003c\/ul\u003e"},[],{"tip":"Via Web"},[],{"tip":"Nerd Sniper","align":"E","size":300},[],{"phid":"PHID-XACT-TASK-pbbxgue2lrejsgj","anchor":"5824638"},{"tip":"Via Web"},[],{"phid":"PHID-XACT-TASK-s7hcfdrrsa3la6q","anchor":"5836721"},{"targetID":"UQ0_5","uri":"\/transactions\/quote\/PHID-XACT-TASK-ebemnv3sogxwrah\/","ref":"T240307#5865067"},[],{"anchor":"5865067"},[],{"items":"\u003cul class=\"phabricator-action-list-view \"\u003e\u003cli id=\"UQ0_149\" class=\"phabricator-action-view phabricator-action-view-href action-has-icon\" style=\"\"\u003e\u003ca href=\"#\" class=\"phabricator-action-view-item\" data-sigil=\"transaction-quote\" data-meta=\"0_686\"\u003e\u003cspan class=\"visual-only phui-icon-view phui-font-fa fa-quote-left phabricator-action-view-icon\" data-meta=\"0_687\" aria-hidden=\"true\"\u003e\u003c\/span\u003eQuote Comment\u003c\/a\u003e\u003c\/li\u003e\u003cli id=\"UQ0_151\" class=\"phabricator-action-view phabricator-action-view-href action-has-icon\" style=\"\"\u003e\u003ca href=\"\/transactions\/raw\/PHID-XACT-TASK-ebemnv3sogxwrah\/\" class=\"phabricator-action-view-item\" data-sigil=\"transaction-raw\" data-meta=\"0_688\"\u003e\u003cspan class=\"visual-only phui-icon-view phui-font-fa fa-code phabricator-action-view-icon\" data-meta=\"0_689\" aria-hidden=\"true\"\u003e\u003c\/span\u003eView Raw Remarkup\u003c\/a\u003e\u003c\/li\u003e\u003c\/ul\u003e"},[],{"tip":"Via Conduit"},[],{"phid":"PHID-XACT-TASK-ebemnv3sogxwrah","anchor":"5865067"},{"tip":"Via Conduit"},[],{"phid":"PHID-XACT-TASK-qqtrrspiixairfw","anchor":"5865068"},{"tip":"Via Web"},[],{"phid":"PHID-XACT-TASK-d7ttuac2sc2sjcx","anchor":"5899330"},{"targetID":"UQ0_5","uri":"\/transactions\/quote\/PHID-XACT-TASK-px3taxs4y7x354h\/","ref":"T240307#5910913"},[],{"anchor":"5910913"},[],{"items":"\u003cul class=\"phabricator-action-list-view \"\u003e\u003cli id=\"UQ0_153\" class=\"phabricator-action-view phabricator-action-view-href action-has-icon\" style=\"\"\u003e\u003ca href=\"#\" class=\"phabricator-action-view-item\" data-sigil=\"transaction-quote\" data-meta=\"0_701\"\u003e\u003cspan class=\"visual-only phui-icon-view phui-font-fa fa-quote-left phabricator-action-view-icon\" data-meta=\"0_702\" aria-hidden=\"true\"\u003e\u003c\/span\u003eQuote Comment\u003c\/a\u003e\u003c\/li\u003e\u003cli id=\"UQ0_155\" class=\"phabricator-action-view phabricator-action-view-href action-has-icon\" style=\"\"\u003e\u003ca href=\"\/transactions\/raw\/PHID-XACT-TASK-px3taxs4y7x354h\/\" class=\"phabricator-action-view-item\" data-sigil=\"transaction-raw\" data-meta=\"0_703\"\u003e\u003cspan class=\"visual-only phui-icon-view phui-font-fa fa-code phabricator-action-view-icon\" data-meta=\"0_704\" aria-hidden=\"true\"\u003e\u003c\/span\u003eView Raw Remarkup\u003c\/a\u003e\u003c\/li\u003e\u003c\/ul\u003e"},[],{"tip":"Via Conduit"},[],{"phid":"PHID-XACT-TASK-px3taxs4y7x354h","anchor":"5910913"},{"targetID":"UQ0_5","uri":"\/transactions\/quote\/PHID-XACT-TASK-oztplda4a3u5bcw\/","ref":"T240307#5918671"},[],{"anchor":"5918671"},[],{"items":"\u003cul class=\"phabricator-action-list-view \"\u003e\u003cli id=\"UQ0_157\" class=\"phabricator-action-view phabricator-action-view-href action-has-icon\" style=\"\"\u003e\u003ca href=\"#\" class=\"phabricator-action-view-item\" data-sigil=\"transaction-quote\" data-meta=\"0_710\"\u003e\u003cspan class=\"visual-only phui-icon-view phui-font-fa fa-quote-left phabricator-action-view-icon\" data-meta=\"0_711\" aria-hidden=\"true\"\u003e\u003c\/span\u003eQuote Comment\u003c\/a\u003e\u003c\/li\u003e\u003cli id=\"UQ0_159\" class=\"phabricator-action-view phabricator-action-view-href action-has-icon\" style=\"\"\u003e\u003ca href=\"\/transactions\/raw\/PHID-XACT-TASK-oztplda4a3u5bcw\/\" class=\"phabricator-action-view-item\" data-sigil=\"transaction-raw\" data-meta=\"0_712\"\u003e\u003cspan class=\"visual-only phui-icon-view phui-font-fa fa-code phabricator-action-view-icon\" data-meta=\"0_713\" aria-hidden=\"true\"\u003e\u003c\/span\u003eView Raw Remarkup\u003c\/a\u003e\u003c\/li\u003e\u003c\/ul\u003e"},[],{"tip":"Via Conduit"},[],{"phid":"PHID-XACT-TASK-oztplda4a3u5bcw","anchor":"5918671"},{"tip":"Via Web"},[],{"phid":"PHID-XACT-TASK-zjiozjz5lgrht6j","anchor":"5918688"},{"targetID":"UQ0_5","uri":"\/transactions\/quote\/PHID-XACT-TASK-3dppwm4f3sp2ulr\/","ref":"T240307#5925594"},[],{"anchor":"5925594"},[],{"items":"\u003cul class=\"phabricator-action-list-view \"\u003e\u003cli id=\"UQ0_161\" class=\"phabricator-action-view phabricator-action-view-href action-has-icon\" style=\"\"\u003e\u003ca href=\"#\" class=\"phabricator-action-view-item\" data-sigil=\"transaction-quote\" data-meta=\"0_722\"\u003e\u003cspan class=\"visual-only phui-icon-view phui-font-fa fa-quote-left phabricator-action-view-icon\" data-meta=\"0_723\" aria-hidden=\"true\"\u003e\u003c\/span\u003eQuote Comment\u003c\/a\u003e\u003c\/li\u003e\u003cli id=\"UQ0_163\" class=\"phabricator-action-view phabricator-action-view-href action-has-icon\" style=\"\"\u003e\u003ca href=\"\/transactions\/raw\/PHID-XACT-TASK-3dppwm4f3sp2ulr\/\" class=\"phabricator-action-view-item\" data-sigil=\"transaction-raw\" data-meta=\"0_724\"\u003e\u003cspan class=\"visual-only phui-icon-view phui-font-fa fa-code phabricator-action-view-icon\" data-meta=\"0_725\" aria-hidden=\"true\"\u003e\u003c\/span\u003eView Raw Remarkup\u003c\/a\u003e\u003c\/li\u003e\u003c\/ul\u003e"},[],{"tip":"Via Conduit"},[],{"phid":"PHID-XACT-TASK-3dppwm4f3sp2ulr","anchor":"5925594"},{"targetID":"UQ0_5","uri":"\/transactions\/quote\/PHID-XACT-TASK-prnqfzqdnvfzb6r\/","ref":"T240307#5945400"},[],{"anchor":"5945400"},[],{"items":"\u003cul class=\"phabricator-action-list-view \"\u003e\u003cli id=\"UQ0_165\" class=\"phabricator-action-view phabricator-action-view-href action-has-icon\" style=\"\"\u003e\u003ca href=\"#\" class=\"phabricator-action-view-item\" data-sigil=\"transaction-quote\" data-meta=\"0_731\"\u003e\u003cspan class=\"visual-only phui-icon-view phui-font-fa fa-quote-left phabricator-action-view-icon\" data-meta=\"0_732\" aria-hidden=\"true\"\u003e\u003c\/span\u003eQuote Comment\u003c\/a\u003e\u003c\/li\u003e\u003cli id=\"UQ0_167\" class=\"phabricator-action-view phabricator-action-view-href action-has-icon\" style=\"\"\u003e\u003ca href=\"\/transactions\/raw\/PHID-XACT-TASK-prnqfzqdnvfzb6r\/\" class=\"phabricator-action-view-item\" data-sigil=\"transaction-raw\" data-meta=\"0_733\"\u003e\u003cspan class=\"visual-only phui-icon-view phui-font-fa fa-code phabricator-action-view-icon\" data-meta=\"0_734\" aria-hidden=\"true\"\u003e\u003c\/span\u003eView Raw Remarkup\u003c\/a\u003e\u003c\/li\u003e\u003c\/ul\u003e"},[],{"tip":"Via Conduit"},[],{"phid":"PHID-XACT-TASK-prnqfzqdnvfzb6r","anchor":"5945400"},{"tip":"Via Conduit"},[],{"phid":"PHID-XACT-TASK-uaxupx4u7re7dan","anchor":"5945430"},{"targetID":"UQ0_5","uri":"\/transactions\/quote\/PHID-XACT-TASK-erwozga5nyyimzd\/","ref":"T240307#5947174"},[],{"anchor":"5947174"},[],{"items":"\u003cul class=\"phabricator-action-list-view \"\u003e\u003cli id=\"UQ0_169\" class=\"phabricator-action-view phabricator-action-view-href action-has-icon\" style=\"\"\u003e\u003ca href=\"#\" class=\"phabricator-action-view-item\" data-sigil=\"transaction-quote\" data-meta=\"0_743\"\u003e\u003cspan class=\"visual-only phui-icon-view phui-font-fa fa-quote-left phabricator-action-view-icon\" data-meta=\"0_744\" aria-hidden=\"true\"\u003e\u003c\/span\u003eQuote Comment\u003c\/a\u003e\u003c\/li\u003e\u003cli id=\"UQ0_171\" class=\"phabricator-action-view phabricator-action-view-href action-has-icon\" style=\"\"\u003e\u003ca href=\"\/transactions\/raw\/PHID-XACT-TASK-erwozga5nyyimzd\/\" class=\"phabricator-action-view-item\" data-sigil=\"transaction-raw\" data-meta=\"0_745\"\u003e\u003cspan class=\"visual-only phui-icon-view phui-font-fa fa-code phabricator-action-view-icon\" data-meta=\"0_746\" aria-hidden=\"true\"\u003e\u003c\/span\u003eView Raw Remarkup\u003c\/a\u003e\u003c\/li\u003e\u003c\/ul\u003e"},[],{"tip":"Via Conduit"},[],{"phid":"PHID-XACT-TASK-erwozga5nyyimzd","anchor":"5947174"},{"tip":"Via Web"},[],{"phid":"PHID-XACT-TASK-yz7ej4hvrzlhvru","anchor":"5953282"},{"tip":"Via Web"},[],{"phid":"PHID-XACT-TASK-zmrvrlvdotmrxr5","anchor":"5960502"},{"tip":"Via Web"},[],[],{"phid":"PHID-XACT-TASK-4yndy7hyhscte5a","anchor":"5980694"},{"tip":"Via Bulk Update"},[],{"phid":"PHID-XACT-TASK-zdet5nn2dcgho4e","anchor":"5987573"},{"tip":"Via Web"},[],{"phid":"PHID-XACT-TASK-obayudyyteufvnp","anchor":"6021288"},{"tip":"Via Web"},[],{"phid":"PHID-XACT-TASK-jxxt2patkscflzx","anchor":"6028455"},{"tip":"Via Web"},[],{"phid":"PHID-XACT-TASK-hd3du5yutwg2b6s","anchor":"6048624"},{"targetID":"UQ0_5","uri":"\/transactions\/quote\/PHID-XACT-TASK-75h2nsgemflivpl\/","ref":"T240307#6064776"},[],{"anchor":"6064776"},[],{"items":"\u003cul class=\"phabricator-action-list-view \"\u003e\u003cli id=\"UQ0_173\" class=\"phabricator-action-view phabricator-action-view-href action-has-icon\" style=\"\"\u003e\u003ca href=\"#\" class=\"phabricator-action-view-item\" data-sigil=\"transaction-quote\" data-meta=\"0_774\"\u003e\u003cspan class=\"visual-only phui-icon-view phui-font-fa fa-quote-left phabricator-action-view-icon\" data-meta=\"0_775\" aria-hidden=\"true\"\u003e\u003c\/span\u003eQuote Comment\u003c\/a\u003e\u003c\/li\u003e\u003cli id=\"UQ0_175\" class=\"phabricator-action-view phabricator-action-view-href action-has-icon\" style=\"\"\u003e\u003ca href=\"\/transactions\/raw\/PHID-XACT-TASK-75h2nsgemflivpl\/\" class=\"phabricator-action-view-item\" data-sigil=\"transaction-raw\" data-meta=\"0_776\"\u003e\u003cspan class=\"visual-only phui-icon-view phui-font-fa fa-code phabricator-action-view-icon\" data-meta=\"0_777\" aria-hidden=\"true\"\u003e\u003c\/span\u003eView Raw Remarkup\u003c\/a\u003e\u003c\/li\u003e\u003c\/ul\u003e"},[],{"tip":"Via Conduit"},[],{"phid":"PHID-XACT-TASK-75h2nsgemflivpl","anchor":"6064776"},{"tip":"Via Web"},[],{"phid":"PHID-XACT-TASK-q3nvhig5cgs4uvb","anchor":"6065433"},{"tip":"Via Web"},[],{"tip":"Chaos Monkey","align":"E","size":300},[],{"phid":"PHID-XACT-TASK-djjrrpcqspjuuxi","anchor":"6065997"},{"tip":"Via Web"},[],{"phid":"PHID-XACT-TASK-g7qzqujlcwhqgrt","anchor":"6066032"},{"targetID":"UQ0_5","uri":"\/transactions\/quote\/PHID-XACT-TASK-sret55wl4ycbsd2\/","ref":"T240307#6066217"},[],{"anchor":"6066217"},[],{"items":"\u003cul class=\"phabricator-action-list-view \"\u003e\u003cli id=\"UQ0_177\" class=\"phabricator-action-view phabricator-action-view-href action-has-icon\" style=\"\"\u003e\u003ca href=\"#\" class=\"phabricator-action-view-item\" data-sigil=\"transaction-quote\" data-meta=\"0_794\"\u003e\u003cspan class=\"visual-only phui-icon-view phui-font-fa fa-quote-left phabricator-action-view-icon\" data-meta=\"0_795\" aria-hidden=\"true\"\u003e\u003c\/span\u003eQuote Comment\u003c\/a\u003e\u003c\/li\u003e\u003cli id=\"UQ0_179\" class=\"phabricator-action-view phabricator-action-view-href action-has-icon\" style=\"\"\u003e\u003ca href=\"\/transactions\/raw\/PHID-XACT-TASK-sret55wl4ycbsd2\/\" class=\"phabricator-action-view-item\" data-sigil=\"transaction-raw\" data-meta=\"0_796\"\u003e\u003cspan class=\"visual-only phui-icon-view phui-font-fa fa-code phabricator-action-view-icon\" data-meta=\"0_797\" aria-hidden=\"true\"\u003e\u003c\/span\u003eView Raw Remarkup\u003c\/a\u003e\u003c\/li\u003e\u003c\/ul\u003e"},[],{"tip":"Via Web"},[],{"phid":"PHID-XACT-TASK-sret55wl4ycbsd2","anchor":"6066217"},{"targetID":"UQ0_5","uri":"\/transactions\/quote\/PHID-XACT-TASK-4x7ywnuiybduiw7\/","ref":"T240307#6073896"},[],{"anchor":"6073896"},[],{"items":"\u003cul class=\"phabricator-action-list-view \"\u003e\u003cli id=\"UQ0_181\" class=\"phabricator-action-view phabricator-action-view-href action-has-icon\" style=\"\"\u003e\u003ca href=\"#\" class=\"phabricator-action-view-item\" data-sigil=\"transaction-quote\" data-meta=\"0_803\"\u003e\u003cspan class=\"visual-only phui-icon-view phui-font-fa fa-quote-left phabricator-action-view-icon\" data-meta=\"0_804\" aria-hidden=\"true\"\u003e\u003c\/span\u003eQuote Comment\u003c\/a\u003e\u003c\/li\u003e\u003cli id=\"UQ0_183\" class=\"phabricator-action-view phabricator-action-view-href action-has-icon\" style=\"\"\u003e\u003ca href=\"\/transactions\/raw\/PHID-XACT-TASK-4x7ywnuiybduiw7\/\" class=\"phabricator-action-view-item\" data-sigil=\"transaction-raw\" data-meta=\"0_805\"\u003e\u003cspan class=\"visual-only phui-icon-view phui-font-fa fa-code phabricator-action-view-icon\" data-meta=\"0_806\" aria-hidden=\"true\"\u003e\u003c\/span\u003eView Raw Remarkup\u003c\/a\u003e\u003c\/li\u003e\u003c\/ul\u003e"},[],{"tip":"Via Conduit"},[],{"phid":"PHID-XACT-TASK-4x7ywnuiybduiw7","anchor":"6073896"},{"targetID":"UQ0_5","uri":"\/transactions\/quote\/PHID-XACT-TASK-4xpm4tt73bn34gs\/","ref":"T240307#6073901"},[],{"anchor":"6073901"},[],{"items":"\u003cul class=\"phabricator-action-list-view \"\u003e\u003cli id=\"UQ0_185\" class=\"phabricator-action-view phabricator-action-view-href action-has-icon\" style=\"\"\u003e\u003ca href=\"#\" class=\"phabricator-action-view-item\" data-sigil=\"transaction-quote\" data-meta=\"0_812\"\u003e\u003cspan class=\"visual-only phui-icon-view phui-font-fa fa-quote-left phabricator-action-view-icon\" data-meta=\"0_813\" aria-hidden=\"true\"\u003e\u003c\/span\u003eQuote Comment\u003c\/a\u003e\u003c\/li\u003e\u003cli id=\"UQ0_187\" class=\"phabricator-action-view phabricator-action-view-href action-has-icon\" style=\"\"\u003e\u003ca href=\"\/transactions\/raw\/PHID-XACT-TASK-4xpm4tt73bn34gs\/\" class=\"phabricator-action-view-item\" data-sigil=\"transaction-raw\" data-meta=\"0_814\"\u003e\u003cspan class=\"visual-only phui-icon-view phui-font-fa fa-code phabricator-action-view-icon\" data-meta=\"0_815\" aria-hidden=\"true\"\u003e\u003c\/span\u003eView Raw Remarkup\u003c\/a\u003e\u003c\/li\u003e\u003c\/ul\u003e"},[],{"tip":"Via Conduit"},[],{"phid":"PHID-XACT-TASK-4xpm4tt73bn34gs","anchor":"6073901"}],"javelin_behaviors":{"phui-hovercards":[],"phabricator-watch-anchor":[],"phabricator-tooltips":[],"phui-dropdown-menu":[]},"javelin_resources":["https:\/\/phab.wmfusercontent.org\/res\/defaultX\/phabricator\/2eeda9e0\/core.pkg.js","https:\/\/phab.wmfusercontent.org\/res\/defaultX\/phabricator\/98e6504a\/rsrc\/externals\/javelin\/core\/init.js","https:\/\/phab.wmfusercontent.org\/res\/defaultX\/phabricator\/968d91ee\/core.pkg.css","https:\/\/phab.wmfusercontent.org\/res\/defaultX\/phabricator\/666e25ad\/rsrc\/css\/phui\/phui-badge.css"]}