/**
 * SSRF guard for the `watch` tool — applied to both the watched URL and any
 * webhook notification URL. Pre-merge review on A1 (the stub PR) flagged
 * that the schema allowed unguarded URLs of either field; B3 closes that
 * gap before any real fetch fires.
 *
 * Reject:
 *   - non-http(s) schemes (file://, ftp://, gopher://, data:, javascript:, ...)
 *   - loopback (localhost, 127.0.0.0/8, ::1)
 *   - all-zeros (0.0.0.0)
 *   - RFC 1918 private ranges (10/8, 172.16/12, 192.168/16)
 *   - link-local (169.254/16, fe80::/10)
 *   - IPv6 unique-local (fc00::/7) and IPv6 loopback
 *
 * Accept ordinary public hostnames + their IPs. DNS rebinding is out of
 * scope — we never actually resolve here. This guard is the gate before a
 * job is persisted; a follow-up tier could re-check at fetch time, but for
 * the v0.3.0 surface the input-side guard is the documented contract.
 */
export interface SsrfRejection {
    ok: false;
    reason: string;
    hint: string;
}
export interface SsrfAllowed {
    ok: true;
    url: URL;
}
export type SsrfResult = SsrfAllowed | SsrfRejection;
/**
 * Guard a single URL string. Returns `{ ok:true, url }` on accept, or
 * `{ ok:false, reason, hint }` on reject. Callers should pipe the reject
 * payload straight into a StageError envelope.
 */
export declare function guardUrl(raw: string, fieldLabel: string): SsrfResult;
//# sourceMappingURL=ssrf.d.ts.map