import type { ImageContent, TextContent } from "../llm/index.js";
import type { AgentMessage } from "../loop/types.js";
import type { AnnouncedListingSnapshot, AnnouncedListingSnapshotInput, GitAnnouncementState, Session, SessionContext, SessionMetadata, SessionStorage, SessionTreeEntry, WorkspaceState } from "../harness/types.js";
import type { BuildContextOptions } from "../harness/types.js";
import type { PromptEpochDescriptor } from "../../prompt-assembly/epoch.js";
/** Build model context from the active session branch and its latest state markers.
 *  `opts` (window awareness, see {@link BuildContextOptions}): when the caller declares the
 *  consuming model's window, the compaction summary's retained invoked-skills area is defensively
 *  re-clamped so 「summary + retained area」 can never push the rebuilt context out of that window
 *  on its own. Absent ⇒ byte-identical legacy rendering. */
export declare function buildSessionContext(pathEntries: SessionTreeEntry[], opts?: BuildContextOptions): SessionContext;
/** High-level session API backed by pluggable tree storage. Implements the vendored `Session` CONTRACT
 *  (`SessionContract`) the harness consumes — dependency inversion so the vendored substrate needs no
 *  `import` of this concrete class (de-vendoring prep); `implements` makes the contract drift caught here. */
export declare class StoredSession<TMetadata extends SessionMetadata = SessionMetadata> implements Session<TMetadata> {
    private storage;
    constructor(storage: SessionStorage<TMetadata>);
    getMetadata(): Promise<TMetadata>;
    getStorage(): SessionStorage<TMetadata>;
    getLeafId(): Promise<string | null>;
    getEntry(id: string): Promise<SessionTreeEntry | undefined>;
    getEntries(): Promise<SessionTreeEntry[]>;
    getBranch(fromId?: string): Promise<SessionTreeEntry[]>;
    buildContext(opts?: BuildContextOptions): Promise<SessionContext>;
    getLabel(id: string): Promise<string | undefined>;
    getSessionName(): Promise<string | undefined>;
    private appendTypedEntry;
    appendMessage(message: AgentMessage): Promise<string>;
    appendThinkingLevelChange(thinkingLevel: string): Promise<string>;
    appendModelChange(provider: string, modelId: string): Promise<string>;
    /**
     * S3 (prompt-assembly §9.2): persist the session's prompt-epoch pin as a first-class
     * typed entry. Written at session start (BEFORE the first conversation entry — the resume path
     * must never see user entries with no pin) and on legacy migration; compactions restate the pin
     * in their own `details.promptEpoch` instead (same-CAS with the new baseline).
     */
    appendPromptEpoch(descriptor: PromptEpochDescriptor): Promise<string>;
    /**
     * design/150 (RB-25): persist the listing announced name-sets as a first-class typed entry.
     * Called best-effort at every listing COMMIT point (the run loop's announce mirror sites) —
     * an append failure degrades to the checkpoint-mirror/transcript-probe rungs, never fails the run.
     */
    appendAnnouncedListing(snapshot: AnnouncedListingSnapshotInput): Promise<string>;
    /**
     * Git-status frame announced state (branch-authority mirror): persist the `(kind, hash)` tuple —
     * announced form carries the frame's own entry id; a compaction restates the tuple as `pending`
     * inside its `details.gitAnnouncement` instead (same-CAS with the new baseline). Called
     * best-effort at every frame COMMIT point (append receipt in hand) — an append failure degrades
     * to a conservative re-announcement on the next leg (duplicate-tolerant), never fails the run.
     */
    appendGitAnnouncement(state: GitAnnouncementState): Promise<string>;
    /**
     * Branch-authority read of the git announced state: the nearest carrier walking back from the
     * leaf (a `git_announcement` entry or a compaction's `details.gitAnnouncement` restatement;
     * SNAPSHOT semantics — first hit wins). The pending gate is a MANDATORY one: a nearest carrier
     * that is pending, or an announced carrier whose frame entryId is NOT on the active branch (a
     * rewind cut the frame while a descendant mirror survived), reads as `status:"pending"` — the
     * caller must conservatively re-announce rather than trust a mirror whose frame the model cannot
     * see. Malformed carriers are skipped (defense in depth behind the import door). Undefined ⇒ no
     * carrier visible on this branch (pre-migration session / bounded-tail floor cut every carrier) —
     * callers fall back to the checkpoint mirror rung, then to conservative re-announcement.
     */
    getGitAnnouncement(): Promise<{
        kind: GitAnnouncementState["kind"];
        hash: string;
        status: "announced" | "pending";
        entryId?: string;
    } | undefined>;
    /**
     * design/155: persist the settle-time workspace state (tracked cwd + active
     * EnterWorktree session) as a first-class typed entry. Called best-effort at task settle when the
     * state changed — an append failure degrades to "the next turn starts at the task root", exactly
     * the pre-155 behavior, never fails the run. The same shape gate guards append, read, and the
     * import door (self-generated data must round-trip its own validator).
     */
    appendWorkspaceState(state: WorkspaceState): Promise<string>;
    /**
     * design/319 (A ticket): persist the session's reminder provenance mark as a first-class typed
     * entry (see {@link ReminderMarkEntry} for the full restore-ladder narrative). Written once by
     * the first prepare that mints/adopts a mark this session (best-effort — an append failure
     * degrades to a per-leg re-mint under the strict declaration, never fails the run). The shape
     * gate is the SCHEME-AGNOSTIC bounded-token one; the caller has already run the mint home's
     * verify port on the value it is persisting.
     */
    appendReminderMark(mark: string): Promise<string>;
    /**
     * design/319: recover the session's reminder provenance mark for the ACTIVE branch — the nearest
     * `reminder_mark` entry walking back from the leaf (SNAPSHOT semantics: first hit wins).
     * Malformed entries are skipped (defense in depth behind the import door). Undefined ⇒ no entry
     * VISIBLE on this branch (a fresh session, a pre-319 session, or a bounded-tail backend whose
     * load floor cut it) — the caller degrades to a fresh mint, which is fail-safe under the strict
     * declaration (historic reminders read as data; forgery gains nothing). The value returned is
     * the STORE's opaque token — the consumer still applies the mint home's verify port and re-mints
     * on failure (scheme evolution: an old-scheme value simply stops verifying).
     */
    getReminderMark(): Promise<string | undefined>;
    /**
     * design/155: recover the workspace-state snapshot for the ACTIVE branch — the nearest
     * `workspace_state` entry walking back from the leaf (SNAPSHOT semantics: first hit wins; a CLEAR
     * snapshot — no cwd, no worktree — is a real hit that shadows older state). Malformed entries are
     * skipped (defense in depth behind the import door). Undefined ⇒ no snapshot VISIBLE on this
     * branch: a fresh session, a pre-155 session, or a bounded-tail backend whose load floor cut every
     * snapshot — all degrade to fresh defaults (the task root), the pre-155 behavior. Rewind gets the
     * correct semantics for free: the branch path ends at the cut, so the walk finds the state that
     * was current THEN.
     */
    getWorkspaceState(): Promise<WorkspaceState | undefined>;
    /**
     * design/150 (RB-25): recover the announced listing snapshot for the ACTIVE branch — the nearest
     * carrier walking back from the leaf (an `announced_listing` entry or a compaction's
     * `details.announcedListings` restatement; SNAPSHOT semantics: first hit wins). Malformed
     * carriers are skipped (defense in depth behind the import door), never returned.
     * Undefined ⇒ no carrier VISIBLE on this branch — callers fall back to the checkpoint mirror /
     * transcript probe. Honest bound (RB-33): a bounded-tail backend whose load floor
     * cut every carrier (and a rewind cut between the floor and the newest compaction) also returns
     * undefined — the ladder degrades to the lower rungs (worst case a duplicate re-announce, never a
     * loss). A floor-anchor seam (the getEpochAnchor analog) is deliberately deferred until a real
     * deployment hits that window.
     */
    getAnnouncedListing(): Promise<AnnouncedListingSnapshot | undefined>;
    /**
     * Recover the pinned prompt epoch for the ACTIVE branch (stage S3). Walks the branch from the
     * leaf backwards: the nearest `compaction` entry's `details.promptEpoch` restatement wins (the
     * bounded-tail/F3 floor may have cut everything older); else the nearest `prompt_epoch` entry
     * (root pin / legacy migration). Undefined ⇒ pre-epoch session (upgrade-in-place migration path).
     * Rewind/resumeAt legs get the SAME semantics for free: the branch path already ends at the
     * historical cut point, so the walk finds the pin that was current THEN, not the latest.
     */
    getPromptEpoch(): Promise<import("../../prompt-assembly/epoch.js").PromptEpochDescriptor | undefined>;
    /**
     * RB-103 (2026-07-25, defect probe): the compaction entry CARRIES the branch's derived conversation
     * state — thinking level and active model — restated automatically here.
     *
     * Both are reconstructed by scanning path entries ({@link buildSessionContext}), so a bounded-tail (F3)
     * wake that loads only `[firstKeptEntryId .. leaf]` cannot see a `thinking_level_change` /
     * `model_change` that sits below the floor: the user's chosen thinking level silently reverted to "off"
     * and the model to null. Until RB-95 the compaction cut point's back-off loop happened to drag those
     * entries above the floor much of the time — an accident, not a mechanism, and one that broke the
     * floor's own "always a user/assistant message" contract to do it.
     *
     * Unlike `promptEpoch` / `announcedListings` — which the CALLER restates because selecting them needs
     * caller-side logic — these two are derived from this session's own branch, so the session computes
     * them itself and every caller of `appendCompaction` gets the carry for free. A caller-supplied
     * `details` still wins if it names the same keys (explicit intent beats the automatic restatement).
     */
    appendCompaction(summary: string, firstKeptEntryId: string, tokensBefore: number, details?: unknown, fromHook?: boolean): Promise<string>;
    /** Append a non-LLM transcript marker for harness-specific state. */
    appendCustomEntry(customType: string, data?: unknown): Promise<string>;
    /** Append harness-specific content that can also be replayed into model context. */
    appendCustomMessageEntry(customType: string, content: string | (TextContent | ImageContent)[], display: boolean, details?: unknown): Promise<string>;
    /** Record or clear the display label for an existing session entry. */
    appendLabel(targetId: string, label: string | undefined): Promise<string>;
    appendSessionName(name: string): Promise<string>;
}
/**
 * Falsification round 1 (F3) — is `entryId` not merely ON the active branch but inside the region
 * a context rebuild can actually contain? A branch walk sees the whole tree; `buildSessionContext`
 * replays only [latest compaction's firstKeptEntryId .. leaf] (plus the summary). A git frame that
 * sits BEFORE the latest compaction's kept tail is therefore gone from every future request even
 * though its id is a legitimate branch member — an announced mirror pointing at it must read as
 * PENDING (re-announce), or the announced hash would suppress re-sends of bytes the model can no
 * longer see. Shared by the session mirror walk and the run loop's checkpoint seeding rung (one
 * rule, both readers). Conservative on damage: an unresolvable firstKeptEntryId reads as invisible.
 */
export declare function gitFrameContextVisible(branch: SessionTreeEntry[], entryId: string): boolean;
