Просмотр исходного кода

feat: add numeric verification rules and batch approve command

- Writer agent: add explicit 数值验算铁律 section to prevent
  arithmetic errors (期初/增量/消耗/期末 must balance)
- Writer agent: reduce recent chapter context from 5 to 3
- Review CLI: add `inkos review approve-all <book-id>` command
  for batch approval during testing
majx_mac 8 месяцев назад
Родитель
Сommit
79b989a59e
2 измененных файлов с 42 добавлено и 2 удалено
  1. 29 0
      packages/cli/src/commands/review.ts
  2. 13 2
      packages/core/src/agents/writer.ts

+ 29 - 0
packages/cli/src/commands/review.ts

@@ -75,6 +75,35 @@ reviewCommand
     }
   });
 
+reviewCommand
+  .command("approve-all")
+  .description("Approve all pending chapters for a book")
+  .argument("<book-id>", "Book ID")
+  .action(async (bookId: string) => {
+    try {
+      const root = findProjectRoot();
+      const state = new StateManager(root);
+
+      const index = [...(await state.loadChapterIndex(bookId))];
+      let count = 0;
+      const now = new Date().toISOString();
+
+      const updated = index.map((ch) => {
+        if (ch.status === "ready-for-review" || ch.status === "audit-failed") {
+          count++;
+          return { ...ch, status: "approved" as const, updatedAt: now };
+        }
+        return ch;
+      });
+
+      await state.saveChapterIndex(bookId, updated);
+      log(`${count} chapter(s) approved.`);
+    } catch (e) {
+      logError(`Failed to approve: ${e}`);
+      process.exit(1);
+    }
+  });
+
 reviewCommand
   .command("reject")
   .description("Reject a chapter")

+ 13 - 2
packages/core/src/agents/writer.ts

@@ -143,6 +143,17 @@ ${styleGuide}
 5. 本章收益能否落到具体资源、数值增量、地位变化或已回收伏笔?
 6. 如果任何问题答不上来,先补逻辑链,再写正文
 
+## 数值验算铁律(必须遵守)
+
+写正文时涉及任何数值变动,必须当场验算:
+- 期初值从账本取(不凭记忆)
+- 增量逐笔列出并注明来源
+- 消耗逐笔列出并注明用途
+- 期末 = 期初 + 增量 - 消耗,不得跳步
+- 正文中出现的系统提示(如【气血值+X】)必须与POST_SETTLEMENT一致
+- 若正文写了"比A还高"这类比较句,必须数值验证后再保留
+- 同质吞噬衰减规则:同一类资源连续第N次吞噬,收益 = 基础值 × max(0.3, 1 - 0.15×(N-1))
+
 ## 输出格式(严格遵守)
 
 === PRE_WRITE_CHECK ===
@@ -226,9 +237,9 @@ ${params.volumeOutline}
     try {
       const files = await readdir(chaptersDir);
       const mdFiles = files
-        .filter((f) => f.endsWith(".md"))
+        .filter((f) => f.endsWith(".md") && !f.startsWith("index"))
         .sort()
-        .slice(-5);
+        .slice(-3);
 
       if (mdFiles.length === 0) return "";