- challenge-window.ts uses createWindowOpenHandler (deny + sanitised
origin log, the link-title window's own hardening) instead of an
inline deny.
- The renderer's outcome type is the generated contract's
FreeTierChallengeResultParams['outcome']; global.d.ts uses the main
process's ChallengeOutcome instead of a third hand-copied union, so a
drift between the window and the contract fails the renderer typecheck.
- runFreeTierChallenge takes the gateway requester itself and builds the
free_tier.challenge_result call, so lifecycle.ts and free-tier.ts stop
each hand-rolling a reporter closure.
No behaviour change.