import type { ContinuityDisclosure, LaneCheckpoint, Session, Thread, ThreadTurn } from "@claudexor/schema"; /** * Pure lane-checkpoint helpers (INV-137). Extracted from `threads.ts` so the * store file stays under the new-file complexity cap (INV-124); the ThreadStore * owns journaling/commit, these just build + query the checkpoint rows. * * A lane is a (thread, harness, profile) triple; its checkpoint is the last turn * it has SEEN (it produced it, or a continuation packet hydrated it up to there). */ /** Composite lane id `::::` — the row identity. */ export declare function laneId(threadId: string, harnessId: string, profileId: string | null): string; /** Build (and validate) a checkpoint row advancing a lane to `turnId`. */ export declare function makeLaneCheckpoint(threadId: string, harnessId: string, profileId: string | null, turnId: string): LaneCheckpoint; /** The last turn a lane has seen, or null when the lane never ran. */ export declare function findLaneCheckpoint(checkpoints: readonly LaneCheckpoint[], threadId: string, harnessId: string, profileId: string | null): string | null; /** All lane checkpoints of a thread (to locate the prior head's lane). */ export declare function threadLaneCheckpoints(checkpoints: readonly LaneCheckpoint[], threadId: string): LaneCheckpoint[]; /** Stamp a turn's continuity disclosure (validated), returning the next turn. */ export declare function stampContinuity(turn: ThreadTurn, disclosure: ContinuityDisclosure): ThreadTurn; /** * Native resume map for a thread (INV-135): harnessId -> {sessionId, profile}. * Resume never crosses credential profiles — a session recorded under one * profile (or the null engine default) is eligible ONLY for a turn running as * exactly that profile; the entry carries its profile so the engine boundary * re-verifies against the RESOLVED profile (preflight rotation may differ). */ export declare function resumeMapFrom(sessions: readonly Session[], threadId: string, profileId: string | null): Record; /** * The thread's durable per-harness ACCOUNT BINDINGS (unified account model, * D-U1 order 2): the account an UNPINNED turn stays on — derived from the * lane evidence the thread already persists (its latest live session, else * its latest lane checkpoint, per harness), never a second hand-maintained * record. Null-profile lanes (unmigrated legacy state) bind nothing. */ export declare function accountBindingsFrom(sessions: readonly Session[], checkpoints: readonly LaneCheckpoint[], threadId: string): Record; /** * Native resume map for an UNPINNED thread turn: the latest live session per * harness REGARDLESS of profile. Each entry carries its own profile, and the * engine boundary (`resumeSessionForProfile`) re-verifies it against the * RESOLVED account, so a pool switch away from the recorded account starts * fresh instead of crossing profiles (INV-135/137). */ export declare function resumeMapAutoFrom(sessions: readonly Session[], threadId: string): Record; /** * Unified-accounts migration mutation (INV-137, one unit with the lane-home * rename): live sessions recorded under the null engine-default subject are * rewritten IN PLACE onto the auto-registered row id, and every * `::::default` lane checkpoint gains a row under the new * lane id (the legacy row stays inert — exact-id lookups never see it). * Idempotent: a second run finds no null sessions and no missing checkpoints. * A row-lane checkpoint that already exists is never moved backwards (a crash * between phases followed by new turns may have advanced it) — but a BEHIND * row checkpoint advances forward to the ::default lane's turn: a rollback * leaves the old row-lane checkpoint in place while new turns advance the * default lane, and resuming the stale checkpoint on re-migration would * re-inject context the lane already saw. Recency is judged by updated_at, * the only ordering evidence at this layer. */ export declare function migrateNullProfileContinuityMutation(sessions: readonly Session[], checkpoints: readonly LaneCheckpoint[], harnessId: string, rowId: string): { sessions: Session[]; checkpoints: LaneCheckpoint[]; }; /** * The supported downgrade path's reverse of the migration mutation: sessions * recorded under the migrated row id return to the null engine-default * subject a legacy engine resumes, and each row-lane checkpoint re-seeds the * `::default` lane id at its turn. */ export declare function rollbackProfileContinuityMutation(sessions: readonly Session[], checkpoints: readonly LaneCheckpoint[], harnessId: string, rowId: string): { sessions: Session[]; checkpoints: LaneCheckpoint[]; }; /** * Credential-profile deletion mutation (INV-135): clear every matching scalar * thread pin (pins predate a harness discriminator, so any harness's pin at * the id clears rather than leave an unrunnable route) and stale the deleted * account's live sessions. */ export declare function invalidateCredentialProfileMutation(threads: readonly Thread[], sessions: readonly Session[], harnessId: string, profileId: string): { threads: Thread[]; sessions: Session[]; }; /** Mark a session row stale (its profile was deleted): drop the resumable id. */ export declare function staleSession(session: Session): Session; /** * Build (and validate) the native-session row a harness emitted, keyed by * (thread, harness, PROFILE) so profile B's session never overwrites A's row * (an A→B→A sequence resumes A's own native conversation; the null engine * default is its own row). `existing` is the current row for that lane, if any. */ export declare function makeSessionRecord(existing: Session | undefined, threadId: string, harnessId: string, nativeSessionId: string, observedModel: string | null | undefined, profileId: string | null): Session; //# sourceMappingURL=thread-lane-checkpoints.d.ts.map