From 6e525c1199a31f53db5ec697cd399763c90c54eb Mon Sep 17 00:00:00 2001 From: Dan Mosedale Date: Sun, 16 Aug 2026 19:06:20 -0400 Subject: [PATCH 1/3] Route Firefox :: Messaging System bugs to #omc-triage Add the desktop Messaging System (about:welcome, feature callouts, Spotlight, Infobars) as a triaged area: a SLACK_CHANNELS entry for "Firefox :: Messaging System", the matching README routing row and component list entry, and the source locations (browser/components/asrouter/, browser/components/aboutwelcome/, toolkit/components/messaging-system/) in the triage rules so localization has somewhere to look. --- agents/frontend-triage/README.md | 18 ++++++++++++++++++ .../hackbot_agents/frontend_triage/config.py | 4 ++++ .../frontend_triage/rules/frontend-triage.md | 18 +++++++++++++++--- agents/frontend-triage/tests/test_notify.py | 1 + 4 files changed, 38 insertions(+), 3 deletions(-) diff --git a/agents/frontend-triage/README.md b/agents/frontend-triage/README.md index fe816b1644..0b8d4cb19b 100644 --- a/agents/frontend-triage/README.md +++ b/agents/frontend-triage/README.md @@ -34,6 +34,7 @@ grouped: `mobile/android/android-components/`. - **Application updater** — `Toolkit :: Application Update` (`.sys.mjs`, IDL, C++). - **Windows installer** — `Firefox :: Installer` (NSIS). +- **Messaging System**: `Firefox :: Messaging System` (incl. about:welcome, feature callouts, Spotlight modal dialogs, Infobars). Install and update bugs are the odd ones out: they arrive as a failure with an error code and an `update.log` or installer log, usually with no steps to @@ -195,7 +196,24 @@ Routing is the `channel` on each `TRIAGE_SCOPE` entry in `config.py`, looked up `ScopedComponent("Firefox", "New Tab Page", "Desktop frontend", "#hnt-dev-triage")` sends a New Tab Page run to `#hnt-dev-triage`. +<<<<<<< HEAD Four things about that which are not obvious from reading the registry: +||||||| parent of 5d6d8e9c (Route Firefox :: Messaging System bugs to #omc-triage) +| Product :: Component | Channel | +| -------------------------------- | ------------------------------- | +| `Firefox :: New Tab Page` | `#hnt-dev-triage` | +| `Firefox for Android :: History` | `#android-core-dev` | +| `Toolkit :: Application Update` | `#installer-updater-bug-triage` | +| `Firefox :: Installer` | `#installer-updater-bug-triage` | +======= +| Product :: Component | Channel | +| -------------------------------- | ------------------------------- | +| `Firefox :: New Tab Page` | `#hnt-dev-triage` | +| `Firefox for Android :: History` | `#android-core-dev` | +| `Toolkit :: Application Update` | `#installer-updater-bug-triage` | +| `Firefox :: Installer` | `#installer-updater-bug-triage` | +| `Firefox :: Messaging System` | `#omc-triage` | +>>>>>>> 5d6d8e9c (Route Firefox :: Messaging System bugs to #omc-triage) - **The key is the component, not the team**, so two components may share a channel, as the installer and the updater do, without either knowing about the other. diff --git a/agents/frontend-triage/hackbot_agents/frontend_triage/config.py b/agents/frontend-triage/hackbot_agents/frontend_triage/config.py index c01bc06f05..2bbc224234 100644 --- a/agents/frontend-triage/hackbot_agents/frontend_triage/config.py +++ b/agents/frontend-triage/hackbot_agents/frontend_triage/config.py @@ -124,6 +124,10 @@ def key(self) -> str: # Where an auto-applied run reports itself, by `" :: "`. Derived, so # that `notify.py` keeps one flat mapping to look up. SLACK_CHANNELS = {c.key: c.channel for c in TRIAGE_SCOPE} + "Toolkit :: Application Update": "#installer-updater-bug-triage", + "Firefox :: Installer": "#installer-updater-bug-triage", + "Firefox :: Messaging System": "#omc-triage", +} # What a `bugzilla.update_bug` from this agent may touch. Enforced at record time # by `hooks.update_bug_hook`, so an out-of-bounds change is refused while the agent diff --git a/agents/frontend-triage/hackbot_agents/frontend_triage/rules/frontend-triage.md b/agents/frontend-triage/hackbot_agents/frontend_triage/rules/frontend-triage.md index 09d87a1b70..54b46e0dbf 100644 --- a/agents/frontend-triage/hackbot_agents/frontend_triage/rules/frontend-triage.md +++ b/agents/frontend-triage/hackbot_agents/frontend_triage/rules/frontend-triage.md @@ -7,6 +7,15 @@ the area whose code layout **Source repository** describes. Any user-facing Fire defect is in scope, though, whether or not its component is on that list; see `scoping.md`. +Typical components: + +- Desktop frontend, all under `Firefox`: `Tabbed Browser`, + `Tabbed Browser: Split View`, `New Tab Page`, `Address Bar`, `Menus`, + `Toolbars and Customization`, `Sidebar`, `Theme`. +- Android: `Firefox for Android :: History`. +- Install and update: `Firefox :: Installer`, `Toolkit :: Application Update`. +- Messaging System: `Firefox :: Messaging System`. + Desktop and Android bugs here are usually UI/UX papercuts, documented with a **video or screenshot** and steps to reproduce. @@ -34,9 +43,12 @@ Core, DevTools-internals, or build-system bug — and say which area it looks li `devtools/` (JS/JSM, CSS, XUL/HTML); Android under `mobile/android/` (Kotlin, Fragment/Store/Middleware/View); the updater under `toolkit/mozapps/update/` (`.sys.mjs`, IDL, C++); the installer under `browser/installer/windows/nsis/` - (NSIS `.nsi`/`.nsh`). Find the module, the markup or layout, and any relevant pref - (often `modules/libpref/init/all.js`, or `app.update.*` for the updater) that - governs the behaviour. Use the `investigator` subagent for deep searches. + (NSIS `.nsi`/`.nsh`), Messaging System under `browser/components/asrouter/`, + `browser/components/aboutwelcome/`, `toolkit/components/messaging-system/` + (JS/JSM, CSS, XUL/HTML, JSON, JSON Schema). Find the module, the markup or layout, + and any relevant pref (often `modules/libpref/init/all.js`, or `app.update.*` + for the updater) that governs the behaviour. Use the `investigator` subagent for + deep searches. 2. **Confirm the area is still live.** Check the referenced code/strings still exist and aren't already changed by a recent commit. If the bug looks already fixed (e.g. cannot reproduce on a newer version per comments, or the code path diff --git a/agents/frontend-triage/tests/test_notify.py b/agents/frontend-triage/tests/test_notify.py index 002601337d..265698b90f 100644 --- a/agents/frontend-triage/tests/test_notify.py +++ b/agents/frontend-triage/tests/test_notify.py @@ -98,6 +98,7 @@ def test_the_channel_belongs_to_the_component(): def test_whitespace_around_either_half_is_stripped(): # Surrounding whitespace is the agent's, not Bugzilla's. assert channel_for(" Firefox ", " New Tab Page ") == "#hnt-dev-triage" + assert channel_for("Firefox", "Messaging System") == "#omc-triage" def test_the_registry_names_each_component_once(): From 94b0d9894cfea384d4c60e4beb58b5f55ae688db Mon Sep 17 00:00:00 2001 From: Jared Wein Date: Tue, 18 Aug 2026 14:24:53 -0400 Subject: [PATCH 2/3] Maintain group separation punctuation Semi-colons are used to separate the groups, not commas. Want to make sure the LLMs don't treat this group differently. --- .../hackbot_agents/frontend_triage/rules/frontend-triage.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/agents/frontend-triage/hackbot_agents/frontend_triage/rules/frontend-triage.md b/agents/frontend-triage/hackbot_agents/frontend_triage/rules/frontend-triage.md index 54b46e0dbf..a35d2dcc4e 100644 --- a/agents/frontend-triage/hackbot_agents/frontend_triage/rules/frontend-triage.md +++ b/agents/frontend-triage/hackbot_agents/frontend_triage/rules/frontend-triage.md @@ -43,7 +43,7 @@ Core, DevTools-internals, or build-system bug — and say which area it looks li `devtools/` (JS/JSM, CSS, XUL/HTML); Android under `mobile/android/` (Kotlin, Fragment/Store/Middleware/View); the updater under `toolkit/mozapps/update/` (`.sys.mjs`, IDL, C++); the installer under `browser/installer/windows/nsis/` - (NSIS `.nsi`/`.nsh`), Messaging System under `browser/components/asrouter/`, + (NSIS `.nsi`/`.nsh`); the Messaging System under `browser/components/asrouter/`, `browser/components/aboutwelcome/`, `toolkit/components/messaging-system/` (JS/JSM, CSS, XUL/HTML, JSON, JSON Schema). Find the module, the markup or layout, and any relevant pref (often `modules/libpref/init/all.js`, or `app.update.*` From 7715068e01193f092afdff03e530393a9f1f101e Mon Sep 17 00:00:00 2001 From: Emily McMinn Date: Tue, 18 Aug 2026 18:33:42 -0400 Subject: [PATCH 3/3] Repair the botched rebase: unparseable config.py, conflict markers in README The rebase of 5d6d8e9c onto the post-registry master landed unresolved: `config.py` kept the tail of the pre-registry `SLACK_CHANNELS` dict after the line that now derives it, so the module raised `IndentationError` at line 127 and every test file failed at collection -- the agent's config did not import at all. `README.md` committed its conflict markers, including both sides of the routing table that 13b54379 deleted on purpose. The routing was the part actually lost. `"Firefox :: Messaging System": "#omc-triage"` existed only inside those orphaned dict lines, which are dead code after 8f1ce545 made `TRIAGE_SCOPE` the source of truth. Deleting them alone would have left the branch parsing and green with Messaging System routed nowhere -- the one thing the commit was for. So it becomes a `ScopedComponent`, which is where a channel now takes effect. That entry names a new area, and `test_every_area_has_prompt_guidance` requires every area to have a `Source repository` bullet in system.md -- the test exists so a component cannot be triaged with the agent having no idea where its code lives. Hence the Messaging System bullet: the three trees, plus the warning that a message is remotely delivered data matched by targeting, so "wrong/duplicate/missing message" is usually not a defect in the tree at all. `rules/frontend-triage.md` is left exactly as it stands, 94b0d989's semicolon included. The README table stays deleted per 13b54379. 46 tests pass. Co-Authored-By: Claude Opus 5 (1M context) --- agents/frontend-triage/README.md | 17 ----------------- .../hackbot_agents/frontend_triage/config.py | 5 +---- .../frontend_triage/prompts/system.md | 2 ++ 3 files changed, 3 insertions(+), 21 deletions(-) diff --git a/agents/frontend-triage/README.md b/agents/frontend-triage/README.md index 0b8d4cb19b..56956555f7 100644 --- a/agents/frontend-triage/README.md +++ b/agents/frontend-triage/README.md @@ -196,24 +196,7 @@ Routing is the `channel` on each `TRIAGE_SCOPE` entry in `config.py`, looked up `ScopedComponent("Firefox", "New Tab Page", "Desktop frontend", "#hnt-dev-triage")` sends a New Tab Page run to `#hnt-dev-triage`. -<<<<<<< HEAD Four things about that which are not obvious from reading the registry: -||||||| parent of 5d6d8e9c (Route Firefox :: Messaging System bugs to #omc-triage) -| Product :: Component | Channel | -| -------------------------------- | ------------------------------- | -| `Firefox :: New Tab Page` | `#hnt-dev-triage` | -| `Firefox for Android :: History` | `#android-core-dev` | -| `Toolkit :: Application Update` | `#installer-updater-bug-triage` | -| `Firefox :: Installer` | `#installer-updater-bug-triage` | -======= -| Product :: Component | Channel | -| -------------------------------- | ------------------------------- | -| `Firefox :: New Tab Page` | `#hnt-dev-triage` | -| `Firefox for Android :: History` | `#android-core-dev` | -| `Toolkit :: Application Update` | `#installer-updater-bug-triage` | -| `Firefox :: Installer` | `#installer-updater-bug-triage` | -| `Firefox :: Messaging System` | `#omc-triage` | ->>>>>>> 5d6d8e9c (Route Firefox :: Messaging System bugs to #omc-triage) - **The key is the component, not the team**, so two components may share a channel, as the installer and the updater do, without either knowing about the other. diff --git a/agents/frontend-triage/hackbot_agents/frontend_triage/config.py b/agents/frontend-triage/hackbot_agents/frontend_triage/config.py index 2bbc224234..f90bdda8d6 100644 --- a/agents/frontend-triage/hackbot_agents/frontend_triage/config.py +++ b/agents/frontend-triage/hackbot_agents/frontend_triage/config.py @@ -98,6 +98,7 @@ def key(self) -> str: "IP Protection", "#team-eng-ip-protection-triage", ), + ScopedComponent("Firefox", "Messaging System", "Messaging System", "#omc-triage"), ScopedComponent( "Firefox for Android", "History", "Firefox for Android", "#android-core-dev" ), @@ -124,10 +125,6 @@ def key(self) -> str: # Where an auto-applied run reports itself, by `" :: "`. Derived, so # that `notify.py` keeps one flat mapping to look up. SLACK_CHANNELS = {c.key: c.channel for c in TRIAGE_SCOPE} - "Toolkit :: Application Update": "#installer-updater-bug-triage", - "Firefox :: Installer": "#installer-updater-bug-triage", - "Firefox :: Messaging System": "#omc-triage", -} # What a `bugzilla.update_bug` from this agent may touch. Enforced at record time # by `hooks.update_bug_hook`, so an out-of-bounds change is refused while the agent diff --git a/agents/frontend-triage/hackbot_agents/frontend_triage/prompts/system.md b/agents/frontend-triage/hackbot_agents/frontend_triage/prompts/system.md index 4971b288d4..901ab793fe 100644 --- a/agents/frontend-triage/hackbot_agents/frontend_triage/prompts/system.md +++ b/agents/frontend-triage/hackbot_agents/frontend_triage/prompts/system.md @@ -46,6 +46,8 @@ Where to look, and what you will find there, depends on the bug's component: - `toolkit/components/ipprotection/docs/` has `StateMachine.rst`, `Preferences.rst`, `Constants.rst` and `Components.rst` — in-tree prose documentation, which none of the other areas here has. **Read it before reasoning about a state transition**; it is faster and more reliable than reconstructing the machine from the source. - A `browser/` → `toolkit/` split is in progress, so both trees can hold a plausible-looking copy of the same concern and the shallow local checkout may be behind. Prefer `search_identifier` / `find_definition`, which see the indexed revision, before citing a path. - Prefs are `browser.ipProtection.*`, registered in `browser/app/profile/firefox.js` — **not** `modules/libpref/init/all.js`. Strings are `browser/locales/en-US/browser/ipProtection.ftl`, and Glean metrics are in a `metrics.yaml` in each of the two directories. +- **Messaging System** — the in-product messaging surfaces: about:welcome, feature callouts, Spotlight modal dialogs, and Infobars. Desktop JS/JSM, CSS and XUL/HTML across three trees: `browser/components/asrouter/` (the router that decides which message shows, and the templates it shows them in), `browser/components/aboutwelcome/` (the onboarding and first-run flow), and `toolkit/components/messaging-system/` (the platform-agnostic layer, including the **JSON Schemas** message definitions are validated against). The router is shared by every surface, so work out which surface the reporter was on before reading any of the three — a bug in one surface is usually not in the router. + - **A message is data, not code.** Message definitions are delivered remotely and matched to a user by targeting expressions, so "I saw the wrong message", "I saw it twice" and "I never saw it" are usually a message-definition, targeting or frequency-cap problem rather than a defect in this tree. Say which of the two you think it is, and if it is the message rather than the code, say what would confirm that instead of planning a change against a definition you cannot see. A rendering or interaction bug in the surface itself is the ordinary case and localizes normally. - **Firefox for Android** — `mobile/android/`, with the Fenix app under `mobile/android/fenix/app/src/main/java/org/mozilla/fenix/` and the reusable components under `mobile/android/android-components/`. This is **Kotlin**, and it is structured as Fragment / Store / Middleware / View rather than as chrome markup plus a script: a `…Fragment.kt` owns the screen, a `…FragmentStore.kt` holds its state and actions, a `…View.kt` or a Compose function renders it, and a `…Middleware.kt` performs side effects. Layouts are Android XML under `mobile/android/fenix/app/src/main/res/layout/`, strings under `res/values/strings.xml`. Fenix is mid-migration to Jetpack Compose, so a screen may have both a `…View.kt` and a `…Composable.kt` and only one of them is live — check which the Fragment actually builds before planning against either. - **Android toolbar** — there are **two** toolbars, and a generation of the widget under each. The browser toolbar is `…/fenix/components/toolbar/` (`BrowserToolbarComposable.kt`, `BrowserToolbarMiddleware.kt`, `BrowserNavigationBar.kt`, `ToolbarPosition.kt` for top-versus-bottom, `BottomToolbarContainerView.kt`, `ToolbarsIntegration.kt`); the homepage has its own at `…/fenix/home/toolbar/` (`HomeToolbarComposable.kt`, `FenixHomeToolbar.kt`, `BrowserSimpleToolbar.kt`). So work out which surface the reporter was on first: a `Homepage` bug can localize into a toolbar file and a `Toolbar` bug into the homepage. Underneath both, android-components has the newer Compose widget at `mobile/android/android-components/components/compose/browser-toolbar/` and the older View-based one at `components/browser/toolbar/`, with `components/concept/toolbar/` holding the interface and `components/feature/toolbar/` the session wiring. Confirm which one Fenix builds before citing it — a fix planned against the retired implementation reads correct and changes nothing. - **Android homepage** — one screen assembled from one package per section, so "which section" comes before "which file". `…/fenix/home/HomeFragment.kt` owns the screen, the Compose UI is under `home/ui/` (`Homepage.kt`, `HomepageHeader.kt`, `SearchBar.kt`, `WallpaperBackground.kt`, `Wordmark.kt`), state is `home/store/HomepageState.kt`, side effects are `home/middleware/`, and the older controller/interactor pair is `home/sessioncontrol/`. Each section is its own subpackage: `topsites/`, `recenttabs/`, `recentsyncedtabs/`, `recentvisits/`, `pocket/`, `bookmarks/`, `collections/`, `setup/`, `sports/`, `mars/`, `logo/`, `privatebrowsing/`. A bug about the top-sites row or the stories feed is localized there, not in `Homepage.kt`. Note also that `Firefox for Android` has separate components for several of these sections — `Top Sites`, `Stories`, `Collections`, `Bookmarks`, `Menu`, `Search` — so the same code can be reached from more than one component, and `Stories` is `home/pocket/` in the tree because nothing was renamed. Triage the bug under the component it was filed in; do not retitle or re-scope it to match.