/** One LSP diagnostic, the subset the model/shell needs (LSP `Diagnostic` narrowed). */
export interface LspDiagnostic {
    message: string;
    /** LSP severity: 1=Error 2=Warning 3=Information 4=Hint. Absent = unknown (sorted last). */
    severity?: number;
    range?: {
        start: {
            line: number;
            character: number;
        };
        end?: {
            line: number;
            character: number;
        };
    };
    code?: string | number;
    source?: string;
}
/** One file's new diagnostics, as drained for injection + the wire frame. */
export interface LspFileDiagnostics {
    uri: string;
    diagnostics: LspDiagnostic[];
}
/**
 * The pending/delivered diagnostics registry.
 *
 * **Lifetime, stated honestly:** ONE registry is constructed per `NodeLspManager`, i.e. per DEPLOYMENT —
 * every task served through `RunnerDeps.lspManager` shares this object. Its two halves scope differently,
 * and deliberately:
 *  - `pending` is the language server's own view of the workspace (whole-file replacement per the LSP
 *    spec) and is therefore deployment-wide, like the servers that feed it;
 *  - `delivered` — "this was already injected into the transcript" — is a per-RUN fact, so it is keyed by
 *    the caller's `runIdent`. Without that scope a diagnostic delivered to one run was filtered out of
 *    every later run's drain for the lifetime of the process, including runs that had never seen it and
 *    (never having edited that file) had no way to make it resurface. Growth is bounded by the ACTIVE
 *    runs, because {@link releaseRun} drops a finished run's keys.
 *
 * `publish` is called by an LSP session's publishDiagnostics subscription; `drain` is called at the turn
 * boundary and returns only diagnostics THAT RUN has not been shown, sorted and volume-capped.
 *
 * NOT durable: diagnostics regenerate from the language server on the next edit, and a resumed run is a
 * new run (fresh delivered scope), so a suspend/resume re-delivers rather than losing anything.
 */
export declare class LspDiagnosticsRegistry {
    /** uri → the LAST published full diagnostic set for that file (LSP replace semantics). */
    private readonly pending;
    /** runIdent → the diagnostic keys already injected into THAT run. Cleared per file when that run edits
     *  it (the problem may resurface against the new text), and wholesale when the run ends
     *  ({@link releaseRun}). A Map of Sets rather than one flat prefixed set so that releasing/clearing a
     *  run can never touch a run whose ident merely starts with the same characters. */
    private readonly delivered;
    /** Record a `textDocument/publishDiagnostics` payload (already version-checked by the session). */
    publish(uri: string, diagnostics: LspDiagnostic[]): void;
    /** The run `runIdent` edited `uri` — that run's delivered keys for the file reset, so a still-present
     *  problem can resurface against the NEW text (CC clears per-file delivered on edit, 198 `Fjn`). Only
     *  the editing run's view is cleared: another run never saw this edit, and re-showing it a diagnostic
     *  it is already carrying in its transcript would be duplication, not news. */
    fileEdited(runIdent: string, uri: string): void;
    /** The run ended — drop its delivered keys. This is what bounds the registry: without it the set grows
     *  monotonically for the lifetime of the (deployment-scoped) manager. Idempotent; unknown idents are a
     *  no-op, so a caller may release a run that never drained. */
    releaseRun(runIdent: string): void;
    /** True when a drain would produce nothing (cheap pre-check for the turn-boundary hook). */
    isEmpty(): boolean;
    /**
     * Take the diagnostics `runIdent` has NOT been shown: sorted Error>Warning>Info>Hint within each file,
     * capped at {@link MAX_PER_FILE}/{@link MAX_TOTAL}, marked delivered FOR THAT RUN. A file whose
     * diagnostics this run has all seen drops out (until its server publishes again or that run edits it).
     * "Delivered" is scoped to the run because it means "already in this transcript" — another run's
     * transcript does not have it, and must be able to see it (see the class note on lifetime).
     *
     * HRD-LSP-3: what the caps hold back is REQUEUED, not dropped. The old body capped the take and then
     * `pending.clear()`-ed unconditionally, so diagnostic #11 of a file — and every file after the 30-item
     * total ceiling — was neither returned nor marked delivered: it vanished, and no later drain could
     * recover it unless the server happened to re-publish. Errors ranked first inside a file made that worse,
     * not better: the highest-severity items were delivered and the REST were the ones destroyed. The
     * remainder now survives into the next drain (the next turn boundary), which is also what makes the
     * per-turn volume cap a PACING rule instead of a silent data cap.
     */
    drain(runIdent: string): LspFileDiagnostics[];
}
/** A drain with every file the run's read face withholds left out (`withheldOf` answers the batch: a withheld file is in
 *  the map; a judgment that fails withholds them all). The run's drain already marked them delivered, so they do not come back. */
export declare function withholdListedDiagnostics(files: LspFileDiagnostics[], withheldOf: (uris: readonly string[]) => Promise<ReadonlyMap<string, unknown>>): Promise<LspFileDiagnostics[]>;
/**
 * CC 198 `formatDiagnosticsSummary` (198:320480-320499), verbatim shape:
 * ```
 * {basename}:
 *   {symbol} [Line {line+1}:{col+1}] {message}[ [{code}]][ ({source})]
 * ```
 * capped at 4000 chars with an honest `…[truncated]` tail.
 *
 * ENVELOPE CONTAINMENT (untrusted-text.ts `ENGINE_ENVELOPES`, the `new-diagnostics` row): the
 * per-diagnostic strings (`message`, `code`, `source`) and the file basename come from a LANGUAGE
 * SERVER — a process the engine launches over repository content, i.e. the same trust class as the
 * repository. They land inside the `<new-diagnostics>` envelope, and (since this block is now
 * delivered inside a marked reminder shell) inside an authority-marked reminder too, so a diagnostic
 * message carrying `</new-diagnostics>` closed the envelope and placed server text at the top level
 * of engine-authored authority. CC 223 does not neutralize here either — a deliberate, disclosed
 * hardening divergence: CC ships the same block inside the same reminder shell, so the hole exists on
 * both sides and only the fix is ours. Neutralization runs BEFORE the join, so the 4000-char cap
 * still bounds the FINAL text and can never cut inside a neutralized marker's own bytes.
 */
export declare function formatDiagnosticsSummary(files: LspFileDiagnostics[]): string;
/** CC 198 model-facing injection block (198:320500-320503), verbatim framing.
 *
 *  DELIVERY (design/319 sibling work): the runner shells this block in a MARKED `<system-reminder>`
 *  before steering it — CC 223 `case "diagnostics"` does the same (`ih([Vr({content: …})])` → the
 *  reminder wrap), and until that was matched this was the engine's only authority text reaching the
 *  model as a bare block with no provenance mark at all. The block's own bytes are unchanged; the
 *  shell is applied at the delivery site (runtask), not baked in here, so this exported renderer keeps
 *  serving callers that place the block themselves. */
export declare function formatDiagnosticsBlock(files: LspFileDiagnostics[]): string;
