/**
 * The LIVE MCP roster lane: applying one server's intake result to a RUNNING roster, and the
 * host-driven re-dial that is the second caller of it.
 *
 * Two faces change a task's MCP roster after prepare has finished — the model's `RefreshMcpTools`
 * tool and the run handle's `reconnectMcpServer` verb — and what they must do to the roster is the
 * same list in the same order: drop the deployment-excluded names, re-fold the safety axes (with the
 * non-monotone restore arm on refusal), replace the server's whole name-prefix domain at its own
 * anchor, rebuild the harness toolset, and re-mint the roster delta. That list lived inside the
 * refresh tool's execute closure, where the second face could only have copied it; a copy would have
 * been a second answer to "what does a mid-task roster change consist of".
 *
 * It is machinery, not a phase: the protocol-tools phase reaches DOWN for it to build the refresh
 * tool, and the run's verb wiring reaches down for the same functions.
 */
import type { AgentTool } from "../../internal/harness.js";
import type { McpDroppedTool, McpReconnectResult, MaterializedMcp, McpToolAxis } from "../mcp.js";
import type { RunnerDeps, TaskSpec, ToolEffect } from "../types.js";
import type { IrreversibilityTier, ToolFaceSnapshot } from "./contracts.js";
import type { RosterBuilder, ToolRosterDeltaSeat } from "../tool-roster.js";
import type { McpInstructionsEntry } from "../prompt-section-seat.js";
/** One server's assertion about its own prefix domain — the shape both faces reduce to. `tools` is
 *  the roster the domain must END UP with (empty withdraws it); `added`/`removed` are the reporting
 *  half and never drive the swap. `instructions`: the server's current connection's instructions entry, when the face that produced
 *  the delta hands it back (a refresh does; a re-dial queues its new text itself). */
export interface McpRosterDelta {
    server: string;
    prefix: string;
    tools: AgentTool[];
    axes: McpToolAxis[];
    dropped: McpDroppedTool[];
    instructions?: McpInstructionsEntry;
}
/** The seats a roster application writes through. Every one of them is borrowed from the phase that
 *  minted it — this module owns nothing. */
export interface McpRosterApplyInput {
    /** borrowed-readonly — the run's spec; only `excludeAllTools` is read: the valve's whole-face switch decides what a live roster
     *  change may mount, beside the selector (`valveLeaves`). */
    spec: Pick<TaskSpec, "excludeAllTools">;
    /** borrowed-readonly — the frozen tool face; its selector keeps a tool the leg may not use from ever
     *  being mounted by a face the model or a host can trigger. */
    toolFaceSnapshot: Pick<ToolFaceSnapshot, "selector">;
    /** borrowed-readonly — the per-server face overlay (the phase's `withFaces`). */
    withFaces: (tools: AgentTool[], server: string) => AgentTool[];
    /** borrowed-readonly — the large-result wrapper every protocol tool is mounted through. */
    remoteToolOffload: (tool: AgentTool) => AgentTool;
    /** borrowed-readonly — the phase's axis fold (throws on a config contradiction). */
    foldProtocolAxes: (axes: McpToolAxis[], label: string) => void;
    /** borrowed-mutable — the two NON-MONOTONE tables the fold writes and this applier snapshots. */
    toolEffects: Map<string, ToolEffect>;
    axisExplicitNegatives: Map<string, {
        irreversible?: false;
        egress?: false;
    }>;
    /** borrowed-mutable — the run's shared roster. */
    roster: RosterBuilder;
    /** borrowed-readonly — the run's frozen MCP server declarations: a roster reading is of a declared server, and a name none is declared under holds nothing. */
    declared: ReadonlyArray<{
        readonly name: string;
    }>;
    /** borrowed-mutable — the materialization's instructions delta lane; a roster change settles the server's adds on it. */
    instructionsDelta: MaterializedMcp["instructionsDelta"];
}
/** What one application did to the server's domain on the roster — read off the roster before and after the swap, the ONE source of
 *  "how many of this server's tools are mounted" for the re-dial's notice and receipt and the refresh tool's receipt. A name the
 *  valve left out, a name the deployment's `toolFaces` overlay refused and a name the server listed but the roster did not take are
 *  all simply absent from `mounted`. */
export interface McpRosterReading {
    /** The names of the server's tools the roster holds after the application, in wire order. */
    mounted: string[];
    /** The names `mounted` holds that the roster did not hold before. */
    added: string[];
    /** The names the roster held before that `mounted` no longer holds. */
    removed: string[];
    /** The names the server listed that the roster did not take (the valve's, the overlay's). */
    excluded: string[];
}
/** What one application did, for the caller's receipt. `applied:false` means the axis fold refused
 *  and the domain was left exactly as it was (the tables restored) — no roster write happened, so `mounted` is what it held. */
export type McpRosterApplyOutcome = ({
    applied: true;
} & McpRosterReading) | ({
    applied: false;
    foldError: string;
} & McpRosterReading);
/** What the roster holds of one server with no swap made — the reading of an arm that asserted no roster (a failed refresh, a refused re-dial, a fold refusal).
 *  A name no server is declared under holds nothing, even when it mints a declared server's prefix. */
export declare function rosterHolding(input: Pick<McpRosterApplyInput, "roster" | "declared">, serverName: string): McpRosterReading;
/** A refresh or re-dial result read off the roster instead of the server's own listing: `toolCount` is the tools mounted, `added` /
 *  `removed` the names that came onto / left the roster, and — on a result that asserts a roster — `tools` the roster's tools of the
 *  server (with `axes` cut to them), so `toolCount === tools.length`. One meaning, the one `MaterializedMcp.refresh` / `reconnect` give
 *  for their own handles. */
export declare function settledOnRoster<T extends {
    toolCount: number;
    added: string[];
    removed: string[];
    tools?: AgentTool[];
    axes?: McpToolAxis[];
}>(result: T, reading: McpRosterReading, roster: Pick<RosterBuilder, "tools">): T;
/**
 * Apply one server's delta to the live roster, and settle the server's instruction adds on the delta lane: the teaching answer over the
 * roster after the swap, against the lane's ledger of what the model holds (both faces — the model's refresh and the host's re-dial —
 * through this one step).
 */
export declare function applyMcpRosterDelta(input: McpRosterApplyInput, delta: McpRosterDelta): McpRosterApplyOutcome;
/** The seats the post-application commit writes through. */
export interface McpRosterCommitInput {
    rebuildHarnessToolsRef: {
        current?: () => Promise<void>;
    };
    rosterSeat: ToolRosterDeltaSeat;
    toolCallGateArmedRef: {
        armed: boolean;
    };
    irreversibleTools: ReadonlySet<string>;
    egressTools: ReadonlySet<string>;
}
/**
 * Publish whatever the applications above changed: rebuild the harness toolset (the content-origin
 * re-wrap runs inside it), then re-mint the roster delta so the stream's rows describe the LIVE
 * objects. Batched deliberately — a refresh spanning several servers rebuilds once.
 *
 * Returns the gate-honesty line when one is due. The built-in integrity policies are composed
 * UNCONDITIONALLY, so `armed` is always true in this engine and the line never fires today; the arm
 * stays as a zero-cost guard for a refactor that would make the composition conditional.
 */
export declare function commitMcpRosterChanges(input: McpRosterCommitInput): Promise<string | undefined>;
/** The re-dial's own seats: the handle it drives, the two operator sinks, and the run identity the
 *  disclosure names. */
export interface McpRedialInput extends McpRosterApplyInput, McpRosterCommitInput {
    mcp: MaterializedMcp;
    deps: Pick<RunnerDeps, "onError" | "onNotice">;
    sessionId: string;
    runId: string;
    irreversibilityTier: IrreversibilityTier;
}
/**
 * The run handle's `reconnectMcpServer` verb, phase-side: re-dial one server, put whatever it
 * asserted about its prefix domain onto the live roster, and disclose.
 *
 * The roster is written IFF the result carries `tools` — the one rule this lane reads. That covers
 * both directions with no second condition: a successful re-dial asserts its fresh roster, a failed
 * DIAL asserts the empty one (the connection it tore down is gone, so leaving its names mounted would
 * leave the model holding tools that can only fail), and an arm that never touched the connection —
 * unknown name, revoked server, re-dial already in flight, disposed materialization — asserts nothing
 * and the mounted roster is left alone.
 *
 * The result it hands back counts what the ROSTER took: `toolCount` is the server's tools mounted after the swap, `added` /
 * `removed` the names that came onto / left the roster, and the notice reads the same three — one source for "how many are mounted".
 */
export declare function redialMcpServer(input: McpRedialInput, server: string): Promise<McpReconnectResult>;
