dsh-novel-write-engine 0.2.2 → 0.2.3

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
@@ -65,9 +65,13 @@ declare const ERROR_CODES: {
65
65
  readonly PROJECT_IDENTITY_MISMATCH: "ENGINE_PROJECT_IDENTITY_MISMATCH";
66
66
  readonly PROJECT_EXISTS: "ENGINE_PROJECT_EXISTS";
67
67
  readonly STAGE_ORDER: "ENGINE_STAGE_ORDER";
68
+ /** The exact same keyed submission already failed in the same context. */
69
+ readonly RETRY_UNCHANGED: "ENGINE_RETRY_UNCHANGED";
68
70
  readonly GATE_BLOCKED: "ENGINE_GATE_BLOCKED";
69
71
  readonly READING_PROOF_INVALID: "ENGINE_READING_PROOF_INVALID";
70
72
  readonly SCORE_MISMATCH: "ENGINE_SCORE_MISMATCH";
73
+ /** A revision tried to rewrite reviewer-owned issue fields. */
74
+ readonly ISSUE_IMMUTABLE: "ENGINE_ISSUE_IMMUTABLE";
71
75
  readonly DELTA_UNVERIFIED: "ENGINE_DELTA_UNVERIFIED";
72
76
  readonly RESOURCE_NEGATIVE_BALANCE: "ENGINE_RESOURCE_NEGATIVE_BALANCE";
73
77
  readonly SCHEMA_TOO_NEW: "ENGINE_SCHEMA_TOO_NEW";
@@ -464,6 +468,8 @@ interface ForeshadowsDocument {
464
468
  resolved_at: number | null;
465
469
  description: string;
466
470
  anchor?: string;
471
+ /** New 0.2.3 writes are distinguishable from pre-0.2.3 rows by this marker. */
472
+ format_version?: 1;
467
473
  advance_log: Array<{
468
474
  chapter: number;
469
475
  note: string;
@@ -786,7 +792,13 @@ interface BookReport {
786
792
  min: number;
787
793
  max: number;
788
794
  last_five: number[];
789
- trend: number;
795
+ /** Null when there are not enough distinct chapter reviews to compare. */
796
+ trend: number | null;
797
+ trend_basis: 'last_five_vs_previous_five' | 'insufficient_samples' | 'insufficient_history';
798
+ /** Number of chapters represented by a final review. */
799
+ samples: number;
800
+ /** Committed review rounds for this report, including history. */
801
+ attempts: number;
790
802
  dimensions: Array<{
791
803
  id: string;
792
804
  average: number;
@@ -1013,6 +1025,8 @@ interface StatusReport {
1013
1025
  chapter: number;
1014
1026
  /** The chapter the pipeline is currently working on. */
1015
1027
  active_chapter: number;
1028
+ /** SHA-256 of the active manuscript, or null when the stage has no draft. */
1029
+ manuscript_hash: string | null;
1016
1030
  stage: Stage;
1017
1031
  rounds: RoundCounters;
1018
1032
  blocking: BlockingItem[];
@@ -1089,6 +1103,10 @@ interface AuditRow {
1089
1103
  /** True when no transaction started: the gate/input refused the call. */
1090
1104
  attempt?: boolean;
1091
1105
  blocking?: BlockingItem[];
1106
+ /** Keyed operation fingerprint; lets an identical failed retry be refused. */
1107
+ retry_key?: string;
1108
+ /** Brief/stage/revision context for `retry_key`. */
1109
+ retry_context?: string;
1092
1110
  }
1093
1111
  /** One diff hunk between two revisions of a chapter. */
1094
1112
  interface DiffReport {
@@ -1401,7 +1419,10 @@ interface PanelSnapshot {
1401
1419
  quality?: {
1402
1420
  averageScore: number;
1403
1421
  scores: number[];
1404
- trend: number;
1422
+ trend: number | null;
1423
+ trend_basis?: 'last_five_vs_previous_five' | 'insufficient_samples' | 'insufficient_history';
1424
+ samples?: number;
1425
+ attempts?: number;
1405
1426
  };
1406
1427
  health?: {
1407
1428
  ok: boolean;
@@ -1414,6 +1435,19 @@ interface PanelSnapshot {
1414
1435
  chapter: number;
1415
1436
  status: string;
1416
1437
  }>;
1438
+ /** Unacknowledged machine advisories; never mixed into `blocking`. */
1439
+ advisories?: Array<{
1440
+ code: string;
1441
+ detail: string;
1442
+ hint?: string;
1443
+ }>;
1444
+ /** Number of advisory codes already acknowledged for the current check. */
1445
+ acknowledgedAdvisories?: number;
1446
+ /** Read-only upgrade findings; null when the project needs no explanation. */
1447
+ legacy?: Array<{
1448
+ code: string;
1449
+ detail: string;
1450
+ }>;
1417
1451
  }
1418
1452
  interface PanelBook {
1419
1453
  premise: string;
@@ -1486,7 +1520,10 @@ interface PanelSummaryDto {
1486
1520
  quality?: {
1487
1521
  averageScore: number;
1488
1522
  scores: number[];
1489
- trend: number;
1523
+ trend: number | null;
1524
+ trend_basis?: 'last_five_vs_previous_five' | 'insufficient_samples' | 'insufficient_history';
1525
+ samples?: number;
1526
+ attempts?: number;
1490
1527
  };
1491
1528
  health?: {
1492
1529
  ok: boolean;
@@ -1499,6 +1536,19 @@ interface PanelSummaryDto {
1499
1536
  chapter: number;
1500
1537
  status: string;
1501
1538
  }>;
1539
+ /** Unacknowledged machine advisories; never mixed into `blocking`. */
1540
+ advisories?: Array<{
1541
+ code: string;
1542
+ detail: string;
1543
+ hint?: string;
1544
+ }>;
1545
+ /** Number of advisory codes already acknowledged for the current check. */
1546
+ acknowledgedAdvisories?: number;
1547
+ /** Read-only upgrade findings; null when the project needs no explanation. */
1548
+ legacy?: Array<{
1549
+ code: string;
1550
+ detail: string;
1551
+ }>;
1502
1552
  }
1503
1553
  interface PanelChapterRow {
1504
1554
  num: number;
@@ -1529,7 +1579,9 @@ interface PanelProjectOption {
1529
1579
  title: string;
1530
1580
  active: boolean;
1531
1581
  registered: boolean;
1532
- state: 'ok' | 'damaged' | 'missing' | 'unreadable';
1582
+ state: 'ok' | 'damaged' | 'missing' | 'not-project' | 'unreadable';
1583
+ /** The path now holds a different project identity; writes will fail closed. */
1584
+ identity_changed?: boolean;
1533
1585
  }
1534
1586
  interface PanelSelection {
1535
1587
  root: string | null;
@@ -1538,8 +1590,8 @@ interface PanelSelection {
1538
1590
  interface PanelMissing {
1539
1591
  root: string;
1540
1592
  title: string;
1541
- code: 'ENGINE_PROJECT_MISSING' | 'ENGINE_PROJECT_NOT_FOUND';
1542
- reason: 'missing' | 'not-project' | 'damaged' | 'not_registered' | 'unreadable';
1593
+ code: 'ENGINE_PROJECT_MISSING' | 'ENGINE_PROJECT_NOT_FOUND' | 'ENGINE_TXN_IN_PROGRESS';
1594
+ reason: 'missing' | 'not-project' | 'damaged' | 'not_registered' | 'unreadable' | 'busy';
1543
1595
  hint: string;
1544
1596
  }
1545
1597
  interface PanelBundle {
@@ -1694,6 +1746,16 @@ interface BriefInput {
1694
1746
  chapter?: number;
1695
1747
  root?: string;
1696
1748
  }
1749
+ type BriefPayload = {
1750
+ stage: BriefStage;
1751
+ chapter: number;
1752
+ digest: string;
1753
+ title: string;
1754
+ content: string;
1755
+ content_hash: string;
1756
+ fields: Record<string, unknown>;
1757
+ context: Record<string, unknown>;
1758
+ };
1697
1759
  interface WorldPlanSubmission extends WorldPlanInput {
1698
1760
  root?: string;
1699
1761
  }
@@ -1971,6 +2033,13 @@ declare class EngineService {
1971
2033
  * the model only learns about the mismatch when that write aborts.
1972
2034
  */
1973
2035
  private journalBlocking;
2036
+ /**
2037
+ * Count review attempts per archived chapter. The journal is authoritative;
2038
+ * history fills any per-chapter gap where it has more distinct historical
2039
+ * reviews than committed journal rows (legacy or a truncated upgrade). A
2040
+ * chapter can never report fewer attempts than readable current reviews.
2041
+ */
2042
+ private reviewAttemptsByChapter;
1974
2043
  /**
1975
2044
  * Count every committed attempt for one chapter, not just the loop since the
1976
2045
  * last rollback. `pipeline.rounds` is deliberately reset by rollback to keep
@@ -1998,20 +2067,18 @@ declare class EngineService {
1998
2067
  state_errors: StateError[];
1999
2068
  }>>;
2000
2069
  search(input: SearchInput): Promise<OpResult<SearchReport>>;
2070
+ /**
2071
+ * Read-only upgrade audit. It never edits a legacy document: the point is to
2072
+ * explain why an old project's numbers look different, not to rewrite history.
2073
+ */
2074
+ private legacyIssues;
2001
2075
  doctor(input?: DoctorInput): Promise<OpResult<DoctorReport>>;
2002
2076
  private recoveryForSafe;
2003
2077
  report(input?: ReportSubmission): Promise<OpResult<BookReport>>;
2004
2078
  guide(input?: GuideInput): Promise<OpResult<GuideReport>>;
2005
- getBrief(input: BriefInput): Promise<OpResult<{
2006
- stage: string;
2007
- chapter: number;
2008
- digest: string;
2009
- title: string;
2010
- content: string;
2011
- content_hash: string;
2012
- fields: Record<string, unknown>;
2013
- context: Record<string, unknown>;
2014
- }>>;
2079
+ getBrief(input: BriefInput): Promise<OpResult<BriefPayload>>;
2080
+ private assertBriefChapter;
2081
+ private briefPayload;
2015
2082
  submitWorldPlan(input: WorldPlanSubmission): Promise<OpResult<{
2016
2083
  chapter: number;
2017
2084
  stage: Stage;
@@ -2120,6 +2187,7 @@ declare class EngineService {
2120
2187
  active: string | null;
2121
2188
  projects: Array<RegistryEntry & {
2122
2189
  state: ProjectState;
2190
+ identity_changed?: boolean;
2123
2191
  }>;
2124
2192
  }>;
2125
2193
  /**
@@ -2147,6 +2215,22 @@ declare class EngineService {
2147
2215
  active: string | null;
2148
2216
  projects: RegistryEntry[];
2149
2217
  }>;
2218
+ /**
2219
+ * Remove only registry rows whose directories are missing, not a project, or
2220
+ * unreadable. The default is a dry run; project files and session bindings are
2221
+ * never touched, and `--yes` is required at the command layer.
2222
+ */
2223
+ pruneProjects(input?: {
2224
+ apply?: boolean;
2225
+ }): Promise<{
2226
+ candidates: Array<{
2227
+ root: string;
2228
+ title: string;
2229
+ state: ProjectState;
2230
+ }>;
2231
+ removed: string[];
2232
+ active: string | null;
2233
+ }>;
2150
2234
  /**
2151
2235
  * Bounded workspace scan. Normal mode is read-only; `register` updates only
2152
2236
  * healthy, newly discovered rows, never active or session bindings.
@@ -2246,10 +2330,10 @@ declare class EngineService {
2246
2330
  private bookStatus;
2247
2331
  private panelSnapshot;
2248
2332
  /**
2249
- * The archive stage has only one legal operation, so a status/panel that
2250
- * recommends it without checking the same gates as the archive creates a
2251
- * loop. Evaluate the real archive gates through `gateInput`, then add the
2252
- * machine pass and semantic evidence that archive re-checks separately.
2333
+ * The archive stage can be left by a direct revision (the 0.2.3 workflow) or
2334
+ * by rollback. Evaluate the same gates as archive so status/panel do not
2335
+ * recommend an operation that will immediately fail; when the failure is
2336
+ * prose-level, `nextStep` recommends the direct P5 revision instead.
2253
2337
  */
2254
2338
  private archivePreflight;
2255
2339
  private nextStep;
@@ -2275,6 +2359,7 @@ declare class EngineService {
2275
2359
  private stateGateBlock;
2276
2360
  /** Whether the stored brief still signs the current snapshot. */
2277
2361
  private readBriefReceipts;
2362
+ private assertBriefReceiptsWritable;
2278
2363
  private briefIsCurrent;
2279
2364
  /** Arguments valid for the tool `STAGE_NEXT` recommends at this stage. */
2280
2365
  private nextArgs;
@@ -2329,7 +2414,7 @@ declare const PLUGIN_NAME = "dsh-novel-write-engine";
2329
2414
  declare const PANEL_ID = "novel-workshop";
2330
2415
  declare const PANEL_ROUTE = "/api/novel-write-engine/panel";
2331
2416
  declare const SKILL_NAME = "novel-write-engine";
2332
- declare const REMOTE_VERSION = 4;
2417
+ declare const REMOTE_VERSION = 5;
2333
2418
  /** The panel is a recent-history view; the wire payload and UI use one cap. */
2334
2419
  declare const PANEL_CHAPTER_LIMIT = 30;
2335
2420
  /** Project-relative locations. Every write goes through these constants. */