Skip to content

frontend-triage: link source files as Searchfox permalinks - #6416

Open
msujaws wants to merge 1 commit into
mozilla:masterfrom
msujaws:searchfox-permalinks-in-triage-comments
Open

frontend-triage: link source files as Searchfox permalinks#6416
msujaws wants to merge 1 commit into
mozilla:masterfrom
msujaws:searchfox-permalinks-in-triage-comments

Conversation

@msujaws

@msujaws msujaws commented Jul 28, 2026

Copy link
Copy Markdown
Contributor

Depends on #6425 (action hooks) — the placeholder expansion is registered as an ActionHook, so this is branched on that PR and should land after it. The commit above it is #6425's and will drop out of this diff once it merges.

What

The triage comment cited source files as bare or backticked repo-relative paths, so a developer reading the bug had to go find the file themselves. Every source-file reference now becomes an inline Markdown link to a revision-pinned searchfox.org URL:

The group line is drawn by the .tab-group-label rule in browser/themes/shared/tabbrowser/tabs.css#1240-1252, which sets border-inline-start unconditionally…

Because the revision is pinned, the link keeps pointing at the code the agent actually read after the tree moves on.

How

The agent never handles the revision. It writes {{searchfox.permalink}}/<path>#<line> — the same placeholder convention as {{actions.<ref>.url}} — and an action hook on bugzilla.add_comment expands the prefix as the comment is recorded. Expanding at record rather than apply time means the comment waiting in summary.json for review is already clickable, which a prior action's result inherently could not be.

New libs/hackbot-runtime/hackbot_runtime/searchfox.py holds the prefix builder, the revision lookup, and the hook.

A path that is not in the checkout is deliberately not linked. The hook unwraps the Markdown link to its backticked label and logs why. Models do invent a plausible path now and then, and a permalink that 404s for whoever clicks it is worse than plain text. The check is a heuristic — the checkout and the pinned revision are hours apart, so a file added in between exists locally but not on Searchfox — but it catches the common case.

Review feedback

Thanks — three of the four are done as suggested, and the placeholder idea in particular deleted a lot of code:

  • Placeholder instead of detection — done, and it removed the whole heuristic: the top-level-directory list, the extension allowlist, the path regex, the fenced-block skipping. The agent now can't mangle a SHA either.
  • Not really a tool — moved to hackbot-runtime; agent-tools is untouched by this PR.
  • Fits as a hook — done, which also let me drop my ActionsRecorder.metadata addition and my edit to actions/bugzilla.py entirely.
  • Use the checkout's base commit — I tried this and measured against it, and I don't think it can work; details below. Happy to be overruled.

Why not the checkout's base commit

Searchfox only serves /rev/<sha> for revisions it has indexed, and its index trails the tip of firefox.git. Measured while writing this:

firefox.git main tip 878b64a4 (2026-07-30 13:27Z)
Searchfox indexed revision d573d849 (2026-07-29 17:08Z)
Gap 83 commits / ~20 hours
GET /firefox-main/rev/878b64a4/toolkit/moz.build HTTP 500

The agent clones main with no pinned ref, so its base commit is at or near the tip — i.e. not yet servable. Links pinned to it would 500 for roughly a day and then start working, which is exactly backwards: the window in which they're broken is the window in which someone reads a freshly-posted triage comment.

So the revision is read from the permalink Searchfox itself publishes on a file page (its "Create a revision-specific link" panel item), which is by construction a revision Searchfox can serve. commit-info/HEAD — what searchfox-cli --permalink uses — turned out not to work either: it only reports a usable revision when HEAD isn't a merge, and HEAD is a Lando merge much of the time. If no revision resolves at all, the placeholder expands to the revision-agnostic /source/ prefix: still a working link, just unpinned.

Also: is_markdown

Comments were posted without is_markdown, so Bugzilla rendered the markup literally — including the existing *This is an automated analysis result…* footer, which showed its asterisks. AddCommentHandler and the coalesced update+comment path now set it. Only frontend-triage and bug-fix record bugzilla.add_comment, and both author LLM prose, so the blast radius is small.

Testing

  • libs/hackbot-runtime/tests/test_searchfox.py: prefix building, revision resolution and every failure mode, placeholder expansion (multiple occurrences, inner whitespace, not clobbering {{actions.*}}, prefix-as-backreference), and each degradation path for a missing file, a missing bare placeholder, a shortened label, a directory, and no repo_root.
  • Full suite green (190 tests on top of hackbot: run per-action-type hooks before recording an action #6425), pre-commit clean.
  • Ran a seeded local run end to end through the real recorder, hook and footer: all generated links verified HTTP 200 including the #412 and #1240-1252 anchor forms, an invented path correctly degraded to plain text, and the trailing plan block kept its bare paths. Rendered it through the console's own Markdown.tsx to confirm it displays as links there too.

Not included: bare-URL autolinking, and AddAttachmentHandler, whose comment is a plain string with no markdown flag on that endpoint.

🤖 Generated with Claude Code

@msujaws
msujaws requested review from a team as code owners July 28, 2026 20:26
crythms
crythms previously approved these changes Jul 29, 2026

@crythms crythms left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍

Comment on lines +159 to +168
async def resolve_index_revision(*, client=None, timeout: float = 10.0) -> str | None:
"""Return the git SHA Searchfox's index is pinned to, or ``None``.

Reads the permalink Searchfox publishes on a file page, so the revision is
by construction one Searchfox can serve.

Never raises: a caller that cannot get a revision should degrade to bare
paths rather than fail its run. ``client`` accepts an httpx-like async
client for testing; when omitted, ``httpx`` is imported lazily.
"""

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we instead relay on the base commit of the checked out repo?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I tried this and I do not think it can work, though I would happily be overruled.

Searchfox only serves /rev/<sha> for revisions it has indexed, and its index trails the tip of firefox.git. Measured today:

firefox.git main tip 878b64a4 (2026-07-30 13:27Z)
Searchfox indexed revision d573d849 (2026-07-29 17:08Z)
Gap 83 commits / ~20 hours
GET /firefox-main/rev/878b64a4/toolkit/moz.build HTTP 500

The agent clones main with no pinned ref, so its base commit sits at or near the tip and is not yet servable. A link pinned to it would 500 for roughly a day and then start working — backwards, since the broken window is exactly when someone reads a freshly-posted triage comment.

So the revision is read from the permalink Searchfox itself publishes on a file page (its "Create a revision-specific link" panel item), which is by construction one it can serve. For what it is worth, commit-info/HEAD — what searchfox-cli --permalink reads — does not work either: it only reports a usable revision when HEAD is not a merge, and HEAD is a Lando merge much of the time.

The tradeoff is that the pinned revision is ~a day older than the bytes the agent read, so a line anchor can be slightly off in a file touched in that window. I think that beats a link that does not resolve, but if you would rather have exactness and accept the delay, the change is a one-liner.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this might be tricky since it will point to a version that is not what the agent saw, and it defeats the whole purpose of a permalink (pointing exactly to what we saw). We could try mitigating that on the Searchfox side (e.g., redirecting or linking to GitHub if the revision is not there yet).

BTW, as now, I see 878b64a4 on both, GitHub main and Searchfox.

Comment thread libs/agent-tools/agent_tools/searchfox_links.py Outdated
Comment thread libs/agent-tools/agent_tools/searchfox_links.py Outdated
Comment thread libs/hackbot-runtime/hackbot_runtime/actions/bugzilla.py Outdated
@suhaibmujahid

Copy link
Copy Markdown
Member

I think this will be a nice feature that would make it much easier to follow up on triage results. Thank you for working on this!

@msujaws
msujaws force-pushed the searchfox-permalinks-in-triage-comments branch from 712c24d to 2383437 Compare July 30, 2026 18:45

@suhaibmujahid suhaibmujahid left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM! Thank you!

I landed #6425. Could you please rebase?

Edit: I enabled the "update branch" button for this repo to make things smother :)

The triage comment cited source files as bare or backticked repo-relative
paths, so a developer reading the bug had to go find the file themselves.
Every source-file reference now becomes an inline Markdown link to a
revision-pinned searchfox.org URL, so the link keeps pointing at the code
the agent actually read after the tree moves on.

The agent never handles the revision. It writes
`{{searchfox.permalink}}/<path>#<line>` — the same placeholder convention
as `{{actions.<ref>.url}}` — and an action hook on bugzilla.add_comment
expands the prefix as the comment is recorded. Expanding at record rather
than apply time means the comment waiting in summary.json for review is
already clickable, which a prior action's result could not be.

A path that is not in the checkout is deliberately not linked: the hook
unwraps the link to its backticked label and logs why. Models do invent a
plausible path now and then, and a permalink that 404s for whoever clicks
it is worse than plain text. The check is a heuristic — the checkout and
the pinned revision are hours apart — but it catches the common case.

The revision comes from the permalink Searchfox publishes on a file page,
not from the checkout's base commit, because Searchfox only serves
/rev/<sha> for revisions it has *indexed*, and its index trails the tip of
firefox.git by hours (83 commits / ~20h when measured). A link pinned to
the checkout 500s for about a day — exactly the window in which someone
reads the comment. If no revision can be resolved the placeholder expands
to Searchfox's revision-agnostic /source/ prefix: still a working link,
just unpinned.

Comments are now posted with is_markdown, without which Bugzilla rendered
the links — and the existing italic footer — literally.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@suhaibmujahid
suhaibmujahid force-pushed the searchfox-permalinks-in-triage-comments branch from 2383437 to 7e846ca Compare July 30, 2026 19:07
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants