Under the Hood: render the report in-product instead of handing users a raw JSON file

Open
#213 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Assessment

Difficulty
5/5
Estimated time
Over a week
Newbie friendliness
35/100
Issue type
Feature
Clarity
Mostly clear
Activity status
Active
Tech stack
scala
Domain
api, backend, data

Research direction

Start with under-the-hood/strato/columns/underTheHoodReport.User.strato:155-158, 180-243, and 296-332, then read under-the-hood/thrift/uth_serving.thrift:10-14, 25-34, 53-57, 99-108. Check how UthReferenceMonthMhPublisherJob.scala supplies cohort data and determine which serving-layer fields and count shapes must reach the response. Done means the repository's serving layer exposes an agreed report shape; the frontend is outside this repository.

Written by the indexing model from the issue text.

Description

The README says the tool will be shaped by feedback, so here is a report on the download path.

What an eligible account gets today

x.com/i/under_the_hood renders a title, two eligibility checkmarks and a Download button. Clicking it hands over the reportJson string from UserUnderTheHoodReport verbatim, as a JSON blob. There is no rendered view of the report anywhere in the product.

Shape of the payload (values synthetic):

{
  "notes": "You can learn more about instances when a post's reach may be limited by reading our open-source code at ...",
  "period": { "startDate": "2026-08-01", "endDate": "2026-08-31", "timezone": "UTC" },
  "generatedAt": "2026-09-09T23:59:59Z",
  "postCount": "412",
  "postLabels": [
    {
      "label": "SPAM_HIGH_RECALL",
      "about": "Post detected by automated systems as one that may contain spam.",
      "effect": "Post hidden from recommendations to non-followers.",
      "posts": "1",
      "totalPostsInMonth": "412",
      "percentageOfPosts": "0.24%"
    }
  ],
  "accountLabels": [],
  "totalAccountLabels": 0
}

Everything needed for a human-readable view is already computed. postLabelRow in under-the-hood/strato/columns/underTheHoodReport.User.strato:180-212 already attaches plain-English about and effect text per label, and percentageOfPosts is already a formatted display string rather than a number. That prose is then serialized into a file and handed over.

So the gap is presentation, not data. The audience for this tool is every eligible account, not the subset of people who open .json files.

Ask

Render the report on the page in X's own UI: a period header, a plain state line ("No labels were applied to your account in August 2026" vs "2 labels"), then one card per label showing the label's human name, its about, its effect, and the count with its percentage. Keep the JSON download as a secondary action for people who want the raw file.

An account that is clean should be able to learn that in one glance without downloading anything.

Four things the served report drops that a rendered view would want

All four are computed upstream and discarded at the serving layer, so they are worth settling before a UI is designed:

  1. Per-day timeline. UthPostLabelAggregate.days is a list<UthDayCarriedRemoved> carrying dayOfMonth (under-the-hood/thrift/uth_serving.thrift:10-14, 53-57), but sumCarried collapses it to a single integer (underTheHoodReport.User.strato:155-158). "1 post, sometime in August" answers much less than a sparkline showing which day.

  2. removed is never read. UthDayCarriedRemoved carries both carried and removed; sumCarried sums only carried. A label that was applied and later lifted is therefore indistinguishable from one that was never applied, which is exactly the case a worried author most wants resolved.

  3. countryCodes is not a field. It reaches postLabelRow (:182) and accountLabelRow (:218) only to be interpolated into the takedown label's name and its about/effect sentences (:205-207, :241-243). For the legal-withholding data added in the September update, "which country" deserves a structured field, not a sentence a UI has to parse back out.

  4. No peer context. UthReferenceCohortStats computes mean and p10/p25/p50/p75/p90/p99 per label per UthFollowerClass (uth_serving.thrift:25-34, 99-108), published by UthReferenceMonthMhPublisherJob.scala. But referenceMonth does not appear anywhere in underTheHoodReport.User.strato, so none of it reaches the user. Without it a reader has no way to judge whether their rate is normal. One line, "typical for accounts your size: 0.4%", turns a number into an answer.

One shape issue worth fixing regardless of the UI

totalPostLabels and totalAccountLabels are emitted only when the corresponding list is empty (underTheHoodReport.User.strato:296-332), so the object has four different key sets depending on which lists are populated. Every consumer has to branch on key presence. Emitting both counts unconditionally would be simpler for a UI and for anyone parsing the file.

On a PR

I have not opened one because the page's frontend is not in this repository: under-the-hood/ ships the daily jobs and the serving layer only. Happy to send a PR for the serving-layer items (1-4 and the count shape) if that is useful.

Verified against main on 2026-09-20: the live page, the UserUnderTheHoodReport GraphQL response, and the checked-in under-the-hood/ sources. Related but distinct: #39 (label-source provenance).

Dominant language
Rust
Stars
33.3k
Forks
5.4k
Avg merge
1d 17h
Merged PRs (30d)
1

Contributor guide

No contributing guide indexed for this repository

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

More from xai-org/x-algorithm

All issues in xai-org/x-algorithm

Similar issues

More Rust issues

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.