فهرست منبع

fix(writer): override LLM-hallucinated chapter numbers in state delta

The settler may extract a chapter number from story content rather than
using the pipeline's authoritative value (e.g. parsing year "1988" from
a contemporary fiction novel as "第1988章").  This corrupts the manifest's
lastAppliedChapter, causing all subsequent chapters to use absurd numbers.

buildRuntimeStateArtifactsIfPresent now accepts an authoritative chapter
number and replaces the delta's chapter field when it disagrees.

Root cause of 旧城暗号v4's ch4→ch1988 numbering jump.
Ma 7 ماه پیش
والد
کامیت
f4ee25b1fe
1فایلهای تغییر یافته به همراه9 افزوده شده و 1 حذف شده
  1. 9 1
      packages/core/src/agents/writer.ts

+ 9 - 1
packages/core/src/agents/writer.ts

@@ -319,6 +319,7 @@ export class WriterAgent extends BaseAgent {
       bookDir,
       bookDir,
       settlement.runtimeStateDelta,
       settlement.runtimeStateDelta,
       resolvedLanguage,
       resolvedLanguage,
+      chapterNumber,
     );
     );
     const resolvedRuntimeStateDelta = runtimeStateArtifacts?.resolvedDelta ?? settlement.runtimeStateDelta;
     const resolvedRuntimeStateDelta = runtimeStateArtifacts?.resolvedDelta ?? settlement.runtimeStateDelta;
     const priorHookIds = new Set(parsePendingHooksMarkdown(hooks).map((hook) => hook.hookId));
     const priorHookIds = new Set(parsePendingHooksMarkdown(hooks).map((hook) => hook.hookId));
@@ -467,6 +468,7 @@ export class WriterAgent extends BaseAgent {
       input.bookDir,
       input.bookDir,
       settlement.runtimeStateDelta,
       settlement.runtimeStateDelta,
       resolvedLanguage,
       resolvedLanguage,
+      input.chapterNumber,
     );
     );
 
 
     return {
     return {
@@ -1098,11 +1100,17 @@ ${overrides}\n`;
     bookDir: string,
     bookDir: string,
     delta: RuntimeStateDelta | undefined,
     delta: RuntimeStateDelta | undefined,
     language: "zh" | "en",
     language: "zh" | "en",
+    authorativeChapterNumber?: number,
   ): Promise<RuntimeStateArtifacts | null> {
   ): Promise<RuntimeStateArtifacts | null> {
     if (!delta) return null;
     if (!delta) return null;
+    // The LLM may hallucinate a chapter number from story content (e.g. year
+    // 1988 parsed as "第1988章").  Always trust the pipeline's chapter number.
+    const safeDelta = authorativeChapterNumber !== undefined && delta.chapter !== authorativeChapterNumber
+      ? { ...delta, chapter: authorativeChapterNumber }
+      : delta;
     return buildRuntimeStateArtifacts({
     return buildRuntimeStateArtifacts({
       bookDir,
       bookDir,
-      delta,
+      delta: safeDelta,
       language,
       language,
     });
     });
   }
   }