Răsfoiți Sursa

fix(pipeline): exclude sequence-level fatigue from revision blockingCount

Long-span-fatigue warnings (mood monotony, title clustering, pacing
repetition, opening/ending pattern similarity) are sequence-level
properties that cannot be fixed by revising the current chapter's text.

Previously these warnings inflated blockingCount in evaluateMergedAudit,
causing the revision gate to trigger or reject revisions for issues that
no single-chapter edit can resolve.

Now blockingCount only counts chapter-level issues (LLM audit, AI tells,
sensitive words). Sequence-level warnings still appear in the audit
report but no longer drive revision decisions.
Ma 7 luni în urmă
părinte
comite
fb8e1aa523
1 a modificat fișierele cu 29 adăugiri și 4 ștergeri
  1. 29 4
      packages/core/src/pipeline/runner.ts

+ 29 - 4
packages/core/src/pipeline/runner.ts

@@ -44,6 +44,19 @@ import { runChapterReviewCycle } from "./chapter-review-cycle.js";
 import { validateChapterTruthPersistence } from "./chapter-truth-validation.js";
 import { loadPersistedPlan, relativeToBookDir } from "./persisted-governed-plan.js";
 
+const SEQUENCE_LEVEL_CATEGORIES = new Set([
+  "Pacing Monotony", "节奏单调",
+  "Mood Monotony", "情绪单调",
+  "Title Collapse", "标题重复",
+  "Title Clustering", "标题聚集",
+  "Opening Pattern Repetition", "开头同构",
+  "Ending Pattern Repetition", "结尾同构",
+]);
+
+function isSequenceLevelCategory(category: string): boolean {
+  return SEQUENCE_LEVEL_CATEGORIES.has(category);
+}
+
 export interface PipelineConfig {
   readonly client: LLMClient;
   readonly model: string;
@@ -2455,11 +2468,14 @@ ${matrix}`,
       return next;
     }
 
+    const revisionRelevant = auditResult.issues.filter(
+      (issue) => !isSequenceLevelCategory(issue.category),
+    );
     return {
       ...next,
       auditResult,
-      blockingCount: auditResult.issues.filter((issue) => issue.severity === "warning" || issue.severity === "critical").length,
-      criticalCount: auditResult.issues.filter((issue) => issue.severity === "critical").length,
+      blockingCount: revisionRelevant.filter((issue) => issue.severity === "warning" || issue.severity === "critical").length,
+      criticalCount: revisionRelevant.filter((issue) => issue.severity === "critical").length,
     };
   }
 
@@ -2510,6 +2526,15 @@ ${matrix}`,
       ...longSpanFatigue.issues,
     ];
 
+    // Long-span-fatigue issues (mood monotony, title clustering, pacing) are
+    // sequence-level properties that cannot be fixed by revising the current
+    // chapter.  Exclude them from blockingCount so they don't inflate the
+    // revision gate or reject otherwise-valid revisions.
+    const longSpanCategories = new Set(longSpanFatigue.issues.map((issue) => issue.category));
+    const revisionRelevantIssues = issues.filter(
+      (issue) => !longSpanCategories.has(issue.category),
+    );
+
     return {
       auditResult: {
         passed: hasBlockedWords ? false : llmAudit.passed,
@@ -2518,8 +2543,8 @@ ${matrix}`,
         tokenUsage: llmAudit.tokenUsage,
       },
       aiTellCount: aiTells.issues.length,
-      blockingCount: issues.filter((issue) => issue.severity === "warning" || issue.severity === "critical").length,
-      criticalCount: issues.filter((issue) => issue.severity === "critical").length,
+      blockingCount: revisionRelevantIssues.filter((issue) => issue.severity === "warning" || issue.severity === "critical").length,
+      criticalCount: revisionRelevantIssues.filter((issue) => issue.severity === "critical").length,
     };
   }