diff --git a/offline/README.md b/offline/README.md
index 78b2815..18c273e 100644
--- a/offline/README.md
+++ b/offline/README.md
@@ -19,6 +19,7 @@ Open replication of the code review benchmark used by companies like [Augment](h
| [GitLab Duo](https://about.gitlab.com/gitlab-duo/) | AI code review |
| [Graphite](https://graphite.dev/) | AI code review |
| [Greptile](https://www.greptile.com/) | AI code review |
+| [gx](https://gx.run) | AI code review |
| [Propel](https://propelauth.com/) | AI code review |
| [KG](https://kg.dev/) | AI code review |
| [Kodus](https://kodus.io/) | AI code review |
diff --git a/offline/analysis/benchmark_dashboard.html b/offline/analysis/benchmark_dashboard.html
index 927d654..0aa4bff 100644
--- a/offline/analysis/benchmark_dashboard.html
+++ b/offline/analysis/benchmark_dashboard.html
@@ -198,15 +198,17 @@
Best for Complex Code ↗
Best for Ui ↗
Best for Critical Risk ↗
+ Best for Bug Fixes ↗
Small PRs + Performance Optimization (Precision) ↗
Bug Fixes + Cross-File ↗
Java + Authentication ↗
+ Best for Scheduling ↗
Best for Medium Python PRs ↗
Best for Concurrency ↗
- Best for Bug Fixes ↗
Ruby + Medium PRs ↗
Highest Recall ↗
Ruby + Features ↗
+ Moderate Bugs + File Context ↗
Best for Moderate Bugs ↗
Ruby + Subtle Bugs ↗
Best for Go ↗
@@ -215,7 +217,6 @@
Best for Small PRs ↗
Best for Caching ↗
Best for Large PRs ↗
- Best for Bug Fixes ↗
Best for Python ↗
High Risk Auth ↗
Best for File Context ↗
@@ -224,7 +225,6 @@
Best for Authentication ↗
Best for Medium Ruby PRs ↗
Best for Medium Java PRs ↗
- Best for Scheduling ↗
Best for Typescript ↗
Best for Cross-File ↗
Best for Medium PRs ↗
@@ -428,10 +428,10 @@
` and confirming it renders as text.",
+ "created_at": "2026-08-15T03:51:38Z"
+ },
+ {
+ "path": "app/models/topic.rb",
+ "line": 719,
+ "body": "**Unsubscribe URL in emails is not authenticated — any recipient can unsubscribe another user**\n\nThe `unsubscribe_url` generated by `Topic#unsubscribe_url` is simply `{topic_url}/unsubscribe` with no token or HMAC. It relies solely on `current_user` (session authentication). However, the URL is placed in email bodies (`unsubscribe_link` locale). If the email is forwarded or the link shared, any logged-in user visiting it will have their own notification level changed (not necessarily the intended user's). More critically, the `List-Unsubscribe` header containing this URL may be processed by email clients that do not carry session cookies, potentially resulting in a redirect loop or error rather than the expected unsubscribe.\n\nEnsures that the unsubscribe mechanism works reliably from email clients and that authentication is handled appropriately for one-click unsubscribe flows.\n\nConsider adding a signed token (HMAC of user_id + topic_id + expiry) to the unsubscribe URL so it can work without an active session, similar to the existing `DigestUnsubscribeKey` pattern in `EmailController`. At minimum, document that the current implementation requires an active session and will not work from email clients that strip cookies. Verify by clicking the List-Unsubscribe link from an email client without an active Discourse session and confirming appropriate behavior.",
+ "created_at": "2026-08-15T03:51:38Z"
+ },
+ {
+ "path": "app/assets/javascripts/discourse/templates/topic/unsubscribe.hbs",
+ "line": 3,
+ "body": "**XSS via triple-brace rendering of user-controlled topic title**\n\nThe Handlebars template `unsubscribe.hbs` uses `{{{stopNotificiationsText}}}` (triple braces = unescaped HTML). The computed property interpolates `model.fancyTitle` into the i18n string. `fancyTitle` may contain HTML entities from the Discourse `fancy_title` pipeline, but if a topic title contains injected HTML (admin-created or via a bug), it will be rendered unescaped in the browser.\n\nEliminates a stored XSS vector where a malicious topic title could execute JavaScript in the context of users visiting the unsubscribe page.\n\nIn `app/assets/javascripts/discourse/templates/topic/unsubscribe.hbs`, replace `{{{stopNotificiationsText}}}` with a safe approach: either use double-braces `{{stopNotificiationsText}}` and handle the bold formatting differently (e.g., separate the title into its own escaped binding), or sanitize the title before interpolation in the controller. Verify by creating a topic with a title containing `
` and confirming the script does not execute on the unsubscribe page.",
+ "created_at": "2026-08-15T03:51:38Z"
+ },
+ {
+ "path": "app/controllers/topics_controller.rb",
+ "line": 107,
+ "body": "**Handle missing TopicUser record in unsubscribe action to avoid 500s**\n\n`TopicUser.find_by(...)` can return nil (e.g., user never visited the topic or record not created yet). The code immediately dereferences `tu.notification_level`, which will raise and 500 the request. This is realistic on a link reached from email notifications (user may not have prior TopicUser row).\n\nPrevents a production 500 on a common user journey (email → unsubscribe link), improving reliability and supportability.\n\nIn `app/controllers/topics_controller.rb#unsubscribe`, replace `find_by` with a creation path when absent. For example: `tu = TopicUser.get(params[:topic_id], current_user) || TopicUser.create!(user_id: current_user.id, topic_id: params[:topic_id], notification_level: TopicUser.notification_levels[:regular])` (or use existing helper that ensures a row exists—there appears to be logic in TopicUser for ensuring consistency). Then apply the toggle and save. Verify with a controller/request spec: user with no topic_users row can hit `/t/:id/unsubscribe` and gets 200/redirect with notification_level updated/created.",
+ "created_at": "2026-08-15T04:15:13Z"
+ },
+ {
+ "path": "app/assets/javascripts/discourse/templates/topic/unsubscribe.hbs",
+ "line": 4,
+ "body": "**Prevent HTML injection in topic unsubscribe page by removing triple-stash rendering**\n\nThe unsubscribe template renders `stopNotificiationsText` via triple-stash (`{{{...}}}`), which bypasses escaping. That text includes `{{title}}` interpolated from `model.fancyTitle`, which is derived from topic title and can be user-controlled. This is a reachable XSS path when a user clicks the unsubscribe link.\n\nEliminates a direct, user-triggerable XSS on a route that is explicitly linked from emails and thus likely to be visited from untrusted contexts.\n\nIn `app/assets/javascripts/discourse/templates/topic/unsubscribe.hbs`, change `{{{stopNotificiationsText}}}` to `{{stopNotificiationsText}}` and update `config/locales/client.en.yml` to avoid embedding raw `` tags in the translation. If bolding is required, use a safe pattern: split into separate keys and wrap the title in a `` in the template using escaped title, or use a framework-sanctioned i18n HTML helper that sanitizes interpolations. Verify by setting a topic title containing `