Where an author link goes

One outcome, three mechanisms. A researcher clicks nngroup.com on the Nielsen codebook page — in the Mac app, in a browser, and in an exported report handed to a client. The experience must be identical: the link opens somewhere else, and the report stays where it was.
Artefact — the frames are the shipped .preview-author-links markup. Commentary — hatched. Not the product.

The three contexts

macOS app — WKWebView
Jakob Nielsen
Co-founder of Nielsen Norman Group…
click → WebKit asks for a new window
createWebViewWith (WebView.swift:598)
not the serve origin → openExternal
scheme is https → NSWorkspace.open
default browser. Returns nil: no new web view.
already works
bristlenose serve — browser
Jakob Nielsen
Co-founder of Nielsen Norman Group…
click → target="_blank"
new tab; the report keeps its scroll,
   its filters and its selection
rel="noopener noreferrer" denies
   the opened page a handle on ours
already works
exported report — file://
Jakob Nielsen
Co-founder of Nielsen Norman Group…
click → same as the browser
but the page is a file, opened by
   someone else, possibly years later
the link may be dead and
   nobody can fix it
works — but rots
Commentary — what the drawing found

All three already work, and the prototype's inert stub is the only thing that differs from shipped behaviour. CodebookPanel.tsx:1525 emits <a href target="_blank" rel="noopener noreferrer"> with the ↗ glyph. There is no handoff to design; there is a stub to replace with the markup that already ships.

The Mac is the safest context, which inverts the intuition. Its decidePolicyFor allows exactly one origin — http://127.0.0.1:<assignedPort> — and sends everything else to openExternal, which passes only http, https and mailto. Its own comment records why: NSWorkspace will happily open file:// (launching a local app), data: and javascript:. So a hostile URL in a codebook is already blocked on the Mac and not blocked in a browser.

The _blank trap is real and we avoid it by luck, not intent. WKWebView has no default new-window behaviour: without createWebViewWith, a target="_blank" click does nothing at all — silently, with no error and no navigation. Ours is implemented for the popout video player, and external links fall out of its else branch. Correct today; worth knowing that the author links depend on a delegate written for another feature.

The export is the one that needs a thought, and it is not a mechanism. A leave-behind is opened by a client, offline, possibly long after the study. Its links rot, and unlike the app there is nobody to repair them. That is not an argument for removing them — a dead link to a book is still a citation — but it is an argument against ever making one load-bearing: nothing in the report may require following a link to be understood.

The invariant, stated once

contextmechanismwho owns itstatus
macOS appcreateWebViewWithopenExternalNSWorkspaceWebView.swiftships, hardened
serve, browsertarget="_blank" rel="noopener noreferrer"CodebookPanel.tsxships
exported, file://same as browserthe export bundleships; links rot
Commentary — the sandbox question, since it comes up

Opening an external URL costs no entitlement. NSWorkspace.shared.open is a request to LaunchServices to hand the URL to whichever app registered for that scheme. The sandbox mediates it and the calling app never touches the target — which is precisely why the handoff is the sandbox-friendly way to leave an app. What would need an entitlement is fetching the URL ourselves (network.client, which the app has for the sidecar) or reading a file:// outside the container.

So the sandbox risk is not the opening; it is which URL you hand over — and that is already gated by scheme. The entitlements files are skip-worktree (git ls-files -v | grep '^S' lists both), so git status cannot see changes to them and committing one obliges regenerating the Mac App Store profile. Read them; do not commit them.