From 32bbea0f32698883284c03c3c1af052ef32f02a9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=B0=8F=E6=A9=98?= Date: Sun, 7 Jun 2026 01:49:04 +0000 Subject: [PATCH] fix: decouple session resume from isFirstVisit guard When frontmatter validation fails, the step is never written to CAS, so isFirstVisit remains true on the next run. Both agent-claude-code and agent-hermes gated session cache lookup behind !isFirstVisit, which caused them to start a fresh session (and a new worktree) instead of resuming the one that already has all the work done. Remove the isFirstVisit guard from both adapters so they always check the session cache. If no cache entry exists, the behavior is unchanged (fresh session). If a cache entry exists, the agent resumes the previous session regardless of CAS step state. Fixes #139 --- packages/agent-claude-code/src/claude-code.ts | 8 ++++++-- packages/agent-hermes/src/hermes.ts | 6 +++++- 2 files changed, 11 insertions(+), 3 deletions(-) diff --git a/packages/agent-claude-code/src/claude-code.ts b/packages/agent-claude-code/src/claude-code.ts index 72be905..b8c5191 100644 --- a/packages/agent-claude-code/src/claude-code.ts +++ b/packages/agent-claude-code/src/claude-code.ts @@ -176,8 +176,12 @@ async function runClaudeCode(ctx: AgentContext, model: string | null): Promise { - if (ctx.isFirstVisit || resumeDisabled) { + if (resumeDisabled) { await client.connect(cwd); return { useContinuation: false, resumed: false }; } + // Check session cache regardless of isFirstVisit. A previous run may + // have completed and cached its session but failed frontmatter + // validation — the step never got written to CAS so isFirstVisit is + // still true, yet we should resume the existing session. const cachedSessionId = await getCachedSessionId(ctx.threadId, ctx.role, ctx.storageRoot); if (cachedSessionId === null) { log("6RWK3N8Q", `no cached session for ${ctx.threadId}:${ctx.role}, starting new session`);