dsh-novel-write-engine 0.2.0 → 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.
package/lib/index.d.ts CHANGED
@@ -23,7 +23,7 @@ type SceneType = (typeof SCENE_TYPES)[number];
23
23
  /** A violation is blocking unless the rule pack declares it advisory. */
24
24
  type Severity = 'blocker' | 'advisory';
25
25
  /** All thirty-one service operations (22 inherited from 0.1.x, 9 book-level). */
26
- 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"];
26
+ 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"];
27
27
  type Operation = (typeof OPERATIONS)[number];
28
28
  /** Structured, non-fatal note attached to a successful result. */
29
29
  interface Warning {
@@ -161,6 +161,7 @@ interface CheckDocument {
161
161
  content_hash: string;
162
162
  machine: {
163
163
  violations: Violation[];
164
+ advisories?: Violation[];
164
165
  metrics: WordMetrics;
165
166
  };
166
167
  semantic: {
@@ -171,6 +172,8 @@ interface CheckDocument {
171
172
  note: string;
172
173
  }>;
173
174
  };
175
+ /** Advisory codes the author has explicitly acknowledged for this content. */
176
+ acknowledged?: string[];
174
177
  verdict: 'pass' | 'fail';
175
178
  }
176
179
  /** Every persisted document whose damage status/panel can report. */
@@ -189,6 +192,8 @@ interface WordMetrics {
189
192
  numbers: number;
190
193
  chinese_punct: number;
191
194
  english_punct: number;
195
+ /** All punctuation counted by the engine; total = cjk + words + numbers + punctuation. */
196
+ punctuation_chars: number;
192
197
  non_ws_chars: number;
193
198
  total_lines: number;
194
199
  non_empty_lines: number;
@@ -211,6 +216,10 @@ interface ChapterRecord {
211
216
  status: 'draft' | 'reviewed';
212
217
  content_hash: string;
213
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;
214
223
  /** Keys allocated by the archive transaction; lets a cross-process retry replay. */
215
224
  assigned_ids?: Record<string, string>;
216
225
  /** Digest of the archive request that produced this row. */
@@ -225,6 +234,7 @@ interface ChapterSummary {
225
234
  key: string;
226
235
  title: string;
227
236
  description: string;
237
+ anchor?: string;
228
238
  }>;
229
239
  advanced: Array<{
230
240
  key: string;
@@ -258,6 +268,8 @@ interface RoundCounters {
258
268
  review: number;
259
269
  revise: number;
260
270
  check: number;
271
+ /** Lifetime rollback count on a chapter record; never stored in the live pipeline. */
272
+ rollbacks?: number;
261
273
  }
262
274
  /** How one ledger entity changed in this chapter. */
263
275
  type DeltaAction = 'created' | 'updated' | 'no_change';
@@ -289,6 +301,8 @@ interface ForeshadowDelta {
289
301
  action: DeltaAction;
290
302
  reason?: string;
291
303
  title?: string;
304
+ /** Verbatim manuscript quote used for verification; title stays a readable label. */
305
+ anchor?: string;
292
306
  description?: string;
293
307
  note?: string;
294
308
  new_info?: boolean;
@@ -331,6 +345,28 @@ interface ArchiveHandoff {
331
345
  act?: string;
332
346
  act_progress?: string;
333
347
  }
348
+ /** One issued task-book receipt; the brief itself is rendered on demand. */
349
+ 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
+ interface BriefReceiptsDocument {
357
+ schema_version: 1;
358
+ receipts: BriefReceipt[];
359
+ }
360
+ /** The active draft's own metadata; P2 plan stays immutable after submission. */
361
+ 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
+ }
334
370
  /** Pipeline document (`state/pipeline.yaml`). */
335
371
  interface PipelineState {
336
372
  schema_version: 1;
@@ -343,6 +379,8 @@ interface PipelineState {
343
379
  digest: string;
344
380
  }>;
345
381
  blocking: BlockingItem[];
382
+ /** Current draft summary/title; never written into the P2 plan file. */
383
+ draft?: DraftState;
346
384
  /** Hash of the review document last written by submitReview/submitRevision. */
347
385
  review_digest?: string;
348
386
  last_action: {
@@ -422,6 +460,7 @@ interface ForeshadowsDocument {
422
460
  status: 'planted' | 'dormant' | 'advanced' | 'resolved';
423
461
  resolved_at: number | null;
424
462
  description: string;
463
+ anchor?: string;
425
464
  advance_log: Array<{
426
465
  chapter: number;
427
466
  note: string;
@@ -614,6 +653,14 @@ interface WorldbookBackstory {
614
653
  time: string;
615
654
  event: string;
616
655
  }
656
+ /** One declared numeric canon, checked against the manuscript on request. */
657
+ interface WorldbookFact {
658
+ alias: string;
659
+ value: number;
660
+ unit: string;
661
+ tolerance?: number;
662
+ note?: string;
663
+ }
617
664
  /** Worldbuilding plan, persisted in `outline/worldbook.yaml`. */
618
665
  interface WorldbookDocument {
619
666
  schema_version: 1;
@@ -626,6 +673,8 @@ interface WorldbookDocument {
626
673
  characters: WorldbookCharacter[];
627
674
  glossary: WorldbookGlossary[];
628
675
  backstory: WorldbookBackstory[];
676
+ /** Optional numeric canon; old documents omit it. */
677
+ facts?: WorldbookFact[];
629
678
  themes: string[];
630
679
  }
631
680
  /** One hit from `novel_search`; the scope names the source family. */
@@ -663,6 +712,22 @@ interface DoctorReport {
663
712
  infos: number;
664
713
  };
665
714
  }
715
+ /** One canonical outline-progress calculation shared by every adapter. */
716
+ 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
+ }
666
731
  /** Book-wide quality, outline, cast and pacing aggregates. */
667
732
  interface BookReport {
668
733
  progress: {
@@ -672,13 +737,22 @@ interface BookReport {
672
737
  average_words: number;
673
738
  percent: number;
674
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';
675
743
  };
676
744
  outline: {
677
745
  present: boolean;
678
746
  strict: boolean;
747
+ target: number | null;
748
+ total: number;
679
749
  planned: number;
680
750
  archived: number;
751
+ missing_cards: number;
752
+ planned_coverage: number | null;
753
+ archived_coverage: number | null;
681
754
  coverage: number;
755
+ card_coverage: number;
682
756
  volumes: Array<{
683
757
  title: string;
684
758
  start: number;
@@ -701,6 +775,7 @@ interface BookReport {
701
775
  rules: number;
702
776
  glossary: number;
703
777
  backstory: number;
778
+ facts?: number;
704
779
  };
705
780
  quality: {
706
781
  average: number;
@@ -715,6 +790,22 @@ interface BookReport {
715
790
  samples: number;
716
791
  }>;
717
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
+ };
718
809
  pacing: {
719
810
  scene_types: Record<string, number>;
720
811
  hook_strength: Record<string, number>;
@@ -805,10 +896,23 @@ interface ReviewInput {
805
896
  total: number;
806
897
  proof: ReadingProof;
807
898
  }
899
+ /** One exact, unique replacement used by patch-mode revisions. */
900
+ 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
+ interface RevisionPatch {
908
+ expected_hash: string;
909
+ edits: RevisionEdit[];
910
+ }
808
911
  /** Revision submission payload. */
809
912
  interface RevisionInput {
810
913
  chapter: number;
811
- content: string;
914
+ content?: string;
915
+ patch?: RevisionPatch;
812
916
  summary: ChapterSummary;
813
917
  }
814
918
  /** Semantic check items supplied by the model. */
@@ -910,10 +1014,15 @@ interface StatusReport {
910
1014
  strict: boolean;
911
1015
  outline: {
912
1016
  present: boolean;
1017
+ target: number | null;
913
1018
  total: number;
914
1019
  planned: number;
915
1020
  archived: number;
1021
+ missing_cards: number;
1022
+ planned_coverage: number | null;
1023
+ archived_coverage: number | null;
916
1024
  coverage: number;
1025
+ card_coverage: number;
917
1026
  volumes: number;
918
1027
  current: OutlineChapter | null;
919
1028
  };
@@ -925,6 +1034,7 @@ interface StatusReport {
925
1034
  rules: number;
926
1035
  glossary: number;
927
1036
  backstory: number;
1037
+ facts?: number;
928
1038
  };
929
1039
  };
930
1040
  next: {
@@ -945,6 +1055,8 @@ interface AdviceReport {
945
1055
  }
946
1056
  /** One history row derived from the journal. */
947
1057
  interface AuditRow {
1058
+ /** Stable chronological cursor; absent only on hand-built test rows. */
1059
+ seq?: number;
948
1060
  at: string;
949
1061
  op: string;
950
1062
  chapter: number;
@@ -952,6 +1064,14 @@ interface AuditRow {
952
1064
  txid: string;
953
1065
  status: 'committed' | 'aborted';
954
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[];
955
1075
  }
956
1076
  /** One diff hunk between two revisions of a chapter. */
957
1077
  interface DiffReport {
@@ -1151,6 +1271,7 @@ interface WorldbookPatch {
1151
1271
  characters?: WorldbookCharacter[];
1152
1272
  glossary?: WorldbookGlossary[];
1153
1273
  backstory?: WorldbookBackstory[];
1274
+ facts?: WorldbookFact[];
1154
1275
  themes?: string[];
1155
1276
  }
1156
1277
  /** One rendered task book. */
@@ -1282,10 +1403,15 @@ interface PanelBook {
1282
1403
  target: number | null;
1283
1404
  outline: {
1284
1405
  present: boolean;
1406
+ target: number | null;
1285
1407
  total: number;
1286
1408
  planned: number;
1287
1409
  archived: number;
1410
+ missing_cards: number;
1411
+ planned_coverage: number | null;
1412
+ archived_coverage: number | null;
1288
1413
  coverage: number;
1414
+ card_coverage: number;
1289
1415
  volumes: Array<{
1290
1416
  title: string;
1291
1417
  start: number;
@@ -1302,6 +1428,7 @@ interface PanelBook {
1302
1428
  rules: number;
1303
1429
  glossary: number;
1304
1430
  backstory: number;
1431
+ facts?: number;
1305
1432
  };
1306
1433
  }
1307
1434
  interface PanelSummaryDto {
@@ -1447,6 +1574,15 @@ type EngineEvent = {
1447
1574
  chapter: number;
1448
1575
  restore_txid: string;
1449
1576
  };
1577
+ } | {
1578
+ name: 'novel/restored';
1579
+ payload: {
1580
+ schemaVersion: 1;
1581
+ projectRoot: string;
1582
+ txid: string;
1583
+ chapter: number;
1584
+ paths: string[];
1585
+ };
1450
1586
  } | {
1451
1587
  name: 'novel/exported';
1452
1588
  payload: {
@@ -1518,6 +1654,8 @@ interface CheckSubmission {
1518
1654
  /** The five P6 semantic items; omission is a failed check, never a pass. */
1519
1655
  semantic: SemanticItem[];
1520
1656
  scope?: string[];
1657
+ /** Advisory codes the author has read and accepts; blockers cannot be acknowledged. */
1658
+ acknowledge?: string[];
1521
1659
  root?: string;
1522
1660
  }
1523
1661
  interface ArchiveSubmission {
@@ -1534,6 +1672,13 @@ interface AmendSubmission {
1534
1672
  reason: string;
1535
1673
  root?: string;
1536
1674
  }
1675
+ interface RestoreSubmission {
1676
+ txid: string;
1677
+ chapter?: number;
1678
+ /** Restrict to these project-relative files; omitted restores every chapter file in the snapshot. */
1679
+ paths?: string[];
1680
+ root?: string;
1681
+ }
1537
1682
  interface RollbackSubmission {
1538
1683
  chapter: number;
1539
1684
  toStage: 'P1' | 'P2' | 'P3' | 'P4' | 'P5' | 'P6';
@@ -1548,6 +1693,12 @@ interface DiffInput {
1548
1693
  }
1549
1694
  interface AuditInput {
1550
1695
  limit?: number;
1696
+ cursor?: number;
1697
+ chapter?: number;
1698
+ op?: string;
1699
+ status?: 'committed' | 'aborted';
1700
+ since?: string;
1701
+ until?: string;
1551
1702
  root?: string;
1552
1703
  }
1553
1704
  interface ExportInput {
@@ -1556,8 +1707,10 @@ interface ExportInput {
1556
1707
  root?: string;
1557
1708
  }
1558
1709
  interface StateQueryInput {
1559
- kind: DocKind | 'novel' | 'planWorld' | 'planChapter';
1710
+ kind: DocKind | 'novel' | 'planWorld' | 'planChapter' | 'history' | 'backups' | 'briefs';
1560
1711
  chapter?: number;
1712
+ /** Select one historical revision instead of listing history. */
1713
+ revision?: number;
1561
1714
  /** Chapter index defaults to a compact read; opt in to the full summaries. */
1562
1715
  include_summary?: boolean;
1563
1716
  /** Inclusive chapter range for the `chapters` index. */
@@ -1689,12 +1842,28 @@ declare class EngineService {
1689
1842
  stage: Stage;
1690
1843
  restore_txid: string;
1691
1844
  }>>;
1845
+ /**
1846
+ * Restore one active chapter from a backup transaction. Archived chapters
1847
+ * are refused: their manuscript hash is bound by the index, so restoring
1848
+ * behind the index would corrupt the project. Reopen first, then restore.
1849
+ */
1850
+ restoreBackup(input: RestoreSubmission): Promise<OpResult<{
1851
+ txid: string;
1852
+ chapter: number;
1853
+ restored: string[];
1854
+ }>>;
1692
1855
  /**
1693
1856
  * Read-only paths must surface a committed-journal mismatch. The write path
1694
1857
  * already fails closed; without this, status recommends the next write and
1695
1858
  * the model only learns about the mismatch when that write aborts.
1696
1859
  */
1697
1860
  private journalBlocking;
1861
+ /**
1862
+ * Count every committed attempt for one chapter, not just the loop since the
1863
+ * last rollback. `pipeline.rounds` is deliberately reset by rollback to keep
1864
+ * the retry budget fair; it is not the chapter's lifetime effort.
1865
+ */
1866
+ private lifetimeRounds;
1698
1867
  getStatus(input?: StatusInput): Promise<OpResult<StatusReport>>;
1699
1868
  countWords(input?: WordCountInput): Promise<OpResult<WordMetrics>>;
1700
1869
  queryState(input: StateQueryInput): Promise<OpResult<unknown>>;
@@ -1756,6 +1925,9 @@ declare class EngineService {
1756
1925
  chapter: number;
1757
1926
  verdict: 'pass' | 'fail';
1758
1927
  violations: number;
1928
+ advisories: number;
1929
+ advisory_codes: string[];
1930
+ acknowledged: string[];
1759
1931
  metrics: WordMetrics;
1760
1932
  stage: Stage;
1761
1933
  }>>;
@@ -1807,7 +1979,10 @@ declare class EngineService {
1807
1979
  lastScore: number;
1808
1980
  openForeshadows: number;
1809
1981
  plannedChapters: number;
1810
- outlineCoverage: number;
1982
+ totalCards: number;
1983
+ outlineCoverage: number | null;
1984
+ archivedCoverage: number | null;
1985
+ missingCards: number;
1811
1986
  blueprintReady: boolean;
1812
1987
  worldbookEntries: number;
1813
1988
  strictOutline: boolean;
@@ -1924,6 +2099,7 @@ declare class EngineService {
1924
2099
  /** State damage that makes this operation unsafe to start. */
1925
2100
  private stateGateBlock;
1926
2101
  /** Whether the stored brief still signs the current snapshot. */
2102
+ private readBriefReceipts;
1927
2103
  private briefIsCurrent;
1928
2104
  /** Arguments valid for the tool `STAGE_NEXT` recommends at this stage. */
1929
2105
  private nextArgs;
@@ -2013,4 +2189,4 @@ declare const Config: Schema<Config>;
2013
2189
  * created lazily per project root.
2014
2190
  */
2015
2191
  declare function apply(ctx: Context, config: Config): void;
2016
- export { AdviceReport, ArchiveHandoff, AuditRow, BlockingItem, BookPlan, BookReport, BriefDocument, BriefLibrary, BriefStage, ChapterCastMember, ChapterPlanInput, ChapterRecord, ChapterStatusRow, ChapterSummary, ChaptersDocument, CharacterDelta, CharactersDocument, CheckDocument, Config, Deduction, DeltaAction, DiffReport, DoctorCheck, DoctorReport, DraftInput, ERROR_CODES, EngineBlockedError, EngineError, EngineFaultError, EngineInputError, EngineService, ErrorCode, ExportChapter, ExportKind, ForeshadowDelta, ForeshadowsDocument, GENRES, GateInput, GateOptions, GateResult, Genre, GuideReport, GuideStep, HandoffDocument, LocksDocument, MachineMetrics, NovelProject, OPERATIONS, OpResult, Operation, OutlineChapter, OutlineDocument, OutlineVolume, PLATFORMS, PanelBook, PanelChapterRow, PanelChaptersDto, PanelDraft, PanelGatesDto, PanelSnapshot, PanelSummaryDto, PipelineState, Platform, ReadingProof, ReadingProofReference, RelationshipDelta, RelationshipsDocument, ReviewDocument, ReviewInput, ReviewIssue, RevisionInput, RoundCounters, SCENE_TYPES, SCHEMA_VERSION, SceneType, ScoreDimension, SearchReport, SearchResultItem, SemanticItem, Severity, Stage, StateDelta, StateError, StateErrorCode, StatusReport, TimelineDelta, TimelineDocument, Violation, Warning, WordMetrics, WorldDelta, WorldDocument, WorldPlanInput, WorldbookBackstory, WorldbookCharacter, WorldbookDocument, WorldbookFaction, WorldbookGlossary, WorldbookLocation, WorldbookRule, applicableGates, apply, blockedError, briefStageFor, chapterHeading, evaluateGates, faultError, gateName, inject, inputError, loadRulepack, name, parseParagraphLocation, phaseStrip, projectChapter, projectChapters, projectGates, projectSummary, renderBlurb, renderCover, renderEpubChapter, renderMarkdown, renderPlainText, renderProposal, verifyReference };
2192
+ export { AdviceReport, ArchiveHandoff, AuditRow, BlockingItem, BookPlan, BookReport, BriefDocument, BriefLibrary, BriefReceipt, BriefReceiptsDocument, BriefStage, ChapterCastMember, ChapterPlanInput, ChapterRecord, ChapterStatusRow, ChapterSummary, ChaptersDocument, CharacterDelta, CharactersDocument, CheckDocument, Config, Deduction, DeltaAction, DiffReport, DoctorCheck, DoctorReport, DraftInput, DraftState, ERROR_CODES, EngineBlockedError, EngineError, EngineFaultError, EngineInputError, EngineService, ErrorCode, ExportChapter, ExportKind, ForeshadowDelta, ForeshadowsDocument, GENRES, GateInput, GateOptions, GateResult, Genre, GuideReport, GuideStep, HandoffDocument, LocksDocument, MachineMetrics, NovelProject, OPERATIONS, OpResult, Operation, OutlineChapter, OutlineDocument, OutlineProgress, OutlineVolume, PLATFORMS, PanelBook, PanelChapterRow, PanelChaptersDto, PanelDraft, PanelGatesDto, PanelSnapshot, PanelSummaryDto, PipelineState, Platform, ReadingProof, ReadingProofReference, RelationshipDelta, RelationshipsDocument, ReviewDocument, ReviewInput, ReviewIssue, RevisionEdit, RevisionInput, RevisionPatch, RoundCounters, SCENE_TYPES, SCHEMA_VERSION, SceneType, ScoreDimension, SearchReport, SearchResultItem, SemanticItem, Severity, Stage, StateDelta, StateError, StateErrorCode, StatusReport, TimelineDelta, TimelineDocument, Violation, Warning, WordMetrics, WorldDelta, WorldDocument, WorldPlanInput, WorldbookBackstory, WorldbookCharacter, WorldbookDocument, WorldbookFact, WorldbookFaction, WorldbookGlossary, WorldbookLocation, WorldbookRule, applicableGates, apply, blockedError, briefStageFor, chapterHeading, evaluateGates, faultError, gateName, inject, inputError, loadRulepack, name, parseParagraphLocation, phaseStrip, projectChapter, projectChapters, projectGates, projectSummary, renderBlurb, renderCover, renderEpubChapter, renderMarkdown, renderPlainText, renderProposal, verifyReference };