dsh-novel-write-engine 0.1.3 → 0.2.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -20,8 +20,8 @@ export declare const SCENE_TYPES: readonly ["战斗/动作章", "日常过渡章
20
20
  export type SceneType = (typeof SCENE_TYPES)[number];
21
21
  /** A violation is blocking unless the rule pack declares it advisory. */
22
22
  export type Severity = 'blocker' | 'advisory';
23
- /** All twenty-two service operations. */
24
- export declare const OPERATIONS: readonly ["initProject", "archiveChapter", "amend", "rollback", "submitWorldPlan", "submitChapterPlan", "submitDraft", "submitReview", "submitRevision", "runCheck", "getStatus", "getBrief", "countWords", "queryState", "diff", "auditHistory", "advise", "export", "panelSummary", "panelChapters", "panelGates", "stats"];
23
+ /** All thirty-one service operations (22 inherited from 0.1.x, 9 book-level). */
24
+ export declare const OPERATIONS: readonly ["initProject", "archiveChapter", "amend", "rollback", "reopenChapter", "submitWorldPlan", "submitChapterPlan", "submitDraft", "submitReview", "submitRevision", "runCheck", "submitBookPlan", "submitOutline", "importOutline", "submitWorldbook", "getStatus", "getBrief", "countWords", "queryState", "diff", "auditHistory", "advise", "search", "doctor", "report", "guide", "export", "panelSummary", "panelChapters", "panelGates", "stats", "restoreBackup"];
25
25
  export type Operation = (typeof OPERATIONS)[number];
26
26
  /** Structured, non-fatal note attached to a successful result. */
27
27
  export interface Warning {
@@ -70,6 +70,8 @@ export declare const ERROR_CODES: {
70
70
  readonly PATH_ESCAPE: "ENGINE_PATH_ESCAPE";
71
71
  readonly LOCK_TIMEOUT: "ENGINE_LOCK_TIMEOUT";
72
72
  readonly TXN_ABORTED: "ENGINE_TXN_ABORTED";
73
+ readonly JOURNAL_MISSING: "ENGINE_JOURNAL_MISSING";
74
+ readonly TXN_IN_PROGRESS: "ENGINE_TXN_IN_PROGRESS";
73
75
  readonly RULEPACK_INVALID: "ENGINE_RULEPACK_INVALID";
74
76
  readonly ID_EXHAUSTED: "ENGINE_ID_EXHAUSTED";
75
77
  readonly CONFIG_INVALID: "ENGINE_CONFIG_INVALID";
@@ -159,6 +161,7 @@ export interface CheckDocument {
159
161
  content_hash: string;
160
162
  machine: {
161
163
  violations: Violation[];
164
+ advisories?: Violation[];
162
165
  metrics: WordMetrics;
163
166
  };
164
167
  semantic: {
@@ -169,10 +172,12 @@ export interface CheckDocument {
169
172
  note: string;
170
173
  }>;
171
174
  };
175
+ /** Advisory codes the author has explicitly acknowledged for this content. */
176
+ acknowledged?: string[];
172
177
  verdict: 'pass' | 'fail';
173
178
  }
174
179
  /** Every persisted document whose damage status/panel can report. */
175
- export type StateErrorCode = 'PROJECT_UNREADABLE' | 'PLAN_UNREADABLE' | 'WORLD_PLAN_UNREADABLE' | 'REVIEW_UNREADABLE' | 'CHECK_UNREADABLE' | 'CHAPTERS_UNREADABLE' | 'CHARACTERS_UNREADABLE' | 'WORLD_UNREADABLE' | 'LOCKS_UNREADABLE' | 'TIMELINE_UNREADABLE' | 'FORESHADOWS_UNREADABLE' | 'RELATIONSHIPS_UNREADABLE' | 'HANDOFF_UNREADABLE';
180
+ export type StateErrorCode = 'PROJECT_UNREADABLE' | 'PLAN_UNREADABLE' | 'WORLD_PLAN_UNREADABLE' | 'REVIEW_UNREADABLE' | 'CHECK_UNREADABLE' | 'CHAPTERS_UNREADABLE' | 'CHARACTERS_UNREADABLE' | 'WORLD_UNREADABLE' | 'LOCKS_UNREADABLE' | 'TIMELINE_UNREADABLE' | 'FORESHADOWS_UNREADABLE' | 'RELATIONSHIPS_UNREADABLE' | 'HANDOFF_UNREADABLE' | 'OUTLINE_UNREADABLE' | 'WORLDBOOK_UNREADABLE';
176
181
  /** A state document that exists but cannot be read safely. */
177
182
  export interface StateError {
178
183
  path: string;
@@ -187,6 +192,8 @@ export interface WordMetrics {
187
192
  numbers: number;
188
193
  chinese_punct: number;
189
194
  english_punct: number;
195
+ /** All punctuation counted by the engine; total = cjk + words + numbers + punctuation. */
196
+ punctuation_chars: number;
190
197
  non_ws_chars: number;
191
198
  total_lines: number;
192
199
  non_empty_lines: number;
@@ -209,6 +216,10 @@ export interface ChapterRecord {
209
216
  status: 'draft' | 'reviewed';
210
217
  content_hash: string;
211
218
  summary: ChapterSummary;
219
+ /** How hard this chapter was before it was archived. */
220
+ rounds?: RoundCounters;
221
+ final_check?: 'pass' | 'fail';
222
+ archived_at?: string;
212
223
  /** Keys allocated by the archive transaction; lets a cross-process retry replay. */
213
224
  assigned_ids?: Record<string, string>;
214
225
  /** Digest of the archive request that produced this row. */
@@ -223,6 +234,7 @@ export interface ChapterSummary {
223
234
  key: string;
224
235
  title: string;
225
236
  description: string;
237
+ anchor?: string;
226
238
  }>;
227
239
  advanced: Array<{
228
240
  key: string;
@@ -256,6 +268,8 @@ export interface RoundCounters {
256
268
  review: number;
257
269
  revise: number;
258
270
  check: number;
271
+ /** Lifetime rollback count on a chapter record; never stored in the live pipeline. */
272
+ rollbacks?: number;
259
273
  }
260
274
  /** How one ledger entity changed in this chapter. */
261
275
  export type DeltaAction = 'created' | 'updated' | 'no_change';
@@ -287,6 +301,8 @@ export interface ForeshadowDelta {
287
301
  action: DeltaAction;
288
302
  reason?: string;
289
303
  title?: string;
304
+ /** Verbatim manuscript quote used for verification; title stays a readable label. */
305
+ anchor?: string;
290
306
  description?: string;
291
307
  note?: string;
292
308
  new_info?: boolean;
@@ -329,6 +345,28 @@ export interface ArchiveHandoff {
329
345
  act?: string;
330
346
  act_progress?: string;
331
347
  }
348
+ /** One issued task-book receipt; the brief itself is rendered on demand. */
349
+ export interface BriefReceipt {
350
+ chapter: number;
351
+ stage: BriefStage;
352
+ digest: string;
353
+ issued_at: string;
354
+ }
355
+ /** `state/briefs.yaml`: append-only task-book evidence outside content transactions. */
356
+ export interface BriefReceiptsDocument {
357
+ schema_version: 1;
358
+ receipts: BriefReceipt[];
359
+ }
360
+ /** The active draft's own metadata; P2 plan stays immutable after submission. */
361
+ export interface DraftState {
362
+ chapter: number;
363
+ title: string;
364
+ scene_type: SceneType;
365
+ narrator: string;
366
+ summary: ChapterSummary;
367
+ content_hash: string;
368
+ updated_at: string;
369
+ }
332
370
  /** Pipeline document (`state/pipeline.yaml`). */
333
371
  export interface PipelineState {
334
372
  schema_version: 1;
@@ -341,6 +379,8 @@ export interface PipelineState {
341
379
  digest: string;
342
380
  }>;
343
381
  blocking: BlockingItem[];
382
+ /** Current draft summary/title; never written into the P2 plan file. */
383
+ draft?: DraftState;
344
384
  /** Hash of the review document last written by submitReview/submitRevision. */
345
385
  review_digest?: string;
346
386
  last_action: {
@@ -420,6 +460,7 @@ export interface ForeshadowsDocument {
420
460
  status: 'planted' | 'dormant' | 'advanced' | 'resolved';
421
461
  resolved_at: number | null;
422
462
  description: string;
463
+ anchor?: string;
423
464
  advance_log: Array<{
424
465
  chapter: number;
425
466
  note: string;
@@ -526,6 +567,317 @@ export interface ChapterPlanInput {
526
567
  /** Optional in 0.1.3: older plans remain readable; new plans may name 1–8 actors. */
527
568
  cast?: ChapterCastMember[];
528
569
  }
570
+ /** Book-level pitch and structure, persisted in `outline/outline.yaml`. */
571
+ export interface BookPlan {
572
+ premise: string;
573
+ logline: string;
574
+ themes: string[];
575
+ tone: string;
576
+ pov: string;
577
+ audience: string;
578
+ selling_points: string[];
579
+ ending: string;
580
+ /** Strict mode requires a chapter card before P2/P3 for every chapter. */
581
+ strict: boolean;
582
+ /** True once the author explicitly chose strict on/off; used for the first-outline default. */
583
+ strict_explicit?: boolean;
584
+ }
585
+ /** One volume of the planned book. `end_chapter` is inclusive. */
586
+ export interface OutlineVolume {
587
+ id: string;
588
+ title: string;
589
+ start_chapter: number;
590
+ end_chapter: number;
591
+ goal: string;
592
+ arc: string;
593
+ climax: string;
594
+ status: 'planned' | 'writing' | 'done';
595
+ }
596
+ /** One planned chapter card. Only the archive transaction may write the archived fields. */
597
+ export interface OutlineChapter {
598
+ num: number;
599
+ volume: number | null;
600
+ title: string;
601
+ scene_type: SceneType;
602
+ goal: string;
603
+ conflict: string;
604
+ hook: string;
605
+ cast: string[];
606
+ target_words: [number, number];
607
+ notes: string;
608
+ status: 'planned' | 'archived';
609
+ archived_at: string | null;
610
+ word_count: number | null;
611
+ score: number | null;
612
+ }
613
+ /** The planning SSOT read by P1–P8, PG-13, report, doctor and export. */
614
+ export interface OutlineDocument {
615
+ schema_version: 1;
616
+ updated_at: string;
617
+ book: BookPlan;
618
+ volumes: OutlineVolume[];
619
+ chapters: OutlineChapter[];
620
+ }
621
+ /** One worldbuilding rule/constraint. */
622
+ export interface WorldbookRule {
623
+ name: string;
624
+ description: string;
625
+ }
626
+ /** One faction in the world bible. */
627
+ export interface WorldbookFaction {
628
+ name: string;
629
+ description: string;
630
+ goal: string;
631
+ }
632
+ /** One location in the world bible. */
633
+ export interface WorldbookLocation {
634
+ name: string;
635
+ description: string;
636
+ layout: string;
637
+ capacity: number;
638
+ }
639
+ /** One planned character (not the post-prose ledger entry). */
640
+ export interface WorldbookCharacter {
641
+ name: string;
642
+ role: string;
643
+ description: string;
644
+ arc: string;
645
+ }
646
+ /** One glossary entry. */
647
+ export interface WorldbookGlossary {
648
+ term: string;
649
+ definition: string;
650
+ }
651
+ /** One backstory event. */
652
+ export interface WorldbookBackstory {
653
+ time: string;
654
+ event: string;
655
+ }
656
+ /** One declared numeric canon, checked against the manuscript on request. */
657
+ export interface WorldbookFact {
658
+ alias: string;
659
+ value: number;
660
+ unit: string;
661
+ tolerance?: number;
662
+ note?: string;
663
+ }
664
+ /** Worldbuilding plan, persisted in `outline/worldbook.yaml`. */
665
+ export interface WorldbookDocument {
666
+ schema_version: 1;
667
+ updated_at: string;
668
+ premise: string;
669
+ setting: string;
670
+ rules: WorldbookRule[];
671
+ factions: WorldbookFaction[];
672
+ locations: WorldbookLocation[];
673
+ characters: WorldbookCharacter[];
674
+ glossary: WorldbookGlossary[];
675
+ backstory: WorldbookBackstory[];
676
+ /** Optional numeric canon; old documents omit it. */
677
+ facts?: WorldbookFact[];
678
+ themes: string[];
679
+ }
680
+ /** One hit from `novel_search`; the scope names the source family. */
681
+ export interface SearchResultItem {
682
+ kind: 'chapters' | 'summaries' | 'outline' | 'worldbook' | 'ledgers';
683
+ chapter?: number;
684
+ title?: string;
685
+ paragraph?: number;
686
+ snippet: string;
687
+ }
688
+ /** Search response; `total` counts every matching segment, `results` is capped by `limit`. */
689
+ export interface SearchReport {
690
+ query: string;
691
+ scope: 'all' | 'chapters' | 'summaries' | 'outline' | 'worldbook' | 'ledgers';
692
+ total: number;
693
+ truncated: boolean;
694
+ results: SearchResultItem[];
695
+ }
696
+ /** One structured health check. */
697
+ export interface DoctorCheck {
698
+ id: string;
699
+ severity: 'ok' | 'info' | 'warning' | 'error';
700
+ title: string;
701
+ detail: string;
702
+ hint?: string;
703
+ }
704
+ /** `novel_doctor` payload; a missing project is reported, never thrown. */
705
+ export interface DoctorReport {
706
+ ok: boolean;
707
+ root: string;
708
+ checks: DoctorCheck[];
709
+ summary: {
710
+ errors: number;
711
+ warnings: number;
712
+ infos: number;
713
+ };
714
+ }
715
+ /** One canonical outline-progress calculation shared by every adapter. */
716
+ export interface OutlineProgress {
717
+ present: boolean;
718
+ target: number | null;
719
+ total: number;
720
+ planned: number;
721
+ archived: number;
722
+ missingCards: number;
723
+ plannedCoverage: number | null;
724
+ archivedCoverage: number | null;
725
+ /** Compatibility alias: planned coverage when a target exists, otherwise card coverage. */
726
+ coverage: number;
727
+ /** Fraction of archived chapters that have a matching archived card. */
728
+ cardCoverage: number;
729
+ volumes: number;
730
+ }
731
+ /** Book-wide quality, outline, cast and pacing aggregates. */
732
+ export interface BookReport {
733
+ progress: {
734
+ archived: number;
735
+ target: number | null;
736
+ words: number;
737
+ average_words: number;
738
+ percent: number;
739
+ remaining_words: number | null;
740
+ remaining_words_min: number | null;
741
+ remaining_words_average: number | null;
742
+ remaining_words_basis: 'actual_average' | 'minimum_target' | 'none';
743
+ };
744
+ outline: {
745
+ present: boolean;
746
+ strict: boolean;
747
+ target: number | null;
748
+ total: number;
749
+ planned: number;
750
+ archived: number;
751
+ missing_cards: number;
752
+ planned_coverage: number | null;
753
+ archived_coverage: number | null;
754
+ coverage: number;
755
+ card_coverage: number;
756
+ volumes: Array<{
757
+ title: string;
758
+ start: number;
759
+ end: number;
760
+ planned: number;
761
+ archived: number;
762
+ }>;
763
+ drift: Array<{
764
+ chapter: number;
765
+ field: string;
766
+ planned: string;
767
+ actual: string;
768
+ }>;
769
+ };
770
+ worldbook: {
771
+ present: boolean;
772
+ characters: number;
773
+ locations: number;
774
+ factions: number;
775
+ rules: number;
776
+ glossary: number;
777
+ backstory: number;
778
+ facts?: number;
779
+ };
780
+ quality: {
781
+ average: number;
782
+ median: number;
783
+ min: number;
784
+ max: number;
785
+ last_five: number[];
786
+ trend: number;
787
+ dimensions: Array<{
788
+ id: string;
789
+ average: number;
790
+ samples: number;
791
+ }>;
792
+ };
793
+ /** Per-chapter effort survives archive (pipeline rounds are reset). */
794
+ effort: {
795
+ reviews: number;
796
+ revisions: number;
797
+ checks: number;
798
+ rollbacks: number;
799
+ chapters: Array<{
800
+ num: number;
801
+ reviews: number;
802
+ revisions: number;
803
+ checks: number;
804
+ rollbacks: number;
805
+ final_check: 'pass' | 'fail' | null;
806
+ archived_at: string | null;
807
+ }>;
808
+ };
809
+ pacing: {
810
+ scene_types: Record<string, number>;
811
+ hook_strength: Record<string, number>;
812
+ plot_advancement: Record<string, number>;
813
+ longest: {
814
+ chapter: number;
815
+ words: number;
816
+ } | null;
817
+ shortest: {
818
+ chapter: number;
819
+ words: number;
820
+ } | null;
821
+ };
822
+ cast: {
823
+ total: number;
824
+ top: Array<{
825
+ name: string;
826
+ appearances: number;
827
+ last_seen: number;
828
+ role: string;
829
+ }>;
830
+ };
831
+ foreshadows: {
832
+ open: number;
833
+ dormant: number;
834
+ overdue: number;
835
+ resolved: number;
836
+ oldest: Array<{
837
+ id: string;
838
+ title: string;
839
+ last_touched: number;
840
+ age: number;
841
+ }>;
842
+ };
843
+ timeline: {
844
+ events: number;
845
+ first_chapter: number | null;
846
+ last_chapter: number | null;
847
+ };
848
+ relationships: {
849
+ total: number;
850
+ types: Record<string, number>;
851
+ };
852
+ activity: Array<{
853
+ at: string;
854
+ op: string;
855
+ chapter: number;
856
+ status: string;
857
+ }>;
858
+ warnings: string[];
859
+ }
860
+ /** One onboarding step. */
861
+ export interface GuideStep {
862
+ id: string;
863
+ title: string;
864
+ detail: string;
865
+ done: boolean;
866
+ tool?: string;
867
+ }
868
+ /** `novel_guide` payload. */
869
+ export interface GuideReport {
870
+ state: 'no-project' | 'new' | 'planning' | 'writing' | 'blocked' | 'finished';
871
+ title: string;
872
+ steps: GuideStep[];
873
+ next: {
874
+ tool: string;
875
+ args: Record<string, unknown>;
876
+ reason: string;
877
+ };
878
+ commands: string[];
879
+ tips: string[];
880
+ }
529
881
  /** Draft submission payload. */
530
882
  export interface DraftInput {
531
883
  chapter: number;
@@ -544,10 +896,23 @@ export interface ReviewInput {
544
896
  total: number;
545
897
  proof: ReadingProof;
546
898
  }
899
+ /** One exact, unique replacement used by patch-mode revisions. */
900
+ export interface RevisionEdit {
901
+ old_text: string;
902
+ new_text: string;
903
+ /** 1-based occurrence; defaults to requiring exactly one match. */
904
+ occurrence?: number;
905
+ }
906
+ /** Patch-mode revision; content and patch are mutually exclusive. */
907
+ export interface RevisionPatch {
908
+ expected_hash: string;
909
+ edits: RevisionEdit[];
910
+ }
547
911
  /** Revision submission payload. */
548
912
  export interface RevisionInput {
549
913
  chapter: number;
550
- content: string;
914
+ content?: string;
915
+ patch?: RevisionPatch;
551
916
  summary: ChapterSummary;
552
917
  }
553
918
  /** Semantic check items supplied by the model. */
@@ -598,6 +963,12 @@ export interface GateInput {
598
963
  /** The three preceding chapters, newest first, for the duplicate rule. */
599
964
  previousTexts: string[];
600
965
  priorSceneTypes: SceneType[];
966
+ /** 0.2.0 planning input; undefined means "no outline" for older fixtures. */
967
+ outline?: OutlineDocument | null;
968
+ /** The chapter plan's target range, used by PG-13. */
969
+ planTargetWords?: [number, number] | null;
970
+ /** The chapter plan's declared cast names, used by PG-13. */
971
+ planCast?: string[] | null;
601
972
  }
602
973
  /** Gate evaluation outcome. */
603
974
  export interface GateResult {
@@ -636,6 +1007,36 @@ export interface StatusReport {
636
1007
  volume_name?: string;
637
1008
  act?: string;
638
1009
  act_progress?: string;
1010
+ /** 0.2.0 book-level visibility; absent on older synthetic payloads. */
1011
+ book?: {
1012
+ premise: string;
1013
+ logline: string;
1014
+ strict: boolean;
1015
+ outline: {
1016
+ present: boolean;
1017
+ target: number | null;
1018
+ total: number;
1019
+ planned: number;
1020
+ archived: number;
1021
+ missing_cards: number;
1022
+ planned_coverage: number | null;
1023
+ archived_coverage: number | null;
1024
+ coverage: number;
1025
+ card_coverage: number;
1026
+ volumes: number;
1027
+ current: OutlineChapter | null;
1028
+ };
1029
+ worldbook: {
1030
+ present: boolean;
1031
+ characters: number;
1032
+ locations: number;
1033
+ factions: number;
1034
+ rules: number;
1035
+ glossary: number;
1036
+ backstory: number;
1037
+ facts?: number;
1038
+ };
1039
+ };
639
1040
  next: {
640
1041
  tool: string;
641
1042
  args: Record<string, unknown>;
@@ -654,6 +1055,8 @@ export interface AdviceReport {
654
1055
  }
655
1056
  /** One history row derived from the journal. */
656
1057
  export interface AuditRow {
1058
+ /** Stable chronological cursor; absent only on hand-built test rows. */
1059
+ seq?: number;
657
1060
  at: string;
658
1061
  op: string;
659
1062
  chapter: number;
@@ -661,6 +1064,14 @@ export interface AuditRow {
661
1064
  txid: string;
662
1065
  status: 'committed' | 'aborted';
663
1066
  files: string[];
1067
+ /** Machine code and human reason for a refused attempt. */
1068
+ code?: string;
1069
+ reason?: string;
1070
+ hint?: string;
1071
+ stage?: string;
1072
+ /** True when no transaction started: the gate/input refused the call. */
1073
+ attempt?: boolean;
1074
+ blocking?: BlockingItem[];
664
1075
  }
665
1076
  /** One diff hunk between two revisions of a chapter. */
666
1077
  export interface DiffReport {
@@ -674,5 +1085,5 @@ export interface DiffReport {
674
1085
  line: string;
675
1086
  }>;
676
1087
  }
677
- /** Export capabilities. */
678
- export type ExportKind = 'md' | 'txt' | 'epub';
1088
+ /** Export capabilities; the last three are book-planning deliverables. */
1089
+ export type ExportKind = 'md' | 'txt' | 'epub' | 'outline' | 'worldbook' | 'proposal';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "dsh-novel-write-engine",
3
- "version": "0.1.3",
3
+ "version": "0.2.1",
4
4
  "description": "Novel writing engine for DeepSeek Harness: state machine, gates, rulepacks and ledgers moved from prompts into code.",
5
5
  "keywords": [
6
6
  "dsh-plugin",
@@ -4,7 +4,7 @@
4
4
  config:
5
5
  id: novel-write-engine
6
6
  name: 网文工坊
7
- description: 网文创作专用会话:18 个小说工具全开,无文件写权限,门控与字数由引擎裁决。
7
+ description: 网文创作专用会话:28 个小说工具全开,无文件写权限,门控与字数由引擎裁决。
8
8
  order: 20
9
9
  plugins:
10
10
  - id: persona
package/skills/entry.md CHANGED
@@ -16,6 +16,10 @@ description: 引擎版小说创作流程——状态、门控、字数与写盘
16
16
  5. **不编设定。** 人物、地点、伏笔、资源状态拿不准就 `novel_state` 查。
17
17
  6. **归档是一次事务,且必须核销。** `novel_archive` 必须带 `state_delta`:本章每个角色/伏笔/事件/新设定/关系逐条声明 `created|updated|no_change`;不要手工拼章节索引或交接文件。
18
18
 
19
+ ## 书级规划(0.2.0)
20
+
21
+ 新项目先 `novel_guide`;推荐但不强制:`novel_blueprint`(蓝图/卷)→ `novel_outline`(章卡)→ `novel_worldbook`(设定集)。已有大纲可用 `novel_outline_import` 导入 Markdown/YAML/JSON。只要存在章卡,P2/P3 就按章卡校验标题、场景、字数与 cast;严格模式还要求章卡必须存在。要改已归档章先 `novel_reopen`(必须带 reason)。
22
+
19
23
  ## 流程路由
20
24
 
21
25
  | 当前阶段 | 任务书 | 下一动作 |
@@ -36,33 +40,43 @@ description: 引擎版小说创作流程——状态、门控、字数与写盘
36
40
  | 工具 | 用途 |
37
41
  | --- | --- |
38
42
  | `novel_init` | 建项目 |
39
- | `novel_status` | 当前章/阶段/阻塞/下一步 |
43
+ | `novel_status` | 当前章/阶段/阻塞/书级摘要/下一步 |
44
+ | `novel_blueprint` | 书级蓝图与卷结构 |
45
+ | `novel_outline` | 卷/章卡 |
46
+ | `novel_outline_import` | 导入 Markdown/YAML/JSON 大纲 |
47
+ | `novel_worldbook` | 世界观设定集 |
48
+ | `novel_search` | 搜索正文/大纲/世界观/台账 |
49
+ | `novel_doctor` | 项目体检 |
50
+ | `novel_report` | 全书报告 |
51
+ | `novel_guide` | 上手引导与下一步 |
52
+ | `novel_reopen` | 从归档备份重开紧邻的上一章 |
53
+ | `novel_restore` | 从标记备份恢复活动章 |
40
54
  | `novel_brief` | 取阶段任务书与上下文 |
41
55
  | `novel_plan_world` | P1 世界观计划 |
42
56
  | `novel_plan_chapter` | P2 章节计划 |
43
57
  | `novel_write_draft` | P3 初稿 |
44
58
  | `novel_review` | P4 十五维评分 |
45
- | `novel_revise` | P5 修订 |
46
- | `novel_check` | P6 一致性校验 |
59
+ | `novel_revise` | P5 修订(支持 exact patch) |
60
+ | `novel_check` | P6 一致性校验(advisory 可 acknowledge) |
47
61
  | `novel_archive` | 归档事务 |
48
62
  | `novel_word_count` | 字数口径 |
49
- | `novel_state` | 只读台账/计划/评审 |
63
+ | `novel_state` | 只读台账/计划/评审/history/backups/briefs |
50
64
  | `novel_amend` | 受控改状态文档 |
51
65
  | `novel_rollback` | 回退阶段 |
52
66
  | `novel_diff` | 与备份/文本对比 |
53
- | `novel_export` | md/txt/epub |
54
- | `novel_audit` | 事务审计 |
67
+ | `novel_export` | md/txt/epub/outline/worldbook/proposal |
68
+ | `novel_audit` | 事务与失败 attempt 审计 |
55
69
  | `novel_pipeline` | 推荐下一步与参数 |
56
70
 
57
71
  ## 工具怎么用
58
72
 
59
73
  - 参数是 JSON 对象;`summary`、`dimensions`、`issues`、`proof` 是结构化对象,按任务书字段填。
60
- - `novel_check` 必须带四个语义项(`L2-SCENE-ANCHOR` / `L2-CHARACTER-STATE` / `L2-CAUSALITY` / `L2-VOICE`),每项都要有正文逐字引用;缺一项即校验不过。
74
+ - `novel_check` 必须带五个语义项(`L2-SCENE-ANCHOR` / `L2-CHARACTER-STATE` / `L2-CAUSALITY` / `L2-VOICE` / `L2-POV`),每项都要有正文逐字引用,且来自不同句子;缺一项即校验不过。
61
75
  - 失败分三类:参数错(改参数)、门控没过(改正文)、系统故障(查目录/稍后重试)。错误消息里的 code 说明属于哪类。
62
76
  - 门控失败会一次列出**全部**阻塞项;一次改完再交,不要逐条试。
63
77
 
64
78
  ## 交付
65
79
 
66
80
  - 每章归档后,用户在面板「网文工坊」看到章节表与阻塞区。
67
- - 导出:`novel_export md|txt|epub`。
81
+ - 导出:`novel_export md|txt|epub|outline|worldbook|proposal`。
68
82
  - 不要在对话里重复整章正文;工具结果已经可见。