/** * Remote message transport — best-effort fetch of the ADR-311 message * feed, cached locally, validated through the ADR-301 content pipeline * BEFORE any message is displayed. * * Design discipline: * 1. **Never blocks the render.** The statusline reads only the local * cache. This module refreshes the cache in the background; per * ADR-311 "zero local promo content" there is NO in-code fallback * pool — a genuinely fresh install (empty cache) shows nothing on * the promo/disclosure row until the first background refresh lands * (see hook-handler.cjs's SessionStart-triggered detached * `hooks refresh-funnel`, usually within seconds of CLI startup, but * contingent on network reachability to the messages endpoint). This * comment previously (incorrectly) described an in-code fallback * pool; there has never been one since ADR-311 — see disclosure.ts's * own "fail-closed" doc comment for the authoritative statement. * 2. **Content pipeline stays authoritative.** Every message the server * returns is validated by `isValidMessage()` from `messages.ts` — * same schema, same host allowlist, same control-char strip, same * 80-column cap. A tampered or accidentally-broken remote feed can * pollute nothing. * 3. **Fail silent.** Any network/parse/validation failure leaves the * previously-cached pool intact (empty, if nothing has landed yet). * 4. **Bounded cache size.** ≤ 128 KiB and ≤ 200 messages — matches * ADR-309's bounded-local-queue discipline. * 5. **Kill switch.** `RUFLO_FUNNEL_MESSAGES=0` (or `RUFLO_FUNNEL=0`) * disables the fetcher entirely. * 6. **Signature-verification hook.** Reserved for a future ADR-311 * amendment; currently the transport-layer TLS + host allowlist is * the trust boundary. All content is treated as untrusted regardless. */ import type { FunnelMessage } from './types.js'; /** * User-Agent for the messages fetch — ADR-309 operational telemetry (see * docs/privacy/funnel-legitimate-interest-assessment.md). Only the CLI * release and the coarse OS/CPU family, so the server can count releases * and platforms. No identifier, path, hostname, or account: the * `ruflo-funnel/messages` prefix stays first so existing log filters match. * A trailing `surface/plugin` marks a fetch made by the ruflo-core plugin's * MCP launch, so plugin-only users (who never run `init`) can be counted. */ export declare function funnelUserAgent(version?: string, platform?: string, arch?: string, surface?: string | undefined): string; /** The surface set by a launcher (plugins/ruflo-core/scripts/mcp-launch.cjs), if any. */ export declare function launchSurface(env?: NodeJS.ProcessEnv): string | undefined; /** Endpoint the client hits — overridable for staging / self-hosted. */ export declare const DEFAULT_MESSAGES_ENDPOINT: string; /** * Best-effort refresh of the cache. Safe to call at any point in the * CLI lifecycle — returns a summary; never throws; never blocks longer * than FETCH_TIMEOUT_MS + write time. */ export declare function refreshRemoteMessages(opts?: { endpoint?: string; force?: boolean; env?: NodeJS.ProcessEnv; }): Promise<{ refreshed: boolean; skipped?: string; accepted?: number; rejected?: number; status?: number; }>; /** * Read the cached remote pool. Returns [] when the cache is empty or * stale enough to distrust — callers should merge with the in-code * fallback pool. */ export declare function getRemoteMessages(): FunnelMessage[]; //# sourceMappingURL=message-transport.d.ts.map