/**
 * # session/paper — the PAPER session driver (kestrel-7o2.12)
 *
 * **The last link.** Every piece of the paper path landed separately — the venue-agnostic
 * {@link import("../adapters/broker.ts").BrokerAdapter Gate seam} + `makeGate` (7o2.4), the safety
 * envelope (7o2.9/.21), the IBKR transport (7o2.5), contracts (7o2.6), feed (7o2.7) and paper order
 * face (7o2.8) — but **nothing started a paper session**: `makeGate("paper", …)` had no production
 * caller, only tests. This module is that caller.
 *
 * ## ONE progression, differing only at the adapters (OSS-ADR-0053)
 * This module is a DRIVER CONFIGURATION over {@link SessionCore} — the same object `runSimSession`
 * (`./sim.ts`) and `runSimulateSession` drive. The per-event pass (clock pin, canonical fold, book
 * fold, engine sweep) lives ONCE, in `SessionCore.step`; a paper session does NOT re-implement it. sim
 * and paper differ at exactly TWO adapters and nothing else (CONTEXT: **Mode** — "same engine, same
 * plans; only the gate differs"):
 *
 *   | | `sim` | `paper` (here) |
 *   |---|---|---|
 *   | feed | a recorded bus file | the IBKR {@link IbkrFeed} — the SAME `BusEvent` union |
 *   | gate | `makeGate("sim", …)` → SimGate | `makeGate("paper", { venue: "ibkr" })` → L0-clamped IBKR face |
 *
 * The gate + the venue-fill feedback are injected into the core through its {@link LiveGateBinding}
 * seam; the feed emits the EXISTING `BusEvent` union (`META`/`TICK SPOT`/`TICK BOOK`/`TICK HEARTBEAT`),
 * which is precisely what `SessionCore.step` already consumes. Because the paper path now shares that
 * pass, the `simulate.*` guard-fixture corpus (driven through the real driver) covers paper too: a
 * wired guard is wired everywhere the progression runs (OSS-ADR-0053 §Consequences).
 *
 * ## Venue substance STAYS in the adapters (OSS-ADR-0053)
 * What remains here is adapter substance, NOT progression logic: the never-live front-matter (mode
 * gate / live-port / handshake account assertion / bounded-limits), the venue seam + its socket
 * lifecycle, the price-anchor/intrinsic the venue's order face reads, the heartbeat + kill-switch +
 * cadence reconciliation pumped each cycle, and the typed {@link PaperSessionRefused} vocabulary.
 *
 * ## NEVER LIVE — structurally, not by policy (AGENTS, ADR-0034 §a/§3)
 * Walls on TWO different things, because they fail differently. Say precisely what enforces this and
 * nothing more — an over-claiming safety string is itself a defect, since it is what an operator reads
 * while deciding whether to trust the system.
 *
 * **On the MODE (what Kestrel intends) — the primary, Kestrel-enforced gate (ADR-0034 §3):**
 *  1. **the mode gate**: {@link openPaperSession} REFUSES any resolved {@link IbkrConfig} whose `mode`
 *     is not `"paper"` — `KESTREL_IBKR_MODE=live` is a LOUD refusal ({@link PaperSessionRefused}
 *     `mode-gate`), never a silent downgrade and never a live route;
 *  2. **the literal**: this module contains exactly ONE `makeGate` call and its mode argument is the
 *     LITERAL `"paper"` — there is no variable to poison, no branch to flip;
 *  3. **the factory**: even if 1+2 were defeated, `makeGate("live", …)` fails closed with
 *     {@link LiveGateRefused} (no human-signed arm exists to hand it, and a {@link PaperArm} can never
 *     authorize live).
 *
 * **On the ENDPOINT (what the socket actually reached) — ADR-0034 §3's second barrier.** Walls 1–3 all
 * guard the mode STRING and the gate OBJECT. A misconfigured port cannot falsify a mode string:
 * `--port 7496` (TWS LIVE) against a live-logged-in gateway is `mode=paper` all the way down while the
 * SOCKET is attached to real money. **The mode was never the leak — the socket was.** So:
 *  4. **the account assertion** (THE barrier): the IBKR transport asserts, on the gateway's OWN
 *     `managedAccounts` handshake and BEFORE any tape is opened / gate is built / order can be
 *     transmitted, that EVERY account the gateway ITSELF REPORTED is a PAPER account (`DU`/`DF`) — the
 *     report must be NON-EMPTY and its EVERY entry paper, so a MIXED report (`DU…,U…`) never passes on
 *     its paper-first entry. It classifies the REPORT, never the operator's pinned CLAIM
 *     (`--account`/`KESTREL_IBKR_ACCOUNT`): ANY reported live `U`-prefixed account — or one that cannot
 *     be classified at all, or an absent report — REFUSES ({@link PaperSessionRefused} `live-account`),
 *     AND, when an account is pinned, the pin must EQUAL one of the gateway's reported (paper) accounts
 *     or it is refused just as loudly (a pinned paper-shaped string can never launder a socket that
 *     reached a different, or a live, account). The socket is CLOSED behind the refusal. Because it
 *     reads the gateway's own report, this holds on ANY port and against ANY pinned claim — it does not
 *     depend on which port you used;
 *  5. **the live-port refusal** (defense-in-depth, secondary): IB's own real-money ports (4001 IB
 *     Gateway live, 7496 TWS live) are refused before a socket is opened (`live-port`), with no
 *     acknowledge-and-proceed escape hatch. A port is a claim about an endpoint, never evidence about
 *     an account — wall 4 (report, not claim) is what actually holds.
 *
 * Live real-money routing (kestrel-7o2.10) is owner-gated and is NOT prepared here.
 *
 * ## REAL LIMITS, TWO CEILINGS (kestrel-7o2.12 AC, ADR-0034 §4)
 * {@link RunPaperOptions.limits} is **REQUIRED** and must be FINITE. This is the point of the bead:
 * `makeGate("paper", …)` with no `limits` falls through to
 * {@link import("../adapters/broker.ts").UNBOUNDED_PAPER_LIMITS}, which makes the seam's L0 clamp a
 * benign no-op and leaves the adapter's WALL 5 as the only real bound. Here ONE config number set is
 * threaded into BOTH layers — the seam clamp (`makeGate`'s `paper.limits`) AND the venue adapter's own
 * WALL 5 (`IbkrBrokerDeps.limits`) — so the two ceilings are defense-in-depth over one source and can
 * never drift. {@link assertBoundedLimits} refuses `Infinity` outright.
 *
 * ## FAIL CLOSED (RUNTIME §8)
 * An unreachable Gateway, a refused socket, an unresolved contract, a missing/absent feed, a dead or
 * stale tape, a degraded transport, or a tripped kill-switch REFUSES LOUDLY with a typed
 * {@link PaperSessionRefused} carrying a logged reason. Never a silent no-op, never a fabricated fill,
 * never a silent default. Defense in depth on the tape: {@link stalenessGatedProvider} ALSO de-arms
 * every market-series read while the feed is degraded, so a plan cannot fire off a dead line even
 * within a cycle of the session-level refusal.
 *
 * ## The injected-time boundary (documented, deliberate — mirrors `./day.ts`)
 * A paper session is a LIVE session: its clock is the venue's tape (`ev.ts`, injected exactly as the
 * sim driver injects the bus's), and the host `sleep`/`now` used to PACE the pump loop are host
 * interaction, not graded computation. Fidelity is `modeled` regardless (CONTEXT: **Fidelity** — sim
 * and paper are both modeled; they differ only by feed).
 *
 * ## Deliberately NOT here (owner decision, kestrel-7o2.12 — stated, not smuggled)
 *  - **the wake/authoring loop.** This driver mirrors {@link runSimSession}: it ARMS a standing
 *    document and drives it. Standing Plans then fire at machine speed — which IS the Plan surface's
 *    own contract (CONTEXT: **Plan** — "fired by the runtime at machine speed; the author is informed
 *    in parallel"). A live wake/authoring loop needs the clock-honest wake machinery (ADR-0040:
 *    deliberation consumes tape time), which is a separate concern; {@link PaperSession} exposes
 *    `step`/`pump`/`bus`, so that layer composes ABOVE this driver rather than being forked into it.
 *  - **BYO-broker credential hardening** (kestrel-7o2.23). IB Gateway auth is a SOCKET to a
 *    locally-running, human-logged-in Gateway (host/port/clientId) — there is no API secret here and
 *    no credential store is invented. {@link PaperVenueSource} is the documented seam if one is ever
 *    needed.
 */
import type { BusEvent, NewBusEvent } from "../bus/index.ts";
import { PlanEngine, type Gate, type InstrumentSpec } from "../engine/index.ts";
import { CanonicalState } from "../series/index.ts";
import type { KestrelNode } from "../lang/index.ts";
import { type PositionSnapshot, type RiskLimits } from "../adapters/broker.ts";
import type { IbkrBroker, IbkrBrokerDeps } from "../adapters/broker/ibkr/broker.ts";
import type { IbkrConfig, IbkrConfigInput } from "../adapters/broker/ibkr/config.ts";
import type { IbkrFeed, FeedWatermark } from "../adapters/broker/ibkr/feed.ts";
import type { BrokerStatus, IbkrTransportDeps } from "../adapters/broker/ibkr/transport.ts";
/**
 * Why a paper session refused (kestrel-7o2.12) — a CLOSED, typed vocabulary a caller branches on and
 * logs before STANDing DOWN. There is deliberately no "degrade and carry on" member: every one of
 * these ends the session.
 *
 * - `mode-gate`          — the resolved config is not `paper`. The driver is paper-only by construction.
 * - `live-port`          — the endpoint names one of IB's own REAL-MONEY API ports (4001 IB Gateway
 *   live, 7496 TWS live). Defense-in-depth, refused before a socket is opened; there is deliberately
 *   no acknowledge-and-proceed escape hatch — this is the PAPER verb, and it has no legitimate reason
 *   to aim at a live port. NOT the real barrier: a live gateway can listen anywhere (see `live-account`).
 * - `live-account`       — THE BARRIER (ADR-0034 §3). Classifies EVERY account the gateway ITSELF
 *   REPORTED (the full `managedAccounts` list, never the pinned claim). Refused unless the report is
 *   NON-EMPTY and EVERY reported account is a PAPER account (`DU`/`DF`): ANY live `U`-prefixed account,
 *   ANY account that cannot be classified at all, or an absent/empty report is refused just as loudly
 *   (never assume paper; a MIXED report `DU…,U…` does not pass on its paper-first entry) — OR when a
 *   pinned `--account` does not EQUAL ANY of the gateway's reported accounts (a pinned paper-shaped
 *   string can never vouch for a socket that reached a different/live account). Raised AFTER the
 *   handshake and BEFORE any tape/gate/order exists, and the socket is CLOSED behind it.
 * - `limits-absent`      — no {@link RiskLimits}, or an UNBOUNDED one. An unbounded paper gate makes the
 *   seam's L0 clamp a no-op; a session is never run without a real ceiling.
 * - `documents-absent`   — nothing to arm. A session with no standing document has no judgment in it.
 * - `connect-failed`     — the IB Gateway is unreachable / the socket was refused / the handshake lapsed.
 * - `contract-unresolved`— a Kestrel identity did not map onto exactly ONE venue contract.
 * - `feed-absent`        — the tape never opened: the underlier subscription is not live.
 * - `feed-stale`         — the tape DIED mid-session (the underlier line is stale/frozen/dark).
 * - `transport-degraded` — the socket dropped / lost its heartbeat mid-session.
 * - `killed`             — the kill-switch tripped (an L0 halt, or a reconciliation break).
 * - `order-refused`      — a wall REFUSED an order the armed judgment wanted to place (the seam's L0
 *   clamp, or one of the venue face's five walls: never-naked, intrinsic floor, price anchor, contract,
 *   budget). NOTHING was transmitted — that part is the system working. The session ENDS anyway; see
 *   {@link standDownOnRefusal} for why that is the conservative call and not an over-reaction.
 */
export type PaperSessionFailure = "mode-gate" | "live-port" | "live-account" | "limits-absent" | "documents-absent" | "connect-failed" | "contract-unresolved" | "feed-absent" | "feed-stale" | "transport-degraded" | "killed" | "order-refused";
/**
 * The LOUD, typed, fail-closed refusal of a paper session (kestrel-7o2.12). A DISTINCT class (never a
 * bare `Error`) so a caller catches a session refusal specifically and can never mistake it for an
 * unrelated fault — and so a refusal can NEVER be a silent no-op. Carries the typed
 * {@link PaperSessionFailure} and a secret-free {@link reason} (the account id is redacted upstream by
 * `describeIbkrConfig`; nothing here ever composes a raw account into a message).
 */
export declare class PaperSessionRefused extends Error {
    readonly name = "PaperSessionRefused";
    readonly failure: PaperSessionFailure;
    /** The secret-free reason, logged verbatim on the STAND_DOWN path. */
    readonly reason: string;
    constructor(failure: PaperSessionFailure, reason: string, options?: {
        cause?: unknown;
    });
}
/** What the driver asks a venue to put a tape on. Pure data — no clock, no socket, no credential. */
export interface PaperVenueRequest {
    /** The underlier symbol (generic tickers only in anything shipped — ARCHITECTURE §7). */
    readonly instrument: string;
    /** The session header's opaque calendar token (`YYYY-MM-DD`). */
    readonly sessionDate: string;
    /** The chain expiry (`YYYYMMDD`). Absent ⇒ an equity-only tape; an expiry is NEVER guessed. */
    readonly expiry: string | undefined;
    /**
     * The OBSERVED underlier price the strike window centres on — WHERE THE MONEY IS. REQUIRED whenever
     * {@link expiry} is present (kestrel-7o2.19): the contract layer refuses a centre-less chain slice.
     * It is an INJECTED observation (the operator's `--spot`), which is exactly what determinism at the
     * edge means; the driver never synthesizes one out of a quote.
     */
    readonly spot: number | undefined;
    /** LISTED strikes each side of the ATM one. Absent ⇒ the surface-window default. */
    readonly halfWidth: number | undefined;
    /** Time to expiry in YEARS for `@fair` — INJECTED, never derived from a clock (RUNTIME §0). */
    readonly tauYears: number | undefined;
    /** IB market-data flavour (1 real-time, 3 delayed). Absent ⇒ the gateway's own default is left alone. */
    readonly marketDataType: number | undefined;
    /** The injected host clock (epoch ms). */
    readonly now: () => number;
    /** Redacted-diagnostic sink. Receives only already-redacted strings. */
    readonly log: (line: string) => void;
}
/**
 * The engine-side deps the driver hands the venue's order face — {@link IbkrBrokerDeps} MINUS the three
 * the venue itself owns (its `client`, its resolved `contracts`, and its gateway-issued `nextOrderId`
 * sequence, which is never ours to invent).
 */
export type PaperBrokerRequest = Omit<IbkrBrokerDeps, "client" | "contracts" | "nextOrderId">;
/** One opened venue session: a tape, an order face, and the socket's health. */
export interface PaperVenueSession {
    /** The venue's tape — a {@link IbkrFeed}, i.e. a `FeedSource` over the EXISTING `BusEvent` union. */
    readonly feed: IbkrFeed;
    /** Build the venue's PAPER order face, once the driver's engine-side deps exist (they cannot exist
     * before the tape does — the engine prices against the tape). */
    broker(req: PaperBrokerRequest): IbkrBroker;
    /** The socket's typed status (the account is redacted). `degraded` is the STAND_DOWN signal. */
    status(): BrokerStatus;
    /** Beat the socket's heartbeat watchdog (host-paced, off the graded path). */
    pulse(): void;
    /** Close the tape and detach every listener. Idempotent. */
    close(): void;
}
/**
 * How the driver reaches a venue (kestrel-7o2.12) — the ONE seam between the deterministic driver and
 * a socket. The default is {@link ibkrPaperVenue} (the real IB Gateway); a test injects a fake so the
 * whole driver runs offline, with no gateway and no real money.
 *
 * MODE-LOCKED BY CONTRACT: the {@link IbkrConfig} handed to {@link open} is ALWAYS `mode: "paper"` —
 * {@link openPaperSession} refuses anything else BEFORE this is ever called, and the IBKR transport
 * refuses `live` again on its own. An implementation may rely on that and must never widen it.
 */
export interface PaperVenueSource {
    open(cfg: IbkrConfig, req: PaperVenueRequest): Promise<PaperVenueSession>;
}
/**
 * The session's ONE Bus (CONTEXT: **Bus**) — append-only, monotonic `seq`, the audit trail and the
 * grading corpus at once. Both the venue's tape events and the engine's own emissions land here in
 * ARRIVAL order under ONE `seq` space: the feed stamps a `seq` in its own space, so it is re-stamped
 * on append (two `seq` spaces on one bus is not a bus).
 */
export declare class PaperBus {
    #private;
    readonly events: BusEvent[];
    /** Append one event, stamping the session's own monotonic `seq`, and return the stamped event. */
    append(ev: BusEvent | NewBusEvent): BusEvent;
}
/** The host-interaction seam — the ONLY wall-clock/sleep/stderr touch points, all off the graded fold
 * (see the header's injected-time boundary). Mirrors `DayHooks`. */
export interface PaperHooks {
    /** Park the HOST between pump cycles (NOT tape time). */
    sleep(ms: number): Promise<void>;
    /** HOST wall clock (ms) — the feed's `now`, and the pump loop's pacing. NOT a graded input. */
    now(): number;
    /** Announce host status lines — a refusal reason, a degraded tape. Never on stdout (a report owns
     * that), never graded. Omitted ⇒ the real `process.stderr`. */
    notify(line: string): void;
}
/** How many pump cycles a session runs for, and how long the host parks between them. */
export declare const DEFAULT_PUMP_MS = 1000;
/** Options for {@link openPaperSession} / {@link runPaperSession}. */
export interface RunPaperOptions {
    /** The underlier symbol (generic tickers only — ARCHITECTURE §7). */
    readonly instrument: string;
    /** The session header's calendar token (`YYYY-MM-DD`). */
    readonly sessionDate: string;
    /** The standing documents to arm — already-parsed Kestrel nodes (a bare statement or a full module;
     * both are normalized), EXACTLY as {@link RunSimOptions.documents}: the caller owns the parse, so a
     * parse escape STANDs DOWN before a socket is ever opened. At least one is required. */
    readonly documents: readonly KestrelNode[];
    /**
     * The REAL L0 ceilings, from config. **REQUIRED and FINITE** — threaded into BOTH the seam clamp and
     * the venue adapter's WALL 5. There is deliberately no default: a defaulted risk ceiling is exactly
     * the silent default AGENTS.md forbids.
     */
    readonly limits: RiskLimits;
    /** The bounded-risk budget in dollars (`size × max_loss ≤ budget`). Absent ⇒ `limits.maxNotionalUsd`. */
    readonly budgetUsd?: number | undefined;
    /** Dollar value of 1R. */
    readonly rUsd: number;
    /** IB Gateway channel: host/port/clientId/account. Absent fields fall through to env then the
     * publication-safe defaults (`127.0.0.1:4002`, IB Gateway PAPER). */
    readonly gateway?: IbkrConfigInput | undefined;
    /** The chain expiry (`YYYYMMDD`). Absent ⇒ an equity-only tape. */
    readonly expiry?: string | undefined;
    /** The OBSERVED spot the strike window centres on — required with {@link expiry} (kestrel-7o2.19). */
    readonly spot?: number | undefined;
    /** LISTED strikes each side of ATM. */
    readonly halfWidth?: number | undefined;
    /** Time to expiry in YEARS for `@fair` — injected, never off a clock. */
    readonly tauYears?: number | undefined;
    /**
     * The operator's DECLARATION that the gateway serves REAL-TIME market data (asks IB for type 1). It
     * is an ASSERTION, never an inference — exactly like `day --no-author`. Absent ⇒ the driver stamps
     * every {@link PriceAnchor} `freshness: "unknown"`, and the order face's price-anchor wall then
     * REFUSES every order (fail-closed: an anchor whose provenance we cannot establish is not provenance).
     * A paper session with this absent still PERCEIVES; it just cannot price.
     */
    readonly liveMarketData?: boolean | undefined;
    /** Instrument specs override (else derived from the feed's META). */
    readonly instruments?: readonly InstrumentSpec[] | undefined;
    /** Reconciliation tolerance (absolute qty per key). Absent ⇒ `0`. */
    readonly tolerance?: number | undefined;
    /** How many pump cycles {@link runPaperSession} drives. Required — an unbounded live loop is not a
     * session, it is a daemon. */
    readonly cycles: number;
    /** Host park between pump cycles. Default {@link DEFAULT_PUMP_MS}. */
    readonly pumpMs?: number | undefined;
    /** The venue seam (test injection point). Default: the real IB Gateway ({@link ibkrPaperVenue}). */
    readonly venue?: PaperVenueSource | undefined;
    /** Transport-level injection for the DEFAULT venue (a fake `makeClient`, a manual scheduler). */
    readonly transport?: IbkrTransportDeps | undefined;
    /** Host-interaction hooks (test seam). Spread OVER {@link DEFAULT_HOOKS} — an omitted field inherits
     * the REAL host, exactly as `DayHooks` documents. */
    readonly hooks?: Partial<PaperHooks> | undefined;
}
/** The live paper Session — the runtime object CONTEXT names: `{ driver, clock, gate, bus, mode }`. */
export interface PaperSession {
    /** CONTEXT: **Mode**. A literal — this object can never describe anything else. */
    readonly mode: "paper";
    /** The L0-clamped paper gate from `makeGate("paper", { venue: "ibkr" })`. NEVER a live gate. */
    readonly gate: Gate;
    /** The venue's paper order face beneath the clamp (its ledger/reconcile/kill-switch surface). */
    readonly broker: IbkrBroker;
    readonly feed: IbkrFeed;
    /** The session's single truth (CONTEXT: **Bus**) — the {@link SessionCore} emitted stream, into which
     * BOTH the feed's tape events and the engine's own emissions land in arrival order under one `seq`
     * space. A read-only projection; the driver never appends to it directly. */
    readonly bus: {
        readonly events: readonly BusEvent[];
    };
    readonly engine: PlanEngine;
    readonly state: CanonicalState;
    /** The REAL ceilings this session is bounded by — the SAME object threaded into both L0 layers. */
    readonly limits: RiskLimits;
    /** Fold ONE tape event through {@link SessionCore.step} — pin the venue clock, append to the bus,
     * fold canonical state, sweep, then feed any venue fills back (post-sweep, the broker ordering). */
    step(ev: BusEvent): void;
    /** One live cycle: check the socket + the kill-switch + the tape's watermark (each refuses LOUDLY),
     * then pump the feed and step everything it drained. */
    pump(): void;
    /** The tape's staleness watermark — freshness is READ, never inferred from canonical state. */
    watermark(): FeedWatermark;
    close(): void;
}
/** What a completed paper session yields. */
export interface PaperSessionResult {
    /** The session's Bus (CONTEXT: **Bus**) — the audit trail a Blotter projects from. */
    readonly events: readonly BusEvent[];
    /** The venue's per-order reconciliation ledger (engine expectation beside broker truth). */
    readonly ledger: ReturnType<IbkrBroker["ledger"]>;
    /** The BROKER's own authoritative closing positions (never the engine's expectation). */
    readonly positions: PositionSnapshot;
    /** The tape's closing watermark. */
    readonly watermark: FeedWatermark;
    /** How many cycles actually ran (a refusal ends the session early — and throws). */
    readonly cycles: number;
}
/**
 * REFUSE an absent/unbounded ceiling (kestrel-7o2.12 AC#2). `makeGate("paper", …)` without `limits`
 * silently falls through to `UNBOUNDED_PAPER_LIMITS` — every ceiling `+Infinity` — which composes the
 * clamp but makes its L0 check a benign no-op. That is precisely the hole this bead closes, so a
 * non-finite ceiling is refused HERE, before a gate is ever built.
 */
export declare function assertBoundedLimits(limits: RiskLimits | undefined): RiskLimits;
/**
 * The REAL IB Gateway venue (kestrel-7o2.12). Every `@stoqey/ib`-bound module is reached through a
 * LAZY `import()` inside `open`, exactly as `adapters/broker.ts` keeps the venue registry behind a
 * thunk: this driver's static graph therefore carries no socket, and importing `session/paper.ts`
 * never pulls the IB client.
 */
export declare function ibkrPaperVenue(transportDeps?: IbkrTransportDeps): PaperVenueSource;
/**
 * Open a live paper Session against the venue: connect, resolve contracts, open the tape, build the
 * L0-clamped paper gate, arm the standing documents. Every failure is a LOUD typed
 * {@link PaperSessionRefused}.
 */
export declare function openPaperSession(opts: RunPaperOptions): Promise<PaperSession>;
/**
 * Run a paper session to completion (kestrel-7o2.12): open it, then drive `cycles` live pump cycles,
 * host-parked `pumpMs` apart. Any refusal (a degraded socket, a dead tape, a tripped kill-switch)
 * THROWS the typed {@link PaperSessionRefused} — a paper session never limps on.
 */
export declare function runPaperSession(opts: RunPaperOptions): Promise<PaperSessionResult>;
//# sourceMappingURL=paper.d.ts.map