/** * Session State Management * Track current session context for auto-injecting into recall calls * Track surfaced scars for auto-bridging Q6 answers to scar_usage records * * Maintains in-memory state of the current active session including: * - session_id from session_start * - linear_issue if working on a Linear issue * - agent identity * - surfaced scars (accumulated from session_start + recall calls) * * This allows recall() to always assign variants even without explicit parameters. */ import type { SurfacedScar, ScarConfirmation, ScarReflection, Observation, SessionChild, ThreadObject } from "../types/index.js"; interface SessionContext { sessionId: string; linearIssue?: string; agent?: string; project?: string; startedAt: Date; recallCalled: boolean; surfacedScars: SurfacedScar[]; confirmations: ScarConfirmation[]; reflections: ScarReflection[]; observations: Observation[]; children: SessionChild[]; threads: ThreadObject[]; feedbackSubmitCount: number; /** * GIT-51: set when this session was recovered from disk and session.json * disagreed with the registry about which project it belongs to. Carried on * the context so a consumer can see that its scope rests on a resolved * conflict rather than on agreement. */ recoveryConflict?: boolean; /** * GIT-93: set when a recall() attempt failed to reach the store, cleared when * one succeeds. * * "No scars surfaced" has two causes that used to be indistinguishable: * retrieval ran and found nothing relevant, or retrieval never ran. Only the * first is safe to proceed on. Without this, confirm_scars answered both with * "Proceed freely" — a green result for a broken store, which is how a * retrieval path that had never worked survived indefinitely (the *_scar_search * RPC 404'd on every call since it was written and nothing downstream said so). */ recallFailure?: { message: string; at: string; } | null; } /** * Set the current active session * Called by session_start */ export declare function setCurrentSession(context: Omit & { surfacedScars?: SurfacedScar[]; observations?: Observation[]; children?: SessionChild[]; threads?: ThreadObject[]; }): void; /** * Resolve the active session, recovering from disk if in-memory state was lost * to an MCP server restart (GIT-51). */ export declare function resolveCurrentSession(): SessionContext | null; /** * Get the current active session * Returns null if no session active */ export declare function getCurrentSession(): SessionContext | null; /** * Clear the current session * Called by session_close */ export declare function clearCurrentSession(): void; /** * Get the active session's project, or null if no session. * Used by list_threads to inherit the correct project default. */ export declare function getProject(): string | null; /** * Check if currently working on a Linear issue */ export declare function hasActiveIssue(): boolean; /** * Mark that recall() was called this session (independent of whether it returned scars). * Called by recall tool before any early return. * * GIT-89: persisted to session.json. This flag drove enforcement Check 3 ("No * recall() was run this session"), and it lived only in memory — so after an * MCP restart every create_learning / create_decision / session_close warned * that recall had never run, in sessions where it demonstrably had. That is the * same class of false alarm as the "No active session" banner: a warning the * agent learns to read past, which is what erodes the enforcement layer. */ export declare function setRecallCalled(): void; /** * GIT-93: record that a recall() attempt could not reach the store. * * Persisted alongside recall_called so it survives an MCP restart, for the same * reason: the failure outlives the process that observed it, and a restart must * not turn a broken store into an apparently clean one. */ export declare function setRecallFailure(message: string): void; /** * GIT-93: clear the failure marker after a recall() that reached the store. * * Cleared on success rather than on attempt, and regardless of how many scars * came back: a successful search returning nothing is a real answer, while a * failed one is not an answer at all. Only the former should let confirm_scars * say "proceed". */ export declare function clearRecallFailure(): void; /** * GIT-93: the unresolved retrieval failure for this session, if any. * * Returns null when retrieval last succeeded — which is the only state in which * an empty scar set means "nothing relevant" rather than "nothing was asked". */ export declare function getRecallFailure(): { message: string; at: string; } | null; /** * Check if recall() was called this session. * Used by enforcement to avoid false positives when recall returns 0 scars. */ export declare function isRecallCalled(): boolean; /** * Add surfaced scars to tracking (deduplicates by scar_id) * Called by session_start and recall when scars are surfaced. * * GIT-89: returns whether the scars were actually tracked. * * This used to read `currentSession` directly and, when it was null, log a * console warning and return. That was the silent discard behind the * recall/confirm_scars asymmetry (scar 810a1624): recall printed scars to the * agent, nothing recorded that it had, and confirm_scars later rejected with * nothing to confirm. The agent saw a green "no scars to confirm" for scars it * had just been shown. * * Two changes close that gap. Identity is resolved (so a session recovered * after an MCP restart still tracks), and the outcome is returned so callers * can fail as loudly as confirm_scars does instead of proceeding as if tracked. */ export declare function addSurfacedScars(scars: SurfacedScar[]): boolean; /** * Get all surfaced scars for the current session */ export declare function getSurfacedScars(): SurfacedScar[]; /** * Add scar confirmations (refute-or-obey) to the current session. * Called by confirm_scars tool after validation. */ export declare function addConfirmations(confirmations: ScarConfirmation[]): void; /** * Get all scar confirmations for the current session. */ export declare function getConfirmations(): ScarConfirmation[]; /** * Add end-of-session scar reflections (OBEYED/REFUTED) to the current session. * Called by reflect_scars tool after validation. */ export declare function addReflections(reflections: ScarReflection[]): void; /** * Get all end-of-session scar reflections for the current session. */ export declare function getReflections(): ScarReflection[]; /** * Check if there are recall-surfaced scars that haven't been confirmed. * Only checks scars with source "recall" — session_start scars don't require confirmation. */ export declare function hasUnconfirmedScars(): boolean; /** * v2 Phase 2: Add observations from sub-agents/teammates */ export declare function addObservations(newObs: Observation[]): number; /** * v2 Phase 2: Get all observations for the current session */ export declare function getObservations(): Observation[]; /** * v2 Phase 2: Register a child agent in the current session */ export declare function addChild(child: SessionChild): void; /** * v2 Phase 2: Get all children for the current session */ export declare function getChildren(): SessionChild[]; /** * Compute session activity signals for close type validation. * Returns null if no active session (e.g., recovered from registry). */ export interface SessionActivity { duration_min: number; recall_count: number; observation_count: number; children_count: number; thread_count: number; } export declare function getSessionActivity(): SessionActivity | null; /** * : Set threads for the current session */ export declare function setThreads(threads: ThreadObject[]): void; /** * : Get threads for the current session */ export declare function getThreads(): ThreadObject[]; /** * Get the current feedback submission count for rate limiting. */ export declare function getFeedbackCount(): number; /** * Increment and return the feedback submission count. */ export declare function incrementFeedbackCount(): number; /** * : Resolve a thread in session state by ID. * Returns the resolved thread or null if not found. */ export declare function resolveThreadInState(threadId: string, resolutionNote?: string): ThreadObject | null; export {}; //# sourceMappingURL=session-state.d.ts.map