/**
 * The live-plan bookkeeping behind the one-live-plan-per-page contract
 * (ADR-0011). One page shows one plan at a time; a *plan swap* is
 * `unstable_destroy()` followed by `load()`, and the next load builds a
 * completely fresh event-scoped world rather than resetting the old one.
 *
 * Two things live here, and nothing else — the module is deliberately free of
 * store, config and DOM imports so `load()` can hold the contract without
 * pulling the event-scoped graph into the entry chunk:
 *
 * - the slot: `load()` claims it and refuses a second plan; `disposePlan()`
 *   frees it, which is what makes `unstable_destroy()` idempotent;
 * - the teardown registry: everything the plan owns — MobX reactions, DOM
 *   listeners, timers, the store graph itself — registers how to undo itself,
 *   because an undisposed reaction stays subscribed to the dead instance and
 *   pins it across the swap (spike finding, `docs/2026-08-27-plan-swap-proxy-spike-verdict.md`).
 *
 * Module-scope *data* that belongs to one event is not registered anywhere: it
 * is memoized on the installed config by `tools/event-scoped-cache.ts`.
 */
type Disposer = () => void;
/**
 * What an embedder sees when their navigation code loads a second plan without
 * destroying the first. Naming the fix is the point — the alternative is a
 * corrupted map (ADR-0011).
 */
export declare const LIVE_PLAN_ERROR: string;
/** Whether a plan currently owns the page. */
export declare function isPlanLive(): boolean;
/**
 * Names the plan currently occupying the page. Bumped by every teardown, so async work started by
 * one plan can tell that it has come back to a different one — or to none.
 *
 * `isPlanLive()` cannot answer that question: the next `load()` claims the slot long before
 * `createLivePlan()` points the barrel at its graph, so a continuation resuming in that window sees
 * a live plan and reads a barrel that is still empty. Capture this before the `await`, compare
 * after, and drop the result when it no longer belongs to anyone (ADR-0011).
 */
export declare function planGeneration(): number;
/**
 * Reserves the page for the plan being loaded. Called at the top of `load()`,
 * before anything is built, so a sequencing bug in the host's navigation
 * surfaces as a rejected promise rather than a half-swapped world.
 *
 * @throws when a plan is already alive; the live plan is left untouched.
 */
export declare function claimPlanSlot(): void;
/**
 * Registers how to undo one thing the live plan owns. Disposers run in reverse
 * registration order, so whatever was built first — the store graph — is the
 * last thing to go.
 */
export declare function registerPlanDisposer(dispose: Disposer): void;
/**
 * Tears the live plan down and frees the slot: the disposer registry runs in
 * reverse, then the page is empty again. Idempotent — a second call, and a
 * call when nothing was ever loaded, do nothing.
 *
 * @throws the first failure once every disposer has run. A disposer that
 * throws is a bug in that module, not a reason to strand the rest of the
 * teardown and leave the page half-alive.
 */
export declare function disposePlan(): void;
export {};
//# sourceMappingURL=plan-lifecycle.d.ts.map