Skip to content

flightcheck: autolink bare URLs in report remediation#208

Open
daeunJe0ng wants to merge 2 commits into
microsoft:mainfrom
daeunJe0ng:dawnjeong/flightcheck-report-autolink-urls
Open

flightcheck: autolink bare URLs in report remediation#208
daeunJe0ng wants to merge 2 commits into
microsoft:mainfrom
daeunJe0ng:dawnjeong/flightcheck-report-autolink-urls

Conversation

@daeunJe0ng

@daeunJe0ng daeunJe0ng commented Jul 21, 2026

Copy link
Copy Markdown
Contributor

Summary

FlightCheck report remediation text supports two link forms: markdown [label](url) and bare https://… URLs. Only the markdown form was linkified. Bare URLs were HTML-escaped and rendered as plain text, so they showed up but were not clickable. Because different checks author URLs differently, operators saw links that worked on some rows and not others.

The concrete live case is the WD-CONN connection-health check (checks/workday.py), whose WARNING and FAILED remediations embed a bare make.powerautomate.com/environments/<env>/connections URL built via f-string. That URL is the operator's path to fix a broken Workday connection, and today it renders as non-clickable plain text.

This makes both forms render as clickable anchors.

What changed

  • _md_links_to_html (in runner.py) now runs a second pass, _autolink_bare_urls, after the markdown pass.
  • The bare-URL pass steps over anchors created by the markdown pass, so [label](url) is never double-wrapped.
  • Trailing sentence punctuation (.,;:!?) and an unbalanced closing paren are trimmed off the link target, so see https://aka.ms/x. keeps the period outside the href.
  • _multiline_html and the manual checklist renderer call _md_links_to_html, so they inherit the fix with no separate change.

Design rationale

The fix lives in the renderer, not in each check. That fixes every existing report immediately and means check authors cannot reintroduce a non-clickable link by pasting a raw URL. The alternative (a lint rule forcing markdown links) would leave current reports broken and add an ongoing authoring burden. The renderer is the single choke point every remediation string already passes through, so it is the correct layer.

Testing

  • Added tests/flightcheck/test_runner_link_rendering.py (12 tests): bare URL becomes an anchor, trailing punctuation and parens excluded, query-string & stays HTML-safe, markdown links still work and are not double-wrapped, mixed markdown + bare, plain text untouched except escaping, _multiline_html linkifies and keeps line breaks, plus end-to-end check cards render clickable links.
  • Full FlightCheck suite: 865 passed.

Scope note

This PR makes bare URLs clickable. It does not check that a link's host is real/intended (typo'd or hallucinated domains) — that host-level hygiene gate is #209.

Risks and assumptions

  • Change touches shared report rendering, used by every check. Mitigated by the full-suite run and by keeping the markdown behavior identical (verified by the no-double-wrap test).
  • Assumes remediation URLs are http/https only. Other schemes are not autolinked, which is intentional for a security-reviewed report surface.
  • Not in scope: _mask_sensitive can rewrite a GUID that appears inside a deep-link URL, which alters the link target. That is a separate concern from clickability and is left untouched here.

daeunJe0ng and others added 2 commits July 21, 2026 14:15
…ble links on manual rows)

Report remediation text supported two link forms but only linkified
markdown [label](url). Bare https:// URLs were escaped to plain text, so
they rendered but were not clickable - worst on MANUAL / NotConfigured
rows where the remediation URL is the operator's only path to the fix.
_md_links_to_html now also autolinks bare URLs (stepping over anchors it
just created so markdown links are not double-wrapped), and trims
trailing sentence punctuation. _multiline_html and the manual checklist
renderer inherit the fix.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 8fb19ec0-cad9-41c2-8064-2208b3844ede
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.

1 participant