/** What ONE landed compaction did to the transcript, recorded at its commit point. */
export interface CompactionEffect {
    /** The entry ids that went into the summarized prefix (everything before `firstKeptEntryId`), or
     *  `"unknown"` when the kept-tail anchor could not be located in the branch — the conservative
     *  reading is that the whole branch was summarized, so a reader treats `"unknown"` as "every
     *  receipt this run holds is invalidated" (the same direction
     *  {@link import("./auto-compaction.js").countSummarizedCrossSessionMessages} already takes). */
    readonly summarizedEntryIds: ReadonlySet<string> | "unknown";
}
/**
 * One receipt ASK: the carrier a frame rides, and — for a frame that rides a TOOL RESULT — the
 * text {@link frameSurvivesInToolResult} must find in that result as committed. An injected frame is its
 * own carrier (the committed message IS the frame), so it carries no text to check.
 */
export interface FrameReceiptAsk {
    /** The injection queue's dedup key of the frame itself, or {@link toolResultReceiptKey} of the call whose result carries it. */
    readonly carrier: string;
    readonly frameText?: string;
}
/**
 * The leg's settlement seam, one cell per run.
 *
 * `awaiting` is an ASK, not a log: only keys a consumer registered are ever given a receipt, an ask
 * leaves when its carrier commits, so a run that delivers thousands of ordinary notification frames
 * does not accumulate one map entry per frame. The key is the consumer's per-frame key.
 */
export interface FrameSettlement {
    /** Receipt asks a consumer is waiting on (key → ask). The receipt sink records nothing for any other key. */
    readonly awaiting: Map<string, FrameReceiptAsk>;
    /** Receipts collected for awaited keys: key → the transcript entry id the frame landed in. */
    readonly receipts: Map<string, string>;
    /** Awaited keys whose carrier COMMITTED WITHOUT the frame and nothing the HOST did explains it (an engine-side
     *  crop): shown nothing, so owed again — never a receipt. */
    readonly withheld: Set<string>;
    /** Carriers whose result a HOST hook rewrote (`postToolUse.updatedOutput`) before the commit — recorded only
     *  for a carrier some ask rides ({@link noteHostRewrite}), consumed by the receipt at its commit: a frame the
     *  rewrite kept gets an ordinary receipt, a frame it removed is host-withheld. */
    readonly hostRewritten: Set<string>;
    /** Awaited keys whose frame is not in the host's rewrite (removed, truncated, or reshaped beyond whitespace): the
     *  host decided what the model reads, so the consumer settles the record as the host's decision (terminal),
     *  discloses it loudly, and never hands it over again. */
    readonly hostWithheld: Set<string>;
    /** Compactions that LANDED this run and have not been consumed by a settlement pass yet, in landing
     *  order. Recorded only while {@link FrameSettlement.wantsEffects} says a record could still be
     *  broken by one, and cleared by the consumer's LOCAL settlement half — which needs no lease, so an
     *  unclaimable or empty box cannot leave them piling up for the whole leg. */
    readonly compactions: CompactionEffect[];
    /**
     * #1036 — "is this engine frame's record still parked in a DURABLE box?" Set by the
     * session-box drain when it binds. The terminal sweep hands back engine-note payloads that never
     * drained and the runner pends them PER SESSION (an in-process copy); for a frame whose record the
     * drain no longer acks on delivery, that copy would be a second source of truth — the box already
     * re-serves it to the session's next run. Absent (no drain bound) ⇒ the pre-1036 behavior, which is
     * correct there: nothing else holds those frames.
     */
    boxBacked?: (payload: unknown) => boolean;
    /**
     * #1036 — "is there a record a landed compaction could still break?" Asked at the compaction
     * COMMIT beat, before an effect is recorded at all. Absent (no drain bound) or `false` ⇒ the effect
     * is not recorded: nothing would ever read it, and a leg that compacts many times would otherwise
     * hold every landing's entry-id set until it ended.
     */
    wantsEffects?: () => boolean;
}
export declare function createFrameSettlement(): FrameSettlement;
/** The carrier key of a TOOL RESULT (the `ReadInbox` pull face): its own domain, so it can never
 *  collide with an injection queue dedup key. One tool result can carry SEVERAL frames, each asked for
 *  under its own key with this carrier. */
export declare function toolResultReceiptKey(toolCallId: string): string;
/**
 * THE rule for a frame that rides a TOOL RESULT: the result can be replaced (`postToolUse.updatedOutput`)
 * or cropped (the aggregate result budget) after the frame was handed to it, so handing it over proves
 * nothing — the frame counts as delivered only when its text is present in the result AS COMMITTED
 * (a string, or the text blocks, each read whole), compared with every whitespace run on both sides folded
 * to one space: a rewrite that only re-spaces, re-indents or re-wraps the frame kept it. Any other change
 * (a word, an escape, the case) did not. Before the commit, nothing is proven. The inbox receipt
 * below reads it; the listing ride (`prepare-listings.ts`) does not call it — it never commits announced
 * state at ride time, the conservative answer for a frame whose commit has not happened yet.
 */
export declare function frameSurvivesInToolResult(committedContent: unknown, frameText: string): boolean;
/** The station that applies a HOST hook's `updatedOutput` marks the carrier — only when an ask rides it, so an
 *  ordinary rewritten result leaves nothing behind. */
export declare function noteHostRewrite(seam: FrameSettlement, toolCallId: string): void;
/** The receipt sink's ONE writer: every ask riding `carrier` is answered — a receipt when its frame is in
 *  the committed content (or it is its own carrier); when it is not, host-withheld if a host hook rewrote the
 *  carrier (the host's decision), withheld otherwise (owed again). */
export declare function recordFrameReceipt(seam: FrameSettlement, carrier: string, committedContent: unknown, entryId: string): void;
/** The carrier a committed frame was riding, as the harness reports it at the transcript append — a tool
 *  result with the content it was committed with (after every result transformation); a user-attachment frame by
 *  its delivery record's key (`inputId`, `ordinal`). */
export type CommittedFrameCarrier = {
    kind: "engine_note";
    payload: unknown;
} | {
    kind: "tool_result";
    toolCallId: string;
    content: unknown;
} | {
    kind: "attachment";
    inputId: string;
    ordinal: number;
};
