@@ -4,6 +4,7 @@ import path from "node:path";
44import { afterEach , beforeEach , describe , expect , it , vi } from "vitest" ;
55import { SessionManager } from "../../agents/sessions/session-manager.js" ;
66import { onSessionTranscriptUpdate } from "../../sessions/transcript-events.js" ;
7+ import { createCanonicalFixtureSkill } from "../../skills/test-support/test-helpers.js" ;
78import type { OpenClawConfig } from "../types.openclaw.js" ;
89import {
910 applyRestartRecoveryLifecycle ,
@@ -533,6 +534,60 @@ describe("session accessor file-backed seam", () => {
533534 } ) ;
534535 } ) ;
535536
537+ it ( "commits reply session initialization despite runtime-only skill snapshot cache" , async ( ) => {
538+ const sessionKey = "agent:main:main" ;
539+ await upsertSessionEntry (
540+ { sessionKey, storePath } ,
541+ {
542+ sessionId : "first-session" ,
543+ skillsSnapshot : {
544+ prompt : `<available_skills>${ "x" . repeat ( 600 ) } </available_skills>` ,
545+ skills : [ { name : "skill-0" } ] ,
546+ version : 1 ,
547+ } ,
548+ updatedAt : 10 ,
549+ } ,
550+ ) ;
551+
552+ const snapshot = loadReplySessionInitializationSnapshot ( { sessionKey, storePath } ) ;
553+ const cachedStore = loadSessionStore ( storePath , { clone : false } ) ;
554+ const cachedEntry = cachedStore [ sessionKey ] ;
555+ if ( ! cachedEntry ?. skillsSnapshot ) {
556+ throw new Error ( "expected cached skills snapshot" ) ;
557+ }
558+ cachedEntry . skillsSnapshot = {
559+ ...cachedEntry . skillsSnapshot ,
560+ resolvedSkills : [
561+ createCanonicalFixtureSkill ( {
562+ baseDir : "/skills/skill-0" ,
563+ description : "skill-0 description" ,
564+ filePath : "/skills/skill-0/SKILL.md" ,
565+ name : "skill-0" ,
566+ source : `# skill-0\n\n${ "x" . repeat ( 3000 ) } ` ,
567+ } ) ,
568+ ] ,
569+ } ;
570+
571+ const committed = await commitReplySessionInitialization ( {
572+ activeSessionKey : sessionKey ,
573+ agentId : "main" ,
574+ expectedRevision : snapshot . revision ,
575+ previousEntry : snapshot . currentEntry ,
576+ sessionEntry : {
577+ sessionId : "next-session" ,
578+ updatedAt : 20 ,
579+ } ,
580+ sessionKey,
581+ storePath,
582+ } ) ;
583+
584+ expect ( committed . ok ) . toBe ( true ) ;
585+ if ( ! committed . ok ) {
586+ throw new Error ( "expected reply session initialization to commit" ) ;
587+ }
588+ expect ( committed . sessionEntry . sessionId ) . toBe ( "next-session" ) ;
589+ } ) ;
590+
536591 it ( "can borrow cached entry objects for read-only hot paths" , async ( ) => {
537592 const scope = {
538593 clone : false ,
0 commit comments